diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 000000000000..201f851370eb --- /dev/null +++ b/.bazelignore @@ -0,0 +1,3 @@ +# These are fetched as external repositories. +third_party/benchmark +third_party/googletest diff --git a/.github/mergeable.yml b/.github/mergeable.yml index 34e06abb7d22..8577f086ee21 100644 --- a/.github/mergeable.yml +++ b/.github/mergeable.yml @@ -11,8 +11,8 @@ mergeable: regex: 'release notes: yes' message: 'Please include release notes: yes' - must_include: - regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby)' - message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: cleanup, conformance tests, integration.' + regex: '^(c#|c\+\+|cleanup|conformance tests|integration|java|javascript|go|objective-c|php|python|ruby|bazel|cmake|protoc)' + message: 'Please include at least a language label (e.g., c++, java, python). Or apply one of the following labels: bazel, cmake, cleanup, conformance tests, integration, protoc.' - must_include: regex: 'release notes: no' message: 'Please include release notes: no' diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 000000000000..f9795e190c7e --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,16 @@ +# GitHub Action to automate the identification of common misspellings in text files. +# https://github.com/codespell-project/actions-codespell +# https://github.com/codespell-project/codespell +name: codespell +on: [push, pull_request] +jobs: + codespell: + name: Check for spelling errors + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: codespell-project/actions-codespell@master + with: + check_filenames: true + skip: ./.git,./conformance/third_party,*.snk,*.pb,*.pb.cc,*.pb.h,./src/google/protobuf/testdata,./objectivec/Tests,./python/compatibility_tests/v2.5.0/tests/google/protobuf/internal + ignore_words_list: "alow,alse,ba,cleare,copyable,cloneable,dedup,dur,errorprone,files',fo,fundementals,hel,importd,inout,leapyear,nd,ois,ons,parseable,process',te,testof,ue,unparseable,wasn,wee,gae,keyserver,objext,od" diff --git a/.gitignore b/.gitignore index 5e38bbf7c283..e06aedea6bd8 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ python/**/*.egg python/.eggs/ python/.tox python/build/ +python/docs/_build/ src/js_embed src/protoc @@ -103,7 +104,7 @@ build_msvc # needed to trigger "pod install" to rerun the preinstall commands. Pods/ -# Comformance test output +# Conformance test output conformance/.libs/ conformance/com/ conformance/conformance-cpp @@ -136,19 +137,24 @@ conformance/*.class # php test output composer.lock +php/tests/.phpunit.result.cache php/tests/generated/ php/tests/old_protoc +php/tests/phpunit-9.phar php/tests/protobuf/ php/tests/core php/tests/vgcore* php/tests/multirequest.result php/tests/nohup.out +php/tests/.phpunit.result.cache +php/tests/phpunit-* php/ext/google/protobuf/.libs/ php/ext/google/protobuf/Makefile.fragments php/ext/google/protobuf/Makefile.global php/ext/google/protobuf/Makefile.objects php/ext/google/protobuf/acinclude.m4 php/ext/google/protobuf/build/ +php/ext/google/protobuf/bundled_php.c php/ext/google/protobuf/config.h php/ext/google/protobuf/config.h.in~ php/ext/google/protobuf/config.nice @@ -208,3 +214,6 @@ cmake/cmake-build-debug/ # IntelliJ .idea *.iml + +# BenchmarkDotNet +BenchmarkDotNet.Artifacts/ diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 000000000000..88f4c100f36a --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,22 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +sphinx: + configuration: python/docs/conf.py + fail_on_warning: false + +# Setup build requirements for docs. +# Use conda so that we can install the latest libprotobuf package without +# having to build from scratch just for docs builds. +conda: + environment: python/docs/environment.yml + +python: + version: 3.7 + install: + - method: setuptools + path: python diff --git a/BUILD b/BUILD index 79871d621c94..1124321602b5 100644 --- a/BUILD +++ b/BUILD @@ -1,9 +1,8 @@ # Bazel (https://bazel.build/) BUILD file for Protobuf. +load("@bazel_skylib//rules:common_settings.bzl", "string_flag") load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test", "objc_library", native_cc_proto_library = "cc_proto_library") -load("@rules_java//java:defs.bzl", "java_library") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") -load("@rules_proto//proto/private:native.bzl", "native_proto_common") load("@rules_python//python:defs.bzl", "py_library") load(":cc_proto_blacklist_test.bzl", "cc_proto_blacklist_test") @@ -12,16 +11,41 @@ licenses(["notice"]) exports_files(["LICENSE"]) ################################################################################ -# Java 9 configuration +# build configuration ################################################################################ +# TODO(yannic): Remove in 3.14.0. +string_flag( + name = "incompatible_use_com_google_googletest", + build_setting_default = "true", + values = ["true", "false"] +) + config_setting( - name = "jdk9", - values = { - "java_toolchain": "@bazel_tools//tools/jdk:toolchain_jdk9", + name = "use_com_google_googletest", + flag_values = { + "//:incompatible_use_com_google_googletest": "true" }, ) +GTEST = select({ + "//:use_com_google_googletest": [ + "@com_google_googletest//:gtest", + ], + "//conditions:default": [ + "//external:gtest", + ], +}) + +GTEST_MAIN = select({ + "//:use_com_google_googletest": [ + "@com_google_googletest//:gtest_main", + ], + "//conditions:default": [ + "//external:gtest_main", + ], +}) + ################################################################################ # ZLIB configuration ################################################################################ @@ -70,6 +94,10 @@ load(":compiler_config_setting.bzl", "create_compiler_config_setting") create_compiler_config_setting( name = "msvc", value = "msvc-cl", + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], ) config_setting( @@ -77,6 +105,10 @@ config_setting( values = { "crosstool_top": "//external:android/crosstool", }, + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], ) config_setting( @@ -84,6 +116,10 @@ config_setting( values = { "crosstool_top": "@androidndk//:toolchain-libcpp", }, + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], ) config_setting( @@ -91,6 +127,10 @@ config_setting( values = { "crosstool_top": "@androidndk//:toolchain-gnu-libstdcpp", }, + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], ) # Android and MSVC builds do not need to link in a separate pthread library. @@ -110,6 +150,7 @@ LINK_OPTS = select({ load( ":protobuf.bzl", + "adapt_proto_library", "cc_proto_library", "internal_copied_filegroup", "internal_gen_well_known_protos_java", @@ -123,6 +164,7 @@ cc_library( # AUTOGEN(protobuf_lite_srcs) "src/google/protobuf/any_lite.cc", "src/google/protobuf/arena.cc", + "src/google/protobuf/arenastring.cc", "src/google/protobuf/extension_set.cc", "src/google/protobuf/generated_enum_util.cc", "src/google/protobuf/generated_message_table_driven_lite.cc", @@ -134,6 +176,7 @@ cc_library( "src/google/protobuf/io/zero_copy_stream.cc", "src/google/protobuf/io/zero_copy_stream_impl.cc", "src/google/protobuf/io/zero_copy_stream_impl_lite.cc", + "src/google/protobuf/map.cc", "src/google/protobuf/message_lite.cc", "src/google/protobuf/parse_context.cc", "src/google/protobuf/repeated_field.cc", @@ -286,13 +329,15 @@ filegroup( visibility = ["//visibility:public"], ) -cc_proto_library( +adapt_proto_library( + name = "cc_wkt_protos_genproto", + deps = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], + visibility = ["//visibility:public"], +) + +cc_library( name = "cc_wkt_protos", - srcs = WELL_KNOWN_PROTOS, - include = "src", - default_runtime = ":protobuf", - internal_bootstrap_hack = 1, - protoc = ":protoc", + deprecation = "Only for backward compatibility. Do not use.", visibility = ["//visibility:public"], ) @@ -324,7 +369,15 @@ cc_proto_library( cc_proto_blacklist_test( name = "cc_proto_blacklist_test", - deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()] + deps = [proto + "_cc_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], + tags = [ + # Exclude this target from wildcard expansion (//...). Due to + # https://github.com/bazelbuild/bazel/issues/10590, this test has to + # be nominated using the `@com_google_protobuf//` prefix. We do that, + # e.g., in kokoro/linux/bazel/build.sh. + # See also https://github.com/protocolbuffers/protobuf/pull/7096. + "manual", + ], ) ################################################################################ @@ -442,7 +495,6 @@ RELATIVE_LITE_TEST_PROTOS = [ "google/protobuf/unittest_import_lite.proto", "google/protobuf/unittest_import_public_lite.proto", "google/protobuf/unittest_lite.proto", - "google/protobuf/unittest_no_arena_lite.proto", ] LITE_TEST_PROTOS = ["src/" + s for s in RELATIVE_LITE_TEST_PROTOS] @@ -469,8 +521,6 @@ RELATIVE_TEST_PROTOS = [ "google/protobuf/unittest_lite_imports_nonlite.proto", "google/protobuf/unittest_mset.proto", "google/protobuf/unittest_mset_wire_format.proto", - "google/protobuf/unittest_no_arena.proto", - "google/protobuf/unittest_no_arena_import.proto", "google/protobuf/unittest_no_field_presence.proto", "google/protobuf/unittest_no_generic_services.proto", "google/protobuf/unittest_optimize_for.proto", @@ -480,6 +530,7 @@ RELATIVE_TEST_PROTOS = [ "google/protobuf/unittest_proto3_arena.proto", "google/protobuf/unittest_proto3_arena_lite.proto", "google/protobuf/unittest_proto3_lite.proto", + "google/protobuf/unittest_proto3_optional.proto", "google/protobuf/unittest_well_known_types.proto", "google/protobuf/util/internal/testdata/anys.proto", "google/protobuf/util/internal/testdata/books.proto", @@ -529,8 +580,7 @@ cc_binary( deps = [ ":protobuf", ":protoc_lib", - "//external:gtest", - ], + ] + GTEST, ) cc_test( @@ -542,8 +592,7 @@ cc_test( ], deps = [ ":protobuf_lite", - "//external:gtest_main", - ], + ] + GTEST_MAIN, ) cc_test( @@ -646,151 +695,49 @@ cc_test( ":cc_test_protos", ":protobuf", ":protoc_lib", - "//external:gtest_main", - ] + PROTOBUF_DEPS, + ] + PROTOBUF_DEPS + GTEST_MAIN, ) ################################################################################ # Java support ################################################################################ + internal_gen_well_known_protos_java( - srcs = WELL_KNOWN_PROTOS, + name = "gen_well_known_protos_java", + deps = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], + visibility = [ + "//java:__subpackages__", + ], ) -java_library( +alias( name = "protobuf_java", - srcs = glob([ - "java/core/src/main/java/com/google/protobuf/*.java", - ]) + [ - ":gen_well_known_protos_java", - ], - javacopts = select({ - "//:jdk9": ["--add-modules=jdk.unsupported"], - "//conditions:default": [ - "-source 7", - "-target 7", - ], - }), + actual = "//java/core", visibility = ["//visibility:public"], ) -java_library( +alias( name = "protobuf_javalite", - srcs = [ - # Keep in sync with java/lite/pom.xml - "java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java", - "java/core/src/main/java/com/google/protobuf/AbstractParser.java", - "java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java", - "java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java", - "java/core/src/main/java/com/google/protobuf/Android.java", - "java/core/src/main/java/com/google/protobuf/ArrayDecoders.java", - "java/core/src/main/java/com/google/protobuf/BinaryReader.java", - "java/core/src/main/java/com/google/protobuf/BinaryWriter.java", - "java/core/src/main/java/com/google/protobuf/BooleanArrayList.java", - "java/core/src/main/java/com/google/protobuf/BufferAllocator.java", - "java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java", - "java/core/src/main/java/com/google/protobuf/ByteOutput.java", - "java/core/src/main/java/com/google/protobuf/ByteString.java", - "java/core/src/main/java/com/google/protobuf/CodedInputStream.java", - "java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java", - "java/core/src/main/java/com/google/protobuf/CodedOutputStream.java", - "java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java", - "java/core/src/main/java/com/google/protobuf/DoubleArrayList.java", - "java/core/src/main/java/com/google/protobuf/ExperimentalApi.java", - "java/core/src/main/java/com/google/protobuf/ExtensionLite.java", - "java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java", - "java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java", - "java/core/src/main/java/com/google/protobuf/ExtensionSchema.java", - "java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java", - "java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java", - "java/core/src/main/java/com/google/protobuf/FieldInfo.java", - "java/core/src/main/java/com/google/protobuf/FieldSet.java", - "java/core/src/main/java/com/google/protobuf/FieldType.java", - "java/core/src/main/java/com/google/protobuf/FloatArrayList.java", - "java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java", - "java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java", - "java/core/src/main/java/com/google/protobuf/IntArrayList.java", - "java/core/src/main/java/com/google/protobuf/Internal.java", - "java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java", - "java/core/src/main/java/com/google/protobuf/IterableByteBufferInputStream.java", - "java/core/src/main/java/com/google/protobuf/JavaType.java", - "java/core/src/main/java/com/google/protobuf/LazyField.java", - "java/core/src/main/java/com/google/protobuf/LazyFieldLite.java", - "java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java", - "java/core/src/main/java/com/google/protobuf/LazyStringList.java", - "java/core/src/main/java/com/google/protobuf/ListFieldSchema.java", - "java/core/src/main/java/com/google/protobuf/LongArrayList.java", - "java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java", - "java/core/src/main/java/com/google/protobuf/MapEntryLite.java", - "java/core/src/main/java/com/google/protobuf/MapFieldLite.java", - "java/core/src/main/java/com/google/protobuf/MapFieldSchema.java", - "java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java", - "java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java", - "java/core/src/main/java/com/google/protobuf/MessageInfo.java", - "java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java", - "java/core/src/main/java/com/google/protobuf/MessageLite.java", - "java/core/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java", - "java/core/src/main/java/com/google/protobuf/MessageLiteToString.java", - "java/core/src/main/java/com/google/protobuf/MessageSchema.java", - "java/core/src/main/java/com/google/protobuf/MessageSetSchema.java", - "java/core/src/main/java/com/google/protobuf/MutabilityOracle.java", - "java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java", - "java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java", - "java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java", - "java/core/src/main/java/com/google/protobuf/NioByteString.java", - "java/core/src/main/java/com/google/protobuf/OneofInfo.java", - "java/core/src/main/java/com/google/protobuf/Parser.java", - "java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java", - "java/core/src/main/java/com/google/protobuf/ProtoSyntax.java", - "java/core/src/main/java/com/google/protobuf/Protobuf.java", - "java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java", - "java/core/src/main/java/com/google/protobuf/ProtobufLists.java", - "java/core/src/main/java/com/google/protobuf/ProtocolStringList.java", - "java/core/src/main/java/com/google/protobuf/RawMessageInfo.java", - "java/core/src/main/java/com/google/protobuf/Reader.java", - "java/core/src/main/java/com/google/protobuf/RopeByteString.java", - "java/core/src/main/java/com/google/protobuf/Schema.java", - "java/core/src/main/java/com/google/protobuf/SchemaFactory.java", - "java/core/src/main/java/com/google/protobuf/SchemaUtil.java", - "java/core/src/main/java/com/google/protobuf/SmallSortedMap.java", - "java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java", - "java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java", - "java/core/src/main/java/com/google/protobuf/UninitializedMessageException.java", - "java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java", - "java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java", - "java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java", - "java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java", - "java/core/src/main/java/com/google/protobuf/UnsafeUtil.java", - "java/core/src/main/java/com/google/protobuf/Utf8.java", - "java/core/src/main/java/com/google/protobuf/WireFormat.java", - "java/core/src/main/java/com/google/protobuf/Writer.java", - ], - javacopts = select({ - "//:jdk9": ["--add-modules=jdk.unsupported"], - "//conditions:default": [ - "-source 7", - "-target 7", - ], - }), + actual = "//java/lite", visibility = ["//visibility:public"], ) -java_library( +alias( name = "protobuf_java_util", - srcs = glob([ - "java/util/src/main/java/com/google/protobuf/util/*.java", - ]), - javacopts = [ - "-source 7", - "-target 7", - ], + actual = "//java/util", + visibility = ["//visibility:public"], +) + +alias( + name = "java_toolchain", + actual = "//java/core:toolchain", + visibility = ["//visibility:public"], +) + +alias( + name = "javalite_toolchain", + actual = "//java/lite:toolchain", visibility = ["//visibility:public"], - deps = [ - "protobuf_java", - "//external:error_prone_annotations", - "//external:gson", - "//external:guava", - ], ) ################################################################################ @@ -801,10 +748,9 @@ py_library( name = "python_srcs", srcs = glob( [ - "python/google/**/*.py", + "python/google/protobuf/**/*.py", ], exclude = [ - "python/google/protobuf/**/__init__.py", "python/google/protobuf/internal/*_test.py", "python/google/protobuf/internal/test_util.py", ], @@ -819,6 +765,13 @@ cc_binary( copts = COPTS + [ "-DPYTHON_PROTO2_CPP_IMPL_V2", ], + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], linkshared = 1, linkstatic = 1, deps = select({ @@ -843,6 +796,13 @@ cc_binary( "python/", "src/", ], + tags = [ + # Exclude this target from wildcard expansion (//...) because it may + # not even be buildable. It will be built if it is needed according + # to :use_fast_cpp_protos. + # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes + "manual", + ], linkshared = 1, linkstatic = 1, deps = [ @@ -859,6 +819,10 @@ config_setting( values = { "define": "use_fast_cpp_protos=true", }, + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], ) config_setting( @@ -866,6 +830,10 @@ config_setting( values = { "define": "allow_oversize_protos=true", }, + visibility = [ + # Public, but Protobuf only visibility. + "//:__subpackages__", + ], ) # Copy the builtin proto files from src/google/protobuf to @@ -897,7 +865,6 @@ py_proto_library( }), default_runtime = "", protoc = ":protoc", - py_extra_srcs = glob(["python/**/__init__.py"]), py_libs = [ ":python_srcs", "@six//:six", @@ -999,114 +966,23 @@ cc_library( ], ) -# Note: We use `native_proto_common` here because we depend on an implementation-detail of -# `proto_lang_toolchain`, which may not be available on `proto_common`. -reject_blacklisted_files = hasattr(native_proto_common, "proto_lang_toolchain_rejects_files_do_not_use_or_we_will_break_you_without_mercy") -cc_toolchain_blacklisted_protos = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()] if reject_blacklisted_files else [":well_known_protos"] proto_lang_toolchain( name = "cc_toolchain", - blacklisted_protos = cc_toolchain_blacklisted_protos, + blacklisted_protos = [proto + "_proto" for proto in WELL_KNOWN_PROTO_MAP.keys()], command_line = "--cpp_out=$(OUT)", runtime = ":protobuf", visibility = ["//visibility:public"], ) -proto_lang_toolchain( - name = "java_toolchain", - command_line = "--java_out=$(OUT)", - runtime = ":protobuf_java", - visibility = ["//visibility:public"], -) - -proto_lang_toolchain( - name = "javalite_toolchain", - command_line = "--java_out=lite:$(OUT)", - runtime = ":protobuf_javalite", - visibility = ["//visibility:public"], -) - alias( name = "objectivec", - actual = ":protobuf_objc", + actual = "//objectivec", visibility = ["//visibility:public"], ) -objc_library( +alias( name = "protobuf_objc", - hdrs = [ - "objectivec/GPBArray.h", - "objectivec/GPBBootstrap.h", - "objectivec/GPBCodedInputStream.h", - "objectivec/GPBCodedOutputStream.h", - "objectivec/GPBDescriptor.h", - "objectivec/GPBDictionary.h", - "objectivec/GPBExtensionInternals.h", - "objectivec/GPBExtensionRegistry.h", - "objectivec/GPBMessage.h", - "objectivec/GPBProtocolBuffers.h", - "objectivec/GPBProtocolBuffers_RuntimeSupport.h", - "objectivec/GPBRootObject.h", - "objectivec/GPBRuntimeTypes.h", - "objectivec/GPBUnknownField.h", - "objectivec/GPBUnknownFieldSet.h", - "objectivec/GPBUtilities.h", - "objectivec/GPBWellKnownTypes.h", - "objectivec/GPBWireFormat.h", - "objectivec/google/protobuf/Any.pbobjc.h", - "objectivec/google/protobuf/Api.pbobjc.h", - "objectivec/google/protobuf/Duration.pbobjc.h", - "objectivec/google/protobuf/Empty.pbobjc.h", - "objectivec/google/protobuf/FieldMask.pbobjc.h", - "objectivec/google/protobuf/SourceContext.pbobjc.h", - "objectivec/google/protobuf/Struct.pbobjc.h", - "objectivec/google/protobuf/Timestamp.pbobjc.h", - "objectivec/google/protobuf/Type.pbobjc.h", - "objectivec/google/protobuf/Wrappers.pbobjc.h", - # Package private headers, but exposed because the generated sources - # need to use them. - "objectivec/GPBArray_PackagePrivate.h", - "objectivec/GPBCodedInputStream_PackagePrivate.h", - "objectivec/GPBCodedOutputStream_PackagePrivate.h", - "objectivec/GPBDescriptor_PackagePrivate.h", - "objectivec/GPBDictionary_PackagePrivate.h", - "objectivec/GPBMessage_PackagePrivate.h", - "objectivec/GPBRootObject_PackagePrivate.h", - "objectivec/GPBUnknownFieldSet_PackagePrivate.h", - "objectivec/GPBUnknownField_PackagePrivate.h", - "objectivec/GPBUtilities_PackagePrivate.h", - ], - copts = [ - "-Wno-vla", - ], - includes = [ - "objectivec", - ], - non_arc_srcs = [ - "objectivec/GPBArray.m", - "objectivec/GPBCodedInputStream.m", - "objectivec/GPBCodedOutputStream.m", - "objectivec/GPBDescriptor.m", - "objectivec/GPBDictionary.m", - "objectivec/GPBExtensionInternals.m", - "objectivec/GPBExtensionRegistry.m", - "objectivec/GPBMessage.m", - "objectivec/GPBRootObject.m", - "objectivec/GPBUnknownField.m", - "objectivec/GPBUnknownFieldSet.m", - "objectivec/GPBUtilities.m", - "objectivec/GPBWellKnownTypes.m", - "objectivec/GPBWireFormat.m", - "objectivec/google/protobuf/Any.pbobjc.m", - "objectivec/google/protobuf/Api.pbobjc.m", - "objectivec/google/protobuf/Duration.pbobjc.m", - "objectivec/google/protobuf/Empty.pbobjc.m", - "objectivec/google/protobuf/FieldMask.pbobjc.m", - "objectivec/google/protobuf/SourceContext.pbobjc.m", - "objectivec/google/protobuf/Struct.pbobjc.m", - "objectivec/google/protobuf/Timestamp.pbobjc.m", - "objectivec/google/protobuf/Type.pbobjc.m", - "objectivec/google/protobuf/Wrappers.pbobjc.m", - ], + actual = "//objectivec", visibility = ["//visibility:public"], ) diff --git a/CHANGES.txt b/CHANGES.txt index 48bd7affd775..b55e275deb25 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,320 @@ +Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * MessageDifferencer: fixed bug when using custom ignore with multiple + unknown fields + * Use init_seg in MSVC to push initialization to an earlier phase. + * Runtime no longer triggers -Wsign-compare warnings. + * Fixed -Wtautological-constant-out-of-range-compare warning. + * DynamicCastToGenerated works for nullptr input for even if RTTI is disabled + * Arena is refactored and optimized. + * Clarified/specified that the exact value of Arena::SpaceAllocated() is an + implementation detail users must not rely on. It should not be used in + unit tests. + * Change the signature of Any::PackFrom() to return false on error. + + Java + * Avoid possible UnsupportedOperationException when using CodedInputSteam + with a direct ByteBuffer. + * Make Durations.comparator() and Timestamps.comparator() Serializable. + * Add more detailed error information for dynamic message field type + validation failure + + Python + * Provided an override for the reverse() method that will reverse the internal + collection directly instead of using the other methods of the BaseContainer. + +2020-11-11 version 3.14.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Protocol Compiler + * The proto compiler no longer requires a .proto filename when it is not + generating code. + * Added flag `--deterministic_output` to `protoc --encode=...`. + * Fixed deadlock when using google.protobuf.Any embedded in aggregate options. + + C++ + * Arenas are now unconditionally enabled. cc_enable_arenas no longer has + any effect. + * Removed inlined string support, which is incompatible with arenas. + * Fix a memory corruption bug in reflection when mixing optional and + non-optional fields. + * Make SpaceUsed() calculation more thorough for map fields. + * Add stack overflow protection for text format with unknown field values. + * FieldPath::FollowAll() now returns a bool to signal if an out-of-bounds + error was encountered. + * Performance improvements for Map. + * Minor formatting fix when dumping a descriptor to .proto format with + DebugString. + * UBSAN fix in RepeatedField (#2073). + * When running under ASAN, skip a test that makes huge allocations. + * Fixed a crash that could happen when creating more than 256 extensions in + a single message. + * Fix a crash in BuildFile when passing in invalid descriptor proto. + * Parser security fix when operating with CodedInputStream. + * Warn against the use of AllowUnknownExtension. + * Migrated to C++11 for-range loops instead of index-based loops where + possible. This fixes a lot of warnings when compiling with -Wsign-compare. + * Fix segment fault for proto3 optional (#7805) + * Adds a CMake option to build `libprotoc` separately (#7949) + + Java + * Bugfix in mergeFrom() when a oneof has multiple message fields. + * Fix RopeByteString.RopeInputStream.read() returning -1 when told to read + 0 bytes when not at EOF. + * Redefine remove(Object) on primitive repeated field Lists to avoid + autoboxing. + * Support "\u" escapes in textformat string literals. + * Trailing empty spaces are no longer ignored for FieldMask. + * Fix FieldMaskUtil.subtract to recursively remove mask. + * Mark enums with `@java.lang.Deprecated` if the proto enum has option + `deprecated = true;`. + * Adding forgotten duration.proto to the lite library (#7738) + + Python + * Print google.protobuf.NullValue as null instead of "NULL_VALUE" when it is + used outside WKT Value/Struct. + * Fix bug occurring when attempting to deep copy an enum type in python 3. + * Add a setuptools extension for generating Python protobufs (#7783) + * Remove uses of pkg_resources in non-namespace packages. (#7902) + * [bazel/py] Omit google/__init__.py from the Protobuf runtime. (#7908) + * Removed the unnecessary setuptools package dependency for Python package (#7511) + * Fix PyUnknownFields memory leak (#7928) + + PHP + * Added support for "==" to the PHP C extension (#7883) + * Added `==` operators for Map and Array. (#7900) + * Native C well-known types (#7944) + * Optimized away hex2bin() call in generated code (#8006) + * New version of upb, and a new hash function wyhash in third_party. (#8000) + * add missing hasOneof method to check presence of oneof fields (#8003) + + Go: + * Update go_package options to reference google.golang.org/protobuf module. + + C#: + * annotate ByteString.CopyFrom(ReadOnlySpan) as SecuritySafeCritical (#7701) + * Fix C# optional field reflection when there are regular fields too (#7705) + * Fix parsing negative Int32Value that crosses segment boundary (#8035) + + Javascript: + * JS: parse (un)packed fields conditionally (#7379) + +2020-07-14 version 3.13.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + PHP: + * The C extension is completely rewritten. The new C extension has significantly + better parsing performance and fixes a handful of conformance issues. It will + also make it easier to add support for more features like proto2 and proto3 presence. + * The new C extension does not support PHP 5.x. PHP 5.x users can still use pure-PHP. + + C++: + * Removed deprecated unsafe arena string accessors + * Enabled heterogeneous lookup for std::string keys in maps. + * Removed implicit conversion from StringPiece to std::string + * Fix use-after-destroy bug when the Map is allocated in the arena. + * Improved the randomness of map ordering + * Added stack overflow protection for text format with unknown fields + * Use std::hash for proto maps to help with portability. + * Added more Windows macros to proto whitelist. + * Arena constructors for map entry messages are now marked "explicit" + (for regular messages they were already explicit). + * Fix subtle aliasing bug in RepeatedField::Add + * Fix mismatch between MapEntry ByteSize and Serialize with respect to unset + fields. + + Python: + * JSON format conformance fixes: + * Reject lowercase t for Timestamp json format. + * Print full_name directly for extensions (no camelCase). + * Reject boolean values for integer fields. + * Reject NaN, Infinity, -Infinity that is not quoted. + * Base64 fixes for bytes fields: accept URL-safe base64 and missing padding. + * Bugfix for fields/files named "async" or "await". + * Improved the error message when AttributeError is returned from __getattr__ + in EnumTypeWrapper. + + Java: + * Fixed a bug where setting optional proto3 enums with setFooValue() would + not mark the value as present. + * Add Subtract function to FieldMaskUtil. + + C#: + * Dropped support for netstandard1.0 (replaced by support for netstandard1.1). + This was required to modernize the parsing stack to use the `Span` + type internally. (#7351) + * Add `ParseFrom(ReadOnlySequence)` method to enable GC friendly + parsing with reduced allocations and buffer copies. (#7351) + * Add support for serialization directly to a `IBufferWriter` or + to a `Span` to enable GC friendly serialization. + The new API is available as extension methods on the `IMessage` type. (#7576) + * Add `GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE` define to make + generated code compatible with old C# compilers (pre-roslyn compilers + from .NET framework and old versions of mono) that do not support + ref structs. Users that are still on a legacy stack that does + not support C# 7.2 compiler might need to use the new define + in their projects to be able to build the newly generated code. (#7490) + * Due to the major overhaul of parsing and serialization internals (#7351 and #7576), + it is recommended to regenerate your generated code to achieve the best + performance (the legacy generated code will still work, but might incur + a slight performance penalty). + +2020-07-28 version 3.12.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + +This release contains no significant changes, but exists because 3.12.3 was +mistakenly tagged at the wrong commit. + +2020-06-01 version 3.12.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Objective-C + * Tweak the union used for Extensions to support old generated code. #7573 + +2020-05-26 version 3.12.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Simplified the template export macros to fix the build for mingw32. (#7539) + + Objective-C + * Fix for the :protobuf_objc target in the Bazel BUILD file. (#7538) + +2020-05-20 version 3.12.1 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Ruby + * Re-add binary gems for Ruby 2.3 and 2.4. These are EOL upstream, however + many people still use them and dropping support will require more + coordination. + +2020-05-12 version 3.12.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + Protocol Compiler + * [experimental] Singular, non-message typed fields in proto3 now support + presence tracking. This is enabled by adding the "optional" field label and + passing the --experimental_allow_proto3_optional flag to protoc. + * For usage info, see docs/field_presence.md. + * During this experimental phase, code generators should update to support + proto3 presence, see docs/implementing_proto3_presence.md for instructions. + * Allow duplicate symbol names when multiple descriptor sets are passed on + the command-line, to match the behavior when multiple .proto files are passed. + * Deterministic `protoc --descriptor_set_out` (#7175) + + C++ + * [experimental] Added proto3 presence support. + * New descriptor APIs to support proto3 presence. + * Enable Arenas by default on all .proto files. + * Documented that users are not allowed to subclass Message or MessageLite. + * Mark generated classes as final; inheriting from protos is strongly discouraged. + * Add stack overflow protection for text format with unknown fields. + * Add accessors for map key and value FieldDescriptors. + * Add FieldMaskUtil::FromFieldNumbers(). + * MessageDifferencer: use ParsePartial() on Any fields so the diff does not + fail when there are missing required fields. + * ReflectionOps::Merge(): lookup messages in the right factory, if it can. + * Added Descriptor::WellKnownTypes enum and Descriptor::well_known_type() + accessor as an easier way of determining if a message is a Well-Known Type. + * Optimized RepeatedField::Add() when it is used in a loop. + * Made proto move/swap more efficient. + * De-virtualize the GetArena() method in MessageLite. + * Improves performance of json_stream_parser.cc by factor 1000 (#7230) + * bug: #7076 undefine Windows OUT and OPTIONAL macros (#7087) + * Fixed a bug in FieldDescriptor::DebugString() that would erroneously print + an "optional" label for a field in a oneof. + * Fix bug in parsing bool extensions that assumed they are always 1 byte. + * Fix off-by-one error in FieldOptions::ByteSize() when extensions are present. + * Clarified the comments to show an example of the difference between + Descriptor::extension and DescriptorPool::FindAllExtensions. + * Add a compiler option 'code_size' to force optimize_for=code_size on all + protos where this is possible. + + Java + * [experimental] Added proto3 presence support. + * Mark java enum _VALUE constants as @Deprecated if the enum field is deprecated + * reduce size for enums with allow_alias set to true. + * Sort map fields alphabetically by the field's key when printing textproto. + * Fixed a bug in map sorting that appeared in -rc1 and -rc2 (#7508). + * TextFormat.merge() handles Any as top level type. + * Throw a descriptive IllegalArgumentException when calling + getValueDescriptor() on enum special value UNRECOGNIZED instead of + ArrayIndexOutOfBoundsException. + * Fixed an issue with JsonFormat.printer() where setting printingEnumsAsInts() + would override the configuration passed into includingDefaultValueFields(). + * Implement overrides of indexOf() and contains() on primitive lists returned + for repeated fields to avoid autoboxing the list contents. + * Add overload to FieldMaskUtil.fromStringList that accepts a descriptor. + * [bazel] Move Java runtime/toolchains into //java (#7190) + + Python + * [experimental] Added proto3 presence support. + * [experimental] fast import protobuf module, only works with cpp generated code linked in. + * Truncate 'float' fields to 4 bytes of precision in setters for pure-Python + implementation (C++ extension was already doing this). + * Fixed a memory leak in C++ bindings. + * Added a deprecation warning when code tries to create Descriptor objects + directly. + * Fix unintended comparison between bytes and string in descriptor.py. + * Avoid printing excess digits for float fields in TextFormat. + * Remove Python 2.5 syntax compatibility from the proto compiler generated _pb2.py module code. + * Drop 3.3, 3.4 and use single version docker images for all python tests (#7396) + + JavaScript + * Fix js message pivot selection (#6813) + + PHP + * Persistent Descriptor Pool (#6899) + * Implement lazy loading of php class for proto messages (#6911) + * Correct @return in Any.unpack docblock (#7089) + * Ignore unknown enum value when ignore_unknown specified (#7455) + + Ruby + * [experimental] Implemented proto3 presence for Ruby. (#7406) + * Stop building binary gems for ruby <2.5 (#7453) + * Fix for wrappers with a zero value (#7195) + * Fix for JSON serialization of 0/empty-valued wrapper types (#7198) + * Call "Class#new" over rb_class_new_instance in decoding (#7352) + * Build extensions for Ruby 2.7 (#7027) + * assigning 'nil' to submessage should clear the field. (#7397) + + C# + * [experimental] Add support for proto3 presence fields in C# (#7382) + * Mark GetOption API as obsolete and expose the "GetOptions()" method on descriptors instead (#7491) + * Remove Has/Clear members for C# message fields in proto2 (#7429) + * Enforce recursion depth checking for unknown fields (#7132) + * Fix conformance test failures for Google.Protobuf (#6910) + * Cleanup various bits of Google.Protobuf (#6674) + * Fix latest ArgumentException for C# extensions (#6938) + * Remove unnecessary branch from ReadTag (#7289) + + Objective-C + * [experimental] ObjC Proto3 optional support (#7421) + * Block subclassing of generated classes (#7124) + * Use references to Obj C classes instead of names in descriptors. (#7026) + * Revisit how the WKTs are bundled with ObjC. (#7173) + + Other + * Add a proto_lang_toolchain for javalite (#6882) + * [bazel] Update gtest and deprecate //external:{gtest,gtest_main} (#7237) + * Add application note for explicit presence tracking. (#7390) + * Howto doc for implementing proto3 presence in a code generator. (#7407) + + +2020-02-14 version 3.11.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C# + * Fix latest ArgumentException for C# extensions (#7188) + * Enforce recursion depth checking for unknown fields (#7210) + + Ruby + * Fix wrappers with a zero value (#7195) + * Fix JSON serialization of 0/empty-valued wrapper types (#7198) + +2020-01-31 version 3.11.3 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + + C++ + * Add OUT and OPTIONAL to windows portability files (#7087) + + PHP + * Refactored ulong to zend_ulong for php7.4 compatibility (#7147) + * Call register_class before getClass from desc to fix segfault (#7077) + + 2019-12-10 version 3.11.2 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) PHP diff --git a/Makefile.am b/Makefile.am index f4cda529a669..4e0452af4c49 100644 --- a/Makefile.am +++ b/Makefile.am @@ -78,6 +78,7 @@ csharp_EXTRA_DIST= \ csharp/protos/unittest_import.proto \ csharp/protos/unittest_issues.proto \ csharp/protos/unittest_proto3.proto \ + csharp/protos/unittest_selfreferential_options.proto \ csharp/protos/unittest.proto \ csharp/src/AddressBook/AddPerson.cs \ csharp/src/AddressBook/Addressbook.cs \ @@ -85,20 +86,25 @@ csharp_EXTRA_DIST= \ csharp/src/AddressBook/ListPeople.cs \ csharp/src/AddressBook/Program.cs \ csharp/src/AddressBook/SampleUsage.cs \ + csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs \ csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs \ csharp/src/Google.Protobuf.Benchmarks/Benchmarks.cs \ + csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs \ csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj \ + csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs \ + csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs \ + csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs \ csharp/src/Google.Protobuf.Benchmarks/Program.cs \ - csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs \ - csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs \ csharp/src/Google.Protobuf.Benchmarks/wrapper_benchmark_messages.proto \ - csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmark.cs \ csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs \ + csharp/src/Google.Protobuf.Benchmarks/WriteMessagesBenchmark.cs \ + csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs \ csharp/src/Google.Protobuf.Conformance/Conformance.cs \ csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj \ csharp/src/Google.Protobuf.Conformance/Program.cs \ csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj \ csharp/src/Google.Protobuf.JsonDump/Program.cs \ + csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs \ csharp/src/Google.Protobuf.Test/ByteStringTest.cs \ csharp/src/Google.Protobuf.Test/CodedInputStreamExtensions.cs \ csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs \ @@ -121,6 +127,11 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs \ csharp/src/Google.Protobuf.Test/JsonParserTest.cs \ csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs \ + csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs \ + csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs \ + csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs \ + csharp/src/Google.Protobuf.Test/ReadOnlySequenceFactory.cs \ + csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs \ csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs \ csharp/src/Google.Protobuf.Test/Reflection/DescriptorDeclarationTest.cs \ csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs \ @@ -147,6 +158,8 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf.Test.TestProtos/UnittestImport.cs \ csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs \ csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3.cs \ + csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs \ + csharp/src/Google.Protobuf.Test.TestProtos/UnittestSelfreferentialOptions.cs \ csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs \ csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs \ csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs \ @@ -159,6 +172,7 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf.sln \ csharp/src/Google.Protobuf/ByteArray.cs \ csharp/src/Google.Protobuf/ByteString.cs \ + csharp/src/Google.Protobuf/ByteStringAsync.cs \ csharp/src/Google.Protobuf/CodedInputStream.cs \ csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs \ csharp/src/Google.Protobuf/CodedOutputStream.cs \ @@ -179,6 +193,7 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/FieldMaskTree.cs \ csharp/src/Google.Protobuf/FrameworkPortability.cs \ csharp/src/Google.Protobuf/Google.Protobuf.csproj \ + csharp/src/Google.Protobuf/IBufferMessage.cs \ csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs \ csharp/src/Google.Protobuf/IDeepCloneable.cs \ csharp/src/Google.Protobuf/IExtendableMessage.cs \ @@ -193,7 +208,13 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/MessageExtensions.cs \ csharp/src/Google.Protobuf/MessageParser.cs \ csharp/src/Google.Protobuf/ObjectIntPair.cs \ + csharp/src/Google.Protobuf/ParseContext.cs \ + csharp/src/Google.Protobuf/ParserInternalState.cs \ + csharp/src/Google.Protobuf/ParsingPrimitives.cs \ + csharp/src/Google.Protobuf/ParsingPrimitivesMessages.cs \ + csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs \ csharp/src/Google.Protobuf/ProtoPreconditions.cs \ + csharp/src/Google.Protobuf/SegmentedBufferHelper.cs \ csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs \ csharp/src/Google.Protobuf/Reflection/CustomOptions.cs \ csharp/src/Google.Protobuf/Reflection/Descriptor.cs \ @@ -243,12 +264,19 @@ csharp_EXTRA_DIST= \ csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs \ csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs \ csharp/src/Google.Protobuf/WireFormat.cs \ + csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs \ + csharp/src/Google.Protobuf/WritingPrimitives.cs \ + csharp/src/Google.Protobuf/WriterInternalState.cs \ + csharp/src/Google.Protobuf/WriteContext.cs \ + csharp/src/Google.Protobuf/WriteBufferHelper.cs \ csharp/src/Google.Protobuf/UnknownField.cs \ - csharp/src/Google.Protobuf/UnknownFieldSet.cs + csharp/src/Google.Protobuf/UnknownFieldSet.cs \ + csharp/src/Google.Protobuf/UnsafeByteOperations.cs java_EXTRA_DIST= \ java/README.md \ java/bom/pom.xml \ + java/core/BUILD \ java/core/generate-sources-build.xml \ java/core/generate-test-sources-build.xml \ java/core/pom.xml \ @@ -504,6 +532,7 @@ java_EXTRA_DIST= java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto \ java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \ java/lite.md \ + java/lite/BUILD \ java/lite/generate-sources-build.xml \ java/lite/generate-test-sources-build.xml \ java/lite/lite.awk \ @@ -512,6 +541,7 @@ java_EXTRA_DIST= java/lite/src/test/java/com/google/protobuf/LiteTest.java \ java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java \ java/pom.xml \ + java/util/BUILD \ java/util/pom.xml \ java/util/src/main/java/com/google/protobuf/util/Durations.java \ java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java \ @@ -524,13 +554,14 @@ java_EXTRA_DIST= java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \ java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \ java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \ - java/util/src/test/java/com/google/protobuf/util/StructsTest.java \ + java/util/src/test/java/com/google/protobuf/util/StructsTest.java \ java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java \ java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \ java/util/src/test/proto/com/google/protobuf/util/json_test.proto objectivec_EXTRA_DIST= \ objectivec/.clang-format \ + objectivec/BUILD \ objectivec/DevTools/check_version_stamps.sh \ objectivec/DevTools/compile_testing_protos.sh \ objectivec/DevTools/full_mac_build.sh \ @@ -538,25 +569,19 @@ objectivec_EXTRA_DIST= \ objectivec/DevTools/pddm_tests.py \ objectivec/generate_well_known_types.sh \ objectivec/google/protobuf/Any.pbobjc.h \ - objectivec/google/protobuf/Any.pbobjc.m \ objectivec/google/protobuf/Api.pbobjc.h \ - objectivec/google/protobuf/Api.pbobjc.m \ objectivec/google/protobuf/Duration.pbobjc.h \ - objectivec/google/protobuf/Duration.pbobjc.m \ objectivec/google/protobuf/Empty.pbobjc.h \ - objectivec/google/protobuf/Empty.pbobjc.m \ objectivec/google/protobuf/FieldMask.pbobjc.h \ - objectivec/google/protobuf/FieldMask.pbobjc.m \ objectivec/google/protobuf/SourceContext.pbobjc.h \ - objectivec/google/protobuf/SourceContext.pbobjc.m \ objectivec/google/protobuf/Struct.pbobjc.h \ - objectivec/google/protobuf/Struct.pbobjc.m \ objectivec/google/protobuf/Timestamp.pbobjc.h \ - objectivec/google/protobuf/Timestamp.pbobjc.m \ objectivec/google/protobuf/Type.pbobjc.h \ - objectivec/google/protobuf/Type.pbobjc.m \ objectivec/google/protobuf/Wrappers.pbobjc.h \ - objectivec/google/protobuf/Wrappers.pbobjc.m \ + objectivec/GPBAny.pbobjc.h \ + objectivec/GPBAny.pbobjc.m \ + objectivec/GPBApi.pbobjc.h \ + objectivec/GPBApi.pbobjc.m \ objectivec/GPBArray.h \ objectivec/GPBArray.m \ objectivec/GPBArray_PackagePrivate.h \ @@ -573,10 +598,16 @@ objectivec_EXTRA_DIST= \ objectivec/GPBDictionary.h \ objectivec/GPBDictionary.m \ objectivec/GPBDictionary_PackagePrivate.h \ + objectivec/GPBDuration.pbobjc.h \ + objectivec/GPBDuration.pbobjc.m \ + objectivec/GPBEmpty.pbobjc.h \ + objectivec/GPBEmpty.pbobjc.m \ objectivec/GPBExtensionInternals.h \ objectivec/GPBExtensionInternals.m \ objectivec/GPBExtensionRegistry.h \ objectivec/GPBExtensionRegistry.m \ + objectivec/GPBFieldMask.pbobjc.h \ + objectivec/GPBFieldMask.pbobjc.m \ objectivec/GPBMessage.h \ objectivec/GPBMessage.m \ objectivec/GPBMessage_PackagePrivate.h \ @@ -587,6 +618,14 @@ objectivec_EXTRA_DIST= \ objectivec/GPBRootObject.m \ objectivec/GPBRootObject_PackagePrivate.h \ objectivec/GPBRuntimeTypes.h \ + objectivec/GPBSourceContext.pbobjc.h \ + objectivec/GPBSourceContext.pbobjc.m \ + objectivec/GPBStruct.pbobjc.h \ + objectivec/GPBStruct.pbobjc.m \ + objectivec/GPBTimestamp.pbobjc.h \ + objectivec/GPBTimestamp.pbobjc.m \ + objectivec/GPBType.pbobjc.h \ + objectivec/GPBType.pbobjc.m \ objectivec/GPBUnknownField.h \ objectivec/GPBUnknownField.m \ objectivec/GPBUnknownField_PackagePrivate.h \ @@ -600,6 +639,8 @@ objectivec_EXTRA_DIST= \ objectivec/GPBWellKnownTypes.m \ objectivec/GPBWireFormat.h \ objectivec/GPBWireFormat.m \ + objectivec/GPBWrappers.pbobjc.h \ + objectivec/GPBWrappers.pbobjc.m \ objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj \ objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata \ objectivec/ProtocolBuffers_iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist \ @@ -730,24 +771,30 @@ php_EXTRA_DIST= \ composer.json \ php/README.md \ php/composer.json \ + php/ext/google/protobuf/arena.c \ + php/ext/google/protobuf/arena.h \ php/ext/google/protobuf/array.c \ - php/ext/google/protobuf/builtin_descriptors.inc \ + php/ext/google/protobuf/array.h \ php/ext/google/protobuf/config.m4 \ + php/ext/google/protobuf/convert.c \ + php/ext/google/protobuf/convert.h \ php/ext/google/protobuf/def.c \ - php/ext/google/protobuf/encode_decode.c \ + php/ext/google/protobuf/def.h \ php/ext/google/protobuf/map.c \ + php/ext/google/protobuf/map.h \ php/ext/google/protobuf/message.c \ + php/ext/google/protobuf/message.h \ + php/ext/google/protobuf/names.c \ + php/ext/google/protobuf/names.h \ php/ext/google/protobuf/package.xml \ + php/ext/google/protobuf/php-upb.c \ + php/ext/google/protobuf/php-upb.h \ php/ext/google/protobuf/protobuf.c \ php/ext/google/protobuf/protobuf.h \ - php/ext/google/protobuf/storage.c \ - php/ext/google/protobuf/type_check.c \ - php/ext/google/protobuf/upb.c \ - php/ext/google/protobuf/upb.h \ - php/ext/google/protobuf/utf8.c \ - php/ext/google/protobuf/utf8.h \ + php/ext/google/protobuf/wkt.inc \ php/generate_descriptor_protos.sh \ php/phpunit.xml \ + php/prepare_c_extension.sh \ php/release.sh \ php/src/GPBMetadata/Google/Protobuf/Any.php \ php/src/GPBMetadata/Google/Protobuf/Api.php \ @@ -783,6 +830,7 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/GPBEmpty.php \ php/src/Google/Protobuf/Int32Value.php \ php/src/Google/Protobuf/Int64Value.php \ + php/src/Google/Protobuf/Internal/AnyBase.php \ php/src/Google/Protobuf/Internal/CodedInputStream.php \ php/src/Google/Protobuf/Internal/CodedOutputStream.php \ php/src/Google/Protobuf/Internal/Descriptor.php \ @@ -842,6 +890,7 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Internal/ServiceOptions.php \ php/src/Google/Protobuf/Internal/SourceCodeInfo.php \ php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php \ + php/src/Google/Protobuf/Internal/TimestampBase.php \ php/src/Google/Protobuf/Internal/UninterpretedOption.php \ php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php \ php/src/Google/Protobuf/Internal/DescriptorProto_ExtensionRange.php \ @@ -872,22 +921,23 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/UInt64Value.php \ php/src/Google/Protobuf/Value.php \ php/src/phpdoc.dist.xml \ - php/tests/array_test.php \ + php/tests/ArrayTest.php \ php/tests/autoload.php \ php/tests/bootstrap_phpunit.php \ php/tests/compatibility_test.sh \ php/tests/compile_extension.sh \ - php/tests/descriptors_test.php \ - php/tests/encode_decode_test.php \ + php/tests/DescriptorsTest.php \ + php/tests/EncodeDecodeTest.php \ php/tests/gdb_test.sh \ - php/tests/generated_class_test.php \ - php/tests/generated_phpdoc_test.php \ - php/tests/generated_service_test.php \ - php/tests/map_field_test.php \ + php/tests/generate_protos.sh \ + php/tests/GeneratedClassTest.php \ + php/tests/GeneratedPhpdocTest.php \ + php/tests/GeneratedServiceTest.php \ + php/tests/MapFieldTest.php \ php/tests/memory_leak_test.php \ php/tests/multirequest.php \ php/tests/multirequest.sh \ - php/tests/php_implementation_test.php \ + php/tests/PhpImplementationTest.php \ php/tests/proto/empty/echo.proto \ php/tests/proto/test.proto \ php/tests/proto/test_descriptors.proto \ @@ -910,8 +960,9 @@ php_EXTRA_DIST= \ php/tests/test_base.php \ php/tests/test_util.php \ php/tests/undefined_test.php \ - php/tests/well_known_test.php \ - php/tests/wrapper_type_setters_test.php + php/tests/valgrind.supp \ + php/tests/WellKnownTest.php \ + php/tests/WrapperTypeSettersTest.php python_EXTRA_DIST= \ python/MANIFEST.in \ @@ -963,6 +1014,7 @@ python_EXTRA_DIST= \ python/google/protobuf/internal/service_reflection_test.py \ python/google/protobuf/internal/symbol_database_test.py \ python/google/protobuf/internal/test_bad_identifiers.proto \ + python/google/protobuf/internal/test_proto3_optional.proto \ python/google/protobuf/internal/test_util.py \ python/google/protobuf/internal/testing_refleaks.py \ python/google/protobuf/internal/text_encoding_test.py \ @@ -1177,6 +1229,10 @@ js_EXTRA_DIST= \ js/data.proto \ js/debug.js \ js/debug_test.js \ + js/experimental/runtime/kernel/message_set.js \ + js/experimental/runtime/kernel/message_set_test.js \ + js/experimental/runtime/kernel/tag.js \ + js/experimental/runtime/kernel/tag_test.js \ js/gulpfile.js \ js/jasmine.json \ js/map.js \ @@ -1202,7 +1258,79 @@ js_EXTRA_DIST= \ js/test15.proto \ js/test_bootstrap.js \ js/testbinary.proto \ - js/testempty.proto + js/testempty.proto \ + js/testlargenumbers.proto \ + js/experimental/runtime/testing/jasmine_protobuf.js \ + js/experimental/runtime/testing/ensure_custom_equality_test.js \ + js/experimental/runtime/testing/binary/test_message.js \ + js/experimental/runtime/kernel/writer_test.js \ + js/experimental/runtime/kernel/writer.js \ + js/experimental/runtime/kernel/wire_type.js \ + js/experimental/runtime/kernel/uint8arrays_test.js \ + js/experimental/runtime/kernel/uint8arrays.js \ + js/experimental/runtime/kernel/uint32_test_pairs.js \ + js/experimental/runtime/kernel/typed_arrays_test.js \ + js/experimental/runtime/kernel/typed_arrays.js \ + js/experimental/runtime/kernel/textencoding_test.js \ + js/experimental/runtime/kernel/textencoding.js \ + js/experimental/runtime/kernel/storage.js \ + js/experimental/runtime/kernel/sint64_test_pairs.js \ + js/experimental/runtime/kernel/sint32_test_pairs.js \ + js/experimental/runtime/kernel/sfixed64_test_pairs.js \ + js/experimental/runtime/kernel/sfixed32_test_pairs.js \ + js/experimental/runtime/kernel/reader_test.js \ + js/experimental/runtime/kernel/reader.js \ + js/experimental/runtime/kernel/packed_uint32_test_pairs.js \ + js/experimental/runtime/kernel/packed_sint64_test_pairs.js \ + js/experimental/runtime/kernel/packed_sint32_test_pairs.js \ + js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js \ + js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js \ + js/experimental/runtime/kernel/packed_int64_test_pairs.js \ + js/experimental/runtime/kernel/packed_int32_test_pairs.js \ + js/experimental/runtime/kernel/packed_float_test_pairs.js \ + js/experimental/runtime/kernel/packed_fixed32_test_pairs.js \ + js/experimental/runtime/kernel/packed_double_test_pairs.js \ + js/experimental/runtime/kernel/packed_bool_test_pairs.js \ + js/experimental/runtime/kernel/kernel_test.js \ + js/experimental/runtime/kernel/kernel_repeated_test.js \ + js/experimental/runtime/kernel/kernel_compatibility_test.js \ + js/experimental/runtime/kernel/kernel.js \ + js/experimental/runtime/kernel/internal_message.js \ + js/experimental/runtime/kernel/int64_test_pairs.js \ + js/experimental/runtime/kernel/int32_test_pairs.js \ + js/experimental/runtime/kernel/indexer_test.js \ + js/experimental/runtime/kernel/indexer.js \ + js/experimental/runtime/kernel/float_test_pairs.js \ + js/experimental/runtime/kernel/fixed32_test_pairs.js \ + js/experimental/runtime/kernel/field.js \ + js/experimental/runtime/kernel/double_test_pairs.js \ + js/experimental/runtime/kernel/conformance/wire_format.js \ + js/experimental/runtime/kernel/conformance/test_all_types_proto3.js \ + js/experimental/runtime/kernel/conformance/test_all_types_proto2.js \ + js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js \ + js/experimental/runtime/kernel/conformance/conformance_testee.js \ + js/experimental/runtime/kernel/conformance/conformance_response.js \ + js/experimental/runtime/kernel/conformance/conformance_request.js \ + js/experimental/runtime/kernel/buffer_decoder_test.js \ + js/experimental/runtime/kernel/buffer_decoder_helper.js \ + js/experimental/runtime/kernel/buffer_decoder.js \ + js/experimental/runtime/kernel/bool_test_pairs.js \ + js/experimental/runtime/kernel/binary_storage_test.js \ + js/experimental/runtime/kernel/binary_storage.js \ + js/experimental/runtime/internal/checks_test.js \ + js/experimental/runtime/internal/checks.js \ + js/experimental/runtime/int64_test.js \ + js/experimental/runtime/int64.js \ + js/experimental/runtime/bytestring_test.js \ + js/experimental/runtime/bytestring_internal.js \ + js/experimental/runtime/bytestring.js \ + js/experimental/benchmarks/code_size/kernel/popular_types.js \ + js/experimental/benchmarks/code_size/kernel/all_types.js \ + js/experimental/benchmarks/code_size/code_size_base.js \ + js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js \ + js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js \ + js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js \ + js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js all_EXTRA_DIST=$(csharp_EXTRA_DIST) $(java_EXTRA_DIST) $(objectivec_EXTRA_DIST) $(php_EXTRA_DIST) $(python_EXTRA_DIST) $(ruby_EXTRA_DIST) $(js_EXTRA_DIST) @@ -1218,7 +1346,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ WORKSPACE \ cmake/CMakeLists.txt \ cmake/README.md \ - cmake/conformance.cmake \ + cmake/conformance.cmake \ cmake/examples.cmake \ cmake/extract_includes.bat.in \ cmake/install.cmake \ @@ -1235,6 +1363,8 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ cmake/tests.cmake \ cmake/version.rc.in \ compiler_config_setting.bzl \ + build_files_updated_unittest.sh \ + cc_proto_blacklist_test.bzl \ editors/README.txt \ editors/proto.vim \ editors/protobuf-mode.el \ @@ -1265,6 +1395,8 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \ python/release/wheel/README.md \ third_party/six.BUILD \ third_party/zlib.BUILD \ + third_party/wyhash/LICENSE \ + third_party/wyhash/wyhash.h \ util/python/BUILD diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec index 1359d0294dbc..3f250e2f2a3e 100644 --- a/Protobuf-C++.podspec +++ b/Protobuf-C++.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Protobuf-C++' - s.version = '3.11.2' + s.version = '3.14.0' s.summary = 'Protocol Buffers v3 runtime library for C++.' s.homepage = 'https://github.com/google/protobuf' s.license = '3-Clause BSD License' diff --git a/Protobuf.podspec b/Protobuf.podspec index 6de36e05ac0d..7a7363aaf0fa 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -5,28 +5,27 @@ # dependent projects use the :git notation to refer to the library. Pod::Spec.new do |s| s.name = 'Protobuf' - s.version = '3.11.2' + s.version = '3.14.0' s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.' s.homepage = 'https://github.com/protocolbuffers/protobuf' s.license = '3-Clause BSD License' s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' } s.cocoapods_version = '>= 1.0' - s.module_name = 'protobuf' s.source = { :git => 'https://github.com/protocolbuffers/protobuf.git', :tag => "v#{s.version}" } s.source_files = 'objectivec/*.{h,m}', - 'objectivec/google/protobuf/Any.pbobjc.{h,m}', - 'objectivec/google/protobuf/Api.pbobjc.{h,m}', - 'objectivec/google/protobuf/Duration.pbobjc.{h,m}', - 'objectivec/google/protobuf/Empty.pbobjc.{h,m}', - 'objectivec/google/protobuf/FieldMask.pbobjc.{h,m}', - 'objectivec/google/protobuf/SourceContext.pbobjc.{h,m}', - 'objectivec/google/protobuf/Struct.pbobjc.{h,m}', - 'objectivec/google/protobuf/Timestamp.pbobjc.{h,m}', - 'objectivec/google/protobuf/Type.pbobjc.{h,m}', - 'objectivec/google/protobuf/Wrappers.pbobjc.{h,m}' + 'objectivec/google/protobuf/Any.pbobjc.h', + 'objectivec/google/protobuf/Api.pbobjc.h', + 'objectivec/google/protobuf/Duration.pbobjc.h', + 'objectivec/google/protobuf/Empty.pbobjc.h', + 'objectivec/google/protobuf/FieldMask.pbobjc.h', + 'objectivec/google/protobuf/SourceContext.pbobjc.h', + 'objectivec/google/protobuf/Struct.pbobjc.h', + 'objectivec/google/protobuf/Timestamp.pbobjc.h', + 'objectivec/google/protobuf/Type.pbobjc.h', + 'objectivec/google/protobuf/Wrappers.pbobjc.h' # The following would cause duplicate symbol definitions. GPBProtocolBuffers is expected to be # left out, as it's an umbrella implementation file. s.exclude_files = 'objectivec/GPBProtocolBuffers.m' @@ -35,7 +34,7 @@ Pod::Spec.new do |s| s.user_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' } s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' } - s.ios.deployment_target = '7.0' + s.ios.deployment_target = '9.0' s.osx.deployment_target = '10.9' s.tvos.deployment_target = '9.0' s.watchos.deployment_target = '2.0' diff --git a/README.md b/README.md index 0e5ae61e264d..d5155ae9ab5d 100644 --- a/README.md +++ b/README.md @@ -56,12 +56,12 @@ how to install protobuf runtime for that specific language: |--------------------------------------|-------------------------------------------------------------|--------|-------|---------| | C++ (include C++ runtime and protoc) | [src](src) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcpp_distcheck%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-bazel.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fbazel%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-dist_install.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fdist_install%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-cpp_distcheck.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fcpp_distcheck%2Fcontinuous) | [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf) | | Java | [java](java) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-java_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjava_compatibility%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-java_jdk7.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjava_jdk7%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-java_oracle7.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjava_oracle7%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-java_linkage_monitor.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjava_linkage_monitor%2Fcontinuous) | | | -| Python | [python](python) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python27.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython27%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python33.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython33%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python34.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython34%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python35.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython35%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python36.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython36%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python37.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython37%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_compatibility%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python27_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython27_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python33_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython33_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python34_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython34_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python35_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython35_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python36_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython36_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python37_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython37_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_release%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_release%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/windows-python-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fwindows%2Fpython_release%2Fcontinuous) | +| Python | [python](python) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python27.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython27%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python35.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython35%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python36.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython36%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python37.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython37%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_compatibility%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python27_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython27_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python35_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython35_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python36_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython36_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python37_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython37_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_release%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_cpp%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_release%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/windows-python-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fwindows%2Fpython_release%2Fcontinuous) | | Objective-C | [objectivec](objectivec) | | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_cocoapods_integration.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_cocoapods_integration%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_debug.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_debug%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_ios_release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_ios_release%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-objectivec_osx.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fobjectivec_osx%2Fcontinuous) | | | C# | [csharp](csharp) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-csharp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fcsharp%2Fcontinuous) | | [![Build status](https://ci.appveyor.com/api/projects/status/73ctee6ua4w2ruin?svg=true)](https://ci.appveyor.com/project/protobuf/protobuf)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/windows-csharp-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fwindows%2Fcsharp_release%2Fcontinuous) | | JavaScript | [js](js) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fjavascript%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-javascript.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fjavascript%2Fcontinuous) | | | Ruby | [ruby](ruby) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby23.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby23%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby24.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby24%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby25.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby25%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby26.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby26%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-ruby-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fruby_release%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby23.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby23%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby24.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby24%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby25.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby25%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby26.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby26%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-ruby-release.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fruby_release%2Fcontinuous) | | -| Go | [golang/protobuf](https://github.com/golang/protobuf) | | | | +| Go | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go) | | | | | PHP | [php](php) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-php_all.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fphp_all%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-32-bit.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2F32-bit%2Fcontinuous) | [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php5.6_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp5.6_mac%2Fcontinuous)
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-php7.0_mac.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fphp7.0_mac%2Fcontinuous) | | | Dart | [dart-lang/protobuf](https://github.com/dart-lang/protobuf) | [![Build Status](https://travis-ci.org/dart-lang/protobuf.svg?branch=master)](https://travis-ci.org/dart-lang/protobuf) | | | diff --git a/WORKSPACE b/WORKSPACE index 39672c88280c..5a767a97c0ac 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,13 +1,20 @@ workspace(name = "com_google_protobuf") +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + local_repository( name = "com_google_protobuf_examples", path = "examples", ) -local_repository( - name = "submodule_gmock", - path = "third_party/googletest", +http_archive( + name = "com_google_googletest", + sha256 = "9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb", + strip_prefix = "googletest-release-1.10.0", + urls = [ + "https://mirror.bazel.build/github.com/google/googletest/archive/release-1.10.0.tar.gz", + "https://github.com/google/googletest/archive/release-1.10.0.tar.gz", + ], ) load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") @@ -22,14 +29,16 @@ bind( actual = "//util/python:python_headers", ) +# TODO(yannic): Remove in 3.14.0. bind( name = "gtest", - actual = "@submodule_gmock//:gtest", + actual = "@com_google_googletest//:gtest", ) +# TODO(yannic): Remove in 3.14.0. bind( name = "gtest_main", - actual = "@submodule_gmock//:gtest_main", + actual = "@com_google_googletest//:gtest_main", ) jvm_maven_import_external( diff --git a/benchmarks/README.md b/benchmarks/README.md index 436c148a34d0..76788175c656 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -135,7 +135,7 @@ $ make go ### PHP -We have two version of php protobuf implemention: pure php, php with c extension. To run these version benchmark, you need to: +We have two version of php protobuf implementation: pure php, php with c extension. To run these version benchmark, you need to: #### Pure PHP ``` $ make php diff --git a/benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto b/benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto index 21261905dafa..e404b9fe1b47 100644 --- a/benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto +++ b/benchmarks/datasets/google_message1/proto2/benchmark_message1_proto2.proto @@ -1,3 +1,33 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + // Benchmark messages for proto2. syntax = "proto2"; diff --git a/benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto b/benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto index 090b554be9c0..8aee2f672832 100644 --- a/benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto +++ b/benchmarks/datasets/google_message1/proto3/benchmark_message1_proto3.proto @@ -1,3 +1,33 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + // Benchmark messages for proto3. syntax = "proto3"; diff --git a/benchmarks/datasets/google_message2/benchmark_message2.proto b/benchmarks/datasets/google_message2/benchmark_message2.proto index 820630e44d6c..500c5d699f1e 100644 --- a/benchmarks/datasets/google_message2/benchmark_message2.proto +++ b/benchmarks/datasets/google_message2/benchmark_message2.proto @@ -1,3 +1,35 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + // Benchmark messages for proto2. syntax = "proto2"; diff --git a/benchmarks/datasets/google_message3/benchmark_message3.proto b/benchmarks/datasets/google_message3/benchmark_message3.proto index d6f0d14e1b50..82422f924ea4 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3.proto @@ -1,5 +1,39 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message3; + import "datasets/google_message3/benchmark_message3_1.proto"; import "datasets/google_message3/benchmark_message3_2.proto"; import "datasets/google_message3/benchmark_message3_3.proto"; @@ -7,7 +41,6 @@ import "datasets/google_message3/benchmark_message3_4.proto"; import "datasets/google_message3/benchmark_message3_5.proto"; import "datasets/google_message3/benchmark_message3_7.proto"; import "datasets/google_message3/benchmark_message3_8.proto"; -package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; @@ -531,4 +564,3 @@ extend .benchmarks.google_message3.Message16945 { repeated .benchmarks.google_message3.Message0 field17617 = 1080; repeated int32 field17618 = 1084; } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_1.proto b/benchmarks/datasets/google_message3/benchmark_message3_1.proto index 3219553cc52f..1ee5c9eca624 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_1.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_1.proto @@ -1,11 +1,44 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message3; + import "datasets/google_message3/benchmark_message3_2.proto"; import "datasets/google_message3/benchmark_message3_3.proto"; import "datasets/google_message3/benchmark_message3_5.proto"; import "datasets/google_message3/benchmark_message3_7.proto"; import "datasets/google_message3/benchmark_message3_8.proto"; -package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; @@ -100,15 +133,13 @@ message Message36876 { optional int32 field37047 = 115; optional int32 field37048 = 157; } - repeated group Message36878 = 168 { - } + repeated group Message36878 = 168 {} repeated group Message36879 = 55 { required string field37050 = 56; optional int32 field37051 = 69; } repeated .benchmarks.google_message3.UnusedEmptyMessage field36984 = 78; - optional group Message36880 = 137 { - } + optional group Message36880 = 137 {} optional uint64 field36986 = 59; optional bytes field36987 = 121; optional .benchmarks.google_message3.UnusedEmptyMessage field36988 = 2; @@ -124,11 +155,9 @@ message Message36876 { optional int32 field36998 = 47; optional int32 field36999 = 48; optional .benchmarks.google_message3.UnusedEmptyMessage field37000 = 68; - repeated group Message36881 = 23 { - } + repeated group Message36881 = 23 {} optional .benchmarks.google_message3.Message4144 field37002 = 125; - repeated group Message36882 = 35 { - } + repeated group Message36882 = 35 {} optional .benchmarks.google_message3.UnusedEmptyMessage field37004 = 49; optional .benchmarks.google_message3.Message18921 field37005 = 52; optional .benchmarks.google_message3.Message36858 field37006 = 46; @@ -141,20 +170,15 @@ message Message36876 { optional .benchmarks.google_message3.Message0 field37013 = 143; optional .benchmarks.google_message3.UnusedEmptyMessage field37014 = 53; optional .benchmarks.google_message3.Message36869 field37015 = 15; - optional group Message36883 = 3 { - } - repeated group Message36884 = 16 { - } - repeated group Message36885 = 27 { - } - optional group Message36886 = 32 { - } + optional group Message36883 = 3 {} + repeated group Message36884 = 16 {} + repeated group Message36885 = 27 {} + optional group Message36886 = 32 {} repeated .benchmarks.google_message3.UnusedEnum field37020 = 71; repeated int32 field37021 = 70; optional .benchmarks.google_message3.UnusedEmptyMessage field37022 = 66; optional .benchmarks.google_message3.Message13090 field37023 = 67; - optional group Message36887 = 62 { - } + optional group Message36887 = 62 {} repeated .benchmarks.google_message3.Message10155 field37025 = 50; repeated .benchmarks.google_message3.Message11874 field37026 = 151; optional string field37027 = 12; @@ -202,8 +226,7 @@ message Message36876 { optional int32 field37118 = 160; repeated string field37119 = 161; } - repeated group Message36910 = 119 { - } + repeated group Message36910 = 119 {} optional group Message36911 = 126 { optional .benchmarks.google_message3.UnusedEmptyMessage field37121 = 127; optional .benchmarks.google_message3.Message35538 field37122 = 130; @@ -217,11 +240,9 @@ message Message36876 { optional .benchmarks.google_message3.UnusedEmptyMessage field37042 = 155; } -message Message1328 { -} +message Message1328 {} -message Message6850 { -} +message Message6850 {} message Message6863 { optional .benchmarks.google_message3.Enum6858 field6931 = 1; @@ -259,8 +280,7 @@ message Message6863 { optional bool field6963 = 34; } -message Message6871 { -} +message Message6871 {} message Message7547 { required bytes field7549 = 1; @@ -282,8 +302,7 @@ message Message7648 { optional bool field7680 = 12; } -message Message7865 { -} +message Message7865 {} message Message7928 { optional string field7940 = 1; @@ -1277,4 +1296,3 @@ message Message16945 { optional .benchmarks.google_message3.Message16945 field17025 = 22068132; } } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_2.proto b/benchmarks/datasets/google_message3/benchmark_message3_2.proto index 7ab993ba5570..d123a7204caa 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_2.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_2.proto @@ -1,11 +1,44 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message3; + import "datasets/google_message3/benchmark_message3_3.proto"; import "datasets/google_message3/benchmark_message3_4.proto"; import "datasets/google_message3/benchmark_message3_5.proto"; import "datasets/google_message3/benchmark_message3_7.proto"; import "datasets/google_message3/benchmark_message3_8.proto"; -package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; @@ -79,8 +112,7 @@ message Message24391 { repeated string field24655 = 6; } -message Message27454 { -} +message Message27454 {} message Message27357 { optional string field27410 = 1; @@ -162,8 +194,7 @@ message Message36869 { } message Message33968 { - repeated group Message33969 = 1 { - } + repeated group Message33969 = 1 {} repeated .benchmarks.google_message3.Message33958 field33989 = 3; optional .benchmarks.google_message3.UnusedEmptyMessage field33990 = 106; optional bool field33991 = 108; @@ -238,8 +269,7 @@ message Message35573 { optional string field35696 = 1000; optional string field35697 = 1004; optional int32 field35698 = 1003; - repeated group Message35574 = 1012 { - } + repeated group Message35574 = 1012 {} optional int64 field35700 = 1011; optional int64 field35701 = 1005; optional int64 field35702 = 1006; @@ -496,4 +526,3 @@ message Message3901 { optional .benchmarks.google_message3.UnusedEnum field4000 = 6; optional int32 field4001 = 5; } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_3.proto b/benchmarks/datasets/google_message3/benchmark_message3_3.proto index e71d26613645..2e534a67d6c5 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_3.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_3.proto @@ -1,10 +1,43 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message3; + import "datasets/google_message3/benchmark_message3_4.proto"; import "datasets/google_message3/benchmark_message3_5.proto"; import "datasets/google_message3/benchmark_message3_7.proto"; import "datasets/google_message3/benchmark_message3_8.proto"; -package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; @@ -66,8 +99,7 @@ message Message2356 { optional bytes field2410 = 124; } optional string field2389 = 120; - optional group Message2358 = 107 { - } + optional group Message2358 = 107 {} repeated group Message2359 = 40 { optional string field2413 = 41; optional string field2414 = 42; @@ -408,8 +440,7 @@ message Message16724 { optional bool field16773 = 13; } -message Message17728 { -} +message Message17728 {} message Message24356 { optional string field24559 = 1; @@ -463,4 +494,3 @@ message Message24366 { repeated string field24587 = 8; repeated string field24588 = 11; } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_4.proto b/benchmarks/datasets/google_message3/benchmark_message3_4.proto index 597cec6d1145..b30414819815 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_4.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_4.proto @@ -1,16 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message3; + import "datasets/google_message3/benchmark_message3_5.proto"; import "datasets/google_message3/benchmark_message3_6.proto"; import "datasets/google_message3/benchmark_message3_7.proto"; import "datasets/google_message3/benchmark_message3_8.proto"; -package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; -message Message24346 { -} +message Message24346 {} message Message24401 { optional .benchmarks.google_message3.Message24400 field24679 = 1; @@ -189,12 +221,9 @@ message Message13083 { optional float field13099 = 45; optional uint64 field13100 = 46; optional float field13101 = 47; - optional group Message13085 = 16 { - } - repeated group Message13086 = 23 { - } - repeated group Message13087 = 29 { - } + optional group Message13085 = 16 {} + repeated group Message13086 = 23 {} + repeated group Message13087 = 29 {} optional .benchmarks.google_message3.UnusedEmptyMessage field13105 = 43; } @@ -262,12 +291,10 @@ message Message16816 { optional float field16826 = 1; optional .benchmarks.google_message3.Enum16819 field16827 = 2; optional float field16828 = 3; - repeated group Message16817 = 4 { - } + repeated group Message16817 = 4 {} optional bool field16830 = 7; optional bool field16831 = 8; - repeated group Message16818 = 12 { - } + repeated group Message16818 = 12 {} optional string field16833 = 10; optional bool field16834 = 13; optional bool field16835 = 14; @@ -308,11 +335,9 @@ message Message1374 { optional string field1376 = 2; } -message Message18943 { -} +message Message18943 {} -message Message18944 { -} +message Message18944 {} message Message18856 { optional string field18857 = 1; @@ -436,8 +461,7 @@ message Message8475 { optional int64 field8482 = 2; } -message Message12559 { -} +message Message12559 {} message Message12817 { optional int32 field12826 = 1; @@ -488,4 +512,3 @@ message Message24317 { repeated string field24473 = 27; optional bool field24474 = 40; } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_5.proto b/benchmarks/datasets/google_message3/benchmark_message3_5.proto index bc6cbc1c81d1..e72d7ee85af4 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_5.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_5.proto @@ -1,18 +1,49 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message3; + import "datasets/google_message3/benchmark_message3_6.proto"; import "datasets/google_message3/benchmark_message3_7.proto"; import "datasets/google_message3/benchmark_message3_8.proto"; -package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; -message Message24377 { -} +message Message24377 {} -message Message24378 { -} +message Message24378 {} message Message24400 { optional int32 field24674 = 1; @@ -22,11 +53,9 @@ message Message24400 { optional int32 field24678 = 5; } -message Message24380 { -} +message Message24380 {} -message Message24381 { -} +message Message24381 {} message Message719 { repeated string field881 = 1; @@ -103,6 +132,7 @@ message Message697 { message Message0 { option message_set_wire_format = true; + extensions 4 to 2147483646; } @@ -193,7 +223,8 @@ message Message10155 { optional fixed64 field10232 = 13; optional fixed64 field10233 = 20; optional bool field10234 = 79; - repeated .benchmarks.google_message3.Enum10167 field10235 = 80 [packed = true]; + repeated .benchmarks.google_message3.Enum10167 field10235 = 80 + [packed = true]; optional int32 field10236 = 14; optional int32 field10237 = 15; optional int32 field10238 = 28; @@ -285,25 +316,20 @@ message Message13145 { extensions 1000 to 536870911; } -message Message16686 { -} +message Message16686 {} message Message12796 { repeated fixed64 field12800 = 1; optional uint64 field12801 = 2; } -message Message6722 { -} +message Message6722 {} -message Message6727 { -} +message Message6727 {} -message Message6724 { -} +message Message6724 {} -message Message6735 { -} +message Message6735 {} message Message8183 { optional string field8226 = 1; @@ -325,8 +351,7 @@ message Message8301 { extensions 64 to 536870911; } -message Message8456 { -} +message Message8456 {} message Message8302 { optional string field8339 = 1; @@ -353,8 +378,7 @@ message Message8302 { extensions 64 to 536870911; } -message Message8457 { -} +message Message8457 {} message Message8449 { optional string field8458 = 1; @@ -470,4 +494,3 @@ message Message698 { optional int64 field785 = 7; repeated string field786 = 8; } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_6.proto b/benchmarks/datasets/google_message3/benchmark_message3_6.proto index 98e1529e2419..c766f7c2efb0 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_6.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_6.proto @@ -1,14 +1,46 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message3; + import "datasets/google_message3/benchmark_message3_7.proto"; import "datasets/google_message3/benchmark_message3_8.proto"; -package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; -message Message10576 { -} +message Message10576 {} message Message10154 { optional bytes field10192 = 1; @@ -343,8 +375,7 @@ message Message8939 { optional string field9012 = 3; repeated string field9013 = 4; optional string field9014 = 5; - repeated group Message8940 = 11 { - } + repeated group Message8940 = 11 {} optional int64 field9016 = 21; optional int64 field9017 = 22; optional int64 field9018 = 23; @@ -423,8 +454,7 @@ message Message9627 { optional float field9672 = 5; } -message Message11020 { -} +message Message11020 {} message Message11013 { optional bytes field11757 = 19; @@ -451,4 +481,3 @@ message Message11013 { optional .benchmarks.google_message3.UnusedEmptyMessage field11778 = 23; repeated .benchmarks.google_message3.Message11011 field11779 = 22; } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_7.proto b/benchmarks/datasets/google_message3/benchmark_message3_7.proto index 2497db5e297b..0f8f10cd3732 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_7.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_7.proto @@ -1,3 +1,33 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + syntax = "proto2"; package benchmarks.google_message3; @@ -5,8 +35,7 @@ package benchmarks.google_message3; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; -message Message11018 { -} +message Message11018 {} message Message10800 { optional string field10808 = 1; @@ -15,8 +44,7 @@ message Message10800 { optional float field10811 = 4; } -message Message10802 { -} +message Message10802 {} message Message10748 { optional string field10750 = 1; @@ -39,18 +67,15 @@ message Message708 { repeated string field828 = 5; } -message Message8942 { -} +message Message8942 {} message Message11011 { required bytes field11752 = 1; required bytes field11753 = 2; } -message UnusedEmptyMessage { -} +message UnusedEmptyMessage {} message Message741 { repeated string field936 = 1; } - diff --git a/benchmarks/datasets/google_message3/benchmark_message3_8.proto b/benchmarks/datasets/google_message3/benchmark_message3_8.proto index 1d2b14723010..68fe8e901a6c 100644 --- a/benchmarks/datasets/google_message3/benchmark_message3_8.proto +++ b/benchmarks/datasets/google_message3/benchmark_message3_8.proto @@ -1,3 +1,33 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + syntax = "proto2"; package benchmarks.google_message3; @@ -609,9 +639,7 @@ enum Enum10325 { ENUM_VALUE10334 = 8; } -enum Enum10335 { - ENUM_VALUE10336 = 0; -} +enum Enum10335 { ENUM_VALUE10336 = 0; } enum Enum10337 { ENUM_VALUE10338 = 0; @@ -1857,9 +1885,7 @@ enum Enum33960 { ENUM_VALUE33967 = 6; } -enum Enum34388 { - ENUM_VALUE34389 = 1; -} +enum Enum34388 { ENUM_VALUE34389 = 1; } enum Enum35477 { ENUM_VALUE35478 = 4; @@ -1897,4 +1923,3 @@ enum Enum36890 { ENUM_VALUE36891 = 0; ENUM_VALUE36892 = 1; } - diff --git a/benchmarks/datasets/google_message4/benchmark_message4.proto b/benchmarks/datasets/google_message4/benchmark_message4.proto index 2161393918d7..424ed1081169 100644 --- a/benchmarks/datasets/google_message4/benchmark_message4.proto +++ b/benchmarks/datasets/google_message4/benchmark_message4.proto @@ -1,9 +1,42 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message4; + import "datasets/google_message4/benchmark_message4_1.proto"; import "datasets/google_message4/benchmark_message4_2.proto"; import "datasets/google_message4/benchmark_message4_3.proto"; -package benchmarks.google_message4; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; @@ -146,8 +179,7 @@ message Message176 { optional .benchmarks.google_message4.UnusedEnum field455 = 37; optional .benchmarks.google_message4.UnusedEnum field456 = 34; optional int32 field457 = 35; - repeated group Message178 = 101 { - } + repeated group Message178 = 101 {} optional bool field459 = 52; optional uint64 field460 = 58; optional uint64 field461 = 59; @@ -428,10 +460,8 @@ message Message2356 { optional bytes field2410 = 124; } optional string field2389 = 120; - optional group Message2358 = 107 { - } - repeated group Message2359 = 40 { - } + optional group Message2358 = 107 {} + repeated group Message2359 = 40 {} optional int32 field2392 = 50; optional .benchmarks.google_message4.UnusedEmptyMessage field2393 = 60; optional .benchmarks.google_message4.UnusedEmptyMessage field2394 = 70; @@ -443,6 +473,7 @@ message Message2356 { message Message0 { option message_set_wire_format = true; + extensions 4 to 2147483646; } @@ -451,4 +482,3 @@ message Message971 { optional int32 field973 = 2; optional bool field974 = 3; } - diff --git a/benchmarks/datasets/google_message4/benchmark_message4_1.proto b/benchmarks/datasets/google_message4/benchmark_message4_1.proto index e7697480524f..c5deecd0df84 100644 --- a/benchmarks/datasets/google_message4/benchmark_message4_1.proto +++ b/benchmarks/datasets/google_message4/benchmark_message4_1.proto @@ -1,8 +1,41 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +// LINT: ALLOW_GROUPS + syntax = "proto2"; +package benchmarks.google_message4; + import "datasets/google_message4/benchmark_message4_2.proto"; import "datasets/google_message4/benchmark_message4_3.proto"; -package benchmarks.google_message4; option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; @@ -16,8 +49,7 @@ message Message12686 { optional .benchmarks.google_message4.Message12685 field12700 = 2; } -message Message11949 { -} +message Message11949 {} message Message11975 { optional string field11992 = 1; @@ -104,8 +136,7 @@ message Message3061 { } optional .benchmarks.google_message4.UnusedEmptyMessage field3315 = 39; optional int32 field3316 = 76; - optional group Message3065 = 63 { - } + optional group Message3065 = 63 {} optional .benchmarks.google_message4.Enum2806 field3318 = 54; optional int32 field3319 = 46; repeated string field3320 = 24; @@ -133,8 +164,7 @@ message Message3061 { optional int32 field3333 = 17; } -message Message12949 { -} +message Message12949 {} message Message8572 { optional bytes field8647 = 1; @@ -239,11 +269,9 @@ message Message12825 { repeated .benchmarks.google_message4.UnusedEmptyMessage field12868 = 7; } -message Message8590 { -} +message Message8590 {} -message Message8587 { -} +message Message8587 {} message Message1374 { required string field1375 = 1; @@ -423,8 +451,7 @@ message Message3052 { optional string field3262 = 9; } -message Message8575 { -} +message Message8575 {} message Message7843 { optional bool field7844 = 5; @@ -471,4 +498,3 @@ message Message7929 { repeated bytes field7960 = 11; optional int64 field7961 = 16; } - diff --git a/benchmarks/datasets/google_message4/benchmark_message4_2.proto b/benchmarks/datasets/google_message4/benchmark_message4_2.proto index d5e9da5aa973..0c4cdfd853a1 100644 --- a/benchmarks/datasets/google_message4/benchmark_message4_2.proto +++ b/benchmarks/datasets/google_message4/benchmark_message4_2.proto @@ -1,8 +1,39 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + syntax = "proto2"; -import "datasets/google_message4/benchmark_message4_3.proto"; package benchmarks.google_message4; +import "datasets/google_message4/benchmark_message4_3.proto"; + option cc_enable_arenas = true; option java_package = "com.google.protobuf.benchmarks"; @@ -102,8 +133,7 @@ message Message5881 { optional .benchmarks.google_message4.Message5880 field5902 = 6; } -message Message6110 { -} +message Message6110 {} message Message6107 { optional .benchmarks.google_message4.Message4016 field6134 = 1; @@ -181,8 +211,7 @@ message Message3850 { optional bool field3929 = 14; } -message Message7865 { -} +message Message7865 {} message Message7511 { optional bool field7523 = 1; @@ -194,8 +223,7 @@ message Message7511 { optional int32 field7529 = 7; } -message Message3920 { -} +message Message3920 {} message Message7928 { optional string field7940 = 1; @@ -231,8 +259,7 @@ message Message6054 { optional string field6090 = 2; } -message Message6127 { -} +message Message6127 {} message Message6052 { required string field6084 = 1; @@ -272,8 +299,7 @@ message Message4016 { required int32 field4020 = 4; } -message Message6108 { -} +message Message6108 {} message Message5907 { optional .benchmarks.google_message4.Message5903 field5967 = 1; @@ -282,11 +308,9 @@ message Message5907 { optional .benchmarks.google_message4.Message5903 field5970 = 4; } -message UnusedEmptyMessage { -} +message UnusedEmptyMessage {} message Message5903 { required int32 field5965 = 1; optional .benchmarks.google_message4.Enum5904 field5966 = 2; } - diff --git a/benchmarks/datasets/google_message4/benchmark_message4_3.proto b/benchmarks/datasets/google_message4/benchmark_message4_3.proto index 544fad202aee..42e254b762f4 100644 --- a/benchmarks/datasets/google_message4/benchmark_message4_3.proto +++ b/benchmarks/datasets/google_message4/benchmark_message4_3.proto @@ -1,3 +1,33 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + syntax = "proto2"; package benchmarks.google_message4; @@ -47,6 +77,7 @@ enum Enum2806 { enum Enum2851 { option allow_alias = true; + ENUM_VALUE2852 = 0; ENUM_VALUE2853 = 0; ENUM_VALUE2854 = 1; @@ -717,9 +748,7 @@ enum Enum10325 { ENUM_VALUE10334 = 8; } -enum Enum10335 { - ENUM_VALUE10336 = 0; -} +enum Enum10335 { ENUM_VALUE10336 = 0; } enum Enum10337 { ENUM_VALUE10338 = 0; @@ -748,4 +777,3 @@ enum Enum12871 { ENUM_VALUE12876 = 5; ENUM_VALUE12877 = 6; } - diff --git a/benchmarks/js/js_benchmark.js b/benchmarks/js/js_benchmark.js index c44fee01c39c..9ba482896916 100644 --- a/benchmarks/js/js_benchmark.js +++ b/benchmarks/js/js_benchmark.js @@ -41,9 +41,9 @@ process.argv.forEach(function(filename, index) { totalBytes += onePayload.length; }); - var senarios = benchmarkSuite.newBenchmark( + var scenarios = benchmarkSuite.newBenchmark( benchmarkDataset.getMessageName(), filename, "js"); - senarios.suite + scenarios.suite .add("js deserialize", function() { benchmarkDataset.getPayloadList().forEach(function(onePayload) { var protoType = getNewPrototype(benchmarkDataset.getMessageName()); @@ -61,15 +61,15 @@ process.argv.forEach(function(filename, index) { results.push({ filename: filename, benchmarks: { - protobufjs_decoding: senarios.benches[0] * totalBytes / 1024 / 1024, - protobufjs_encoding: senarios.benches[1] * totalBytes / 1024 / 1024 + protobufjs_decoding: scenarios.benches[0] * totalBytes / 1024 / 1024, + protobufjs_encoding: scenarios.benches[1] * totalBytes / 1024 / 1024 } }) console.log("Throughput for deserialize: " - + senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" ); + + scenarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" ); console.log("Throughput for serialize: " - + senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" ); + + scenarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" ); console.log(""); }); console.log("#####################################################"); diff --git a/benchmarks/protobuf.js/protobufjs_benchmark.js b/benchmarks/protobuf.js/protobufjs_benchmark.js index 19e54972b86d..e062d1c6b898 100644 --- a/benchmarks/protobuf.js/protobufjs_benchmark.js +++ b/benchmarks/protobuf.js/protobufjs_benchmark.js @@ -31,9 +31,9 @@ process.argv.forEach(function(filename, index) { totalBytes += onePayload.length; }); - var senarios = benchmarkSuite.newBenchmark( + var scenarios = benchmarkSuite.newBenchmark( benchmarkDataset.messageName, filename, "protobufjs"); - senarios.suite + scenarios.suite .add("protobuf.js static decoding", function() { benchmarkDataset.payload.forEach(function(onePayload) { var protoType = getNewPrototype(benchmarkDataset.messageName); @@ -51,15 +51,15 @@ process.argv.forEach(function(filename, index) { results.push({ filename: filename, benchmarks: { - protobufjs_decoding: senarios.benches[0] * totalBytes, - protobufjs_encoding: senarios.benches[1] * totalBytes + protobufjs_decoding: scenarios.benches[0] * totalBytes, + protobufjs_encoding: scenarios.benches[1] * totalBytes } }) console.log("Throughput for decoding: " - + senarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" ); + + scenarios.benches[0] * totalBytes / 1024 / 1024 + "MB/s" ); console.log("Throughput for encoding: " - + senarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" ); + + scenarios.benches[1] * totalBytes / 1024 / 1024 + "MB/s" ); console.log(""); }); console.log("#####################################################"); diff --git a/benchmarks/python/py_benchmark.py b/benchmarks/python/py_benchmark.py old mode 100755 new mode 100644 diff --git a/benchmarks/util/result_parser.py b/benchmarks/util/result_parser.py old mode 100755 new mode 100644 diff --git a/benchmarks/util/result_uploader.py b/benchmarks/util/result_uploader.py old mode 100755 new mode 100644 diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 8e5e68073bc1..52661f522d99 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -28,11 +28,23 @@ else() set(CMAKE_CXX_EXTENSIONS OFF) endif() +# The Intel compiler isn't able to deal with noinline member functions of +# template classes defined in headers. As such it spams the output with +# warning #2196: routine is both "inline" and "noinline" +# This silences that warning. +if (CMAKE_CXX_COMPILER_ID MATCHES Intel) + string(APPEND CMAKE_CXX_FLAGS " -diag-disable=2196") +endif() + # Options +if(WITH_PROTOC) + set(protobuf_PROTOC_EXE ${WITH_PROTOC} CACHE FILEPATH "Protocol Buffer Compiler executable" FORCE) +endif() option(protobuf_BUILD_TESTS "Build tests" ON) option(protobuf_BUILD_CONFORMANCE "Build conformance tests" OFF) option(protobuf_BUILD_EXAMPLES "Build examples" OFF) option(protobuf_BUILD_PROTOC_BINARIES "Build libprotoc and protoc compiler" ON) +option(protobuf_BUILD_LIBPROTOC "Build libprotoc" OFF) if (BUILD_SHARED_LIBS) set(protobuf_BUILD_SHARED_LIBS_DEFAULT ON) else (BUILD_SHARED_LIBS) @@ -50,6 +62,10 @@ mark_as_advanced(protobuf_DEBUG_POSTFIX) # User options include(protobuf-options.cmake) +# Overrides for option dependencies +if (protobuf_BUILD_PROTOC_BINARIES OR protobuf_BUILD_TESTS) + set(protobuf_BUILD_LIBPROTOC ON) +endif () # Path to main configure script set(protobuf_CONFIGURE_SCRIPT "../configure.ac") @@ -234,11 +250,29 @@ endif (protobuf_UNICODE) include(libprotobuf-lite.cmake) include(libprotobuf.cmake) -if (protobuf_BUILD_PROTOC_BINARIES) +if (protobuf_BUILD_LIBPROTOC) include(libprotoc.cmake) +endif (protobuf_BUILD_LIBPROTOC) +if (protobuf_BUILD_PROTOC_BINARIES) include(protoc.cmake) + if (NOT DEFINED protobuf_PROTOC_EXE) + set(protobuf_PROTOC_EXE protoc) + endif (NOT DEFINED protobuf_PROTOC_EXE) endif (protobuf_BUILD_PROTOC_BINARIES) +# Ensure we have a protoc executable if we need one +if (protobuf_BUILD_TESTS OR protobuf_BUILD_CONFORMANCE OR protobuf_BUILD_EXAMPLES) + if (NOT DEFINED protobuf_PROTOC_EXE) + find_program(protobuf_PROTOC_EXE protoc) + if (NOT protobuf_PROTOC_EXE) + message(FATAL "Build requires 'protoc' but binary not found and not building protoc.") + endif () + endif () + if(protobuf_VERBOSE) + message(STATUS "Using protoc : ${protobuf_PROTOC_EXE}") + endif(protobuf_VERBOSE) +endif () + if (protobuf_BUILD_TESTS) include(tests.cmake) endif (protobuf_BUILD_TESTS) @@ -254,5 +288,5 @@ if (protobuf_BUILD_EXAMPLES) endif (protobuf_BUILD_EXAMPLES) if(protobuf_VERBOSE) - message(STATUS "Protocol Buffers Configuring done") -endif() + message(STATUS "Protocol Buffers Configuring done") +endif(protobuf_VERBOSE) diff --git a/cmake/conformance.cmake b/cmake/conformance.cmake index 82b4cf580a7d..76eae8a3acd5 100644 --- a/cmake/conformance.cmake +++ b/cmake/conformance.cmake @@ -1,8 +1,8 @@ add_custom_command( OUTPUT ${protobuf_source_dir}/conformance/conformance.pb.cc - DEPENDS protoc ${protobuf_source_dir}/conformance/conformance.proto - COMMAND protoc ${protobuf_source_dir}/conformance/conformance.proto + DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/conformance/conformance.proto + COMMAND ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/conformance/conformance.proto --proto_path=${protobuf_source_dir}/conformance --cpp_out=${protobuf_source_dir}/conformance ) @@ -10,9 +10,9 @@ add_custom_command( add_custom_command( OUTPUT ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.pb.cc ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.pb.cc - DEPENDS protoc ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.proto - protoc ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.proto - COMMAND protoc ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.proto + DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.proto + ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.proto + COMMAND ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/google/protobuf/test_messages_proto3.proto ${protobuf_source_dir}/src/google/protobuf/test_messages_proto2.proto --proto_path=${protobuf_source_dir}/src --cpp_out=${protobuf_source_dir}/src diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 007cc8066945..5c5799efa1e8 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -53,7 +53,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tab copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\inlined_string_field.h" include\google\protobuf\inlined_string_field.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\io_win32.h" include\google\protobuf\io\io_win32.h @@ -88,7 +87,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\bytestream.h" i copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\callback.h" include\google\protobuf\stubs\callback.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\casts.h" include\google\protobuf\stubs\casts.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\common.h" include\google\protobuf\stubs\common.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\fastmem.h" include\google\protobuf\stubs\fastmem.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\hash.h" include\google\protobuf\stubs\hash.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\logging.h" include\google\protobuf\stubs\logging.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\stubs\macros.h" include\google\protobuf\stubs\macros.h diff --git a/cmake/install.cmake b/cmake/install.cmake index be47c54a1e21..9dd6e7710f0c 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -6,9 +6,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/protobuf-lite.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/protobuf-lite.pc @ONLY) set(_protobuf_libraries libprotobuf-lite libprotobuf) -if (protobuf_BUILD_PROTOC_BINARIES) +if (protobuf_BUILD_LIBPROTOC) list(APPEND _protobuf_libraries libprotoc) -endif (protobuf_BUILD_PROTOC_BINARIES) +endif (protobuf_BUILD_LIBPROTOC) foreach(_library ${_protobuf_libraries}) set_property(TARGET ${_library} @@ -102,12 +102,16 @@ endforeach() # Install configuration set(_cmakedir_desc "Directory relative to CMAKE_INSTALL to install the cmake configuration files") +set(_exampledir_desc "Directory relative to CMAKE_INSTALL_DATA to install examples") if(NOT MSVC) set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/protobuf" CACHE STRING "${_cmakedir_desc}") + set(CMAKE_INSTALL_EXAMPLEDIR "${CMAKE_INSTALL_DATADIR}/protobuf/examples" CACHE STRING "${_exampledir_desc}") else() set(CMAKE_INSTALL_CMAKEDIR "cmake" CACHE STRING "${_cmakedir_desc}") + set(CMAKE_INSTALL_EXAMPLEDIR "examples" CACHE STRING "${_exampledir_desc}") endif() mark_as_advanced(CMAKE_INSTALL_CMAKEDIR) +mark_as_advanced(CMAKE_INSTALL_EXAMPLEDIR) configure_file(protobuf-config.cmake.in ${CMAKE_INSTALL_CMAKEDIR}/protobuf-config.cmake @ONLY) @@ -145,6 +149,7 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}/ option(protobuf_INSTALL_EXAMPLES "Install the examples folder" OFF) if(protobuf_INSTALL_EXAMPLES) - install(DIRECTORY ../examples/ DESTINATION examples + install(DIRECTORY ../examples/ + DESTINATION "${CMAKE_INSTALL_EXAMPLEDIR}" COMPONENT protobuf-examples) endif() diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index 6bf86a2770e1..6d325d5dcad4 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -1,6 +1,7 @@ set(libprotobuf_lite_files ${protobuf_source_dir}/src/google/protobuf/any_lite.cc ${protobuf_source_dir}/src/google/protobuf/arena.cc + ${protobuf_source_dir}/src/google/protobuf/arenastring.cc ${protobuf_source_dir}/src/google/protobuf/extension_set.cc ${protobuf_source_dir}/src/google/protobuf/generated_enum_util.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.cc @@ -12,6 +13,7 @@ set(libprotobuf_lite_files ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.cc ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl.cc ${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc + ${protobuf_source_dir}/src/google/protobuf/map.cc ${protobuf_source_dir}/src/google/protobuf/message_lite.cc ${protobuf_source_dir}/src/google/protobuf/parse_context.cc ${protobuf_source_dir}/src/google/protobuf/repeated_field.cc @@ -67,6 +69,9 @@ target_link_libraries(libprotobuf-lite ${CMAKE_THREAD_LIBS_INIT}) if(protobuf_LINK_LIBATOMIC) target_link_libraries(libprotobuf-lite atomic) endif() +if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + target_link_libraries(libprotobuf-lite log) +endif() target_include_directories(libprotobuf-lite PUBLIC ${protobuf_source_dir}/src) if(MSVC AND protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf-lite diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index 0c12596c238b..a5be494fb702 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -121,6 +121,9 @@ endif() if(protobuf_LINK_LIBATOMIC) target_link_libraries(libprotobuf atomic) endif() +if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + target_link_libraries(libprotobuf log) +endif() target_include_directories(libprotobuf PUBLIC ${protobuf_source_dir}/src) if(MSVC AND protobuf_BUILD_SHARED_LIBS) target_compile_definitions(libprotobuf diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in index 29e39d88af79..fac5efe44077 100644 --- a/cmake/protobuf-config.cmake.in +++ b/cmake/protobuf-config.cmake.in @@ -11,7 +11,7 @@ function(protobuf_generate) include(CMakeParseArguments) set(_options APPEND_PATH) - set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR) + set(_singleargs LANGUAGE OUT_VAR EXPORT_MACRO PROTOC_OUT_DIR PLUGIN) if(COMMAND target_sources) list(APPEND _singleargs TARGET) endif() @@ -41,6 +41,10 @@ function(protobuf_generate) if(protobuf_generate_EXPORT_MACRO AND protobuf_generate_LANGUAGE STREQUAL cpp) set(_dll_export_decl "dllexport_decl=${protobuf_generate_EXPORT_MACRO}:") endif() + + if(protobuf_generate_PLUGIN) + set(_plugin "--plugin=${protobuf_generate_PLUGIN}") + endif() if(NOT protobuf_generate_GENERATE_EXTENSIONS) if(protobuf_generate_LANGUAGE STREQUAL cpp) @@ -77,8 +81,6 @@ function(protobuf_generate) list(APPEND _protobuf_include_path -I ${_abs_path}) endif() endforeach() - else() - set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) endif() foreach(DIR ${protobuf_generate_IMPORT_DIRS}) @@ -89,12 +91,35 @@ function(protobuf_generate) endif() endforeach() + if(NOT _protobuf_include_path) + set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) + endif() + set(_generated_srcs_all) foreach(_proto ${protobuf_generate_PROTOS}) get_filename_component(_abs_file ${_proto} ABSOLUTE) get_filename_component(_abs_dir ${_abs_file} DIRECTORY) - get_filename_component(_basename ${_proto} NAME_WE) - file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir}) + + get_filename_component(_file_full_name ${_proto} NAME) + string(FIND "${_file_full_name}" "." _file_last_ext_pos REVERSE) + string(SUBSTRING "${_file_full_name}" 0 ${_file_last_ext_pos} _basename) + + set(_suitable_include_found FALSE) + foreach(DIR ${_protobuf_include_path}) + if(NOT DIR STREQUAL "-I") + file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir}) + string(FIND "${_rel_dir}" "../" _is_in_parent_folder) + if (NOT ${_is_in_parent_folder} EQUAL 0) + set(_suitable_include_found TRUE) + break() + endif() + endif() + endforeach() + + if(NOT _suitable_include_found) + message(SEND_ERROR "Error: protobuf_generate could not find any correct proto include directory.") + return() + endif() set(_generated_srcs) foreach(_ext ${protobuf_generate_GENERATE_EXTENSIONS}) @@ -105,7 +130,7 @@ function(protobuf_generate) add_custom_command( OUTPUT ${_generated_srcs} COMMAND protobuf::protoc - ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_protobuf_include_path} ${_abs_file} + ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} DEPENDS ${_abs_file} protobuf::protoc COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" VERBATIM ) diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in index 74c5488729a1..810256e54cfb 100644 --- a/cmake/protobuf-module.cmake.in +++ b/cmake/protobuf-module.cmake.in @@ -97,6 +97,10 @@ function(_protobuf_find_libraries name filename) else() get_target_property(${name}_LIBRARY_RELEASE protobuf::lib${filename} LOCATION_RELEASE) + get_target_property(${name}_LIBRARY_RELWITHDEBINFO protobuf::lib${filename} + LOCATION_RELWITHDEBINFO) + get_target_property(${name}_LIBRARY_MINSIZEREL protobuf::lib${filename} + LOCATION_MINSIZEREL) get_target_property(${name}_LIBRARY_DEBUG protobuf::lib${filename} LOCATION_DEBUG) @@ -146,6 +150,14 @@ get_target_property(Protobuf_INCLUDE_DIRS protobuf::libprotobuf # Set the protoc Executable get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc IMPORTED_LOCATION_RELEASE) +if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_RELWITHDEBINFO) +endif() +if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") + get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc + IMPORTED_LOCATION_MINSIZEREL) +endif() if(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") get_target_property(Protobuf_PROTOC_EXECUTABLE protobuf::protoc IMPORTED_LOCATION_DEBUG) diff --git a/cmake/protobuf-options.cmake b/cmake/protobuf-options.cmake index 47fb15825752..93ec898e4a44 100644 --- a/cmake/protobuf-options.cmake +++ b/cmake/protobuf-options.cmake @@ -2,6 +2,6 @@ option(protobuf_VERBOSE "Enable for verbose output" OFF) mark_as_advanced(protobuf_VERBOSE) -# FindProtobuf module compatibel -option(protobuf_MODULE_COMPATIBLE "CMake build-in FindProtobuf.cmake module compatible" OFF) +# FindProtobuf module compatible +option(protobuf_MODULE_COMPATIBLE "CMake built-in FindProtobuf.cmake module compatible" OFF) mark_as_advanced(protobuf_MODULE_COMPATIBLE) diff --git a/cmake/tests.cmake b/cmake/tests.cmake index d4b47c54e500..4a54b70d7424 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -33,7 +33,6 @@ set(lite_test_protos google/protobuf/unittest_import_lite.proto google/protobuf/unittest_import_public_lite.proto google/protobuf/unittest_lite.proto - google/protobuf/unittest_no_arena_lite.proto ) set(tests_protos @@ -56,8 +55,6 @@ set(tests_protos google/protobuf/unittest_lite_imports_nonlite.proto google/protobuf/unittest_mset.proto google/protobuf/unittest_mset_wire_format.proto - google/protobuf/unittest_no_arena.proto - google/protobuf/unittest_no_arena_import.proto google/protobuf/unittest_no_field_presence.proto google/protobuf/unittest_no_generic_services.proto google/protobuf/unittest_optimize_for.proto @@ -67,6 +64,7 @@ set(tests_protos google/protobuf/unittest_proto3_arena.proto google/protobuf/unittest_proto3_arena_lite.proto google/protobuf/unittest_proto3_lite.proto + google/protobuf/unittest_proto3_optional.proto google/protobuf/unittest_well_known_types.proto google/protobuf/util/internal/testdata/anys.proto google/protobuf/util/internal/testdata/books.proto @@ -89,10 +87,11 @@ macro(compile_proto_file filename) get_filename_component(basename ${filename} NAME_WE) add_custom_command( OUTPUT ${protobuf_source_dir}/src/${dirname}/${basename}.pb.cc - DEPENDS protoc ${protobuf_source_dir}/src/${dirname}/${basename}.proto - COMMAND protoc ${protobuf_source_dir}/src/${dirname}/${basename}.proto + DEPENDS ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/${dirname}/${basename}.proto + COMMAND ${protobuf_PROTOC_EXE} ${protobuf_source_dir}/src/${dirname}/${basename}.proto --proto_path=${protobuf_source_dir}/src --cpp_out=${protobuf_source_dir}/src + --experimental_allow_proto3_optional ) endmacro(compile_proto_file) diff --git a/compiler_config_setting.bzl b/compiler_config_setting.bzl index 5e52a6524ffe..f4d1f7b9ef4a 100644 --- a/compiler_config_setting.bzl +++ b/compiler_config_setting.bzl @@ -1,6 +1,6 @@ """Creates config_setting that allows selecting based on 'compiler' value.""" -def create_compiler_config_setting(name, value): +def create_compiler_config_setting(name, value, visibility = None): # The "do_not_use_tools_cpp_compiler_present" attribute exists to # distinguish between older versions of Bazel that do not support # "@bazel_tools//tools/cpp:compiler" flag_value, and newer ones that do. @@ -13,9 +13,11 @@ def create_compiler_config_setting(name, value): flag_values = { "@bazel_tools//tools/cpp:compiler": value, }, + visibility = visibility, ) else: native.config_setting( name = name, values = {"compiler": value}, + visibility = visibility, ) diff --git a/configure.ac b/configure.ac index df39c05ea5f6..eb70a76e165a 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.59) # In the SVN trunk, the version should always be the next anticipated release # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # the size of one file name in the dist tarfile over the 99-char limit.) -AC_INIT([Protocol Buffers],[3.11.2],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[3.14.0],[protobuf@googlegroups.com],[protobuf]) AM_MAINTAINER_MODE([enable]) diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java index fa4dfb774ddf..531998262d72 100644 --- a/conformance/ConformanceJava.java +++ b/conformance/ConformanceJava.java @@ -236,8 +236,10 @@ private MessageType parseBinary( private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest request) { com.google.protobuf.AbstractMessage testMessage; - boolean isProto3 = request.getMessageType().equals("protobuf_test_messages.proto3.TestAllTypesProto3"); - boolean isProto2 = request.getMessageType().equals("protobuf_test_messages.proto2.TestAllTypesProto2"); + boolean isProto3 = + request.getMessageType().equals("protobuf_test_messages.proto3.TestAllTypesProto3"); + boolean isProto2 = + request.getMessageType().equals("protobuf_test_messages.proto2.TestAllTypesProto2"); switch (request.getPayloadCase()) { case PROTOBUF_PAYLOAD: { @@ -264,15 +266,24 @@ private Conformance.ConformanceResponse doTest(Conformance.ConformanceRequest re } case JSON_PAYLOAD: { try { - TestMessagesProto3.TestAllTypesProto3.Builder builder = - TestMessagesProto3.TestAllTypesProto3.newBuilder(); JsonFormat.Parser parser = JsonFormat.parser().usingTypeRegistry(typeRegistry); if (request.getTestCategory() == Conformance.TestCategory.JSON_IGNORE_UNKNOWN_PARSING_TEST) { parser = parser.ignoringUnknownFields(); } - parser.merge(request.getJsonPayload(), builder); - testMessage = builder.build(); + if (isProto3) { + TestMessagesProto3.TestAllTypesProto3.Builder builder = + TestMessagesProto3.TestAllTypesProto3.newBuilder(); + parser.merge(request.getJsonPayload(), builder); + testMessage = builder.build(); + } else if (isProto2) { + TestMessagesProto2.TestAllTypesProto2.Builder builder = + TestMessagesProto2.TestAllTypesProto2.newBuilder(); + parser.merge(request.getJsonPayload(), builder); + testMessage = builder.build(); + } else { + throw new RuntimeException("Protobuf request doesn't have specific payload type."); + } } catch (InvalidProtocolBufferException e) { return Conformance.ConformanceResponse.newBuilder().setParseError(e.getMessage()).build(); } diff --git a/conformance/Makefile.am b/conformance/Makefile.am index 6815c733a522..0b6fd535f534 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -333,7 +333,7 @@ conformance-php-c: # Targets for actually running tests. test_cpp: protoc_middleman conformance-test-runner conformance-cpp - ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt ./conformance-cpp + ./conformance-test-runner --enforce_recommended --failure_list failure_list_cpp.txt --text_format_failure_list text_format_failure_list_cpp.txt ./conformance-cpp test_java: protoc_middleman conformance-test-runner conformance-java ./conformance-test-runner --enforce_recommended --failure_list failure_list_java.txt --text_format_failure_list text_format_failure_list_java.txt ./conformance-java @@ -353,16 +353,27 @@ test_php: protoc_middleman conformance-test-runner conformance-php $(other_langu test_php_c: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs) ./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c -test_php_c_32: protoc_middleman conformance-test-runner conformance-php-c $(other_language_protoc_outputs) - ./conformance-test-runner --enforce_recommended --failure_list failure_list_php_c_32.txt --text_format_failure_list text_format_failure_list_php.txt ./conformance-php-c - # These depend on library paths being properly set up. The easiest way to # run them is to just use "tox" from the python dir. test_python: protoc_middleman conformance-test-runner - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py + VERSION="$(shell python --version 2>&1)"; \ + if [[ "$$VERSION" == "Python 2.7"* ]]; then \ + echo "Using Python 2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python_2.7.txt ./conformance_python.py; \ + else \ + echo "Using Python >2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py; \ + fi test_python_cpp: protoc_middleman conformance-test-runner - ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py + VERSION="$(shell python --version 2>&1)"; \ + if [[ "$$VERSION" == "Python 2.7"* ]]; then \ + echo "Using Python 2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp_2.7.txt ./conformance_python.py; \ + else \ + echo "Using Python >2.7 failure list."; \ + ./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt --text_format_failure_list text_format_failure_list_python_cpp.txt ./conformance_python.py; \ + fi test_nodejs: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) NODE_PATH=../js:. ./conformance-test-runner --enforce_recommended --failure_list failure_list_js.txt ./conformance_nodejs.js diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index f8665e2c3e0e..4a0d8e848048 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -556,24 +556,24 @@ void BinaryAndJsonConformanceSuite::RunValidProtobufTestWithMessage( equivalent_text_format, is_proto3); } -// According to proto3 JSON specification, JSON serializers follow more strict +// According to proto JSON specification, JSON serializers follow more strict // rules than parsers (e.g., a serializer must serialize int32 values as JSON // numbers while the parser is allowed to accept them as JSON strings). This -// method allows strict checking on a proto3 JSON serializer by inspecting +// method allows strict checking on a proto JSON serializer by inspecting // the JSON output directly. void BinaryAndJsonConformanceSuite::RunValidJsonTestWithValidator( const string& test_name, ConformanceLevel level, const string& input_json, - const Validator& validator) { - TestAllTypesProto3 prototype; - ConformanceRequestSetting setting( - level, conformance::JSON, conformance::JSON, - conformance::JSON_TEST, - prototype, test_name, input_json); + const Validator& validator, bool is_proto3) { + std::unique_ptr prototype = NewTestMessage(is_proto3); + ConformanceRequestSetting setting(level, conformance::JSON, conformance::JSON, + conformance::JSON_TEST, *prototype, + test_name, input_json); const ConformanceRequest& request = setting.GetRequest(); ConformanceResponse response; string effective_test_name = StrCat(setting.ConformanceLevelToString(level), - ".Proto3.JsonInput.", test_name, ".Validator"); + is_proto3 ? ".Proto3.JsonInput." : ".Proto2.JsonInput.", + test_name, ".Validator"); RunTest(effective_test_name, request, &response); @@ -1800,7 +1800,8 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { value.isMember("fieldName2") && value.isMember("FieldName3") && value.isMember("fieldName4"); - }); + }, + true); RunValidJsonTestWithValidator( "FieldNameWithNumbers", REQUIRED, R"({ @@ -1810,7 +1811,8 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { [](const Json::Value& value) { return value.isMember("field0name5") && value.isMember("field0Name6"); - }); + }, + true); RunValidJsonTestWithValidator( "FieldNameWithMixedCases", REQUIRED, R"({ @@ -1828,7 +1830,8 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { value.isMember("FieldName10") && value.isMember("FIELDNAME11") && value.isMember("FIELDName12"); - }); + }, + true); RunValidJsonTestWithValidator( "FieldNameWithDoubleUnderscores", RECOMMENDED, R"({ @@ -1846,7 +1849,32 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldNameConvention() { value.isMember("fieldName16") && value.isMember("fieldName17") && value.isMember("FieldName18"); - }); + }, + true); + RunValidJsonTestWithValidator( + "StoresDefaultPrimitive", REQUIRED, + R"({ + "FieldName13": 0 + })", + [](const Json::Value& value) { return value.isMember("FieldName13"); }, + false); + RunValidJsonTestWithValidator( + "SkipsDefaultPrimitive", REQUIRED, + R"({ + "FieldName13": 0 + })", + [](const Json::Value& value) { return !value.isMember("FieldName13"); }, + true); + RunValidJsonTestWithValidator( + "FieldNameExtension", RECOMMENDED, + R"({ + "[protobuf_test_messages.proto2.extension_int32]": 1 + })", + [](const Json::Value& value) { + return value.isMember( + "[protobuf_test_messages.proto2.extension_int32]"); + }, + false); } void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { @@ -1995,19 +2023,19 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { // 64-bit values are serialized as strings. RunValidJsonTestWithValidator( - "Int64FieldBeString", RECOMMENDED, - R"({"optionalInt64": 1})", + "Int64FieldBeString", RECOMMENDED, R"({"optionalInt64": 1})", [](const Json::Value& value) { return value["optionalInt64"].type() == Json::stringValue && value["optionalInt64"].asString() == "1"; - }); + }, + true); RunValidJsonTestWithValidator( - "Uint64FieldBeString", RECOMMENDED, - R"({"optionalUint64": 1})", + "Uint64FieldBeString", RECOMMENDED, R"({"optionalUint64": 1})", [](const Json::Value& value) { return value["optionalUint64"].type() == Json::stringValue && value["optionalUint64"].asString() == "1"; - }); + }, + true); // Bool fields. RunValidJsonTest( @@ -2156,12 +2184,12 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { { TestAllTypesProto3 message; message.set_optional_double( - WireFormatLite::DecodeDouble(0x7FFA123456789ABCLL)); + WireFormatLite::DecodeDouble(int64{0x7FFA123456789ABC})); RunValidJsonTestWithProtobufInput( "DoubleFieldNormalizeQuietNan", REQUIRED, message, "optional_double: nan"); message.set_optional_double( - WireFormatLite::DecodeDouble(0xFFFBCBA987654321LL)); + WireFormatLite::DecodeDouble(uint64{0xFFFBCBA987654321})); RunValidJsonTestWithProtobufInput( "DoubleFieldNormalizeSignalingNan", REQUIRED, message, "optional_double: nan"); @@ -2223,12 +2251,12 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForNonRepeatedTypes() { "optional_nested_enum: BAR"); // Unknown enum values are represented as numeric values. RunValidJsonTestWithValidator( - "EnumFieldUnknownValue", REQUIRED, - R"({"optionalNestedEnum": 123})", + "EnumFieldUnknownValue", REQUIRED, R"({"optionalNestedEnum": 123})", [](const Json::Value& value) { return value["optionalNestedEnum"].type() == Json::intValue && value["optionalNestedEnum"].asInt() == 123; - }); + }, + true); // String fields. RunValidJsonTest( @@ -2712,25 +2740,29 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForWrapperTypes() { R"({"optionalDuration": "1.000000000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1s"; - }); + }, + true); RunValidJsonTestWithValidator( "DurationHas3FractionalDigits", RECOMMENDED, R"({"optionalDuration": "1.010000000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.010s"; - }); + }, + true); RunValidJsonTestWithValidator( "DurationHas6FractionalDigits", RECOMMENDED, R"({"optionalDuration": "1.000010000s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.000010s"; - }); + }, + true); RunValidJsonTestWithValidator( "DurationHas9FractionalDigits", RECOMMENDED, R"({"optionalDuration": "1.000000010s"})", [](const Json::Value& value) { return value["optionalDuration"].asString() == "1.000000010s"; - }); + }, + true); // Timestamp RunValidJsonTest( @@ -2794,34 +2826,39 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForWrapperTypes() { R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z"; - }); + }, + true); RunValidJsonTestWithValidator( "TimestampHasZeroFractionalDigit", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000000000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00Z"; - }); + }, + true); RunValidJsonTestWithValidator( "TimestampHas3FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.010000000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.010Z"; - }); + }, + true); RunValidJsonTestWithValidator( "TimestampHas6FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000010000Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.000010Z"; - }); + }, + true); RunValidJsonTestWithValidator( "TimestampHas9FractionalDigits", RECOMMENDED, R"({"optionalTimestamp": "1970-01-01T00:00:00.000000010Z"})", [](const Json::Value& value) { return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.000000010Z"; - }); + }, + true); } void BinaryAndJsonConformanceSuite::RunJsonTestsForFieldMask() { @@ -3014,6 +3051,29 @@ void BinaryAndJsonConformanceSuite::RunJsonTestsForValue() { } ] )"); + RunValidJsonTestWithValidator( + "NullValueInOtherOneofOldFormat", RECOMMENDED, + R"({"oneofNullValue": "NULL_VALUE"})", + [](const Json::Value& value) { + return (value.isMember("oneofNullValue") && + value["oneofNullValue"].isNull()); + }, + true); + RunValidJsonTestWithValidator( + "NullValueInOtherOneofNewFormat", RECOMMENDED, + R"({"oneofNullValue": null})", + [](const Json::Value& value) { + return (value.isMember("oneofNullValue") && + value["oneofNullValue"].isNull()); + }, + true); + RunValidJsonTestWithValidator( + "NullValueInNormalMessage", RECOMMENDED, + R"({"optionalNullValue": null})", + [](const Json::Value& value) { + return value.empty(); + }, + true); } void BinaryAndJsonConformanceSuite::RunJsonTestsForAny() { diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h index aaf8bb4d9ef8..0a1752634d55 100644 --- a/conformance/binary_json_conformance_suite.h +++ b/conformance/binary_json_conformance_suite.h @@ -53,35 +53,34 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { void RunJsonTestsForStruct(); void RunJsonTestsForValue(); void RunJsonTestsForAny(); - void RunValidJsonTest(const string& test_name, - ConformanceLevel level, - const string& input_json, - const string& equivalent_text_format); + void RunValidJsonTest(const std::string& test_name, ConformanceLevel level, + const std::string& input_json, + const std::string& equivalent_text_format); void RunValidJsonTestWithProtobufInput( - const string& test_name, - ConformanceLevel level, + const std::string& test_name, ConformanceLevel level, const protobuf_test_messages::proto3::TestAllTypesProto3& input, - const string& equivalent_text_format); - void RunValidJsonIgnoreUnknownTest( - const string& test_name, ConformanceLevel level, const string& input_json, - const string& equivalent_text_format); - void RunValidProtobufTest(const string& test_name, ConformanceLevel level, - const string& input_protobuf, - const string& equivalent_text_format, + const std::string& equivalent_text_format); + void RunValidJsonIgnoreUnknownTest(const std::string& test_name, + ConformanceLevel level, + const std::string& input_json, + const std::string& equivalent_text_format); + void RunValidProtobufTest(const std::string& test_name, + ConformanceLevel level, + const std::string& input_protobuf, + const std::string& equivalent_text_format, bool is_proto3); - void RunValidBinaryProtobufTest(const string& test_name, + void RunValidBinaryProtobufTest(const std::string& test_name, ConformanceLevel level, - const string& input_protobuf, + const std::string& input_protobuf, bool is_proto3); - void RunValidBinaryProtobufTest(const string& test_name, + void RunValidBinaryProtobufTest(const std::string& test_name, ConformanceLevel level, - const string& input_protobuf, - const string& expected_protobuf, + const std::string& input_protobuf, + const std::string& expected_protobuf, bool is_proto3); void RunValidProtobufTestWithMessage( - const string& test_name, ConformanceLevel level, - const Message *input, - const string& equivalent_text_format, + const std::string& test_name, ConformanceLevel level, + const Message* input, const std::string& equivalent_text_format, bool is_proto3); bool ParseJsonResponse( @@ -93,20 +92,21 @@ class BinaryAndJsonConformanceSuite : public ConformanceTestSuite { Message* test_message) override; typedef std::function Validator; - void RunValidJsonTestWithValidator(const string& test_name, + void RunValidJsonTestWithValidator(const std::string& test_name, ConformanceLevel level, - const string& input_json, - const Validator& validator); - void ExpectParseFailureForJson(const string& test_name, + const std::string& input_json, + const Validator& validator, + bool is_proto3); + void ExpectParseFailureForJson(const std::string& test_name, ConformanceLevel level, - const string& input_json); - void ExpectSerializeFailureForJson(const string& test_name, + const std::string& input_json); + void ExpectSerializeFailureForJson(const std::string& test_name, ConformanceLevel level, - const string& text_format); - void ExpectParseFailureForProtoWithProtoVersion (const string& proto, - const string& test_name, - ConformanceLevel level, - bool is_proto3); + const std::string& text_format); + void ExpectParseFailureForProtoWithProtoVersion(const std::string& proto, + const std::string& test_name, + ConformanceLevel level, + bool is_proto3); void ExpectParseFailureForProto(const std::string& proto, const std::string& test_name, ConformanceLevel level); diff --git a/conformance/conformance.proto b/conformance/conformance.proto index 26c0bd26f336..49608b38f4c4 100644 --- a/conformance/conformance.proto +++ b/conformance/conformance.proto @@ -64,7 +64,7 @@ enum TestCategory { BINARY_TEST = 1; // Test binary wire format. JSON_TEST = 2; // Test json wire format. // Similar to JSON_TEST. However, during parsing json, testee should ignore - // unknown fields. This feature is optional. Each implementation can descide + // unknown fields. This feature is optional. Each implementation can decide // whether to support it. See // https://developers.google.com/protocol-buffers/docs/proto3#json_options // for more detail. @@ -113,7 +113,7 @@ message ConformanceRequest { string message_type = 4; // Each test is given a specific test category. Some category may need - // spedific support in testee programs. Refer to the definition of TestCategory + // specific support in testee programs. Refer to the definition of TestCategory // for more information. TestCategory test_category = 5; diff --git a/conformance/conformance_cpp.cc b/conformance/conformance_cpp.cc index 1cdfdae45736..9546518bf553 100644 --- a/conformance/conformance_cpp.cc +++ b/conformance/conformance_cpp.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include "conformance.pb.h" #include #include @@ -125,9 +126,9 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) { options.ignore_unknown_fields = (request.test_category() == conformance::JSON_IGNORE_UNKNOWN_PARSING_TEST); - Status status = JsonToBinaryString(type_resolver, *type_url, - request.json_payload(), &proto_binary, - options); + util::Status status = + JsonToBinaryString(type_resolver, *type_url, request.json_payload(), + &proto_binary, options); if (!status.ok()) { response->set_parse_error(string("Parse error: ") + std::string(status.error_message())); @@ -179,8 +180,9 @@ void DoTest(const ConformanceRequest& request, ConformanceResponse* response) { case conformance::JSON: { string proto_binary; GOOGLE_CHECK(test_message->SerializeToString(&proto_binary)); - Status status = BinaryToJsonString(type_resolver, *type_url, proto_binary, - response->mutable_json_payload()); + util::Status status = + BinaryToJsonString(type_resolver, *type_url, proto_binary, + response->mutable_json_payload()); if (!status.ok()) { response->set_serialize_error( string("Failed to serialize JSON output: ") + diff --git a/conformance/conformance_php.php b/conformance/conformance_php.php old mode 100755 new mode 100644 diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 417ec4e3cc56..76bd1bc3f1c9 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -88,7 +88,7 @@ class ForkPipeRunner : public ConformanceTestRunner { const std::vector& suites); ForkPipeRunner(const std::string& executable, - const std::vector& executable_args) + const std::vector& executable_args) : child_pid_(-1), executable_(executable), executable_args_(executable_args) {} @@ -113,7 +113,7 @@ class ForkPipeRunner : public ConformanceTestRunner { int read_fd_; pid_t child_pid_; std::string executable_; - const std::vector executable_args_; + const std::vector executable_args_; std::string current_test_name_; }; @@ -168,9 +168,7 @@ class ConformanceTestSuite { // Gets the flag name to the failure list file. // By default, this would return --failure_list - string GetFailureListFlagName() { - return failure_list_flag_name_; - } + std::string GetFailureListFlagName() { return failure_list_flag_name_; } void SetFailureListFlagName(const std::string& failure_list_flag_name) { failure_list_flag_name_ = failure_list_flag_name; @@ -207,18 +205,18 @@ class ConformanceTestSuite { class ConformanceRequestSetting { public: - ConformanceRequestSetting( - ConformanceLevel level, - conformance::WireFormat input_format, - conformance::WireFormat output_format, - conformance::TestCategory test_category, - const Message& prototype_message, - const string& test_name, const string& input); + ConformanceRequestSetting(ConformanceLevel level, + conformance::WireFormat input_format, + conformance::WireFormat output_format, + conformance::TestCategory test_category, + const Message& prototype_message, + const std::string& test_name, + const std::string& input); virtual ~ConformanceRequestSetting() {} std::unique_ptr NewTestMessage() const; - string GetTestName() const; + std::string GetTestName() const; const conformance::ConformanceRequest& GetRequest() const { return request_; @@ -228,7 +226,7 @@ class ConformanceTestSuite { return level_; } - string ConformanceLevelToString(ConformanceLevel level) const; + std::string ConformanceLevelToString(ConformanceLevel level) const; void SetPrintUnknownFields(bool print_unknown_fields) { request_.set_print_unknown_fields(true); @@ -239,8 +237,9 @@ class ConformanceTestSuite { } protected: - virtual string InputFormatString(conformance::WireFormat format) const; - virtual string OutputFormatString(conformance::WireFormat format) const; + virtual std::string InputFormatString(conformance::WireFormat format) const; + virtual std::string OutputFormatString( + conformance::WireFormat format) const; conformance::ConformanceRequest request_; private: @@ -249,12 +248,12 @@ class ConformanceTestSuite { ::conformance::WireFormat output_format_; const Message& prototype_message_; std::unique_ptr prototype_message_for_compare_; - string test_name_; + std::string test_name_; }; - bool CheckSetEmpty(const std::set& set_to_check, + bool CheckSetEmpty(const std::set& set_to_check, const std::string& write_to_file, const std::string& msg); - string WireFormatToString(conformance::WireFormat wire_format); + std::string WireFormatToString(conformance::WireFormat wire_format); // Parse payload in the response to the given message. Returns true on // success. @@ -264,24 +263,23 @@ class ConformanceTestSuite { Message* test_message) = 0; void VerifyResponse(const ConformanceRequestSetting& setting, - const string& equivalent_wire_format, + const std::string& equivalent_wire_format, const conformance::ConformanceResponse& response, bool need_report_success, bool require_same_wire_format); void ReportSuccess(const std::string& test_name); - void ReportFailure(const string& test_name, - ConformanceLevel level, + void ReportFailure(const std::string& test_name, ConformanceLevel level, const conformance::ConformanceRequest& request, const conformance::ConformanceResponse& response, const char* fmt, ...); - void ReportSkip(const string& test_name, + void ReportSkip(const std::string& test_name, const conformance::ConformanceRequest& request, const conformance::ConformanceResponse& response); void RunValidInputTest(const ConformanceRequestSetting& setting, - const string& equivalent_text_format); + const std::string& equivalent_text_format); void RunValidBinaryInputTest(const ConformanceRequestSetting& setting, - const string& equivalent_wire_format, + const std::string& equivalent_wire_format, bool require_same_wire_format = false); void RunTest(const std::string& test_name, diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index 0c01e1e40c7e..d55fa9ff349f 100644 --- a/conformance/failure_list_cpp.txt +++ b/conformance/failure_list_cpp.txt @@ -34,3 +34,4 @@ Recommended.Proto3.JsonInput.TrailingCommaInAnObject Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithNewlines Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpace Recommended.Proto3.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace +Recommended.Proto2.JsonInput.FieldNameExtension.Validator diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt index 2a20aa78e7ff..31bdf25ebf45 100644 --- a/conformance/failure_list_csharp.txt +++ b/conformance/failure_list_csharp.txt @@ -1,2 +1,3 @@ Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput +Recommended.Proto2.JsonInput.FieldNameExtension.Validator diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt index dc1f9ba5c9fa..b29a63f5e430 100644 --- a/conformance/failure_list_java.txt +++ b/conformance/failure_list_java.txt @@ -34,6 +34,7 @@ Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted +Recommended.Proto2.JsonInput.FieldNameExtension.Validator Required.Proto3.JsonInput.EnumFieldNotQuoted Required.Proto3.JsonInput.Int32FieldLeadingZero Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero diff --git a/conformance/failure_list_js.txt b/conformance/failure_list_js.txt index ef9131a78eac..e69de29bb2d1 100644 --- a/conformance/failure_list_js.txt +++ b/conformance/failure_list_js.txt @@ -1,115 +0,0 @@ - -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput -Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MergeValue.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput diff --git a/conformance/failure_list_php.txt b/conformance/failure_list_php.txt index 7ee5b9aae1a5..d51a75dc3644 100644 --- a/conformance/failure_list_php.txt +++ b/conformance/failure_list_php.txt @@ -1,66 +1,12 @@ Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput Recommended.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter Recommended.Proto3.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput +Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator Required.Proto3.JsonInput.DoubleFieldTooSmall Required.Proto3.JsonInput.FloatFieldTooLarge Required.Proto3.JsonInput.FloatFieldTooSmall @@ -75,8 +21,8 @@ Required.Proto3.JsonInput.Uint32FieldNotInteger Required.Proto3.JsonInput.Uint64FieldNotInteger Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.JsonOutput Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput +Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.JsonOutput +Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.ProtobufOutput Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput -Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.JsonOutput -Required.Proto3.ProtobufInput.ValidDataOneof.MESSAGE.Merge.ProtobufOutput diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt index 6a6949fe4047..63c7e8a024cc 100644 --- a/conformance/failure_list_php_c.txt +++ b/conformance/failure_list_php_c.txt @@ -1,109 +1,2 @@ -Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput -Recommended.FieldMaskPathsDontRoundTrip.JsonOutput -Recommended.FieldMaskTooManyUnderscore.JsonOutput -Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput -Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput -Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator -Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator -Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter -Recommended.Proto3.JsonInput.MapFieldValueIsNull -Recommended.Proto3.JsonInput.OneofZeroBytes.JsonOutput -Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull -Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull -Recommended.Proto3.JsonInput.StringEndsWithEscapeChar -Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder -Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate -Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate -Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator -Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator -Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput -Required.DurationProtoInputTooLarge.JsonOutput -Required.DurationProtoInputTooSmall.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput -Required.Proto3.JsonInput.DurationMinValue.JsonOutput -Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput -Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput -Required.Proto3.JsonInput.FloatFieldNan.JsonOutput -Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput -Required.Proto3.JsonInput.OneofFieldDuplicate -Required.Proto3.JsonInput.RejectTopLevelNull -Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput -Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput -Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput -Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput -Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput -Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput -Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput -Required.TimestampProtoInputTooLarge.JsonOutput -Required.TimestampProtoInputTooSmall.JsonOutput +Recommended.Proto2.JsonInput.FieldNameExtension.Validator +Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator diff --git a/conformance/failure_list_php_c_32.txt b/conformance/failure_list_php_c_32.txt deleted file mode 100644 index f516f13ac300..000000000000 --- a/conformance/failure_list_php_c_32.txt +++ /dev/null @@ -1,142 +0,0 @@ -Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput -Recommended.FieldMaskPathsDontRoundTrip.JsonOutput -Recommended.FieldMaskTooManyUnderscore.JsonOutput -Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput -Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput -Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator -Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator -Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator -Recommended.Proto3.JsonInput.DurationHasZeroFractionalDigit.Validator -Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter -Recommended.Proto3.JsonInput.MapFieldValueIsNull -Recommended.Proto3.JsonInput.OneofZeroBytes.JsonOutput -Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull -Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull -Recommended.Proto3.JsonInput.StringEndsWithEscapeChar -Recommended.Proto3.JsonInput.StringFieldSurrogateInWrongOrder -Recommended.Proto3.JsonInput.StringFieldUnpairedHighSurrogate -Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate -Recommended.Proto3.JsonInput.TimestampHas3FractionalDigits.Validator -Recommended.Proto3.JsonInput.TimestampHas6FractionalDigits.Validator -Recommended.Proto3.JsonInput.TimestampHas9FractionalDigits.Validator -Recommended.Proto3.JsonInput.TimestampHasZeroFractionalDigit.Validator -Recommended.Proto3.JsonInput.TimestampZeroNormalized.Validator -Recommended.Proto3.ProtobufInput.OneofZeroBytes.JsonOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput -Required.DurationProtoInputTooLarge.JsonOutput -Required.DurationProtoInputTooSmall.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput -Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldNan.JsonOutput -Required.Proto3.JsonInput.DurationMaxValue.JsonOutput -Required.Proto3.JsonInput.DurationMaxValue.ProtobufOutput -Required.Proto3.JsonInput.DurationMinValue.JsonOutput -Required.Proto3.JsonInput.DurationMinValue.ProtobufOutput -Required.Proto3.JsonInput.DurationRepeatedValue.JsonOutput -Required.Proto3.JsonInput.DurationRepeatedValue.ProtobufOutput -Required.Proto3.JsonInput.FloatFieldInfinity.JsonOutput -Required.Proto3.JsonInput.FloatFieldNan.JsonOutput -Required.Proto3.JsonInput.FloatFieldNegativeInfinity.JsonOutput -Required.Proto3.JsonInput.Int64FieldMaxValue.JsonOutput -Required.Proto3.JsonInput.Int64FieldMaxValue.ProtobufOutput -Required.Proto3.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput -Required.Proto3.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput -Required.Proto3.JsonInput.Int64FieldMinValue.JsonOutput -Required.Proto3.JsonInput.Int64FieldMinValue.ProtobufOutput -Required.Proto3.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput -Required.Proto3.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput -Required.Proto3.JsonInput.OneofFieldDuplicate -Required.Proto3.JsonInput.RejectTopLevelNull -Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput -Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput -Required.Proto3.JsonInput.TimestampLeap.JsonOutput -Required.Proto3.JsonInput.TimestampLeap.ProtobufOutput -Required.Proto3.JsonInput.TimestampMaxValue.JsonOutput -Required.Proto3.JsonInput.TimestampMaxValue.ProtobufOutput -Required.Proto3.JsonInput.TimestampMinValue.JsonOutput -Required.Proto3.JsonInput.TimestampMinValue.ProtobufOutput -Required.Proto3.JsonInput.TimestampRepeatedValue.JsonOutput -Required.Proto3.JsonInput.TimestampRepeatedValue.ProtobufOutput -Required.Proto3.JsonInput.TimestampWithNegativeOffset.JsonOutput -Required.Proto3.JsonInput.TimestampWithNegativeOffset.ProtobufOutput -Required.Proto3.JsonInput.TimestampWithPositiveOffset.JsonOutput -Required.Proto3.JsonInput.TimestampWithPositiveOffset.ProtobufOutput -Required.Proto3.JsonInput.Uint64FieldMaxValue.JsonOutput -Required.Proto3.JsonInput.Uint64FieldMaxValue.ProtobufOutput -Required.Proto3.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput -Required.Proto3.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput -Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput -Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput -Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput -Required.Proto3.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput -Required.Proto3.ProtobufInput.ValidDataOneof.BYTES.DefaultValue.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.BYTES.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.JsonOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.STRING.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataScalar.FLOAT[2].JsonOutput -Required.TimestampProtoInputTooLarge.JsonOutput -Required.TimestampProtoInputTooSmall.JsonOutput diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index f55122790b0e..e69de29bb2d1 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -1,31 +0,0 @@ -Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput -Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput -Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted -Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted -Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted -Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted -Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted -Recommended.Proto3.JsonInput.FloatFieldNegativeInfinityNotQuoted -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BOOL[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.BYTES[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.DOUBLE[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED32[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FIXED64[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.FLOAT[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT32[6].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.INT64[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED32[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SFIXED64[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT32[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.SINT64[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.STRING[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[0].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT32[5].ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.UINT64[0].ProtobufOutput -Required.Proto3.JsonInput.DoubleFieldTooSmall -Required.Proto3.JsonInput.FloatFieldTooLarge -Required.Proto3.JsonInput.FloatFieldTooSmall -Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool -Required.Proto3.JsonInput.TimestampJsonInputLowercaseT diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index 59a969d2f590..9efb6cf8b77b 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -6,17 +6,3 @@ # # TODO(haberman): insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? - -Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput -Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput -Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted -Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted -Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted -Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted -Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted -Recommended.Proto3.JsonInput.FloatFieldNegativeInfinityNotQuoted -Required.Proto3.JsonInput.DoubleFieldTooSmall -Required.Proto3.JsonInput.FloatFieldTooLarge -Required.Proto3.JsonInput.FloatFieldTooSmall -Required.Proto3.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool -Required.Proto3.JsonInput.TimestampJsonInputLowercaseT diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt index 4573c59e4e53..1aea14560c90 100644 --- a/conformance/failure_list_ruby.txt +++ b/conformance/failure_list_ruby.txt @@ -1,12 +1,16 @@ Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput Recommended.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter Recommended.Proto3.JsonInput.MapFieldValueIsNull +Recommended.Proto3.JsonInput.NullValueInNormalMessage.Validator +Recommended.Proto3.JsonInput.NullValueInOtherOneofNewFormat.Validator +Recommended.Proto3.JsonInput.NullValueInOtherOneofOldFormat.Validator Recommended.Proto3.JsonInput.RepeatedFieldMessageElementIsNull Recommended.Proto3.JsonInput.RepeatedFieldPrimitiveElementIsNull Recommended.Proto3.JsonInput.StringEndsWithEscapeChar @@ -77,6 +81,7 @@ Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[3].ProtobufOutput Recommended.Proto3.ProtobufInput.ValidDataScalarBinary.ENUM[4].ProtobufOutput Required.DurationProtoInputTooLarge.JsonOutput Required.DurationProtoInputTooSmall.JsonOutput +Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput Required.Proto3.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput Required.Proto3.JsonInput.DoubleFieldMinPositiveValue.JsonOutput @@ -94,25 +99,7 @@ Required.Proto3.JsonInput.IgnoreUnknownJsonObject.ProtobufOutput Required.Proto3.JsonInput.IgnoreUnknownJsonString.ProtobufOutput Required.Proto3.JsonInput.IgnoreUnknownJsonTrue.ProtobufOutput Required.Proto3.JsonInput.OneofFieldDuplicate -Required.Proto3.JsonInput.OptionalBoolWrapper.JsonOutput -Required.Proto3.JsonInput.OptionalBytesWrapper.JsonOutput -Required.Proto3.JsonInput.OptionalDoubleWrapper.JsonOutput -Required.Proto3.JsonInput.OptionalFloatWrapper.JsonOutput -Required.Proto3.JsonInput.OptionalInt32Wrapper.JsonOutput -Required.Proto3.JsonInput.OptionalInt64Wrapper.JsonOutput -Required.Proto3.JsonInput.OptionalStringWrapper.JsonOutput -Required.Proto3.JsonInput.OptionalUint32Wrapper.JsonOutput -Required.Proto3.JsonInput.OptionalUint64Wrapper.JsonOutput Required.Proto3.JsonInput.RejectTopLevelNull -Required.Proto3.JsonInput.RepeatedBoolWrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedBytesWrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedDoubleWrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedFloatWrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedInt32Wrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedInt64Wrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedStringWrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedUint32Wrapper.JsonOutput -Required.Proto3.JsonInput.RepeatedUint64Wrapper.JsonOutput Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index fc7b2515230b..4c9dc7dbe051 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -258,6 +258,84 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED, "optional_float: 18446744073709551616"); + // String literals x {Strings, Bytes} + for (const auto& field_type : std::vector{"String", "Bytes"}) { + const std::string field_name = + field_type == "String" ? "optional_string" : "optional_bytes"; + RunValidTextFormatTest( + StrCat("StringLiteralConcat", field_type), REQUIRED, + StrCat(field_name, ": 'first' \"second\"\n'third'")); + RunValidTextFormatTest( + StrCat("StringLiteralBasicEscapes", field_type), REQUIRED, + StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'")); + RunValidTextFormatTest( + StrCat("StringLiteralOctalEscapes", field_type), REQUIRED, + StrCat(field_name, ": '\\341\\210\\264'")); + RunValidTextFormatTest(StrCat("StringLiteralHexEscapes", field_type), + REQUIRED, + StrCat(field_name, ": '\\xe1\\x88\\xb4'")); + RunValidTextFormatTest( + StrCat("StringLiteralShortUnicodeEscape", field_type), + RECOMMENDED, StrCat(field_name, ": '\\u1234'")); + RunValidTextFormatTest( + StrCat("StringLiteralLongUnicodeEscapes", field_type), + RECOMMENDED, StrCat(field_name, ": '\\U00001234\\U00010437'")); + // String literals don't include line feeds. + ExpectParseFailure(StrCat("StringLiteralIncludesLF", field_type), + REQUIRED, + StrCat(field_name, ": 'first line\nsecond line'")); + // Unicode escapes don't include code points that lie beyond the planes + // (> 0x10ffff). + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type), + REQUIRED, StrCat(field_name, ": '\\U00110000'")); + // Unicode escapes don't include surrogates. + ExpectParseFailure( + StrCat("StringLiteralShortUnicodeEscapeSurrogatePair", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\ud801\\udc37'")); + ExpectParseFailure( + StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\ud800'")); + ExpectParseFailure( + StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\udc00'")); + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000d800'")); + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000dc00'")); + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeSurrogatePair", field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\U00000dc37'")); + ExpectParseFailure( + StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\udc37'")); + ExpectParseFailure( + StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\ud801\\U0000dc37'")); + + // The following method depend on the type of field, as strings have extra + // validation. + const auto test_method = + field_type == "String" + ? &TextFormatConformanceTestSuite::ExpectParseFailure + : &TextFormatConformanceTestSuite::RunValidTextFormatTest; + + // String fields reject invalid UTF-8 byte sequences; bytes fields don't. + (this->*test_method)(StrCat(field_type, "FieldBadUTF8Octal"), + REQUIRED, StrCat(field_name, ": '\\300'")); + (this->*test_method)(StrCat(field_type, "FieldBadUTF8Hex"), REQUIRED, + StrCat(field_name, ": '\\xc0'")); + } + // Group fields RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED, "Data { group_int32: 1 }"); @@ -313,6 +391,66 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { } } )"); + + // Map fields + TestAllTypesProto3 prototype; + (*prototype.mutable_map_string_string())["c"] = "value"; + (*prototype.mutable_map_string_string())["b"] = "value"; + (*prototype.mutable_map_string_string())["a"] = "value"; + RunValidTextFormatTestWithMessage("AlphabeticallySortedMapStringKeys", + REQUIRED, + R"( + map_string_string { + key: "a" + value: "value" + } + map_string_string { + key: "b" + value: "value" + } + map_string_string { + key: "c" + value: "value" + } + )", + prototype); + + prototype.Clear(); + (*prototype.mutable_map_int32_int32())[3] = 0; + (*prototype.mutable_map_int32_int32())[2] = 0; + (*prototype.mutable_map_int32_int32())[1] = 0; + RunValidTextFormatTestWithMessage("AlphabeticallySortedMapIntKeys", REQUIRED, + R"( + map_int32_int32 { + key: 1 + value: 0 + } + map_int32_int32 { + key: 2 + value: 0 + } + map_int32_int32 { + key: 3 + value: 0 + } + )", + prototype); + + prototype.Clear(); + (*prototype.mutable_map_bool_bool())[true] = false; + (*prototype.mutable_map_bool_bool())[false] = false; + RunValidTextFormatTestWithMessage("AlphabeticallySortedMapBoolKeys", REQUIRED, + R"( + map_bool_bool { + key: false + value: false + } + map_bool_bool { + key: true + value: false + } + )", + prototype); } } // namespace protobuf diff --git a/conformance/text_format_conformance_suite.h b/conformance/text_format_conformance_suite.h index dd258f50b8ab..d68f4aa3ef72 100644 --- a/conformance/text_format_conformance_suite.h +++ b/conformance/text_format_conformance_suite.h @@ -42,19 +42,19 @@ class TextFormatConformanceTestSuite : public ConformanceTestSuite { private: void RunSuiteImpl(); - void RunValidTextFormatTest(const string& test_name, ConformanceLevel level, - const string& input); - void RunValidTextFormatTestProto2(const string& test_name, + void RunValidTextFormatTest(const std::string& test_name, + ConformanceLevel level, const std::string& input); + void RunValidTextFormatTestProto2(const std::string& test_name, ConformanceLevel level, - const string& input); - void RunValidTextFormatTestWithMessage(const string& test_name, + const std::string& input); + void RunValidTextFormatTestWithMessage(const std::string& test_name, ConformanceLevel level, - const string& input_text, + const std::string& input_text, const Message& prototype); - void RunValidUnknownTextFormatTest(const string& test_name, + void RunValidUnknownTextFormatTest(const std::string& test_name, const Message& message); - void ExpectParseFailure(const string& test_name, ConformanceLevel level, - const string& input); + void ExpectParseFailure(const std::string& test_name, ConformanceLevel level, + const std::string& input); bool ParseTextFormatResponse(const conformance::ConformanceResponse& response, const ConformanceRequestSetting& setting, Message* test_message); diff --git a/conformance/text_format_failure_list_cpp.txt b/conformance/text_format_failure_list_cpp.txt new file mode 100644 index 000000000000..a25f04faf2aa --- /dev/null +++ b/conformance/text_format_failure_list_cpp.txt @@ -0,0 +1,20 @@ +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex +Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString diff --git a/conformance/text_format_failure_list_java.txt b/conformance/text_format_failure_list_java.txt old mode 100755 new mode 100644 index 81433b441a4e..71e32429ec68 --- a/conformance/text_format_failure_list_java.txt +++ b/conformance/text_format_failure_list_java.txt @@ -4,3 +4,10 @@ Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput Required.Proto3.TextFormatInput.AnyField.ProtobufOutput Required.Proto3.TextFormatInput.AnyField.TextFormatOutput + +Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex +Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/conformance/text_format_failure_list_python.txt b/conformance/text_format_failure_list_python.txt index b2db95e7de3f..6bf7c1aa6362 100644 --- a/conformance/text_format_failure_list_python.txt +++ b/conformance/text_format_failure_list_python.txt @@ -3,3 +3,32 @@ # TODO: These should be fixed. Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput + +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/conformance/text_format_failure_list_python_2.7.txt b/conformance/text_format_failure_list_python_2.7.txt new file mode 100644 index 000000000000..cada2bc03b2e --- /dev/null +++ b/conformance/text_format_failure_list_python_2.7.txt @@ -0,0 +1,36 @@ +# This is the list of text format conformance tests that are known to fail right +# now. +# TODO: These should be fixed. +Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput +Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput + +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString diff --git a/conformance/text_format_failure_list_python_cpp.txt b/conformance/text_format_failure_list_python_cpp.txt new file mode 100644 index 000000000000..91fc2ea3cdaf --- /dev/null +++ b/conformance/text_format_failure_list_python_cpp.txt @@ -0,0 +1,28 @@ +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/conformance/text_format_failure_list_python_cpp_2.7.txt b/conformance/text_format_failure_list_python_cpp_2.7.txt new file mode 100644 index 000000000000..ba2089bcaad3 --- /dev/null +++ b/conformance/text_format_failure_list_python_cpp_2.7.txt @@ -0,0 +1,30 @@ +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString diff --git a/conformance/third_party/jsoncpp/json.h b/conformance/third_party/jsoncpp/json.h index 5639c92451b4..373ec98bde97 100644 --- a/conformance/third_party/jsoncpp/json.h +++ b/conformance/third_party/jsoncpp/json.h @@ -1371,7 +1371,7 @@ class JSON_API Reader { */ std::string getFormattedErrorMessages() const; - /** \brief Returns a vector of structured errors encounted while parsing. + /** \brief Returns a vector of structured errors encountered while parsing. * \return A (possibly empty) vector of StructuredError objects. Currently * only one error can be returned, but the caller should tolerate * multiple @@ -1867,7 +1867,7 @@ class JSON_API FastWriter : public Writer { * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their *#CommentPlacement. * * \sa Reader, Value, Value::setComment() @@ -1928,7 +1928,7 @@ class JSON_API StyledWriter : public Writer { * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their #CommentPlacement. * * \param indentation Each level will be indented by this amount extra. diff --git a/conformance/third_party/jsoncpp/jsoncpp.cpp b/conformance/third_party/jsoncpp/jsoncpp.cpp index d313d0563cdf..78919eac0f0c 100644 --- a/conformance/third_party/jsoncpp/jsoncpp.cpp +++ b/conformance/third_party/jsoncpp/jsoncpp.cpp @@ -142,7 +142,7 @@ enum { typedef char UIntToStringBuffer[uintToStringBufferSize]; /** Converts an unsigned integer to string. - * @param value Unsigned interger to convert to string + * @param value Unsigned integer to convert to string * @param current Input/Output string buffer. * Must have at least uintToStringBufferSize chars free. */ diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 3823e205831b..0fb4b15093bd 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -5,7 +5,7 @@ Google Protocol Buffers tools Tools for Protocol Buffers - Google's data interchange format. See project site for more info. - 3.11.2 + 3.14.0 Google Inc. protobuf-packages https://github.com/protocolbuffers/protobuf/blob/master/LICENSE @@ -20,7 +20,6 @@ - diff --git a/csharp/build_tools.sh b/csharp/build_tools.sh index 182c5c5c82ea..771affdc400c 100755 --- a/csharp/build_tools.sh +++ b/csharp/build_tools.sh @@ -19,7 +19,6 @@ VERSION_NUMBER=$1 declare -a FILE_NAMES=( \ windows_x86 windows-x86_32.exe \ windows_x64 windows-x86_64.exe \ - macosx_x86 osx-x86_32.exe \ macosx_x64 osx-x86_64.exe \ linux_x86 linux-x86_32.exe \ linux_x64 linux-x86_64.exe \ diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs index 73a578d2b5a9..11d06f1d7b43 100644 --- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs +++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedInputStreamTest.cs @@ -201,29 +201,29 @@ public void ReadLittleEndian() [Test] public void DecodeZigZag32() { - Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0)); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1)); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2)); - Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3)); - Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE)); - Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF)); - Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE)); - Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF)); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(0)); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(1)); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(2)); + Assert.AreEqual(-2, ParsingPrimitives.DecodeZigZag32(3)); + Assert.AreEqual(0x3FFFFFFF, ParsingPrimitives.DecodeZigZag32(0x7FFFFFFE)); + Assert.AreEqual(unchecked((int) 0xC0000000), ParsingPrimitives.DecodeZigZag32(0x7FFFFFFF)); + Assert.AreEqual(0x7FFFFFFF, ParsingPrimitives.DecodeZigZag32(0xFFFFFFFE)); + Assert.AreEqual(unchecked((int) 0x80000000), ParsingPrimitives.DecodeZigZag32(0xFFFFFFFF)); } [Test] public void DecodeZigZag64() { - Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0)); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1)); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2)); - Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3)); - Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL)); - Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL)); - Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL)); - Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL)); - Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL)); - Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL)); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(0)); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(1)); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(2)); + Assert.AreEqual(-2, ParsingPrimitives.DecodeZigZag64(3)); + Assert.AreEqual(0x000000003FFFFFFFL, ParsingPrimitives.DecodeZigZag64(0x000000007FFFFFFEL)); + Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), ParsingPrimitives.DecodeZigZag64(0x000000007FFFFFFFL)); + Assert.AreEqual(0x000000007FFFFFFFL, ParsingPrimitives.DecodeZigZag64(0x00000000FFFFFFFEL)); + Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), ParsingPrimitives.DecodeZigZag64(0x00000000FFFFFFFFL)); + Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, ParsingPrimitives.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL)); + Assert.AreEqual(unchecked((long) 0x8000000000000000L), ParsingPrimitives.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL)); } [Test] diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs index 01bd3218f337..e9b4ea8cf0f3 100644 --- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs +++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/CodedOutputStreamTest.cs @@ -211,35 +211,35 @@ public void WriteWholeMessage_VaryingBlockSizes() [Test] public void EncodeZigZag32() { - Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0)); - Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1)); - Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1)); - Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2)); - Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF)); - Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000))); - Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF)); - Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000))); + Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag32(0)); + Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1)); + Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1)); + Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2)); + Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF)); + Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000))); + Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF)); + Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000))); } [Test] public void EncodeZigZag64() { - Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0)); - Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1)); - Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1)); - Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2)); + Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0)); + Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1)); + Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1)); + Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2)); Assert.AreEqual(0x000000007FFFFFFEuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL))); Assert.AreEqual(0x000000007FFFFFFFuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL))); Assert.AreEqual(0x00000000FFFFFFFEuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL))); Assert.AreEqual(0x00000000FFFFFFFFuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL))); Assert.AreEqual(0xFFFFFFFFFFFFFFFEL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL))); Assert.AreEqual(0xFFFFFFFFFFFFFFFFL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x8000000000000000UL))); } [Test] @@ -247,26 +247,26 @@ public void RoundTripZigZag32() { // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) // were chosen semi-randomly via keyboard bashing. - Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0))); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1))); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1))); - Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927))); - Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612))); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0))); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1))); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1))); + Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927))); + Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612))); } [Test] public void RoundTripZigZag64() { - Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0))); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1))); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1))); - Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927))); - Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612))); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0))); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1))); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1))); + Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927))); + Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612))); Assert.AreEqual(856912304801416L, - CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L))); + ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L))); Assert.AreEqual(-75123905439571256L, - CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L))); + ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-75123905439571256L))); } [Test] @@ -395,7 +395,7 @@ public void Dispose_DisposesUnderlyingStream() Assert.IsTrue(memoryStream.CanWrite); using (var cos = new CodedOutputStream(memoryStream)) { - cos.WriteRawByte(0); + cos.WriteRawBytes(new byte[] {0}); Assert.AreEqual(0, memoryStream.Position); // Not flushed yet } Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream @@ -409,7 +409,7 @@ public void Dispose_WithLeaveOpen() Assert.IsTrue(memoryStream.CanWrite); using (var cos = new CodedOutputStream(memoryStream, true)) { - cos.WriteRawByte(0); + cos.WriteRawBytes(new byte[] {0}); Assert.AreEqual(0, memoryStream.Position); // Not flushed yet } Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs index 390766682797..18e876721797 100644 --- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs +++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/FieldCodecTest.cs @@ -124,11 +124,20 @@ public void TestRoundTripRaw() { var stream = new MemoryStream(); var codedOutput = new CodedOutputStream(stream); - codec.ValueWriter(codedOutput, sampleValue); + WriteContext.Initialize(codedOutput, out WriteContext ctx); + try + { + // only write the value using the codec + codec.ValueWriter(ref ctx, sampleValue); + } + finally + { + ctx.CopyStateTo(codedOutput); + } codedOutput.Flush(); stream.Position = 0; var codedInput = new CodedInputStream(stream); - Assert.AreEqual(sampleValue, codec.ValueReader(codedInput)); + Assert.AreEqual(sampleValue, codec.Read(codedInput)); Assert.IsTrue(codedInput.IsAtEnd); } @@ -172,13 +181,22 @@ public void TestDefaultValue() if (codec.DefaultValue != null) // This part isn't appropriate for message types. { codedOutput = new CodedOutputStream(stream); - codec.ValueWriter(codedOutput, codec.DefaultValue); + WriteContext.Initialize(codedOutput, out WriteContext ctx); + try + { + // only write the value using the codec + codec.ValueWriter(ref ctx, codec.DefaultValue); + } + finally + { + ctx.CopyStateTo(codedOutput); + } codedOutput.Flush(); Assert.AreNotEqual(0, stream.Position); Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue)); stream.Position = 0; var codedInput = new CodedInputStream(stream); - Assert.AreEqual(codec.DefaultValue, codec.ValueReader(codedInput)); + Assert.AreEqual(codec.DefaultValue, codec.Read(codedInput)); } } diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh index e6687c308e47..b663138d1087 100755 --- a/csharp/generate_protos.sh +++ b/csharp/generate_protos.sh @@ -45,6 +45,7 @@ $PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf \ # and old_extensions2.proto, which are generated with an older version # of protoc. $PROTOC -Isrc -Icsharp/protos \ + --experimental_allow_proto3_optional \ --csharp_out=csharp/src/Google.Protobuf.Test.TestProtos \ --descriptor_set_out=csharp/src/Google.Protobuf.Test/testprotos.pb \ --include_source_info \ @@ -61,9 +62,11 @@ $PROTOC -Isrc -Icsharp/protos \ csharp/protos/unittest_issue6936_a.proto \ csharp/protos/unittest_issue6936_b.proto \ csharp/protos/unittest_issue6936_c.proto \ + csharp/protos/unittest_selfreferential_options.proto \ src/google/protobuf/unittest_well_known_types.proto \ src/google/protobuf/test_messages_proto3.proto \ - src/google/protobuf/test_messages_proto2.proto + src/google/protobuf/test_messages_proto2.proto \ + src/google/protobuf/unittest_proto3_optional.proto # AddressBook sample protos $PROTOC -Iexamples -Isrc --csharp_out=csharp/src/AddressBook \ diff --git a/csharp/install_dotnet_sdk.ps1 b/csharp/install_dotnet_sdk.ps1 old mode 100644 new mode 100755 index 9e300eda067b..8bc967c9f4d6 --- a/csharp/install_dotnet_sdk.ps1 +++ b/csharp/install_dotnet_sdk.ps1 @@ -1,5 +1,5 @@ #!/usr/bin/env powershell -# Install dotnet SDK based on the SDK version from global.json +# Install dotnet SDK using the official dotnet-install.ps1 script Set-StrictMode -Version 2 $ErrorActionPreference = 'Stop' @@ -9,16 +9,12 @@ $ErrorActionPreference = 'Stop' $InstallScriptUrl = 'https://dot.net/v1/dotnet-install.ps1' $InstallScriptPath = Join-Path "$env:TEMP" 'dotnet-install.ps1' -$GlobalJsonPath = Join-Path $PSScriptRoot '..' | Join-Path -ChildPath 'global.json' - -# Resolve SDK version from global.json file -$GlobalJson = Get-Content -Raw $GlobalJsonPath | ConvertFrom-Json -$SDKVersion = $GlobalJson.sdk.version # Download install script Write-Host "Downloading install script: $InstallScriptUrl => $InstallScriptPath" Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath -&$InstallScriptPath -Version $SDKVersion -# Also install dotnet SDK LTS which is required to run some of the tests +# The SDK versions to install should be kept in sync with versions +# installed by kokoro/linux/dockerfile/test/csharp/Dockerfile &$InstallScriptPath -Version 2.1.802 +&$InstallScriptPath -Version 3.1.301 diff --git a/csharp/protos/unittest_issues.proto b/csharp/protos/unittest_issues.proto index b4a88d86481b..388998f0a0ea 100644 --- a/csharp/protos/unittest_issues.proto +++ b/csharp/protos/unittest_issues.proto @@ -8,6 +8,8 @@ option csharp_namespace = "UnitTest.Issues.TestProtos"; package unittest_issues; +import "google/protobuf/struct.proto"; + // Issue 307: when generating doubly-nested types, any references // should be of the form A.Types.B.Types.C. message Issue307 { @@ -137,4 +139,20 @@ message OneofMerging { string text = 1; Nested nested = 2; } -} \ No newline at end of file +} + +message NullValueOutsideStruct { + oneof value { + string string_value = 1; + google.protobuf.NullValue null_value = 2; + } +} + +message NullValueNotInOneof { + google.protobuf.NullValue null_value = 2; +} + +message MixedRegularAndOptional { + string regular_field = 1; + optional string optional_field = 2; +} diff --git a/csharp/protos/unittest_selfreferential_options.proto b/csharp/protos/unittest_selfreferential_options.proto new file mode 100644 index 000000000000..22f16cfbf5a8 --- /dev/null +++ b/csharp/protos/unittest_selfreferential_options.proto @@ -0,0 +1,64 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +syntax = "proto2"; + +package protobuf_unittest_selfreferential_options; +option csharp_namespace = "UnitTest.Issues.TestProtos.SelfreferentialOptions"; + +import "google/protobuf/descriptor.proto"; + +message FooOptions { + // Custom field option used in definition of the extension message. + optional int32 int_opt = 1 [(foo_options) = { + int_opt: 1 + [foo_int_opt]: 2 + [foo_foo_opt]: { + int_opt: 3 + } + }]; + + // Custom field option used in definition of the custom option's message. + optional int32 foo = 2 [(foo_options) = {foo: 1234}]; + + extensions 1000 to max; +} + +extend google.protobuf.FieldOptions { + // Custom field option used on the definition of that field option. + optional int32 bar_options = 1000 [(bar_options) = 1234]; + + optional FooOptions foo_options = 1001; +} + +extend FooOptions { + optional int32 foo_int_opt = 1000; + optional FooOptions foo_foo_opt = 1001; +} diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index cbd977269620..042f69ee60b8 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -49,7 +49,11 @@ public static partial class AddressbookReflection { /// /// [START messages] /// - public sealed partial class Person : pb::IMessage { + public sealed partial class Person : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Person()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -186,6 +190,9 @@ public sealed partial class Person : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -206,8 +213,35 @@ public sealed partial class Person : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (Id != 0) { + output.WriteRawTag(16); + output.WriteInt32(Id); + } + if (Email.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Email); + } + phones_.WriteTo(ref output, _repeated_phones_codec); + if (lastUpdated_ != null) { + output.WriteRawTag(42); + output.WriteMessage(LastUpdated); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -256,6 +290,9 @@ public sealed partial class Person : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -287,7 +324,45 @@ public sealed partial class Person : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 16: { + Id = input.ReadInt32(); + break; + } + case 26: { + Email = input.ReadString(); + break; + } + case 34: { + phones_.AddEntriesFrom(ref input, _repeated_phones_codec); + break; + } + case 42: { + if (lastUpdated_ == null) { + LastUpdated = new global::Google.Protobuf.WellKnownTypes.Timestamp(); + } + input.ReadMessage(LastUpdated); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the Person message type. @@ -299,7 +374,11 @@ public enum PhoneType { [pbr::OriginalName("WORK")] Work = 2, } - public sealed partial class PhoneNumber : pb::IMessage { + public sealed partial class PhoneNumber : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PhoneNumber()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -392,6 +471,9 @@ public sealed partial class PhoneNumber : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Number.Length != 0) { output.WriteRawTag(10); output.WriteString(Number); @@ -403,7 +485,25 @@ public sealed partial class PhoneNumber : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Number.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Number); + } + if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.Mobile) { + output.WriteRawTag(16); + output.WriteEnum((int) Type); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -436,6 +536,9 @@ public sealed partial class PhoneNumber : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -452,8 +555,31 @@ public sealed partial class PhoneNumber : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Number = input.ReadString(); + break; + } + case 16: { + Type = (global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) input.ReadEnum(); + break; + } + } + } + } + #endif + } } @@ -464,7 +590,11 @@ public sealed partial class PhoneNumber : pb::IMessage { /// /// Our address book file is just one of these. /// - public sealed partial class AddressBook : pb::IMessage { + public sealed partial class AddressBook : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new AddressBook()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -542,12 +672,26 @@ public sealed partial class AddressBook : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else people_.WriteTo(output, _repeated_people_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + people_.WriteTo(ref output, _repeated_people_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -569,6 +713,9 @@ public sealed partial class AddressBook : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -581,7 +728,26 @@ public sealed partial class AddressBook : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + people_.AddEntriesFrom(ref input, _repeated_people_codec); + break; + } + } + } } + #endif } diff --git a/csharp/src/AddressBook/Program.cs b/csharp/src/AddressBook/Program.cs index ff7b9c085e07..de4867a0ce21 100644 --- a/csharp/src/AddressBook/Program.cs +++ b/csharp/src/AddressBook/Program.cs @@ -37,7 +37,7 @@ namespace Google.Protobuf.Examples.AddressBook /// /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour /// to individual actions. Each action has its own Main method, so that it can be used as an - /// invidual complete program. + /// individual complete program. /// internal class Program { diff --git a/csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs similarity index 89% rename from csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs rename to csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs index 679f16cb9a87..c0754190b6c9 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/SerializationConfig.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkDatasetConfig.cs @@ -43,20 +43,20 @@ namespace Google.Protobuf.Benchmarks /// /// The configuration for a single serialization test, loaded from a dataset. /// - public class SerializationConfig + public class BenchmarkDatasetConfig { private static readonly Dictionary parsersByMessageName = - typeof(SerializationBenchmark).Assembly.GetTypes() + typeof(GoogleMessageBenchmark).Assembly.GetTypes() .Where(t => typeof(IMessage).IsAssignableFrom(t)) .ToDictionary( t => ((MessageDescriptor) t.GetProperty("Descriptor", BindingFlags.Static | BindingFlags.Public).GetValue(null)).FullName, t => ((MessageParser) t.GetProperty("Parser", BindingFlags.Static | BindingFlags.Public).GetValue(null))); public MessageParser Parser { get; } - public IEnumerable Payloads { get; } + public List Payloads { get; } public string Name { get; } - public SerializationConfig(string resource) + public BenchmarkDatasetConfig(string resource, string shortName = null) { var data = LoadData(resource); var dataset = BenchmarkDataset.Parser.ParseFrom(data); @@ -66,13 +66,13 @@ public SerializationConfig(string resource) throw new ArgumentException($"No parser for message {dataset.MessageName} in this assembly"); } Parser = parser; - Payloads = dataset.Payload; - Name = dataset.Name; + Payloads = new List(dataset.Payload.Select(p => p.ToByteArray())); + Name = shortName ?? dataset.Name; } private static byte[] LoadData(string resource) { - using (var stream = typeof(SerializationBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}")) + using (var stream = typeof(GoogleMessageBenchmark).Assembly.GetManifestResourceStream($"Google.Protobuf.Benchmarks.{resource}")) { if (stream == null) { diff --git a/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs index 9e8c330a2b63..027da02a10b5 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/BenchmarkMessage1Proto3.cs @@ -64,7 +64,11 @@ public static partial class BenchmarkMessage1Proto3Reflection { } #region Messages - public sealed partial class GoogleMessage1 : pb::IMessage { + public sealed partial class GoogleMessage1 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new GoogleMessage1()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -702,6 +706,9 @@ public sealed partial class GoogleMessage1 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Field1.Length != 0) { output.WriteRawTag(10); output.WriteString(Field1); @@ -866,8 +873,179 @@ public sealed partial class GoogleMessage1 : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Field1.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Field1); + } + if (Field2 != 0) { + output.WriteRawTag(16); + output.WriteInt32(Field2); + } + if (Field3 != 0) { + output.WriteRawTag(24); + output.WriteInt32(Field3); + } + if (Field4.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Field4); + } + field5_.WriteTo(ref output, _repeated_field5_codec); + if (Field6 != 0) { + output.WriteRawTag(48); + output.WriteInt32(Field6); + } + if (Field7.Length != 0) { + output.WriteRawTag(58); + output.WriteString(Field7); + } + if (Field9.Length != 0) { + output.WriteRawTag(74); + output.WriteString(Field9); + } + if (Field12 != false) { + output.WriteRawTag(96); + output.WriteBool(Field12); + } + if (Field13 != false) { + output.WriteRawTag(104); + output.WriteBool(Field13); + } + if (Field14 != false) { + output.WriteRawTag(112); + output.WriteBool(Field14); + } + if (field15_ != null) { + output.WriteRawTag(122); + output.WriteMessage(Field15); + } + if (Field16 != 0) { + output.WriteRawTag(128, 1); + output.WriteInt32(Field16); + } + if (Field17 != false) { + output.WriteRawTag(136, 1); + output.WriteBool(Field17); + } + if (Field18.Length != 0) { + output.WriteRawTag(146, 1); + output.WriteString(Field18); + } + if (Field22 != 0L) { + output.WriteRawTag(176, 1); + output.WriteInt64(Field22); + } + if (Field23 != 0) { + output.WriteRawTag(184, 1); + output.WriteInt32(Field23); + } + if (Field24 != false) { + output.WriteRawTag(192, 1); + output.WriteBool(Field24); + } + if (Field25 != 0) { + output.WriteRawTag(200, 1); + output.WriteInt32(Field25); + } + if (Field29 != 0) { + output.WriteRawTag(232, 1); + output.WriteInt32(Field29); + } + if (Field30 != false) { + output.WriteRawTag(240, 1); + output.WriteBool(Field30); + } + if (Field59 != false) { + output.WriteRawTag(216, 3); + output.WriteBool(Field59); + } + if (Field60 != 0) { + output.WriteRawTag(224, 3); + output.WriteInt32(Field60); + } + if (Field67 != 0) { + output.WriteRawTag(152, 4); + output.WriteInt32(Field67); + } + if (Field68 != 0) { + output.WriteRawTag(160, 4); + output.WriteInt32(Field68); + } + if (Field78 != false) { + output.WriteRawTag(240, 4); + output.WriteBool(Field78); + } + if (Field80 != false) { + output.WriteRawTag(128, 5); + output.WriteBool(Field80); + } + if (Field81 != false) { + output.WriteRawTag(136, 5); + output.WriteBool(Field81); + } + if (Field100 != 0) { + output.WriteRawTag(160, 6); + output.WriteInt32(Field100); + } + if (Field101 != 0) { + output.WriteRawTag(168, 6); + output.WriteInt32(Field101); + } + if (Field102.Length != 0) { + output.WriteRawTag(178, 6); + output.WriteString(Field102); + } + if (Field103.Length != 0) { + output.WriteRawTag(186, 6); + output.WriteString(Field103); + } + if (Field104 != 0) { + output.WriteRawTag(192, 6); + output.WriteInt32(Field104); + } + if (Field128 != 0) { + output.WriteRawTag(128, 8); + output.WriteInt32(Field128); + } + if (Field129.Length != 0) { + output.WriteRawTag(138, 8); + output.WriteString(Field129); + } + if (Field130 != 0) { + output.WriteRawTag(144, 8); + output.WriteInt32(Field130); + } + if (Field131 != 0) { + output.WriteRawTag(152, 8); + output.WriteInt32(Field131); + } + if (Field150 != 0) { + output.WriteRawTag(176, 9); + output.WriteInt32(Field150); + } + if (Field271 != 0) { + output.WriteRawTag(248, 16); + output.WriteInt32(Field271); + } + if (Field272 != 0) { + output.WriteRawTag(128, 17); + output.WriteInt32(Field272); + } + if (Field280 != 0) { + output.WriteRawTag(192, 17); + output.WriteInt32(Field280); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -1107,36 +1285,221 @@ public sealed partial class GoogleMessage1 : pb::IMessage { if (field15_ == null) { Field15 = new global::Benchmarks.Proto3.GoogleMessage1SubMessage(); } - Field15.MergeFrom(other.Field15); - } - if (other.Field78 != false) { - Field78 = other.Field78; - } - if (other.Field67 != 0) { - Field67 = other.Field67; - } - if (other.Field68 != 0) { - Field68 = other.Field68; - } - if (other.Field128 != 0) { - Field128 = other.Field128; - } - if (other.Field129.Length != 0) { - Field129 = other.Field129; - } - if (other.Field131 != 0) { - Field131 = other.Field131; + Field15.MergeFrom(other.Field15); + } + if (other.Field78 != false) { + Field78 = other.Field78; + } + if (other.Field67 != 0) { + Field67 = other.Field67; + } + if (other.Field68 != 0) { + Field68 = other.Field68; + } + if (other.Field128 != 0) { + Field128 = other.Field128; + } + if (other.Field129.Length != 0) { + Field129 = other.Field129; + } + if (other.Field131 != 0) { + Field131 = other.Field131; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + Field1 = input.ReadString(); + break; + } + case 16: { + Field2 = input.ReadInt32(); + break; + } + case 24: { + Field3 = input.ReadInt32(); + break; + } + case 34: { + Field4 = input.ReadString(); + break; + } + case 42: + case 41: { + field5_.AddEntriesFrom(input, _repeated_field5_codec); + break; + } + case 48: { + Field6 = input.ReadInt32(); + break; + } + case 58: { + Field7 = input.ReadString(); + break; + } + case 74: { + Field9 = input.ReadString(); + break; + } + case 96: { + Field12 = input.ReadBool(); + break; + } + case 104: { + Field13 = input.ReadBool(); + break; + } + case 112: { + Field14 = input.ReadBool(); + break; + } + case 122: { + if (field15_ == null) { + Field15 = new global::Benchmarks.Proto3.GoogleMessage1SubMessage(); + } + input.ReadMessage(Field15); + break; + } + case 128: { + Field16 = input.ReadInt32(); + break; + } + case 136: { + Field17 = input.ReadBool(); + break; + } + case 146: { + Field18 = input.ReadString(); + break; + } + case 176: { + Field22 = input.ReadInt64(); + break; + } + case 184: { + Field23 = input.ReadInt32(); + break; + } + case 192: { + Field24 = input.ReadBool(); + break; + } + case 200: { + Field25 = input.ReadInt32(); + break; + } + case 232: { + Field29 = input.ReadInt32(); + break; + } + case 240: { + Field30 = input.ReadBool(); + break; + } + case 472: { + Field59 = input.ReadBool(); + break; + } + case 480: { + Field60 = input.ReadInt32(); + break; + } + case 536: { + Field67 = input.ReadInt32(); + break; + } + case 544: { + Field68 = input.ReadInt32(); + break; + } + case 624: { + Field78 = input.ReadBool(); + break; + } + case 640: { + Field80 = input.ReadBool(); + break; + } + case 648: { + Field81 = input.ReadBool(); + break; + } + case 800: { + Field100 = input.ReadInt32(); + break; + } + case 808: { + Field101 = input.ReadInt32(); + break; + } + case 818: { + Field102 = input.ReadString(); + break; + } + case 826: { + Field103 = input.ReadString(); + break; + } + case 832: { + Field104 = input.ReadInt32(); + break; + } + case 1024: { + Field128 = input.ReadInt32(); + break; + } + case 1034: { + Field129 = input.ReadString(); + break; + } + case 1040: { + Field130 = input.ReadInt32(); + break; + } + case 1048: { + Field131 = input.ReadInt32(); + break; + } + case 1200: { + Field150 = input.ReadInt32(); + break; + } + case 2168: { + Field271 = input.ReadInt32(); + break; + } + case 2176: { + Field272 = input.ReadInt32(); + break; + } + case 2240: { + Field280 = input.ReadInt32(); + break; + } + } } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 10: { Field1 = input.ReadString(); @@ -1156,7 +1519,7 @@ public sealed partial class GoogleMessage1 : pb::IMessage { } case 42: case 41: { - field5_.AddEntriesFrom(input, _repeated_field5_codec); + field5_.AddEntriesFrom(ref input, _repeated_field5_codec); break; } case 48: { @@ -1309,10 +1672,15 @@ public sealed partial class GoogleMessage1 : pb::IMessage { } } } + #endif } - public sealed partial class GoogleMessage1SubMessage : pb::IMessage { + public sealed partial class GoogleMessage1SubMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new GoogleMessage1SubMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1657,6 +2025,9 @@ public sealed partial class GoogleMessage1SubMessage : pb::IMessage { + public sealed partial class BenchmarkDataset : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BenchmarkDataset()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -172,6 +176,9 @@ public sealed partial class BenchmarkDataset : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -184,8 +191,27 @@ public sealed partial class BenchmarkDataset : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (MessageName.Length != 0) { + output.WriteRawTag(18); + output.WriteString(MessageName); + } + payload_.WriteTo(ref output, _repeated_payload_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -219,6 +245,9 @@ public sealed partial class BenchmarkDataset : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -239,7 +268,34 @@ public sealed partial class BenchmarkDataset : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + MessageName = input.ReadString(); + break; + } + case 26: { + payload_.AddEntriesFrom(ref input, _repeated_payload_codec); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs new file mode 100644 index 000000000000..a755850a66e1 --- /dev/null +++ b/csharp/src/Google.Protobuf.Benchmarks/ByteStringBenchmark.cs @@ -0,0 +1,72 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2019 Google Inc. All rights reserved. +// https://github.com/protocolbuffers/protobuf +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using BenchmarkDotNet.Attributes; + +namespace Google.Protobuf.Benchmarks +{ + /// + /// Benchmarks using ByteString. + /// + [MemoryDiagnoser] + public class ByteStringBenchmark + { + private const int Zero = 0; + private const int Kilobyte = 1024; + private const int _128Kilobytes = 1024 * 128; + private const int Megabyte = 1024 * 1024; + private const int _10Megabytes = 1024 * 1024 * 10; + + byte[] byteBuffer; + + [GlobalSetup] + public void GlobalSetup() + { + byteBuffer = new byte[PayloadSize]; + } + + [Params(Zero, Kilobyte, _128Kilobytes, Megabyte, _10Megabytes)] + public int PayloadSize { get; set; } + + [Benchmark] + public ByteString CopyFrom() + { + return ByteString.CopyFrom(byteBuffer); + } + + [Benchmark] + public ByteString UnsafeWrap() + { + return UnsafeByteOperations.UnsafeWrap(byteBuffer); + } + } +} diff --git a/csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj b/csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj index ecc064ea7d09..37bbc3ef2f0e 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj +++ b/csharp/src/Google.Protobuf.Benchmarks/Google.Protobuf.Benchmarks.csproj @@ -2,12 +2,21 @@ Exe - netcoreapp2.1 + netcoreapp3.1 + ../../keys/Google.Protobuf.snk + true + true False + pdbonly + true - + + + + + diff --git a/csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs similarity index 74% rename from csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs rename to csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs index d8c2ec11d73e..132967e00a29 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/SerializationBenchmark.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/GoogleMessageBenchmark.cs @@ -38,23 +38,27 @@ namespace Google.Protobuf.Benchmarks { /// - /// Benchmark for serializing (to a MemoryStream) and deserializing (from a ByteString). + /// Benchmark for serializing and deserializing of standard datasets that are also + /// measured by benchmarks in other languages. /// Over time we may wish to test the various different approaches to serialization and deserialization separately. + /// See https://github.com/protocolbuffers/protobuf/blob/master/benchmarks/README.md + /// See https://github.com/protocolbuffers/protobuf/blob/master/docs/performance.md /// [MemoryDiagnoser] - public class SerializationBenchmark + public class GoogleMessageBenchmark { /// - /// All the configurations to be tested. Add more datasets to the array as they're available. + /// All the datasets to be tested. Add more datasets to the array as they're available. /// (When C# supports proto2, this will increase significantly.) /// - public static SerializationConfig[] Configurations => new[] + public static BenchmarkDatasetConfig[] DatasetConfigurations => new[] { - new SerializationConfig("dataset.google_message1_proto3.pb") + // short name is specified to make results table more readable + new BenchmarkDatasetConfig("dataset.google_message1_proto3.pb", "goog_msg1_proto3") }; - [ParamsSource(nameof(Configurations))] - public SerializationConfig Configuration { get; set; } + [ParamsSource(nameof(DatasetConfigurations))] + public BenchmarkDatasetConfig Dataset { get; set; } private MessageParser parser; /// @@ -67,8 +71,8 @@ public class SerializationBenchmark [GlobalSetup] public void GlobalSetup() { - parser = Configuration.Parser; - subTests = Configuration.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList(); + parser = Dataset.Parser; + subTests = Dataset.Payloads.Select(p => new SubTest(p, parser.ParseFrom(p))).ToList(); } [Benchmark] @@ -78,7 +82,7 @@ public void GlobalSetup() public void ToByteArray() => subTests.ForEach(item => item.ToByteArray()); [Benchmark] - public void ParseFromByteString() => subTests.ForEach(item => item.ParseFromByteString(parser)); + public void ParseFromByteArray() => subTests.ForEach(item => item.ParseFromByteArray(parser)); [Benchmark] public void ParseFromStream() => subTests.ForEach(item => item.ParseFromStream(parser)); @@ -87,13 +91,13 @@ private class SubTest { private readonly Stream destinationStream; private readonly Stream sourceStream; - private readonly ByteString data; + private readonly byte[] data; private readonly IMessage message; - public SubTest(ByteString data, IMessage message) + public SubTest(byte[] data, IMessage message) { destinationStream = new MemoryStream(data.Length); - sourceStream = new MemoryStream(data.ToByteArray()); + sourceStream = new MemoryStream(data); this.data = data; this.message = message; } @@ -108,7 +112,7 @@ public void WriteToStream() public void ToByteArray() => message.ToByteArray(); - public void ParseFromByteString(MessageParser parser) => parser.ParseFrom(data); + public void ParseFromByteArray(MessageParser parser) => parser.ParseFrom(data); public void ParseFromStream(MessageParser parser) { diff --git a/csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs new file mode 100644 index 000000000000..8e6710b7089c --- /dev/null +++ b/csharp/src/Google.Protobuf.Benchmarks/ParseMessagesBenchmark.cs @@ -0,0 +1,258 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2019 Google Inc. All rights reserved. +// https://github.com/protocolbuffers/protobuf +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using BenchmarkDotNet.Attributes; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Buffers; +using Google.Protobuf.WellKnownTypes; +using Benchmarks.Proto3; + +namespace Google.Protobuf.Benchmarks +{ + /// + /// Benchmark that tests parsing performance for various messages. + /// + [MemoryDiagnoser] + public class ParseMessagesBenchmark + { + const int MaxMessages = 100; + + SubTest manyWrapperFieldsTest = new SubTest(CreateManyWrapperFieldsMessage(), ManyWrapperFieldsMessage.Parser, () => new ManyWrapperFieldsMessage(), MaxMessages); + SubTest manyPrimitiveFieldsTest = new SubTest(CreateManyPrimitiveFieldsMessage(), ManyPrimitiveFieldsMessage.Parser, () => new ManyPrimitiveFieldsMessage(), MaxMessages); + SubTest repeatedFieldTest = new SubTest(CreateRepeatedFieldMessage(), GoogleMessage1.Parser, () => new GoogleMessage1(), MaxMessages); + SubTest emptyMessageTest = new SubTest(new Empty(), Empty.Parser, () => new Empty(), MaxMessages); + + public IEnumerable MessageCountValues => new[] { 10, 100 }; + + [GlobalSetup] + public void GlobalSetup() + { + } + + [Benchmark] + public IMessage ManyWrapperFieldsMessage_ParseFromByteArray() + { + return manyWrapperFieldsTest.ParseFromByteArray(); + } + + [Benchmark] + public IMessage ManyWrapperFieldsMessage_ParseFromReadOnlySequence() + { + return manyWrapperFieldsTest.ParseFromReadOnlySequence(); + } + + [Benchmark] + public IMessage ManyPrimitiveFieldsMessage_ParseFromByteArray() + { + return manyPrimitiveFieldsTest.ParseFromByteArray(); + } + + [Benchmark] + public IMessage ManyPrimitiveFieldsMessage_ParseFromReadOnlySequence() + { + return manyPrimitiveFieldsTest.ParseFromReadOnlySequence(); + } + + [Benchmark] + public IMessage RepeatedFieldMessage_ParseFromByteArray() + { + return repeatedFieldTest.ParseFromByteArray(); + } + + [Benchmark] + public IMessage RepeatedFieldMessage_ParseFromReadOnlySequence() + { + return repeatedFieldTest.ParseFromReadOnlySequence(); + } + + [Benchmark] + public IMessage EmptyMessage_ParseFromByteArray() + { + return emptyMessageTest.ParseFromByteArray(); + } + + [Benchmark] + public IMessage EmptyMessage_ParseFromReadOnlySequence() + { + return emptyMessageTest.ParseFromReadOnlySequence(); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount) + { + manyWrapperFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyWrapperFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount) + { + manyWrapperFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromByteArray(int messageCount) + { + manyPrimitiveFieldsTest.ParseDelimitedMessagesFromByteArray(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyPrimitiveFieldsMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount) + { + manyPrimitiveFieldsTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void RepeatedFieldMessage_ParseDelimitedMessagesFromByteArray(int messageCount) + { + repeatedFieldTest.ParseDelimitedMessagesFromByteArray(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void RepeatedFieldMessage_ParseDelimitedMessagesFromReadOnlySequence(int messageCount) + { + repeatedFieldTest.ParseDelimitedMessagesFromReadOnlySequence(messageCount); + } + + public static ManyWrapperFieldsMessage CreateManyWrapperFieldsMessage() + { + // Example data match data of an internal benchmarks + return new ManyWrapperFieldsMessage() + { + Int64Field19 = 123, + Int64Field37 = 1000032, + Int64Field26 = 3453524500, + DoubleField79 = 1.2, + DoubleField25 = 234, + DoubleField9 = 123.3, + DoubleField28 = 23, + DoubleField7 = 234, + DoubleField50 = 2.45 + }; + } + + public static ManyPrimitiveFieldsMessage CreateManyPrimitiveFieldsMessage() + { + // Example data match data of an internal benchmarks + return new ManyPrimitiveFieldsMessage() + { + Int64Field19 = 123, + Int64Field37 = 1000032, + Int64Field26 = 3453524500, + DoubleField79 = 1.2, + DoubleField25 = 234, + DoubleField9 = 123.3, + DoubleField28 = 23, + DoubleField7 = 234, + DoubleField50 = 2.45 + }; + } + + public static GoogleMessage1 CreateRepeatedFieldMessage() + { + // Message with a repeated fixed length item collection + var message = new GoogleMessage1(); + for (ulong i = 0; i < 1000; i++) + { + message.Field5.Add(i); + } + return message; + } + + private class SubTest + { + private readonly IMessage message; + private readonly MessageParser parser; + private readonly Func factory; + private readonly byte[] data; + private readonly byte[] multipleMessagesData; + + private ReadOnlySequence dataSequence; + private ReadOnlySequence multipleMessagesDataSequence; + + public SubTest(IMessage message, MessageParser parser, Func factory, int maxMessageCount) + { + this.message = message; + this.parser = parser; + this.factory = factory; + this.data = message.ToByteArray(); + this.multipleMessagesData = CreateBufferWithMultipleMessages(message, maxMessageCount); + this.dataSequence = new ReadOnlySequence(this.data); + this.multipleMessagesDataSequence = new ReadOnlySequence(this.multipleMessagesData); + } + + public IMessage ParseFromByteArray() => parser.ParseFrom(data); + + public IMessage ParseFromReadOnlySequence() => parser.ParseFrom(dataSequence); + + public void ParseDelimitedMessagesFromByteArray(int messageCount) + { + var input = new CodedInputStream(multipleMessagesData); + for (int i = 0; i < messageCount; i++) + { + var msg = factory(); + input.ReadMessage(msg); + } + } + + public void ParseDelimitedMessagesFromReadOnlySequence(int messageCount) + { + ParseContext.Initialize(multipleMessagesDataSequence, out ParseContext ctx); + for (int i = 0; i < messageCount; i++) + { + var msg = factory(); + ctx.ReadMessage(msg); + } + } + + private static byte[] CreateBufferWithMultipleMessages(IMessage msg, int msgCount) + { + var ms = new MemoryStream(); + var cos = new CodedOutputStream(ms); + for (int i = 0; i < msgCount; i++) + { + cos.WriteMessage(msg); + } + cos.Flush(); + return ms.ToArray(); + } + } + } +} diff --git a/csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs new file mode 100644 index 000000000000..6df1c872c3ca --- /dev/null +++ b/csharp/src/Google.Protobuf.Benchmarks/ParseRawPrimitivesBenchmark.cs @@ -0,0 +1,536 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2019 Google Inc. All rights reserved. +// https://github.com/protocolbuffers/protobuf +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using BenchmarkDotNet.Attributes; +using System; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Buffers; + +namespace Google.Protobuf.Benchmarks +{ + /// + /// Benchmarks throughput when parsing raw primitives. + /// + [MemoryDiagnoser] + public class ParseRawPrimitivesBenchmark + { + // key is the encodedSize of varint values + Dictionary varintInputBuffers; + + byte[] doubleInputBuffer; + byte[] floatInputBuffer; + byte[] fixedIntInputBuffer; + + // key is the encodedSize of string values + Dictionary stringInputBuffers; + Dictionary> stringInputBuffersSegmented; + + Random random = new Random(417384220); // random but deterministic seed + + public IEnumerable StringEncodedSizes => new[] { 1, 4, 10, 105, 10080 }; + public IEnumerable StringSegmentedEncodedSizes => new[] { 105, 10080 }; + + [GlobalSetup] + public void GlobalSetup() + { + // add some extra values that we won't read just to make sure we are far enough from the end of the buffer + // which allows the parser fastpath to always kick in. + const int paddingValueCount = 100; + + varintInputBuffers = new Dictionary(); + for (int encodedSize = 1; encodedSize <= 10; encodedSize++) + { + byte[] buffer = CreateBufferWithRandomVarints(random, BytesToParse / encodedSize, encodedSize, paddingValueCount); + varintInputBuffers.Add(encodedSize, buffer); + } + + doubleInputBuffer = CreateBufferWithRandomDoubles(random, BytesToParse / sizeof(double), paddingValueCount); + floatInputBuffer = CreateBufferWithRandomFloats(random, BytesToParse / sizeof(float), paddingValueCount); + fixedIntInputBuffer = CreateBufferWithRandomData(random, BytesToParse / sizeof(long), sizeof(long), paddingValueCount); + + stringInputBuffers = new Dictionary(); + foreach (var encodedSize in StringEncodedSizes) + { + byte[] buffer = CreateBufferWithStrings(BytesToParse / encodedSize, encodedSize, encodedSize < 10 ? 10 : 1 ); + stringInputBuffers.Add(encodedSize, buffer); + } + + stringInputBuffersSegmented = new Dictionary>(); + foreach (var encodedSize in StringSegmentedEncodedSizes) + { + byte[] buffer = CreateBufferWithStrings(BytesToParse / encodedSize, encodedSize, encodedSize < 10 ? 10 : 1); + stringInputBuffersSegmented.Add(encodedSize, ReadOnlySequenceFactory.CreateWithContent(buffer, segmentSize: 128, addEmptySegmentDelimiters: false)); + } + } + + // Total number of bytes that each benchmark will parse. + // Measuring the time taken to parse buffer of given size makes it easier to compare parsing speed for different + // types and makes it easy to calculate the througput (in MB/s) + // 10800 bytes is chosen because it is divisible by all possible encoded sizes for all primitive types {1..10} + [Params(10080)] + public int BytesToParse { get; set; } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + public int ParseRawVarint32_CodedInputStream(int encodedSize) + { + CodedInputStream cis = new CodedInputStream(varintInputBuffers[encodedSize]); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadInt32(); + } + return sum; + } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + public int ParseRawVarint32_ParseContext(int encodedSize) + { + InitializeParseContext(varintInputBuffers[encodedSize], out ParseContext ctx); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadInt32(); + } + return sum; + } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + [Arguments(6)] + [Arguments(7)] + [Arguments(8)] + [Arguments(9)] + [Arguments(10)] + public long ParseRawVarint64_CodedInputStream(int encodedSize) + { + CodedInputStream cis = new CodedInputStream(varintInputBuffers[encodedSize]); + long sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadInt64(); + } + return sum; + } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + [Arguments(6)] + [Arguments(7)] + [Arguments(8)] + [Arguments(9)] + [Arguments(10)] + public long ParseRawVarint64_ParseContext(int encodedSize) + { + InitializeParseContext(varintInputBuffers[encodedSize], out ParseContext ctx); + long sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadInt64(); + } + return sum; + } + + [Benchmark] + public uint ParseFixed32_CodedInputStream() + { + const int encodedSize = sizeof(uint); + CodedInputStream cis = new CodedInputStream(fixedIntInputBuffer); + uint sum = 0; + for (uint i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadFixed32(); + } + return sum; + } + + [Benchmark] + public uint ParseFixed32_ParseContext() + { + const int encodedSize = sizeof(uint); + InitializeParseContext(fixedIntInputBuffer, out ParseContext ctx); + uint sum = 0; + for (uint i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadFixed32(); + } + return sum; + } + + [Benchmark] + public ulong ParseFixed64_CodedInputStream() + { + const int encodedSize = sizeof(ulong); + CodedInputStream cis = new CodedInputStream(fixedIntInputBuffer); + ulong sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadFixed64(); + } + return sum; + } + + [Benchmark] + public ulong ParseFixed64_ParseContext() + { + const int encodedSize = sizeof(ulong); + InitializeParseContext(fixedIntInputBuffer, out ParseContext ctx); + ulong sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadFixed64(); + } + return sum; + } + + [Benchmark] + public float ParseRawFloat_CodedInputStream() + { + const int encodedSize = sizeof(float); + CodedInputStream cis = new CodedInputStream(floatInputBuffer); + float sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadFloat(); + } + return sum; + } + + [Benchmark] + public float ParseRawFloat_ParseContext() + { + const int encodedSize = sizeof(float); + InitializeParseContext(floatInputBuffer, out ParseContext ctx); + float sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadFloat(); + } + return sum; + } + + [Benchmark] + public double ParseRawDouble_CodedInputStream() + { + const int encodedSize = sizeof(double); + CodedInputStream cis = new CodedInputStream(doubleInputBuffer); + double sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadDouble(); + } + return sum; + } + + [Benchmark] + public double ParseRawDouble_ParseContext() + { + const int encodedSize = sizeof(double); + InitializeParseContext(doubleInputBuffer, out ParseContext ctx); + double sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadDouble(); + } + return sum; + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public int ParseString_CodedInputStream(int encodedSize) + { + CodedInputStream cis = new CodedInputStream(stringInputBuffers[encodedSize]); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadString().Length; + } + return sum; + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public int ParseString_ParseContext(int encodedSize) + { + InitializeParseContext(stringInputBuffers[encodedSize], out ParseContext ctx); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadString().Length; + } + return sum; + } + + [Benchmark] + [ArgumentsSource(nameof(StringSegmentedEncodedSizes))] + public int ParseString_ParseContext_MultipleSegments(int encodedSize) + { + InitializeParseContext(stringInputBuffersSegmented[encodedSize], out ParseContext ctx); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadString().Length; + } + return sum; + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public int ParseBytes_CodedInputStream(int encodedSize) + { + CodedInputStream cis = new CodedInputStream(stringInputBuffers[encodedSize]); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += cis.ReadBytes().Length; + } + return sum; + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public int ParseBytes_ParseContext(int encodedSize) + { + InitializeParseContext(stringInputBuffers[encodedSize], out ParseContext ctx); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadBytes().Length; + } + return sum; + } + + [Benchmark] + [ArgumentsSource(nameof(StringSegmentedEncodedSizes))] + public int ParseBytes_ParseContext_MultipleSegments(int encodedSize) + { + InitializeParseContext(stringInputBuffersSegmented[encodedSize], out ParseContext ctx); + int sum = 0; + for (int i = 0; i < BytesToParse / encodedSize; i++) + { + sum += ctx.ReadBytes().Length; + } + return sum; + } + + private static void InitializeParseContext(byte[] buffer, out ParseContext ctx) + { + ParseContext.Initialize(new ReadOnlySequence(buffer), out ctx); + } + + private static void InitializeParseContext(ReadOnlySequence buffer, out ParseContext ctx) + { + ParseContext.Initialize(buffer, out ctx); + } + + private static byte[] CreateBufferWithRandomVarints(Random random, int valueCount, int encodedSize, int paddingValueCount) + { + MemoryStream ms = new MemoryStream(); + CodedOutputStream cos = new CodedOutputStream(ms); + for (int i = 0; i < valueCount + paddingValueCount; i++) + { + cos.WriteUInt64(RandomUnsignedVarint(random, encodedSize, false)); + } + cos.Flush(); + var buffer = ms.ToArray(); + + if (buffer.Length != encodedSize * (valueCount + paddingValueCount)) + { + throw new InvalidOperationException($"Unexpected output buffer length {buffer.Length}"); + } + return buffer; + } + + private static byte[] CreateBufferWithRandomFloats(Random random, int valueCount, int paddingValueCount) + { + MemoryStream ms = new MemoryStream(); + CodedOutputStream cos = new CodedOutputStream(ms); + for (int i = 0; i < valueCount + paddingValueCount; i++) + { + cos.WriteFloat((float)random.NextDouble()); + } + cos.Flush(); + var buffer = ms.ToArray(); + return buffer; + } + + private static byte[] CreateBufferWithRandomDoubles(Random random, int valueCount, int paddingValueCount) + { + MemoryStream ms = new MemoryStream(); + CodedOutputStream cos = new CodedOutputStream(ms); + for (int i = 0; i < valueCount + paddingValueCount; i++) + { + cos.WriteDouble(random.NextDouble()); + } + cos.Flush(); + var buffer = ms.ToArray(); + return buffer; + } + + private static byte[] CreateBufferWithRandomData(Random random, int valueCount, int encodedSize, int paddingValueCount) + { + int bufferSize = (valueCount + paddingValueCount) * encodedSize; + byte[] buffer = new byte[bufferSize]; + random.NextBytes(buffer); + return buffer; + } + + /// + /// Generate a random value that will take exactly "encodedSize" bytes when varint-encoded. + /// + public static ulong RandomUnsignedVarint(Random random, int encodedSize, bool fitsIn32Bits) + { + Span randomBytesBuffer = stackalloc byte[8]; + + if (encodedSize < 1 || encodedSize > 10 || (fitsIn32Bits && encodedSize > 5)) + { + throw new ArgumentException("Illegal encodedSize value requested", nameof(encodedSize)); + } + const int bitsPerByte = 7; + + ulong result = 0; + while (true) + { + random.NextBytes(randomBytesBuffer); + ulong randomValue = BinaryPrimitives.ReadUInt64LittleEndian(randomBytesBuffer); + + // only use the number of random bits we need + ulong bitmask = encodedSize < 10 ? ((1UL << (encodedSize * bitsPerByte)) - 1) : ulong.MaxValue; + result = randomValue & bitmask; + + if (fitsIn32Bits) + { + // make sure the resulting value is representable by a uint. + result &= uint.MaxValue; + } + + if (encodedSize == 10) + { + // for 10-byte values the highest bit always needs to be set (7*9=63) + result |= ulong.MaxValue; + break; + } + + // some random values won't require the full "encodedSize" bytes, check that at least + // one of the top 7 bits is set. Retrying is fine since it only happens rarely + if (encodedSize == 1 || (result & (0x7FUL << ((encodedSize - 1) * bitsPerByte))) != 0) + { + break; + } + } + return result; + } + + private static byte[] CreateBufferWithStrings(int valueCount, int encodedSize, int paddingValueCount) + { + var str = CreateStringWithEncodedSize(encodedSize); + + MemoryStream ms = new MemoryStream(); + CodedOutputStream cos = new CodedOutputStream(ms); + for (int i = 0; i < valueCount + paddingValueCount; i++) + { + cos.WriteString(str); + } + cos.Flush(); + var buffer = ms.ToArray(); + + if (buffer.Length != encodedSize * (valueCount + paddingValueCount)) + { + throw new InvalidOperationException($"Unexpected output buffer length {buffer.Length}"); + } + return buffer; + } + + public static string CreateStringWithEncodedSize(int encodedSize) + { + var str = new string('a', encodedSize); + while (CodedOutputStream.ComputeStringSize(str) > encodedSize) + { + str = str.Substring(1); + } + + if (CodedOutputStream.ComputeStringSize(str) != encodedSize) + { + throw new InvalidOperationException($"Generated string with wrong encodedSize"); + } + return str; + } + + public static string CreateNonAsciiStringWithEncodedSize(int encodedSize) + { + if (encodedSize < 3) + { + throw new ArgumentException("Illegal encoded size for a string with non-ascii chars."); + } + var twoByteChar = '\u00DC'; // U-umlaut, UTF8 encoding has 2 bytes + var str = new string(twoByteChar, encodedSize / 2); + while (CodedOutputStream.ComputeStringSize(str) > encodedSize) + { + str = str.Substring(1); + } + + // add padding of ascii characters to reach the desired encoded size. + while (CodedOutputStream.ComputeStringSize(str) < encodedSize) + { + str += 'a'; + } + + // Note that for a few specific encodedSize values, it might be impossible to generate + // the string with the desired encodedSize using the algorithm above. For testing purposes, checking that + // the encoded size we got is actually correct is good enough. + if (CodedOutputStream.ComputeStringSize(str) != encodedSize) + { + throw new InvalidOperationException($"Generated string with wrong encodedSize"); + } + return str; + } + } +} diff --git a/csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmark.cs deleted file mode 100644 index ae17c1819af0..000000000000 --- a/csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmark.cs +++ /dev/null @@ -1,102 +0,0 @@ -#region Copyright notice and license -// Protocol Buffers - Google's data interchange format -// Copyright 2019 Google Inc. All rights reserved. -// https://github.com/protocolbuffers/protobuf -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. -#endregion - -using BenchmarkDotNet.Attributes; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Google.Protobuf.Benchmarks -{ - /// - /// Benchmark that tests serialization/deserialization of wrapper fields. - /// - [MemoryDiagnoser] - public class WrapperBenchmark - { - byte[] manyWrapperFieldsData; - byte[] manyPrimitiveFieldsData; - - [GlobalSetup] - public void GlobalSetup() - { - manyWrapperFieldsData = CreateManyWrapperFieldsMessage().ToByteArray(); - manyPrimitiveFieldsData = CreateManyPrimitiveFieldsMessage().ToByteArray(); - } - - [Benchmark] - public ManyWrapperFieldsMessage ParseWrapperFields() - { - return ManyWrapperFieldsMessage.Parser.ParseFrom(manyWrapperFieldsData); - } - - [Benchmark] - public ManyPrimitiveFieldsMessage ParsePrimitiveFields() - { - return ManyPrimitiveFieldsMessage.Parser.ParseFrom(manyPrimitiveFieldsData); - } - - private static ManyWrapperFieldsMessage CreateManyWrapperFieldsMessage() - { - // Example data match data of an internal benchmarks - return new ManyWrapperFieldsMessage() - { - Int64Field19 = 123, - Int64Field37 = 1000032, - Int64Field26 = 3453524500, - DoubleField79 = 1.2, - DoubleField25 = 234, - DoubleField9 = 123.3, - DoubleField28 = 23, - DoubleField7 = 234, - DoubleField50 = 2.45 - }; - } - - private static ManyPrimitiveFieldsMessage CreateManyPrimitiveFieldsMessage() - { - // Example data match data of an internal benchmarks - return new ManyPrimitiveFieldsMessage() - { - Int64Field19 = 123, - Int64Field37 = 1000032, - Int64Field26 = 3453524500, - DoubleField79 = 1.2, - DoubleField25 = 234, - DoubleField9 = 123.3, - DoubleField28 = 23, - DoubleField7 = 234, - DoubleField50 = 2.45 - }; - } - } -} diff --git a/csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs b/csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs index 0cc86e2ad406..9db92447ee94 100644 --- a/csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs +++ b/csharp/src/Google.Protobuf.Benchmarks/WrapperBenchmarkMessages.cs @@ -237,7 +237,11 @@ public static partial class WrapperBenchmarkMessagesReflection { /// a message that has a large number of wrapper fields /// obfuscated version of an internal message /// - public sealed partial class ManyWrapperFieldsMessage : pb::IMessage { + public sealed partial class ManyWrapperFieldsMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ManyWrapperFieldsMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2069,6 +2073,9 @@ public sealed partial class ManyWrapperFieldsMessage : pb::IMessage - /// same as ManyWrapperFieldsMessages, but with primitive fields - /// for comparison. - /// - public sealed partial class ManyPrimitiveFieldsMessage : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ManyPrimitiveFieldsMessage()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.Benchmarks.WrapperBenchmarkMessagesReflection.Descriptor.MessageTypes[1]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public ManyPrimitiveFieldsMessage() { - OnConstruction(); - } - + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + double? value = _single_doubleField1_codec.Read(ref input); + if (doubleField1_ == null || value != 0D) { + DoubleField1 = value; + } + break; + } + case 18: { + long? value = _single_int64Field2_codec.Read(ref input); + if (int64Field2_ == null || value != 0L) { + Int64Field2 = value; + } + break; + } + case 26: { + long? value = _single_int64Field3_codec.Read(ref input); + if (int64Field3_ == null || value != 0L) { + Int64Field3 = value; + } + break; + } + case 34: { + long? value = _single_int64Field4_codec.Read(ref input); + if (int64Field4_ == null || value != 0L) { + Int64Field4 = value; + } + break; + } + case 58: { + double? value = _single_doubleField7_codec.Read(ref input); + if (doubleField7_ == null || value != 0D) { + DoubleField7 = value; + } + break; + } + case 66: { + double? value = _single_doubleField8_codec.Read(ref input); + if (doubleField8_ == null || value != 0D) { + DoubleField8 = value; + } + break; + } + case 74: { + double? value = _single_doubleField9_codec.Read(ref input); + if (doubleField9_ == null || value != 0D) { + DoubleField9 = value; + } + break; + } + case 82: { + double? value = _single_doubleField10_codec.Read(ref input); + if (doubleField10_ == null || value != 0D) { + DoubleField10 = value; + } + break; + } + case 90: { + double? value = _single_doubleField11_codec.Read(ref input); + if (doubleField11_ == null || value != 0D) { + DoubleField11 = value; + } + break; + } + case 114: { + double? value = _single_doubleField14_codec.Read(ref input); + if (doubleField14_ == null || value != 0D) { + DoubleField14 = value; + } + break; + } + case 122: { + double? value = _single_doubleField15_codec.Read(ref input); + if (doubleField15_ == null || value != 0D) { + DoubleField15 = value; + } + break; + } + case 154: { + long? value = _single_int64Field19_codec.Read(ref input); + if (int64Field19_ == null || value != 0L) { + Int64Field19 = value; + } + break; + } + case 162: { + double? value = _single_doubleField20_codec.Read(ref input); + if (doubleField20_ == null || value != 0D) { + DoubleField20 = value; + } + break; + } + case 170: { + double? value = _single_doubleField21_codec.Read(ref input); + if (doubleField21_ == null || value != 0D) { + DoubleField21 = value; + } + break; + } + case 178: { + double? value = _single_doubleField22_codec.Read(ref input); + if (doubleField22_ == null || value != 0D) { + DoubleField22 = value; + } + break; + } + case 202: { + double? value = _single_doubleField25_codec.Read(ref input); + if (doubleField25_ == null || value != 0D) { + DoubleField25 = value; + } + break; + } + case 210: { + long? value = _single_int64Field26_codec.Read(ref input); + if (int64Field26_ == null || value != 0L) { + Int64Field26 = value; + } + break; + } + case 226: { + double? value = _single_doubleField28_codec.Read(ref input); + if (doubleField28_ == null || value != 0D) { + DoubleField28 = value; + } + break; + } + case 234: { + double? value = _single_doubleField29_codec.Read(ref input); + if (doubleField29_ == null || value != 0D) { + DoubleField29 = value; + } + break; + } + case 242: { + double? value = _single_doubleField30_codec.Read(ref input); + if (doubleField30_ == null || value != 0D) { + DoubleField30 = value; + } + break; + } + case 250: { + double? value = _single_doubleField31_codec.Read(ref input); + if (doubleField31_ == null || value != 0D) { + DoubleField31 = value; + } + break; + } + case 258: { + long? value = _single_int64Field32_codec.Read(ref input); + if (int64Field32_ == null || value != 0L) { + Int64Field32 = value; + } + break; + } + case 298: { + long? value = _single_int64Field37_codec.Read(ref input); + if (int64Field37_ == null || value != 0L) { + Int64Field37 = value; + } + break; + } + case 306: { + double? value = _single_doubleField38_codec.Read(ref input); + if (doubleField38_ == null || value != 0D) { + DoubleField38 = value; + } + break; + } + case 314: { + long? value = _single_interactions_codec.Read(ref input); + if (interactions_ == null || value != 0L) { + Interactions = value; + } + break; + } + case 322: { + double? value = _single_doubleField40_codec.Read(ref input); + if (doubleField40_ == null || value != 0D) { + DoubleField40 = value; + } + break; + } + case 330: { + long? value = _single_int64Field41_codec.Read(ref input); + if (int64Field41_ == null || value != 0L) { + Int64Field41 = value; + } + break; + } + case 338: { + double? value = _single_doubleField42_codec.Read(ref input); + if (doubleField42_ == null || value != 0D) { + DoubleField42 = value; + } + break; + } + case 346: { + long? value = _single_int64Field43_codec.Read(ref input); + if (int64Field43_ == null || value != 0L) { + Int64Field43 = value; + } + break; + } + case 354: { + long? value = _single_int64Field44_codec.Read(ref input); + if (int64Field44_ == null || value != 0L) { + Int64Field44 = value; + } + break; + } + case 362: { + double? value = _single_doubleField45_codec.Read(ref input); + if (doubleField45_ == null || value != 0D) { + DoubleField45 = value; + } + break; + } + case 370: { + double? value = _single_doubleField46_codec.Read(ref input); + if (doubleField46_ == null || value != 0D) { + DoubleField46 = value; + } + break; + } + case 378: { + double? value = _single_doubleField47_codec.Read(ref input); + if (doubleField47_ == null || value != 0D) { + DoubleField47 = value; + } + break; + } + case 386: { + double? value = _single_doubleField48_codec.Read(ref input); + if (doubleField48_ == null || value != 0D) { + DoubleField48 = value; + } + break; + } + case 394: { + double? value = _single_doubleField49_codec.Read(ref input); + if (doubleField49_ == null || value != 0D) { + DoubleField49 = value; + } + break; + } + case 402: { + double? value = _single_doubleField50_codec.Read(ref input); + if (doubleField50_ == null || value != 0D) { + DoubleField50 = value; + } + break; + } + case 410: { + double? value = _single_doubleField51_codec.Read(ref input); + if (doubleField51_ == null || value != 0D) { + DoubleField51 = value; + } + break; + } + case 418: { + double? value = _single_doubleField52_codec.Read(ref input); + if (doubleField52_ == null || value != 0D) { + DoubleField52 = value; + } + break; + } + case 426: { + double? value = _single_doubleField53_codec.Read(ref input); + if (doubleField53_ == null || value != 0D) { + DoubleField53 = value; + } + break; + } + case 434: { + double? value = _single_doubleField54_codec.Read(ref input); + if (doubleField54_ == null || value != 0D) { + DoubleField54 = value; + } + break; + } + case 442: { + double? value = _single_doubleField55_codec.Read(ref input); + if (doubleField55_ == null || value != 0D) { + DoubleField55 = value; + } + break; + } + case 450: { + double? value = _single_doubleField56_codec.Read(ref input); + if (doubleField56_ == null || value != 0D) { + DoubleField56 = value; + } + break; + } + case 458: { + double? value = _single_doubleField57_codec.Read(ref input); + if (doubleField57_ == null || value != 0D) { + DoubleField57 = value; + } + break; + } + case 466: { + double? value = _single_doubleField58_codec.Read(ref input); + if (doubleField58_ == null || value != 0D) { + DoubleField58 = value; + } + break; + } + case 474: { + long? value = _single_int64Field59_codec.Read(ref input); + if (int64Field59_ == null || value != 0L) { + Int64Field59 = value; + } + break; + } + case 482: { + long? value = _single_int64Field60_codec.Read(ref input); + if (int64Field60_ == null || value != 0L) { + Int64Field60 = value; + } + break; + } + case 498: { + double? value = _single_doubleField62_codec.Read(ref input); + if (doubleField62_ == null || value != 0D) { + DoubleField62 = value; + } + break; + } + case 522: { + double? value = _single_doubleField65_codec.Read(ref input); + if (doubleField65_ == null || value != 0D) { + DoubleField65 = value; + } + break; + } + case 530: { + double? value = _single_doubleField66_codec.Read(ref input); + if (doubleField66_ == null || value != 0D) { + DoubleField66 = value; + } + break; + } + case 538: { + double? value = _single_doubleField67_codec.Read(ref input); + if (doubleField67_ == null || value != 0D) { + DoubleField67 = value; + } + break; + } + case 546: { + double? value = _single_doubleField68_codec.Read(ref input); + if (doubleField68_ == null || value != 0D) { + DoubleField68 = value; + } + break; + } + case 554: { + double? value = _single_doubleField69_codec.Read(ref input); + if (doubleField69_ == null || value != 0D) { + DoubleField69 = value; + } + break; + } + case 562: { + double? value = _single_doubleField70_codec.Read(ref input); + if (doubleField70_ == null || value != 0D) { + DoubleField70 = value; + } + break; + } + case 570: { + double? value = _single_doubleField71_codec.Read(ref input); + if (doubleField71_ == null || value != 0D) { + DoubleField71 = value; + } + break; + } + case 578: { + double? value = _single_doubleField72_codec.Read(ref input); + if (doubleField72_ == null || value != 0D) { + DoubleField72 = value; + } + break; + } + case 586: { + string value = _single_stringField73_codec.Read(ref input); + if (stringField73_ == null || value != "") { + StringField73 = value; + } + break; + } + case 594: { + string value = _single_stringField74_codec.Read(ref input); + if (stringField74_ == null || value != "") { + StringField74 = value; + } + break; + } + case 602: { + double? value = _single_doubleField75_codec.Read(ref input); + if (doubleField75_ == null || value != 0D) { + DoubleField75 = value; + } + break; + } + case 618: { + double? value = _single_doubleField77_codec.Read(ref input); + if (doubleField77_ == null || value != 0D) { + DoubleField77 = value; + } + break; + } + case 626: { + double? value = _single_doubleField78_codec.Read(ref input); + if (doubleField78_ == null || value != 0D) { + DoubleField78 = value; + } + break; + } + case 634: { + double? value = _single_doubleField79_codec.Read(ref input); + if (doubleField79_ == null || value != 0D) { + DoubleField79 = value; + } + break; + } + case 640: { + EnumField80 = input.ReadInt32(); + break; + } + case 648: { + EnumField81 = input.ReadInt32(); + break; + } + case 658: { + long? value = _single_int64Field82_codec.Read(ref input); + if (int64Field82_ == null || value != 0L) { + Int64Field82 = value; + } + break; + } + case 664: { + EnumField83 = input.ReadInt32(); + break; + } + case 674: { + double? value = _single_doubleField84_codec.Read(ref input); + if (doubleField84_ == null || value != 0D) { + DoubleField84 = value; + } + break; + } + case 682: { + long? value = _single_int64Field85_codec.Read(ref input); + if (int64Field85_ == null || value != 0L) { + Int64Field85 = value; + } + break; + } + case 690: { + long? value = _single_int64Field86_codec.Read(ref input); + if (int64Field86_ == null || value != 0L) { + Int64Field86 = value; + } + break; + } + case 698: { + long? value = _single_int64Field87_codec.Read(ref input); + if (int64Field87_ == null || value != 0L) { + Int64Field87 = value; + } + break; + } + case 706: { + double? value = _single_doubleField88_codec.Read(ref input); + if (doubleField88_ == null || value != 0D) { + DoubleField88 = value; + } + break; + } + case 714: { + double? value = _single_doubleField89_codec.Read(ref input); + if (doubleField89_ == null || value != 0D) { + DoubleField89 = value; + } + break; + } + case 722: { + double? value = _single_doubleField90_codec.Read(ref input); + if (doubleField90_ == null || value != 0D) { + DoubleField90 = value; + } + break; + } + case 730: { + double? value = _single_doubleField91_codec.Read(ref input); + if (doubleField91_ == null || value != 0D) { + DoubleField91 = value; + } + break; + } + case 738: { + double? value = _single_doubleField92_codec.Read(ref input); + if (doubleField92_ == null || value != 0D) { + DoubleField92 = value; + } + break; + } + case 746: { + double? value = _single_doubleField93_codec.Read(ref input); + if (doubleField93_ == null || value != 0D) { + DoubleField93 = value; + } + break; + } + case 754: { + double? value = _single_doubleField94_codec.Read(ref input); + if (doubleField94_ == null || value != 0D) { + DoubleField94 = value; + } + break; + } + case 762: { + double? value = _single_doubleField95_codec.Read(ref input); + if (doubleField95_ == null || value != 0D) { + DoubleField95 = value; + } + break; + } + case 770: { + double? value = _single_doubleField96_codec.Read(ref input); + if (doubleField96_ == null || value != 0D) { + DoubleField96 = value; + } + break; + } + case 778: { + double? value = _single_doubleField97_codec.Read(ref input); + if (doubleField97_ == null || value != 0D) { + DoubleField97 = value; + } + break; + } + case 786: { + double? value = _single_doubleField98_codec.Read(ref input); + if (doubleField98_ == null || value != 0D) { + DoubleField98 = value; + } + break; + } + case 794: { + double? value = _single_doubleField99_codec.Read(ref input); + if (doubleField99_ == null || value != 0D) { + DoubleField99 = value; + } + break; + } + case 802: + case 800: { + repeatedIntField100_.AddEntriesFrom(ref input, _repeated_repeatedIntField100_codec); + break; + } + case 810: { + double? value = _single_doubleField101_codec.Read(ref input); + if (doubleField101_ == null || value != 0D) { + DoubleField101 = value; + } + break; + } + case 818: { + double? value = _single_doubleField102_codec.Read(ref input); + if (doubleField102_ == null || value != 0D) { + DoubleField102 = value; + } + break; + } + case 826: { + double? value = _single_doubleField103_codec.Read(ref input); + if (doubleField103_ == null || value != 0D) { + DoubleField103 = value; + } + break; + } + case 834: { + double? value = _single_doubleField104_codec.Read(ref input); + if (doubleField104_ == null || value != 0D) { + DoubleField104 = value; + } + break; + } + case 842: { + double? value = _single_doubleField105_codec.Read(ref input); + if (doubleField105_ == null || value != 0D) { + DoubleField105 = value; + } + break; + } + case 850: { + double? value = _single_doubleField106_codec.Read(ref input); + if (doubleField106_ == null || value != 0D) { + DoubleField106 = value; + } + break; + } + case 858: { + long? value = _single_int64Field107_codec.Read(ref input); + if (int64Field107_ == null || value != 0L) { + Int64Field107 = value; + } + break; + } + case 866: { + double? value = _single_doubleField108_codec.Read(ref input); + if (doubleField108_ == null || value != 0D) { + DoubleField108 = value; + } + break; + } + case 874: { + double? value = _single_doubleField109_codec.Read(ref input); + if (doubleField109_ == null || value != 0D) { + DoubleField109 = value; + } + break; + } + case 882: { + long? value = _single_int64Field110_codec.Read(ref input); + if (int64Field110_ == null || value != 0L) { + Int64Field110 = value; + } + break; + } + case 890: { + double? value = _single_doubleField111_codec.Read(ref input); + if (doubleField111_ == null || value != 0D) { + DoubleField111 = value; + } + break; + } + case 898: { + long? value = _single_int64Field112_codec.Read(ref input); + if (int64Field112_ == null || value != 0L) { + Int64Field112 = value; + } + break; + } + case 906: { + double? value = _single_doubleField113_codec.Read(ref input); + if (doubleField113_ == null || value != 0D) { + DoubleField113 = value; + } + break; + } + case 914: { + long? value = _single_int64Field114_codec.Read(ref input); + if (int64Field114_ == null || value != 0L) { + Int64Field114 = value; + } + break; + } + case 922: { + long? value = _single_int64Field115_codec.Read(ref input); + if (int64Field115_ == null || value != 0L) { + Int64Field115 = value; + } + break; + } + case 930: { + double? value = _single_doubleField116_codec.Read(ref input); + if (doubleField116_ == null || value != 0D) { + DoubleField116 = value; + } + break; + } + case 938: { + long? value = _single_int64Field117_codec.Read(ref input); + if (int64Field117_ == null || value != 0L) { + Int64Field117 = value; + } + break; + } + case 946: { + double? value = _single_doubleField118_codec.Read(ref input); + if (doubleField118_ == null || value != 0D) { + DoubleField118 = value; + } + break; + } + case 954: { + double? value = _single_doubleField119_codec.Read(ref input); + if (doubleField119_ == null || value != 0D) { + DoubleField119 = value; + } + break; + } + case 962: { + double? value = _single_doubleField120_codec.Read(ref input); + if (doubleField120_ == null || value != 0D) { + DoubleField120 = value; + } + break; + } + case 970: { + double? value = _single_doubleField121_codec.Read(ref input); + if (doubleField121_ == null || value != 0D) { + DoubleField121 = value; + } + break; + } + case 978: { + double? value = _single_doubleField122_codec.Read(ref input); + if (doubleField122_ == null || value != 0D) { + DoubleField122 = value; + } + break; + } + case 986: { + double? value = _single_doubleField123_codec.Read(ref input); + if (doubleField123_ == null || value != 0D) { + DoubleField123 = value; + } + break; + } + case 994: { + double? value = _single_doubleField124_codec.Read(ref input); + if (doubleField124_ == null || value != 0D) { + DoubleField124 = value; + } + break; + } + case 1002: { + long? value = _single_int64Field125_codec.Read(ref input); + if (int64Field125_ == null || value != 0L) { + Int64Field125 = value; + } + break; + } + case 1010: { + long? value = _single_int64Field126_codec.Read(ref input); + if (int64Field126_ == null || value != 0L) { + Int64Field126 = value; + } + break; + } + case 1018: { + long? value = _single_int64Field127_codec.Read(ref input); + if (int64Field127_ == null || value != 0L) { + Int64Field127 = value; + } + break; + } + case 1026: { + double? value = _single_doubleField128_codec.Read(ref input); + if (doubleField128_ == null || value != 0D) { + DoubleField128 = value; + } + break; + } + case 1034: { + double? value = _single_doubleField129_codec.Read(ref input); + if (doubleField129_ == null || value != 0D) { + DoubleField129 = value; + } + break; + } + } + } + } + #endif + + } + + /// + /// same as ManyWrapperFieldsMessages, but with primitive fields + /// for comparison. + /// + public sealed partial class ManyPrimitiveFieldsMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ManyPrimitiveFieldsMessage()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Google.Protobuf.Benchmarks.WrapperBenchmarkMessagesReflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ManyPrimitiveFieldsMessage() { + OnConstruction(); + } + partial void OnConstruction(); [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public ManyPrimitiveFieldsMessage(ManyPrimitiveFieldsMessage other) : this() { - doubleField95_ = other.doubleField95_; - doubleField1_ = other.doubleField1_; - doubleField79_ = other.doubleField79_; - int64Field2_ = other.int64Field2_; - doubleField96_ = other.doubleField96_; - int64Field3_ = other.int64Field3_; - int64Field4_ = other.int64Field4_; - doubleField97_ = other.doubleField97_; - doubleField65_ = other.doubleField65_; - doubleField66_ = other.doubleField66_; - doubleField7_ = other.doubleField7_; - doubleField62_ = other.doubleField62_; - doubleField118_ = other.doubleField118_; - doubleField119_ = other.doubleField119_; - doubleField67_ = other.doubleField67_; - doubleField120_ = other.doubleField120_; - doubleField121_ = other.doubleField121_; - doubleField122_ = other.doubleField122_; - doubleField123_ = other.doubleField123_; - doubleField124_ = other.doubleField124_; - doubleField8_ = other.doubleField8_; - doubleField9_ = other.doubleField9_; - doubleField98_ = other.doubleField98_; - doubleField10_ = other.doubleField10_; - doubleField11_ = other.doubleField11_; - doubleField99_ = other.doubleField99_; - doubleField84_ = other.doubleField84_; - doubleField14_ = other.doubleField14_; - doubleField77_ = other.doubleField77_; - doubleField15_ = other.doubleField15_; - int64Field19_ = other.int64Field19_; - int64Field115_ = other.int64Field115_; - doubleField116_ = other.doubleField116_; - int64Field117_ = other.int64Field117_; - doubleField20_ = other.doubleField20_; - doubleField21_ = other.doubleField21_; - stringField73_ = other.stringField73_; - stringField74_ = other.stringField74_; - doubleField22_ = other.doubleField22_; - doubleField69_ = other.doubleField69_; - doubleField70_ = other.doubleField70_; - doubleField71_ = other.doubleField71_; - doubleField72_ = other.doubleField72_; - doubleField25_ = other.doubleField25_; - int64Field26_ = other.int64Field26_; - doubleField68_ = other.doubleField68_; - doubleField28_ = other.doubleField28_; - doubleField106_ = other.doubleField106_; - doubleField29_ = other.doubleField29_; - doubleField30_ = other.doubleField30_; - doubleField101_ = other.doubleField101_; - doubleField102_ = other.doubleField102_; - doubleField103_ = other.doubleField103_; - doubleField104_ = other.doubleField104_; - doubleField105_ = other.doubleField105_; - doubleField31_ = other.doubleField31_; - int64Field32_ = other.int64Field32_; - doubleField75_ = other.doubleField75_; - doubleField129_ = other.doubleField129_; - enumField80_ = other.enumField80_; - enumField81_ = other.enumField81_; - int64Field82_ = other.int64Field82_; - enumField83_ = other.enumField83_; - int64Field85_ = other.int64Field85_; - int64Field86_ = other.int64Field86_; - int64Field87_ = other.int64Field87_; - int64Field125_ = other.int64Field125_; - int64Field37_ = other.int64Field37_; - doubleField38_ = other.doubleField38_; - interactions_ = other.interactions_; - repeatedIntField100_ = other.repeatedIntField100_.Clone(); - doubleField40_ = other.doubleField40_; - int64Field41_ = other.int64Field41_; - int64Field126_ = other.int64Field126_; - int64Field127_ = other.int64Field127_; - doubleField128_ = other.doubleField128_; - doubleField109_ = other.doubleField109_; - int64Field110_ = other.int64Field110_; - doubleField111_ = other.doubleField111_; - int64Field112_ = other.int64Field112_; - doubleField113_ = other.doubleField113_; - int64Field114_ = other.int64Field114_; - doubleField42_ = other.doubleField42_; - int64Field43_ = other.int64Field43_; - int64Field44_ = other.int64Field44_; - doubleField45_ = other.doubleField45_; - doubleField46_ = other.doubleField46_; - doubleField78_ = other.doubleField78_; - doubleField88_ = other.doubleField88_; - doubleField47_ = other.doubleField47_; - doubleField89_ = other.doubleField89_; - doubleField48_ = other.doubleField48_; - doubleField49_ = other.doubleField49_; - doubleField50_ = other.doubleField50_; - doubleField90_ = other.doubleField90_; - doubleField51_ = other.doubleField51_; - doubleField91_ = other.doubleField91_; - doubleField92_ = other.doubleField92_; - int64Field107_ = other.int64Field107_; - doubleField93_ = other.doubleField93_; - doubleField108_ = other.doubleField108_; - doubleField52_ = other.doubleField52_; - doubleField53_ = other.doubleField53_; - doubleField94_ = other.doubleField94_; - doubleField54_ = other.doubleField54_; - doubleField55_ = other.doubleField55_; - doubleField56_ = other.doubleField56_; - doubleField57_ = other.doubleField57_; - doubleField58_ = other.doubleField58_; - int64Field59_ = other.int64Field59_; - int64Field60_ = other.int64Field60_; - _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + public ManyPrimitiveFieldsMessage(ManyPrimitiveFieldsMessage other) : this() { + doubleField95_ = other.doubleField95_; + doubleField1_ = other.doubleField1_; + doubleField79_ = other.doubleField79_; + int64Field2_ = other.int64Field2_; + doubleField96_ = other.doubleField96_; + int64Field3_ = other.int64Field3_; + int64Field4_ = other.int64Field4_; + doubleField97_ = other.doubleField97_; + doubleField65_ = other.doubleField65_; + doubleField66_ = other.doubleField66_; + doubleField7_ = other.doubleField7_; + doubleField62_ = other.doubleField62_; + doubleField118_ = other.doubleField118_; + doubleField119_ = other.doubleField119_; + doubleField67_ = other.doubleField67_; + doubleField120_ = other.doubleField120_; + doubleField121_ = other.doubleField121_; + doubleField122_ = other.doubleField122_; + doubleField123_ = other.doubleField123_; + doubleField124_ = other.doubleField124_; + doubleField8_ = other.doubleField8_; + doubleField9_ = other.doubleField9_; + doubleField98_ = other.doubleField98_; + doubleField10_ = other.doubleField10_; + doubleField11_ = other.doubleField11_; + doubleField99_ = other.doubleField99_; + doubleField84_ = other.doubleField84_; + doubleField14_ = other.doubleField14_; + doubleField77_ = other.doubleField77_; + doubleField15_ = other.doubleField15_; + int64Field19_ = other.int64Field19_; + int64Field115_ = other.int64Field115_; + doubleField116_ = other.doubleField116_; + int64Field117_ = other.int64Field117_; + doubleField20_ = other.doubleField20_; + doubleField21_ = other.doubleField21_; + stringField73_ = other.stringField73_; + stringField74_ = other.stringField74_; + doubleField22_ = other.doubleField22_; + doubleField69_ = other.doubleField69_; + doubleField70_ = other.doubleField70_; + doubleField71_ = other.doubleField71_; + doubleField72_ = other.doubleField72_; + doubleField25_ = other.doubleField25_; + int64Field26_ = other.int64Field26_; + doubleField68_ = other.doubleField68_; + doubleField28_ = other.doubleField28_; + doubleField106_ = other.doubleField106_; + doubleField29_ = other.doubleField29_; + doubleField30_ = other.doubleField30_; + doubleField101_ = other.doubleField101_; + doubleField102_ = other.doubleField102_; + doubleField103_ = other.doubleField103_; + doubleField104_ = other.doubleField104_; + doubleField105_ = other.doubleField105_; + doubleField31_ = other.doubleField31_; + int64Field32_ = other.int64Field32_; + doubleField75_ = other.doubleField75_; + doubleField129_ = other.doubleField129_; + enumField80_ = other.enumField80_; + enumField81_ = other.enumField81_; + int64Field82_ = other.int64Field82_; + enumField83_ = other.enumField83_; + int64Field85_ = other.int64Field85_; + int64Field86_ = other.int64Field86_; + int64Field87_ = other.int64Field87_; + int64Field125_ = other.int64Field125_; + int64Field37_ = other.int64Field37_; + doubleField38_ = other.doubleField38_; + interactions_ = other.interactions_; + repeatedIntField100_ = other.repeatedIntField100_.Clone(); + doubleField40_ = other.doubleField40_; + int64Field41_ = other.int64Field41_; + int64Field126_ = other.int64Field126_; + int64Field127_ = other.int64Field127_; + doubleField128_ = other.doubleField128_; + doubleField109_ = other.doubleField109_; + int64Field110_ = other.int64Field110_; + doubleField111_ = other.doubleField111_; + int64Field112_ = other.int64Field112_; + doubleField113_ = other.doubleField113_; + int64Field114_ = other.int64Field114_; + doubleField42_ = other.doubleField42_; + int64Field43_ = other.int64Field43_; + int64Field44_ = other.int64Field44_; + doubleField45_ = other.doubleField45_; + doubleField46_ = other.doubleField46_; + doubleField78_ = other.doubleField78_; + doubleField88_ = other.doubleField88_; + doubleField47_ = other.doubleField47_; + doubleField89_ = other.doubleField89_; + doubleField48_ = other.doubleField48_; + doubleField49_ = other.doubleField49_; + doubleField50_ = other.doubleField50_; + doubleField90_ = other.doubleField90_; + doubleField51_ = other.doubleField51_; + doubleField91_ = other.doubleField91_; + doubleField92_ = other.doubleField92_; + int64Field107_ = other.int64Field107_; + doubleField93_ = other.doubleField93_; + doubleField108_ = other.doubleField108_; + doubleField52_ = other.doubleField52_; + doubleField53_ = other.doubleField53_; + doubleField94_ = other.doubleField94_; + doubleField54_ = other.doubleField54_; + doubleField55_ = other.doubleField55_; + doubleField56_ = other.doubleField56_; + doubleField57_ = other.doubleField57_; + doubleField58_ = other.doubleField58_; + int64Field59_ = other.int64Field59_; + int64Field60_ = other.int64Field60_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ManyPrimitiveFieldsMessage Clone() { + return new ManyPrimitiveFieldsMessage(this); + } + + /// Field number for the "double_field_95" field. + public const int DoubleField95FieldNumber = 95; + private double doubleField95_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField95 { + get { return doubleField95_; } + set { + doubleField95_ = value; + } + } + + /// Field number for the "double_field_1" field. + public const int DoubleField1FieldNumber = 1; + private double doubleField1_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField1 { + get { return doubleField1_; } + set { + doubleField1_ = value; + } + } + + /// Field number for the "double_field_79" field. + public const int DoubleField79FieldNumber = 79; + private double doubleField79_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField79 { + get { return doubleField79_; } + set { + doubleField79_ = value; + } + } + + /// Field number for the "int64_field_2" field. + public const int Int64Field2FieldNumber = 2; + private long int64Field2_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field2 { + get { return int64Field2_; } + set { + int64Field2_ = value; + } + } + + /// Field number for the "double_field_96" field. + public const int DoubleField96FieldNumber = 96; + private double doubleField96_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField96 { + get { return doubleField96_; } + set { + doubleField96_ = value; + } + } + + /// Field number for the "int64_field_3" field. + public const int Int64Field3FieldNumber = 3; + private long int64Field3_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field3 { + get { return int64Field3_; } + set { + int64Field3_ = value; + } + } + + /// Field number for the "int64_field_4" field. + public const int Int64Field4FieldNumber = 4; + private long int64Field4_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field4 { + get { return int64Field4_; } + set { + int64Field4_ = value; + } + } + + /// Field number for the "double_field_97" field. + public const int DoubleField97FieldNumber = 97; + private double doubleField97_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField97 { + get { return doubleField97_; } + set { + doubleField97_ = value; + } + } + + /// Field number for the "double_field_65" field. + public const int DoubleField65FieldNumber = 65; + private double doubleField65_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField65 { + get { return doubleField65_; } + set { + doubleField65_ = value; + } + } + + /// Field number for the "double_field_66" field. + public const int DoubleField66FieldNumber = 66; + private double doubleField66_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField66 { + get { return doubleField66_; } + set { + doubleField66_ = value; + } + } + + /// Field number for the "double_field_7" field. + public const int DoubleField7FieldNumber = 7; + private double doubleField7_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField7 { + get { return doubleField7_; } + set { + doubleField7_ = value; + } + } + + /// Field number for the "double_field_62" field. + public const int DoubleField62FieldNumber = 62; + private double doubleField62_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField62 { + get { return doubleField62_; } + set { + doubleField62_ = value; + } + } + + /// Field number for the "double_field_118" field. + public const int DoubleField118FieldNumber = 118; + private double doubleField118_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField118 { + get { return doubleField118_; } + set { + doubleField118_ = value; + } + } + + /// Field number for the "double_field_119" field. + public const int DoubleField119FieldNumber = 119; + private double doubleField119_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField119 { + get { return doubleField119_; } + set { + doubleField119_ = value; + } + } + + /// Field number for the "double_field_67" field. + public const int DoubleField67FieldNumber = 67; + private double doubleField67_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField67 { + get { return doubleField67_; } + set { + doubleField67_ = value; + } + } + + /// Field number for the "double_field_120" field. + public const int DoubleField120FieldNumber = 120; + private double doubleField120_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField120 { + get { return doubleField120_; } + set { + doubleField120_ = value; + } + } + + /// Field number for the "double_field_121" field. + public const int DoubleField121FieldNumber = 121; + private double doubleField121_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField121 { + get { return doubleField121_; } + set { + doubleField121_ = value; + } + } + + /// Field number for the "double_field_122" field. + public const int DoubleField122FieldNumber = 122; + private double doubleField122_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField122 { + get { return doubleField122_; } + set { + doubleField122_ = value; + } + } + + /// Field number for the "double_field_123" field. + public const int DoubleField123FieldNumber = 123; + private double doubleField123_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField123 { + get { return doubleField123_; } + set { + doubleField123_ = value; + } + } + + /// Field number for the "double_field_124" field. + public const int DoubleField124FieldNumber = 124; + private double doubleField124_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField124 { + get { return doubleField124_; } + set { + doubleField124_ = value; + } + } + + /// Field number for the "double_field_8" field. + public const int DoubleField8FieldNumber = 8; + private double doubleField8_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField8 { + get { return doubleField8_; } + set { + doubleField8_ = value; + } + } + + /// Field number for the "double_field_9" field. + public const int DoubleField9FieldNumber = 9; + private double doubleField9_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField9 { + get { return doubleField9_; } + set { + doubleField9_ = value; + } + } + + /// Field number for the "double_field_98" field. + public const int DoubleField98FieldNumber = 98; + private double doubleField98_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField98 { + get { return doubleField98_; } + set { + doubleField98_ = value; + } + } + + /// Field number for the "double_field_10" field. + public const int DoubleField10FieldNumber = 10; + private double doubleField10_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField10 { + get { return doubleField10_; } + set { + doubleField10_ = value; + } + } + + /// Field number for the "double_field_11" field. + public const int DoubleField11FieldNumber = 11; + private double doubleField11_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField11 { + get { return doubleField11_; } + set { + doubleField11_ = value; + } + } + + /// Field number for the "double_field_99" field. + public const int DoubleField99FieldNumber = 99; + private double doubleField99_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField99 { + get { return doubleField99_; } + set { + doubleField99_ = value; + } + } + + /// Field number for the "double_field_84" field. + public const int DoubleField84FieldNumber = 84; + private double doubleField84_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField84 { + get { return doubleField84_; } + set { + doubleField84_ = value; + } + } + + /// Field number for the "double_field_14" field. + public const int DoubleField14FieldNumber = 14; + private double doubleField14_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField14 { + get { return doubleField14_; } + set { + doubleField14_ = value; + } + } + + /// Field number for the "double_field_77" field. + public const int DoubleField77FieldNumber = 77; + private double doubleField77_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField77 { + get { return doubleField77_; } + set { + doubleField77_ = value; + } + } + + /// Field number for the "double_field_15" field. + public const int DoubleField15FieldNumber = 15; + private double doubleField15_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField15 { + get { return doubleField15_; } + set { + doubleField15_ = value; + } + } + + /// Field number for the "int64_field_19" field. + public const int Int64Field19FieldNumber = 19; + private long int64Field19_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field19 { + get { return int64Field19_; } + set { + int64Field19_ = value; + } + } + + /// Field number for the "int64_field_115" field. + public const int Int64Field115FieldNumber = 115; + private long int64Field115_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field115 { + get { return int64Field115_; } + set { + int64Field115_ = value; + } + } + + /// Field number for the "double_field_116" field. + public const int DoubleField116FieldNumber = 116; + private double doubleField116_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField116 { + get { return doubleField116_; } + set { + doubleField116_ = value; + } + } + + /// Field number for the "int64_field_117" field. + public const int Int64Field117FieldNumber = 117; + private long int64Field117_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field117 { + get { return int64Field117_; } + set { + int64Field117_ = value; + } + } + + /// Field number for the "double_field_20" field. + public const int DoubleField20FieldNumber = 20; + private double doubleField20_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField20 { + get { return doubleField20_; } + set { + doubleField20_ = value; + } + } + + /// Field number for the "double_field_21" field. + public const int DoubleField21FieldNumber = 21; + private double doubleField21_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField21 { + get { return doubleField21_; } + set { + doubleField21_ = value; + } + } + + /// Field number for the "string_field_73" field. + public const int StringField73FieldNumber = 73; + private string stringField73_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string StringField73 { + get { return stringField73_; } + set { + stringField73_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "string_field_74" field. + public const int StringField74FieldNumber = 74; + private string stringField74_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string StringField74 { + get { return stringField74_; } + set { + stringField74_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "double_field_22" field. + public const int DoubleField22FieldNumber = 22; + private double doubleField22_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField22 { + get { return doubleField22_; } + set { + doubleField22_ = value; + } + } + + /// Field number for the "double_field_69" field. + public const int DoubleField69FieldNumber = 69; + private double doubleField69_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField69 { + get { return doubleField69_; } + set { + doubleField69_ = value; + } + } + + /// Field number for the "double_field_70" field. + public const int DoubleField70FieldNumber = 70; + private double doubleField70_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField70 { + get { return doubleField70_; } + set { + doubleField70_ = value; + } + } + + /// Field number for the "double_field_71" field. + public const int DoubleField71FieldNumber = 71; + private double doubleField71_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField71 { + get { return doubleField71_; } + set { + doubleField71_ = value; + } + } + + /// Field number for the "double_field_72" field. + public const int DoubleField72FieldNumber = 72; + private double doubleField72_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField72 { + get { return doubleField72_; } + set { + doubleField72_ = value; + } + } + + /// Field number for the "double_field_25" field. + public const int DoubleField25FieldNumber = 25; + private double doubleField25_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField25 { + get { return doubleField25_; } + set { + doubleField25_ = value; + } + } + + /// Field number for the "int64_field_26" field. + public const int Int64Field26FieldNumber = 26; + private long int64Field26_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field26 { + get { return int64Field26_; } + set { + int64Field26_ = value; + } + } + + /// Field number for the "double_field_68" field. + public const int DoubleField68FieldNumber = 68; + private double doubleField68_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField68 { + get { return doubleField68_; } + set { + doubleField68_ = value; + } + } + + /// Field number for the "double_field_28" field. + public const int DoubleField28FieldNumber = 28; + private double doubleField28_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField28 { + get { return doubleField28_; } + set { + doubleField28_ = value; + } + } + + /// Field number for the "double_field_106" field. + public const int DoubleField106FieldNumber = 106; + private double doubleField106_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField106 { + get { return doubleField106_; } + set { + doubleField106_ = value; + } + } + + /// Field number for the "double_field_29" field. + public const int DoubleField29FieldNumber = 29; + private double doubleField29_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField29 { + get { return doubleField29_; } + set { + doubleField29_ = value; + } + } + + /// Field number for the "double_field_30" field. + public const int DoubleField30FieldNumber = 30; + private double doubleField30_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField30 { + get { return doubleField30_; } + set { + doubleField30_ = value; + } + } + + /// Field number for the "double_field_101" field. + public const int DoubleField101FieldNumber = 101; + private double doubleField101_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField101 { + get { return doubleField101_; } + set { + doubleField101_ = value; + } + } + + /// Field number for the "double_field_102" field. + public const int DoubleField102FieldNumber = 102; + private double doubleField102_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField102 { + get { return doubleField102_; } + set { + doubleField102_ = value; + } + } + + /// Field number for the "double_field_103" field. + public const int DoubleField103FieldNumber = 103; + private double doubleField103_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField103 { + get { return doubleField103_; } + set { + doubleField103_ = value; + } + } + + /// Field number for the "double_field_104" field. + public const int DoubleField104FieldNumber = 104; + private double doubleField104_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField104 { + get { return doubleField104_; } + set { + doubleField104_ = value; + } + } + + /// Field number for the "double_field_105" field. + public const int DoubleField105FieldNumber = 105; + private double doubleField105_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField105 { + get { return doubleField105_; } + set { + doubleField105_ = value; + } + } + + /// Field number for the "double_field_31" field. + public const int DoubleField31FieldNumber = 31; + private double doubleField31_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField31 { + get { return doubleField31_; } + set { + doubleField31_ = value; + } + } + + /// Field number for the "int64_field_32" field. + public const int Int64Field32FieldNumber = 32; + private long int64Field32_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field32 { + get { return int64Field32_; } + set { + int64Field32_ = value; + } + } + + /// Field number for the "double_field_75" field. + public const int DoubleField75FieldNumber = 75; + private double doubleField75_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField75 { + get { return doubleField75_; } + set { + doubleField75_ = value; + } + } + + /// Field number for the "double_field_129" field. + public const int DoubleField129FieldNumber = 129; + private double doubleField129_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField129 { + get { return doubleField129_; } + set { + doubleField129_ = value; + } + } + + /// Field number for the "enum_field_80" field. + public const int EnumField80FieldNumber = 80; + private int enumField80_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int EnumField80 { + get { return enumField80_; } + set { + enumField80_ = value; + } + } + + /// Field number for the "enum_field_81" field. + public const int EnumField81FieldNumber = 81; + private int enumField81_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int EnumField81 { + get { return enumField81_; } + set { + enumField81_ = value; + } + } + + /// Field number for the "int64_field_82" field. + public const int Int64Field82FieldNumber = 82; + private long int64Field82_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field82 { + get { return int64Field82_; } + set { + int64Field82_ = value; + } + } + + /// Field number for the "enum_field_83" field. + public const int EnumField83FieldNumber = 83; + private int enumField83_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int EnumField83 { + get { return enumField83_; } + set { + enumField83_ = value; + } + } + + /// Field number for the "int64_field_85" field. + public const int Int64Field85FieldNumber = 85; + private long int64Field85_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field85 { + get { return int64Field85_; } + set { + int64Field85_ = value; + } + } + + /// Field number for the "int64_field_86" field. + public const int Int64Field86FieldNumber = 86; + private long int64Field86_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field86 { + get { return int64Field86_; } + set { + int64Field86_ = value; + } + } + + /// Field number for the "int64_field_87" field. + public const int Int64Field87FieldNumber = 87; + private long int64Field87_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field87 { + get { return int64Field87_; } + set { + int64Field87_ = value; + } + } + + /// Field number for the "int64_field_125" field. + public const int Int64Field125FieldNumber = 125; + private long int64Field125_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field125 { + get { return int64Field125_; } + set { + int64Field125_ = value; + } + } + + /// Field number for the "int64_field_37" field. + public const int Int64Field37FieldNumber = 37; + private long int64Field37_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field37 { + get { return int64Field37_; } + set { + int64Field37_ = value; + } + } + + /// Field number for the "double_field_38" field. + public const int DoubleField38FieldNumber = 38; + private double doubleField38_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField38 { + get { return doubleField38_; } + set { + doubleField38_ = value; + } + } + + /// Field number for the "interactions" field. + public const int InteractionsFieldNumber = 39; + private long interactions_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Interactions { + get { return interactions_; } + set { + interactions_ = value; + } + } + + /// Field number for the "repeated_int_field_100" field. + public const int RepeatedIntField100FieldNumber = 100; + private static readonly pb::FieldCodec _repeated_repeatedIntField100_codec + = pb::FieldCodec.ForInt32(802); + private readonly pbc::RepeatedField repeatedIntField100_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pbc::RepeatedField RepeatedIntField100 { + get { return repeatedIntField100_; } + } + + /// Field number for the "double_field_40" field. + public const int DoubleField40FieldNumber = 40; + private double doubleField40_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField40 { + get { return doubleField40_; } + set { + doubleField40_ = value; + } + } + + /// Field number for the "int64_field_41" field. + public const int Int64Field41FieldNumber = 41; + private long int64Field41_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field41 { + get { return int64Field41_; } + set { + int64Field41_ = value; + } + } + + /// Field number for the "int64_field_126" field. + public const int Int64Field126FieldNumber = 126; + private long int64Field126_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field126 { + get { return int64Field126_; } + set { + int64Field126_ = value; + } + } + + /// Field number for the "int64_field_127" field. + public const int Int64Field127FieldNumber = 127; + private long int64Field127_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field127 { + get { return int64Field127_; } + set { + int64Field127_ = value; + } + } + + /// Field number for the "double_field_128" field. + public const int DoubleField128FieldNumber = 128; + private double doubleField128_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField128 { + get { return doubleField128_; } + set { + doubleField128_ = value; + } + } + + /// Field number for the "double_field_109" field. + public const int DoubleField109FieldNumber = 109; + private double doubleField109_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField109 { + get { return doubleField109_; } + set { + doubleField109_ = value; + } + } + + /// Field number for the "int64_field_110" field. + public const int Int64Field110FieldNumber = 110; + private long int64Field110_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field110 { + get { return int64Field110_; } + set { + int64Field110_ = value; + } + } + + /// Field number for the "double_field_111" field. + public const int DoubleField111FieldNumber = 111; + private double doubleField111_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField111 { + get { return doubleField111_; } + set { + doubleField111_ = value; + } + } + + /// Field number for the "int64_field_112" field. + public const int Int64Field112FieldNumber = 112; + private long int64Field112_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field112 { + get { return int64Field112_; } + set { + int64Field112_ = value; + } + } + + /// Field number for the "double_field_113" field. + public const int DoubleField113FieldNumber = 113; + private double doubleField113_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField113 { + get { return doubleField113_; } + set { + doubleField113_ = value; + } + } + + /// Field number for the "int64_field_114" field. + public const int Int64Field114FieldNumber = 114; + private long int64Field114_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field114 { + get { return int64Field114_; } + set { + int64Field114_ = value; + } + } + + /// Field number for the "double_field_42" field. + public const int DoubleField42FieldNumber = 42; + private double doubleField42_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField42 { + get { return doubleField42_; } + set { + doubleField42_ = value; + } + } + + /// Field number for the "int64_field_43" field. + public const int Int64Field43FieldNumber = 43; + private long int64Field43_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field43 { + get { return int64Field43_; } + set { + int64Field43_ = value; + } } + /// Field number for the "int64_field_44" field. + public const int Int64Field44FieldNumber = 44; + private long int64Field44_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public ManyPrimitiveFieldsMessage Clone() { - return new ManyPrimitiveFieldsMessage(this); + public long Int64Field44 { + get { return int64Field44_; } + set { + int64Field44_ = value; + } } - /// Field number for the "double_field_95" field. - public const int DoubleField95FieldNumber = 95; - private double doubleField95_; + /// Field number for the "double_field_45" field. + public const int DoubleField45FieldNumber = 45; + private double doubleField45_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField95 { - get { return doubleField95_; } + public double DoubleField45 { + get { return doubleField45_; } set { - doubleField95_ = value; + doubleField45_ = value; } } - /// Field number for the "double_field_1" field. - public const int DoubleField1FieldNumber = 1; - private double doubleField1_; + /// Field number for the "double_field_46" field. + public const int DoubleField46FieldNumber = 46; + private double doubleField46_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField1 { - get { return doubleField1_; } + public double DoubleField46 { + get { return doubleField46_; } set { - doubleField1_ = value; + doubleField46_ = value; } } - /// Field number for the "double_field_79" field. - public const int DoubleField79FieldNumber = 79; - private double doubleField79_; + /// Field number for the "double_field_78" field. + public const int DoubleField78FieldNumber = 78; + private double doubleField78_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField79 { - get { return doubleField79_; } + public double DoubleField78 { + get { return doubleField78_; } set { - doubleField79_ = value; + doubleField78_ = value; } } - /// Field number for the "int64_field_2" field. - public const int Int64Field2FieldNumber = 2; - private long int64Field2_; + /// Field number for the "double_field_88" field. + public const int DoubleField88FieldNumber = 88; + private double doubleField88_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field2 { - get { return int64Field2_; } + public double DoubleField88 { + get { return doubleField88_; } set { - int64Field2_ = value; + doubleField88_ = value; } } - /// Field number for the "double_field_96" field. - public const int DoubleField96FieldNumber = 96; - private double doubleField96_; + /// Field number for the "double_field_47" field. + public const int DoubleField47FieldNumber = 47; + private double doubleField47_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField96 { - get { return doubleField96_; } + public double DoubleField47 { + get { return doubleField47_; } set { - doubleField96_ = value; + doubleField47_ = value; } } - /// Field number for the "int64_field_3" field. - public const int Int64Field3FieldNumber = 3; - private long int64Field3_; + /// Field number for the "double_field_89" field. + public const int DoubleField89FieldNumber = 89; + private double doubleField89_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field3 { - get { return int64Field3_; } + public double DoubleField89 { + get { return doubleField89_; } set { - int64Field3_ = value; + doubleField89_ = value; } } - /// Field number for the "int64_field_4" field. - public const int Int64Field4FieldNumber = 4; - private long int64Field4_; + /// Field number for the "double_field_48" field. + public const int DoubleField48FieldNumber = 48; + private double doubleField48_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field4 { - get { return int64Field4_; } + public double DoubleField48 { + get { return doubleField48_; } set { - int64Field4_ = value; + doubleField48_ = value; } } - /// Field number for the "double_field_97" field. - public const int DoubleField97FieldNumber = 97; - private double doubleField97_; + /// Field number for the "double_field_49" field. + public const int DoubleField49FieldNumber = 49; + private double doubleField49_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField97 { - get { return doubleField97_; } + public double DoubleField49 { + get { return doubleField49_; } set { - doubleField97_ = value; + doubleField49_ = value; } } - /// Field number for the "double_field_65" field. - public const int DoubleField65FieldNumber = 65; - private double doubleField65_; + /// Field number for the "double_field_50" field. + public const int DoubleField50FieldNumber = 50; + private double doubleField50_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField65 { - get { return doubleField65_; } + public double DoubleField50 { + get { return doubleField50_; } set { - doubleField65_ = value; + doubleField50_ = value; } } - /// Field number for the "double_field_66" field. - public const int DoubleField66FieldNumber = 66; - private double doubleField66_; + /// Field number for the "double_field_90" field. + public const int DoubleField90FieldNumber = 90; + private double doubleField90_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField66 { - get { return doubleField66_; } + public double DoubleField90 { + get { return doubleField90_; } set { - doubleField66_ = value; + doubleField90_ = value; } } - /// Field number for the "double_field_7" field. - public const int DoubleField7FieldNumber = 7; - private double doubleField7_; + /// Field number for the "double_field_51" field. + public const int DoubleField51FieldNumber = 51; + private double doubleField51_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField7 { - get { return doubleField7_; } + public double DoubleField51 { + get { return doubleField51_; } + set { + doubleField51_ = value; + } + } + + /// Field number for the "double_field_91" field. + public const int DoubleField91FieldNumber = 91; + private double doubleField91_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField91 { + get { return doubleField91_; } + set { + doubleField91_ = value; + } + } + + /// Field number for the "double_field_92" field. + public const int DoubleField92FieldNumber = 92; + private double doubleField92_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField92 { + get { return doubleField92_; } + set { + doubleField92_ = value; + } + } + + /// Field number for the "int64_field_107" field. + public const int Int64Field107FieldNumber = 107; + private long int64Field107_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long Int64Field107 { + get { return int64Field107_; } + set { + int64Field107_ = value; + } + } + + /// Field number for the "double_field_93" field. + public const int DoubleField93FieldNumber = 93; + private double doubleField93_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField93 { + get { return doubleField93_; } + set { + doubleField93_ = value; + } + } + + /// Field number for the "double_field_108" field. + public const int DoubleField108FieldNumber = 108; + private double doubleField108_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField108 { + get { return doubleField108_; } + set { + doubleField108_ = value; + } + } + + /// Field number for the "double_field_52" field. + public const int DoubleField52FieldNumber = 52; + private double doubleField52_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField52 { + get { return doubleField52_; } + set { + doubleField52_ = value; + } + } + + /// Field number for the "double_field_53" field. + public const int DoubleField53FieldNumber = 53; + private double doubleField53_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField53 { + get { return doubleField53_; } + set { + doubleField53_ = value; + } + } + + /// Field number for the "double_field_94" field. + public const int DoubleField94FieldNumber = 94; + private double doubleField94_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField94 { + get { return doubleField94_; } + set { + doubleField94_ = value; + } + } + + /// Field number for the "double_field_54" field. + public const int DoubleField54FieldNumber = 54; + private double doubleField54_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField54 { + get { return doubleField54_; } + set { + doubleField54_ = value; + } + } + + /// Field number for the "double_field_55" field. + public const int DoubleField55FieldNumber = 55; + private double doubleField55_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double DoubleField55 { + get { return doubleField55_; } set { - doubleField7_ = value; + doubleField55_ = value; } } - /// Field number for the "double_field_62" field. - public const int DoubleField62FieldNumber = 62; - private double doubleField62_; + /// Field number for the "double_field_56" field. + public const int DoubleField56FieldNumber = 56; + private double doubleField56_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField62 { - get { return doubleField62_; } + public double DoubleField56 { + get { return doubleField56_; } set { - doubleField62_ = value; + doubleField56_ = value; } } - /// Field number for the "double_field_118" field. - public const int DoubleField118FieldNumber = 118; - private double doubleField118_; + /// Field number for the "double_field_57" field. + public const int DoubleField57FieldNumber = 57; + private double doubleField57_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField118 { - get { return doubleField118_; } + public double DoubleField57 { + get { return doubleField57_; } set { - doubleField118_ = value; + doubleField57_ = value; } } - /// Field number for the "double_field_119" field. - public const int DoubleField119FieldNumber = 119; - private double doubleField119_; + /// Field number for the "double_field_58" field. + public const int DoubleField58FieldNumber = 58; + private double doubleField58_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField119 { - get { return doubleField119_; } + public double DoubleField58 { + get { return doubleField58_; } set { - doubleField119_ = value; + doubleField58_ = value; } } - /// Field number for the "double_field_67" field. - public const int DoubleField67FieldNumber = 67; - private double doubleField67_; + /// Field number for the "int64_field_59" field. + public const int Int64Field59FieldNumber = 59; + private long int64Field59_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField67 { - get { return doubleField67_; } + public long Int64Field59 { + get { return int64Field59_; } set { - doubleField67_ = value; + int64Field59_ = value; } } - /// Field number for the "double_field_120" field. - public const int DoubleField120FieldNumber = 120; - private double doubleField120_; + /// Field number for the "int64_field_60" field. + public const int Int64Field60FieldNumber = 60; + private long int64Field60_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField120 { - get { return doubleField120_; } + public long Int64Field60 { + get { return int64Field60_; } set { - doubleField120_ = value; + int64Field60_ = value; } } - /// Field number for the "double_field_121" field. - public const int DoubleField121FieldNumber = 121; - private double doubleField121_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField121 { - get { return doubleField121_; } - set { - doubleField121_ = value; - } + public override bool Equals(object other) { + return Equals(other as ManyPrimitiveFieldsMessage); } - /// Field number for the "double_field_122" field. - public const int DoubleField122FieldNumber = 122; - private double doubleField122_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField122 { - get { return doubleField122_; } - set { - doubleField122_ = value; + public bool Equals(ManyPrimitiveFieldsMessage other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; } + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField95, other.DoubleField95)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField1, other.DoubleField1)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField79, other.DoubleField79)) return false; + if (Int64Field2 != other.Int64Field2) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField96, other.DoubleField96)) return false; + if (Int64Field3 != other.Int64Field3) return false; + if (Int64Field4 != other.Int64Field4) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField97, other.DoubleField97)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField65, other.DoubleField65)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField66, other.DoubleField66)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField7, other.DoubleField7)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField62, other.DoubleField62)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField118, other.DoubleField118)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField119, other.DoubleField119)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField67, other.DoubleField67)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField120, other.DoubleField120)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField121, other.DoubleField121)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField122, other.DoubleField122)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField123, other.DoubleField123)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField124, other.DoubleField124)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField8, other.DoubleField8)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField9, other.DoubleField9)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField98, other.DoubleField98)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField10, other.DoubleField10)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField11, other.DoubleField11)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField99, other.DoubleField99)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField84, other.DoubleField84)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField14, other.DoubleField14)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField77, other.DoubleField77)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField15, other.DoubleField15)) return false; + if (Int64Field19 != other.Int64Field19) return false; + if (Int64Field115 != other.Int64Field115) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField116, other.DoubleField116)) return false; + if (Int64Field117 != other.Int64Field117) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField20, other.DoubleField20)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField21, other.DoubleField21)) return false; + if (StringField73 != other.StringField73) return false; + if (StringField74 != other.StringField74) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField22, other.DoubleField22)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField69, other.DoubleField69)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField70, other.DoubleField70)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField71, other.DoubleField71)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField72, other.DoubleField72)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField25, other.DoubleField25)) return false; + if (Int64Field26 != other.Int64Field26) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField68, other.DoubleField68)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField28, other.DoubleField28)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField106, other.DoubleField106)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField29, other.DoubleField29)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField30, other.DoubleField30)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField101, other.DoubleField101)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField102, other.DoubleField102)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField103, other.DoubleField103)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField104, other.DoubleField104)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField105, other.DoubleField105)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField31, other.DoubleField31)) return false; + if (Int64Field32 != other.Int64Field32) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField75, other.DoubleField75)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField129, other.DoubleField129)) return false; + if (EnumField80 != other.EnumField80) return false; + if (EnumField81 != other.EnumField81) return false; + if (Int64Field82 != other.Int64Field82) return false; + if (EnumField83 != other.EnumField83) return false; + if (Int64Field85 != other.Int64Field85) return false; + if (Int64Field86 != other.Int64Field86) return false; + if (Int64Field87 != other.Int64Field87) return false; + if (Int64Field125 != other.Int64Field125) return false; + if (Int64Field37 != other.Int64Field37) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField38, other.DoubleField38)) return false; + if (Interactions != other.Interactions) return false; + if(!repeatedIntField100_.Equals(other.repeatedIntField100_)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField40, other.DoubleField40)) return false; + if (Int64Field41 != other.Int64Field41) return false; + if (Int64Field126 != other.Int64Field126) return false; + if (Int64Field127 != other.Int64Field127) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField128, other.DoubleField128)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField109, other.DoubleField109)) return false; + if (Int64Field110 != other.Int64Field110) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField111, other.DoubleField111)) return false; + if (Int64Field112 != other.Int64Field112) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField113, other.DoubleField113)) return false; + if (Int64Field114 != other.Int64Field114) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField42, other.DoubleField42)) return false; + if (Int64Field43 != other.Int64Field43) return false; + if (Int64Field44 != other.Int64Field44) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField45, other.DoubleField45)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField46, other.DoubleField46)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField78, other.DoubleField78)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField88, other.DoubleField88)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField47, other.DoubleField47)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField89, other.DoubleField89)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField48, other.DoubleField48)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField49, other.DoubleField49)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField50, other.DoubleField50)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField90, other.DoubleField90)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField51, other.DoubleField51)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField91, other.DoubleField91)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField92, other.DoubleField92)) return false; + if (Int64Field107 != other.Int64Field107) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField93, other.DoubleField93)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField108, other.DoubleField108)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField52, other.DoubleField52)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField53, other.DoubleField53)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField94, other.DoubleField94)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField54, other.DoubleField54)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField55, other.DoubleField55)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField56, other.DoubleField56)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField57, other.DoubleField57)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField58, other.DoubleField58)) return false; + if (Int64Field59 != other.Int64Field59) return false; + if (Int64Field60 != other.Int64Field60) return false; + return Equals(_unknownFields, other._unknownFields); } - /// Field number for the "double_field_123" field. - public const int DoubleField123FieldNumber = 123; - private double doubleField123_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField123 { - get { return doubleField123_; } - set { - doubleField123_ = value; + public override int GetHashCode() { + int hash = 1; + if (DoubleField95 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField95); + if (DoubleField1 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField1); + if (DoubleField79 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField79); + if (Int64Field2 != 0L) hash ^= Int64Field2.GetHashCode(); + if (DoubleField96 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField96); + if (Int64Field3 != 0L) hash ^= Int64Field3.GetHashCode(); + if (Int64Field4 != 0L) hash ^= Int64Field4.GetHashCode(); + if (DoubleField97 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField97); + if (DoubleField65 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField65); + if (DoubleField66 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField66); + if (DoubleField7 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField7); + if (DoubleField62 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField62); + if (DoubleField118 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField118); + if (DoubleField119 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField119); + if (DoubleField67 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField67); + if (DoubleField120 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField120); + if (DoubleField121 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField121); + if (DoubleField122 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField122); + if (DoubleField123 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField123); + if (DoubleField124 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField124); + if (DoubleField8 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField8); + if (DoubleField9 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField9); + if (DoubleField98 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField98); + if (DoubleField10 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField10); + if (DoubleField11 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField11); + if (DoubleField99 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField99); + if (DoubleField84 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField84); + if (DoubleField14 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField14); + if (DoubleField77 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField77); + if (DoubleField15 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField15); + if (Int64Field19 != 0L) hash ^= Int64Field19.GetHashCode(); + if (Int64Field115 != 0L) hash ^= Int64Field115.GetHashCode(); + if (DoubleField116 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField116); + if (Int64Field117 != 0L) hash ^= Int64Field117.GetHashCode(); + if (DoubleField20 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField20); + if (DoubleField21 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField21); + if (StringField73.Length != 0) hash ^= StringField73.GetHashCode(); + if (StringField74.Length != 0) hash ^= StringField74.GetHashCode(); + if (DoubleField22 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField22); + if (DoubleField69 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField69); + if (DoubleField70 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField70); + if (DoubleField71 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField71); + if (DoubleField72 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField72); + if (DoubleField25 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField25); + if (Int64Field26 != 0L) hash ^= Int64Field26.GetHashCode(); + if (DoubleField68 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField68); + if (DoubleField28 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField28); + if (DoubleField106 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField106); + if (DoubleField29 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField29); + if (DoubleField30 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField30); + if (DoubleField101 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField101); + if (DoubleField102 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField102); + if (DoubleField103 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField103); + if (DoubleField104 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField104); + if (DoubleField105 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField105); + if (DoubleField31 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField31); + if (Int64Field32 != 0L) hash ^= Int64Field32.GetHashCode(); + if (DoubleField75 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField75); + if (DoubleField129 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField129); + if (EnumField80 != 0) hash ^= EnumField80.GetHashCode(); + if (EnumField81 != 0) hash ^= EnumField81.GetHashCode(); + if (Int64Field82 != 0L) hash ^= Int64Field82.GetHashCode(); + if (EnumField83 != 0) hash ^= EnumField83.GetHashCode(); + if (Int64Field85 != 0L) hash ^= Int64Field85.GetHashCode(); + if (Int64Field86 != 0L) hash ^= Int64Field86.GetHashCode(); + if (Int64Field87 != 0L) hash ^= Int64Field87.GetHashCode(); + if (Int64Field125 != 0L) hash ^= Int64Field125.GetHashCode(); + if (Int64Field37 != 0L) hash ^= Int64Field37.GetHashCode(); + if (DoubleField38 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField38); + if (Interactions != 0L) hash ^= Interactions.GetHashCode(); + hash ^= repeatedIntField100_.GetHashCode(); + if (DoubleField40 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField40); + if (Int64Field41 != 0L) hash ^= Int64Field41.GetHashCode(); + if (Int64Field126 != 0L) hash ^= Int64Field126.GetHashCode(); + if (Int64Field127 != 0L) hash ^= Int64Field127.GetHashCode(); + if (DoubleField128 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField128); + if (DoubleField109 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField109); + if (Int64Field110 != 0L) hash ^= Int64Field110.GetHashCode(); + if (DoubleField111 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField111); + if (Int64Field112 != 0L) hash ^= Int64Field112.GetHashCode(); + if (DoubleField113 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField113); + if (Int64Field114 != 0L) hash ^= Int64Field114.GetHashCode(); + if (DoubleField42 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField42); + if (Int64Field43 != 0L) hash ^= Int64Field43.GetHashCode(); + if (Int64Field44 != 0L) hash ^= Int64Field44.GetHashCode(); + if (DoubleField45 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField45); + if (DoubleField46 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField46); + if (DoubleField78 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField78); + if (DoubleField88 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField88); + if (DoubleField47 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField47); + if (DoubleField89 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField89); + if (DoubleField48 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField48); + if (DoubleField49 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField49); + if (DoubleField50 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField50); + if (DoubleField90 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField90); + if (DoubleField51 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField51); + if (DoubleField91 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField91); + if (DoubleField92 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField92); + if (Int64Field107 != 0L) hash ^= Int64Field107.GetHashCode(); + if (DoubleField93 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField93); + if (DoubleField108 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField108); + if (DoubleField52 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField52); + if (DoubleField53 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField53); + if (DoubleField94 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField94); + if (DoubleField54 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField54); + if (DoubleField55 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField55); + if (DoubleField56 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField56); + if (DoubleField57 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField57); + if (DoubleField58 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField58); + if (Int64Field59 != 0L) hash ^= Int64Field59.GetHashCode(); + if (Int64Field60 != 0L) hash ^= Int64Field60.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); } + return hash; } - /// Field number for the "double_field_124" field. - public const int DoubleField124FieldNumber = 124; - private double doubleField124_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField124 { - get { return doubleField124_; } - set { - doubleField124_ = value; - } + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); } - /// Field number for the "double_field_8" field. - public const int DoubleField8FieldNumber = 8; - private double doubleField8_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField8 { - get { return doubleField8_; } - set { - doubleField8_ = value; + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (DoubleField1 != 0D) { + output.WriteRawTag(9); + output.WriteDouble(DoubleField1); } - } - - /// Field number for the "double_field_9" field. - public const int DoubleField9FieldNumber = 9; - private double doubleField9_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField9 { - get { return doubleField9_; } - set { - doubleField9_ = value; + if (Int64Field2 != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Int64Field2); } - } - - /// Field number for the "double_field_98" field. - public const int DoubleField98FieldNumber = 98; - private double doubleField98_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField98 { - get { return doubleField98_; } - set { - doubleField98_ = value; + if (Int64Field3 != 0L) { + output.WriteRawTag(24); + output.WriteInt64(Int64Field3); } - } - - /// Field number for the "double_field_10" field. - public const int DoubleField10FieldNumber = 10; - private double doubleField10_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField10 { - get { return doubleField10_; } - set { - doubleField10_ = value; + if (Int64Field4 != 0L) { + output.WriteRawTag(32); + output.WriteInt64(Int64Field4); } - } - - /// Field number for the "double_field_11" field. - public const int DoubleField11FieldNumber = 11; - private double doubleField11_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField11 { - get { return doubleField11_; } - set { - doubleField11_ = value; + if (DoubleField7 != 0D) { + output.WriteRawTag(57); + output.WriteDouble(DoubleField7); } - } - - /// Field number for the "double_field_99" field. - public const int DoubleField99FieldNumber = 99; - private double doubleField99_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField99 { - get { return doubleField99_; } - set { - doubleField99_ = value; + if (DoubleField8 != 0D) { + output.WriteRawTag(65); + output.WriteDouble(DoubleField8); } - } - - /// Field number for the "double_field_84" field. - public const int DoubleField84FieldNumber = 84; - private double doubleField84_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField84 { - get { return doubleField84_; } - set { - doubleField84_ = value; + if (DoubleField9 != 0D) { + output.WriteRawTag(73); + output.WriteDouble(DoubleField9); } - } - - /// Field number for the "double_field_14" field. - public const int DoubleField14FieldNumber = 14; - private double doubleField14_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField14 { - get { return doubleField14_; } - set { - doubleField14_ = value; + if (DoubleField10 != 0D) { + output.WriteRawTag(81); + output.WriteDouble(DoubleField10); } - } - - /// Field number for the "double_field_77" field. - public const int DoubleField77FieldNumber = 77; - private double doubleField77_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField77 { - get { return doubleField77_; } - set { - doubleField77_ = value; + if (DoubleField11 != 0D) { + output.WriteRawTag(89); + output.WriteDouble(DoubleField11); } - } - - /// Field number for the "double_field_15" field. - public const int DoubleField15FieldNumber = 15; - private double doubleField15_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField15 { - get { return doubleField15_; } - set { - doubleField15_ = value; + if (DoubleField14 != 0D) { + output.WriteRawTag(113); + output.WriteDouble(DoubleField14); } - } - - /// Field number for the "int64_field_19" field. - public const int Int64Field19FieldNumber = 19; - private long int64Field19_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field19 { - get { return int64Field19_; } - set { - int64Field19_ = value; + if (DoubleField15 != 0D) { + output.WriteRawTag(121); + output.WriteDouble(DoubleField15); } - } - - /// Field number for the "int64_field_115" field. - public const int Int64Field115FieldNumber = 115; - private long int64Field115_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field115 { - get { return int64Field115_; } - set { - int64Field115_ = value; + if (Int64Field19 != 0L) { + output.WriteRawTag(152, 1); + output.WriteInt64(Int64Field19); } - } - - /// Field number for the "double_field_116" field. - public const int DoubleField116FieldNumber = 116; - private double doubleField116_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField116 { - get { return doubleField116_; } - set { - doubleField116_ = value; + if (DoubleField20 != 0D) { + output.WriteRawTag(161, 1); + output.WriteDouble(DoubleField20); } - } - - /// Field number for the "int64_field_117" field. - public const int Int64Field117FieldNumber = 117; - private long int64Field117_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field117 { - get { return int64Field117_; } - set { - int64Field117_ = value; + if (DoubleField21 != 0D) { + output.WriteRawTag(169, 1); + output.WriteDouble(DoubleField21); } - } - - /// Field number for the "double_field_20" field. - public const int DoubleField20FieldNumber = 20; - private double doubleField20_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField20 { - get { return doubleField20_; } - set { - doubleField20_ = value; + if (DoubleField22 != 0D) { + output.WriteRawTag(177, 1); + output.WriteDouble(DoubleField22); } - } - - /// Field number for the "double_field_21" field. - public const int DoubleField21FieldNumber = 21; - private double doubleField21_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField21 { - get { return doubleField21_; } - set { - doubleField21_ = value; + if (DoubleField25 != 0D) { + output.WriteRawTag(201, 1); + output.WriteDouble(DoubleField25); } - } - - /// Field number for the "string_field_73" field. - public const int StringField73FieldNumber = 73; - private string stringField73_ = ""; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string StringField73 { - get { return stringField73_; } - set { - stringField73_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + if (Int64Field26 != 0L) { + output.WriteRawTag(208, 1); + output.WriteInt64(Int64Field26); } - } - - /// Field number for the "string_field_74" field. - public const int StringField74FieldNumber = 74; - private string stringField74_ = ""; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public string StringField74 { - get { return stringField74_; } - set { - stringField74_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + if (DoubleField28 != 0D) { + output.WriteRawTag(225, 1); + output.WriteDouble(DoubleField28); } - } - - /// Field number for the "double_field_22" field. - public const int DoubleField22FieldNumber = 22; - private double doubleField22_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField22 { - get { return doubleField22_; } - set { - doubleField22_ = value; + if (DoubleField29 != 0D) { + output.WriteRawTag(233, 1); + output.WriteDouble(DoubleField29); } - } - - /// Field number for the "double_field_69" field. - public const int DoubleField69FieldNumber = 69; - private double doubleField69_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField69 { - get { return doubleField69_; } - set { - doubleField69_ = value; + if (DoubleField30 != 0D) { + output.WriteRawTag(241, 1); + output.WriteDouble(DoubleField30); } - } - - /// Field number for the "double_field_70" field. - public const int DoubleField70FieldNumber = 70; - private double doubleField70_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField70 { - get { return doubleField70_; } - set { - doubleField70_ = value; + if (DoubleField31 != 0D) { + output.WriteRawTag(249, 1); + output.WriteDouble(DoubleField31); } - } - - /// Field number for the "double_field_71" field. - public const int DoubleField71FieldNumber = 71; - private double doubleField71_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField71 { - get { return doubleField71_; } - set { - doubleField71_ = value; + if (Int64Field32 != 0L) { + output.WriteRawTag(128, 2); + output.WriteInt64(Int64Field32); } - } - - /// Field number for the "double_field_72" field. - public const int DoubleField72FieldNumber = 72; - private double doubleField72_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField72 { - get { return doubleField72_; } - set { - doubleField72_ = value; + if (Int64Field37 != 0L) { + output.WriteRawTag(168, 2); + output.WriteInt64(Int64Field37); } - } - - /// Field number for the "double_field_25" field. - public const int DoubleField25FieldNumber = 25; - private double doubleField25_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField25 { - get { return doubleField25_; } - set { - doubleField25_ = value; + if (DoubleField38 != 0D) { + output.WriteRawTag(177, 2); + output.WriteDouble(DoubleField38); } - } - - /// Field number for the "int64_field_26" field. - public const int Int64Field26FieldNumber = 26; - private long int64Field26_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field26 { - get { return int64Field26_; } - set { - int64Field26_ = value; + if (Interactions != 0L) { + output.WriteRawTag(184, 2); + output.WriteInt64(Interactions); } - } - - /// Field number for the "double_field_68" field. - public const int DoubleField68FieldNumber = 68; - private double doubleField68_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField68 { - get { return doubleField68_; } - set { - doubleField68_ = value; + if (DoubleField40 != 0D) { + output.WriteRawTag(193, 2); + output.WriteDouble(DoubleField40); } - } - - /// Field number for the "double_field_28" field. - public const int DoubleField28FieldNumber = 28; - private double doubleField28_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField28 { - get { return doubleField28_; } - set { - doubleField28_ = value; + if (Int64Field41 != 0L) { + output.WriteRawTag(200, 2); + output.WriteInt64(Int64Field41); } - } - - /// Field number for the "double_field_106" field. - public const int DoubleField106FieldNumber = 106; - private double doubleField106_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField106 { - get { return doubleField106_; } - set { - doubleField106_ = value; + if (DoubleField42 != 0D) { + output.WriteRawTag(209, 2); + output.WriteDouble(DoubleField42); } - } - - /// Field number for the "double_field_29" field. - public const int DoubleField29FieldNumber = 29; - private double doubleField29_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField29 { - get { return doubleField29_; } - set { - doubleField29_ = value; + if (Int64Field43 != 0L) { + output.WriteRawTag(216, 2); + output.WriteInt64(Int64Field43); } - } - - /// Field number for the "double_field_30" field. - public const int DoubleField30FieldNumber = 30; - private double doubleField30_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField30 { - get { return doubleField30_; } - set { - doubleField30_ = value; + if (Int64Field44 != 0L) { + output.WriteRawTag(224, 2); + output.WriteInt64(Int64Field44); } - } - - /// Field number for the "double_field_101" field. - public const int DoubleField101FieldNumber = 101; - private double doubleField101_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField101 { - get { return doubleField101_; } - set { - doubleField101_ = value; + if (DoubleField45 != 0D) { + output.WriteRawTag(233, 2); + output.WriteDouble(DoubleField45); } - } - - /// Field number for the "double_field_102" field. - public const int DoubleField102FieldNumber = 102; - private double doubleField102_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField102 { - get { return doubleField102_; } - set { - doubleField102_ = value; + if (DoubleField46 != 0D) { + output.WriteRawTag(241, 2); + output.WriteDouble(DoubleField46); } - } - - /// Field number for the "double_field_103" field. - public const int DoubleField103FieldNumber = 103; - private double doubleField103_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField103 { - get { return doubleField103_; } - set { - doubleField103_ = value; + if (DoubleField47 != 0D) { + output.WriteRawTag(249, 2); + output.WriteDouble(DoubleField47); + } + if (DoubleField48 != 0D) { + output.WriteRawTag(129, 3); + output.WriteDouble(DoubleField48); + } + if (DoubleField49 != 0D) { + output.WriteRawTag(137, 3); + output.WriteDouble(DoubleField49); } - } - - /// Field number for the "double_field_104" field. - public const int DoubleField104FieldNumber = 104; - private double doubleField104_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField104 { - get { return doubleField104_; } - set { - doubleField104_ = value; + if (DoubleField50 != 0D) { + output.WriteRawTag(145, 3); + output.WriteDouble(DoubleField50); } - } - - /// Field number for the "double_field_105" field. - public const int DoubleField105FieldNumber = 105; - private double doubleField105_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField105 { - get { return doubleField105_; } - set { - doubleField105_ = value; + if (DoubleField51 != 0D) { + output.WriteRawTag(153, 3); + output.WriteDouble(DoubleField51); } - } - - /// Field number for the "double_field_31" field. - public const int DoubleField31FieldNumber = 31; - private double doubleField31_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField31 { - get { return doubleField31_; } - set { - doubleField31_ = value; + if (DoubleField52 != 0D) { + output.WriteRawTag(161, 3); + output.WriteDouble(DoubleField52); } - } - - /// Field number for the "int64_field_32" field. - public const int Int64Field32FieldNumber = 32; - private long int64Field32_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field32 { - get { return int64Field32_; } - set { - int64Field32_ = value; + if (DoubleField53 != 0D) { + output.WriteRawTag(169, 3); + output.WriteDouble(DoubleField53); } - } - - /// Field number for the "double_field_75" field. - public const int DoubleField75FieldNumber = 75; - private double doubleField75_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField75 { - get { return doubleField75_; } - set { - doubleField75_ = value; + if (DoubleField54 != 0D) { + output.WriteRawTag(177, 3); + output.WriteDouble(DoubleField54); } - } - - /// Field number for the "double_field_129" field. - public const int DoubleField129FieldNumber = 129; - private double doubleField129_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField129 { - get { return doubleField129_; } - set { - doubleField129_ = value; + if (DoubleField55 != 0D) { + output.WriteRawTag(185, 3); + output.WriteDouble(DoubleField55); } - } - - /// Field number for the "enum_field_80" field. - public const int EnumField80FieldNumber = 80; - private int enumField80_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int EnumField80 { - get { return enumField80_; } - set { - enumField80_ = value; + if (DoubleField56 != 0D) { + output.WriteRawTag(193, 3); + output.WriteDouble(DoubleField56); } - } - - /// Field number for the "enum_field_81" field. - public const int EnumField81FieldNumber = 81; - private int enumField81_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int EnumField81 { - get { return enumField81_; } - set { - enumField81_ = value; + if (DoubleField57 != 0D) { + output.WriteRawTag(201, 3); + output.WriteDouble(DoubleField57); } - } - - /// Field number for the "int64_field_82" field. - public const int Int64Field82FieldNumber = 82; - private long int64Field82_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field82 { - get { return int64Field82_; } - set { - int64Field82_ = value; + if (DoubleField58 != 0D) { + output.WriteRawTag(209, 3); + output.WriteDouble(DoubleField58); } - } - - /// Field number for the "enum_field_83" field. - public const int EnumField83FieldNumber = 83; - private int enumField83_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int EnumField83 { - get { return enumField83_; } - set { - enumField83_ = value; + if (Int64Field59 != 0L) { + output.WriteRawTag(216, 3); + output.WriteInt64(Int64Field59); } - } - - /// Field number for the "int64_field_85" field. - public const int Int64Field85FieldNumber = 85; - private long int64Field85_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field85 { - get { return int64Field85_; } - set { - int64Field85_ = value; + if (Int64Field60 != 0L) { + output.WriteRawTag(224, 3); + output.WriteInt64(Int64Field60); } - } - - /// Field number for the "int64_field_86" field. - public const int Int64Field86FieldNumber = 86; - private long int64Field86_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field86 { - get { return int64Field86_; } - set { - int64Field86_ = value; + if (DoubleField62 != 0D) { + output.WriteRawTag(241, 3); + output.WriteDouble(DoubleField62); } - } - - /// Field number for the "int64_field_87" field. - public const int Int64Field87FieldNumber = 87; - private long int64Field87_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field87 { - get { return int64Field87_; } - set { - int64Field87_ = value; + if (DoubleField65 != 0D) { + output.WriteRawTag(137, 4); + output.WriteDouble(DoubleField65); } - } - - /// Field number for the "int64_field_125" field. - public const int Int64Field125FieldNumber = 125; - private long int64Field125_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field125 { - get { return int64Field125_; } - set { - int64Field125_ = value; + if (DoubleField66 != 0D) { + output.WriteRawTag(145, 4); + output.WriteDouble(DoubleField66); } - } - - /// Field number for the "int64_field_37" field. - public const int Int64Field37FieldNumber = 37; - private long int64Field37_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field37 { - get { return int64Field37_; } - set { - int64Field37_ = value; + if (DoubleField67 != 0D) { + output.WriteRawTag(153, 4); + output.WriteDouble(DoubleField67); } - } - - /// Field number for the "double_field_38" field. - public const int DoubleField38FieldNumber = 38; - private double doubleField38_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField38 { - get { return doubleField38_; } - set { - doubleField38_ = value; + if (DoubleField68 != 0D) { + output.WriteRawTag(161, 4); + output.WriteDouble(DoubleField68); } - } - - /// Field number for the "interactions" field. - public const int InteractionsFieldNumber = 39; - private long interactions_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Interactions { - get { return interactions_; } - set { - interactions_ = value; + if (DoubleField69 != 0D) { + output.WriteRawTag(169, 4); + output.WriteDouble(DoubleField69); } - } - - /// Field number for the "repeated_int_field_100" field. - public const int RepeatedIntField100FieldNumber = 100; - private static readonly pb::FieldCodec _repeated_repeatedIntField100_codec - = pb::FieldCodec.ForInt32(802); - private readonly pbc::RepeatedField repeatedIntField100_ = new pbc::RepeatedField(); - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public pbc::RepeatedField RepeatedIntField100 { - get { return repeatedIntField100_; } - } - - /// Field number for the "double_field_40" field. - public const int DoubleField40FieldNumber = 40; - private double doubleField40_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField40 { - get { return doubleField40_; } - set { - doubleField40_ = value; + if (DoubleField70 != 0D) { + output.WriteRawTag(177, 4); + output.WriteDouble(DoubleField70); } - } - - /// Field number for the "int64_field_41" field. - public const int Int64Field41FieldNumber = 41; - private long int64Field41_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field41 { - get { return int64Field41_; } - set { - int64Field41_ = value; + if (DoubleField71 != 0D) { + output.WriteRawTag(185, 4); + output.WriteDouble(DoubleField71); } - } - - /// Field number for the "int64_field_126" field. - public const int Int64Field126FieldNumber = 126; - private long int64Field126_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field126 { - get { return int64Field126_; } - set { - int64Field126_ = value; + if (DoubleField72 != 0D) { + output.WriteRawTag(193, 4); + output.WriteDouble(DoubleField72); } - } - - /// Field number for the "int64_field_127" field. - public const int Int64Field127FieldNumber = 127; - private long int64Field127_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field127 { - get { return int64Field127_; } - set { - int64Field127_ = value; + if (StringField73.Length != 0) { + output.WriteRawTag(202, 4); + output.WriteString(StringField73); } - } - - /// Field number for the "double_field_128" field. - public const int DoubleField128FieldNumber = 128; - private double doubleField128_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField128 { - get { return doubleField128_; } - set { - doubleField128_ = value; + if (StringField74.Length != 0) { + output.WriteRawTag(210, 4); + output.WriteString(StringField74); } - } - - /// Field number for the "double_field_109" field. - public const int DoubleField109FieldNumber = 109; - private double doubleField109_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField109 { - get { return doubleField109_; } - set { - doubleField109_ = value; + if (DoubleField75 != 0D) { + output.WriteRawTag(217, 4); + output.WriteDouble(DoubleField75); } - } - - /// Field number for the "int64_field_110" field. - public const int Int64Field110FieldNumber = 110; - private long int64Field110_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field110 { - get { return int64Field110_; } - set { - int64Field110_ = value; + if (DoubleField77 != 0D) { + output.WriteRawTag(233, 4); + output.WriteDouble(DoubleField77); } - } - - /// Field number for the "double_field_111" field. - public const int DoubleField111FieldNumber = 111; - private double doubleField111_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField111 { - get { return doubleField111_; } - set { - doubleField111_ = value; + if (DoubleField78 != 0D) { + output.WriteRawTag(241, 4); + output.WriteDouble(DoubleField78); } - } - - /// Field number for the "int64_field_112" field. - public const int Int64Field112FieldNumber = 112; - private long int64Field112_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field112 { - get { return int64Field112_; } - set { - int64Field112_ = value; + if (DoubleField79 != 0D) { + output.WriteRawTag(249, 4); + output.WriteDouble(DoubleField79); } - } - - /// Field number for the "double_field_113" field. - public const int DoubleField113FieldNumber = 113; - private double doubleField113_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField113 { - get { return doubleField113_; } - set { - doubleField113_ = value; + if (EnumField80 != 0) { + output.WriteRawTag(128, 5); + output.WriteInt32(EnumField80); } - } - - /// Field number for the "int64_field_114" field. - public const int Int64Field114FieldNumber = 114; - private long int64Field114_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field114 { - get { return int64Field114_; } - set { - int64Field114_ = value; + if (EnumField81 != 0) { + output.WriteRawTag(136, 5); + output.WriteInt32(EnumField81); } - } - - /// Field number for the "double_field_42" field. - public const int DoubleField42FieldNumber = 42; - private double doubleField42_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField42 { - get { return doubleField42_; } - set { - doubleField42_ = value; + if (Int64Field82 != 0L) { + output.WriteRawTag(144, 5); + output.WriteInt64(Int64Field82); } - } - - /// Field number for the "int64_field_43" field. - public const int Int64Field43FieldNumber = 43; - private long int64Field43_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field43 { - get { return int64Field43_; } - set { - int64Field43_ = value; + if (EnumField83 != 0) { + output.WriteRawTag(152, 5); + output.WriteInt32(EnumField83); } - } - - /// Field number for the "int64_field_44" field. - public const int Int64Field44FieldNumber = 44; - private long int64Field44_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field44 { - get { return int64Field44_; } - set { - int64Field44_ = value; + if (DoubleField84 != 0D) { + output.WriteRawTag(161, 5); + output.WriteDouble(DoubleField84); } - } - - /// Field number for the "double_field_45" field. - public const int DoubleField45FieldNumber = 45; - private double doubleField45_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField45 { - get { return doubleField45_; } - set { - doubleField45_ = value; + if (Int64Field85 != 0L) { + output.WriteRawTag(168, 5); + output.WriteInt64(Int64Field85); } - } - - /// Field number for the "double_field_46" field. - public const int DoubleField46FieldNumber = 46; - private double doubleField46_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField46 { - get { return doubleField46_; } - set { - doubleField46_ = value; + if (Int64Field86 != 0L) { + output.WriteRawTag(176, 5); + output.WriteInt64(Int64Field86); } - } - - /// Field number for the "double_field_78" field. - public const int DoubleField78FieldNumber = 78; - private double doubleField78_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField78 { - get { return doubleField78_; } - set { - doubleField78_ = value; + if (Int64Field87 != 0L) { + output.WriteRawTag(184, 5); + output.WriteInt64(Int64Field87); } - } - - /// Field number for the "double_field_88" field. - public const int DoubleField88FieldNumber = 88; - private double doubleField88_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField88 { - get { return doubleField88_; } - set { - doubleField88_ = value; + if (DoubleField88 != 0D) { + output.WriteRawTag(193, 5); + output.WriteDouble(DoubleField88); } - } - - /// Field number for the "double_field_47" field. - public const int DoubleField47FieldNumber = 47; - private double doubleField47_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField47 { - get { return doubleField47_; } - set { - doubleField47_ = value; + if (DoubleField89 != 0D) { + output.WriteRawTag(201, 5); + output.WriteDouble(DoubleField89); } - } - - /// Field number for the "double_field_89" field. - public const int DoubleField89FieldNumber = 89; - private double doubleField89_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField89 { - get { return doubleField89_; } - set { - doubleField89_ = value; + if (DoubleField90 != 0D) { + output.WriteRawTag(209, 5); + output.WriteDouble(DoubleField90); } - } - - /// Field number for the "double_field_48" field. - public const int DoubleField48FieldNumber = 48; - private double doubleField48_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField48 { - get { return doubleField48_; } - set { - doubleField48_ = value; + if (DoubleField91 != 0D) { + output.WriteRawTag(217, 5); + output.WriteDouble(DoubleField91); + } + if (DoubleField92 != 0D) { + output.WriteRawTag(225, 5); + output.WriteDouble(DoubleField92); + } + if (DoubleField93 != 0D) { + output.WriteRawTag(233, 5); + output.WriteDouble(DoubleField93); } - } - - /// Field number for the "double_field_49" field. - public const int DoubleField49FieldNumber = 49; - private double doubleField49_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField49 { - get { return doubleField49_; } - set { - doubleField49_ = value; + if (DoubleField94 != 0D) { + output.WriteRawTag(241, 5); + output.WriteDouble(DoubleField94); } - } - - /// Field number for the "double_field_50" field. - public const int DoubleField50FieldNumber = 50; - private double doubleField50_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField50 { - get { return doubleField50_; } - set { - doubleField50_ = value; + if (DoubleField95 != 0D) { + output.WriteRawTag(249, 5); + output.WriteDouble(DoubleField95); } - } - - /// Field number for the "double_field_90" field. - public const int DoubleField90FieldNumber = 90; - private double doubleField90_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField90 { - get { return doubleField90_; } - set { - doubleField90_ = value; + if (DoubleField96 != 0D) { + output.WriteRawTag(129, 6); + output.WriteDouble(DoubleField96); } - } - - /// Field number for the "double_field_51" field. - public const int DoubleField51FieldNumber = 51; - private double doubleField51_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField51 { - get { return doubleField51_; } - set { - doubleField51_ = value; + if (DoubleField97 != 0D) { + output.WriteRawTag(137, 6); + output.WriteDouble(DoubleField97); } - } - - /// Field number for the "double_field_91" field. - public const int DoubleField91FieldNumber = 91; - private double doubleField91_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField91 { - get { return doubleField91_; } - set { - doubleField91_ = value; + if (DoubleField98 != 0D) { + output.WriteRawTag(145, 6); + output.WriteDouble(DoubleField98); } - } - - /// Field number for the "double_field_92" field. - public const int DoubleField92FieldNumber = 92; - private double doubleField92_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField92 { - get { return doubleField92_; } - set { - doubleField92_ = value; + if (DoubleField99 != 0D) { + output.WriteRawTag(153, 6); + output.WriteDouble(DoubleField99); } - } - - /// Field number for the "int64_field_107" field. - public const int Int64Field107FieldNumber = 107; - private long int64Field107_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field107 { - get { return int64Field107_; } - set { - int64Field107_ = value; + repeatedIntField100_.WriteTo(output, _repeated_repeatedIntField100_codec); + if (DoubleField101 != 0D) { + output.WriteRawTag(169, 6); + output.WriteDouble(DoubleField101); } - } - - /// Field number for the "double_field_93" field. - public const int DoubleField93FieldNumber = 93; - private double doubleField93_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField93 { - get { return doubleField93_; } - set { - doubleField93_ = value; + if (DoubleField102 != 0D) { + output.WriteRawTag(177, 6); + output.WriteDouble(DoubleField102); } - } - - /// Field number for the "double_field_108" field. - public const int DoubleField108FieldNumber = 108; - private double doubleField108_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField108 { - get { return doubleField108_; } - set { - doubleField108_ = value; + if (DoubleField103 != 0D) { + output.WriteRawTag(185, 6); + output.WriteDouble(DoubleField103); } - } - - /// Field number for the "double_field_52" field. - public const int DoubleField52FieldNumber = 52; - private double doubleField52_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField52 { - get { return doubleField52_; } - set { - doubleField52_ = value; + if (DoubleField104 != 0D) { + output.WriteRawTag(193, 6); + output.WriteDouble(DoubleField104); } - } - - /// Field number for the "double_field_53" field. - public const int DoubleField53FieldNumber = 53; - private double doubleField53_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField53 { - get { return doubleField53_; } - set { - doubleField53_ = value; + if (DoubleField105 != 0D) { + output.WriteRawTag(201, 6); + output.WriteDouble(DoubleField105); } - } - - /// Field number for the "double_field_94" field. - public const int DoubleField94FieldNumber = 94; - private double doubleField94_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField94 { - get { return doubleField94_; } - set { - doubleField94_ = value; + if (DoubleField106 != 0D) { + output.WriteRawTag(209, 6); + output.WriteDouble(DoubleField106); } - } - - /// Field number for the "double_field_54" field. - public const int DoubleField54FieldNumber = 54; - private double doubleField54_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField54 { - get { return doubleField54_; } - set { - doubleField54_ = value; + if (Int64Field107 != 0L) { + output.WriteRawTag(216, 6); + output.WriteInt64(Int64Field107); } - } - - /// Field number for the "double_field_55" field. - public const int DoubleField55FieldNumber = 55; - private double doubleField55_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField55 { - get { return doubleField55_; } - set { - doubleField55_ = value; + if (DoubleField108 != 0D) { + output.WriteRawTag(225, 6); + output.WriteDouble(DoubleField108); } - } - - /// Field number for the "double_field_56" field. - public const int DoubleField56FieldNumber = 56; - private double doubleField56_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField56 { - get { return doubleField56_; } - set { - doubleField56_ = value; + if (DoubleField109 != 0D) { + output.WriteRawTag(233, 6); + output.WriteDouble(DoubleField109); } - } - - /// Field number for the "double_field_57" field. - public const int DoubleField57FieldNumber = 57; - private double doubleField57_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField57 { - get { return doubleField57_; } - set { - doubleField57_ = value; + if (Int64Field110 != 0L) { + output.WriteRawTag(240, 6); + output.WriteInt64(Int64Field110); } - } - - /// Field number for the "double_field_58" field. - public const int DoubleField58FieldNumber = 58; - private double doubleField58_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public double DoubleField58 { - get { return doubleField58_; } - set { - doubleField58_ = value; + if (DoubleField111 != 0D) { + output.WriteRawTag(249, 6); + output.WriteDouble(DoubleField111); } - } - - /// Field number for the "int64_field_59" field. - public const int Int64Field59FieldNumber = 59; - private long int64Field59_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field59 { - get { return int64Field59_; } - set { - int64Field59_ = value; + if (Int64Field112 != 0L) { + output.WriteRawTag(128, 7); + output.WriteInt64(Int64Field112); } - } - - /// Field number for the "int64_field_60" field. - public const int Int64Field60FieldNumber = 60; - private long int64Field60_; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public long Int64Field60 { - get { return int64Field60_; } - set { - int64Field60_ = value; + if (DoubleField113 != 0D) { + output.WriteRawTag(137, 7); + output.WriteDouble(DoubleField113); + } + if (Int64Field114 != 0L) { + output.WriteRawTag(144, 7); + output.WriteInt64(Int64Field114); + } + if (Int64Field115 != 0L) { + output.WriteRawTag(152, 7); + output.WriteInt64(Int64Field115); } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override bool Equals(object other) { - return Equals(other as ManyPrimitiveFieldsMessage); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool Equals(ManyPrimitiveFieldsMessage other) { - if (ReferenceEquals(other, null)) { - return false; + if (DoubleField116 != 0D) { + output.WriteRawTag(161, 7); + output.WriteDouble(DoubleField116); } - if (ReferenceEquals(other, this)) { - return true; + if (Int64Field117 != 0L) { + output.WriteRawTag(168, 7); + output.WriteInt64(Int64Field117); + } + if (DoubleField118 != 0D) { + output.WriteRawTag(177, 7); + output.WriteDouble(DoubleField118); + } + if (DoubleField119 != 0D) { + output.WriteRawTag(185, 7); + output.WriteDouble(DoubleField119); + } + if (DoubleField120 != 0D) { + output.WriteRawTag(193, 7); + output.WriteDouble(DoubleField120); + } + if (DoubleField121 != 0D) { + output.WriteRawTag(201, 7); + output.WriteDouble(DoubleField121); + } + if (DoubleField122 != 0D) { + output.WriteRawTag(209, 7); + output.WriteDouble(DoubleField122); + } + if (DoubleField123 != 0D) { + output.WriteRawTag(217, 7); + output.WriteDouble(DoubleField123); + } + if (DoubleField124 != 0D) { + output.WriteRawTag(225, 7); + output.WriteDouble(DoubleField124); + } + if (Int64Field125 != 0L) { + output.WriteRawTag(232, 7); + output.WriteInt64(Int64Field125); + } + if (Int64Field126 != 0L) { + output.WriteRawTag(240, 7); + output.WriteInt64(Int64Field126); + } + if (Int64Field127 != 0L) { + output.WriteRawTag(248, 7); + output.WriteInt64(Int64Field127); + } + if (DoubleField128 != 0D) { + output.WriteRawTag(129, 8); + output.WriteDouble(DoubleField128); + } + if (DoubleField129 != 0D) { + output.WriteRawTag(137, 8); + output.WriteDouble(DoubleField129); } - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField95, other.DoubleField95)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField1, other.DoubleField1)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField79, other.DoubleField79)) return false; - if (Int64Field2 != other.Int64Field2) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField96, other.DoubleField96)) return false; - if (Int64Field3 != other.Int64Field3) return false; - if (Int64Field4 != other.Int64Field4) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField97, other.DoubleField97)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField65, other.DoubleField65)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField66, other.DoubleField66)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField7, other.DoubleField7)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField62, other.DoubleField62)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField118, other.DoubleField118)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField119, other.DoubleField119)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField67, other.DoubleField67)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField120, other.DoubleField120)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField121, other.DoubleField121)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField122, other.DoubleField122)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField123, other.DoubleField123)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField124, other.DoubleField124)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField8, other.DoubleField8)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField9, other.DoubleField9)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField98, other.DoubleField98)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField10, other.DoubleField10)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField11, other.DoubleField11)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField99, other.DoubleField99)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField84, other.DoubleField84)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField14, other.DoubleField14)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField77, other.DoubleField77)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField15, other.DoubleField15)) return false; - if (Int64Field19 != other.Int64Field19) return false; - if (Int64Field115 != other.Int64Field115) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField116, other.DoubleField116)) return false; - if (Int64Field117 != other.Int64Field117) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField20, other.DoubleField20)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField21, other.DoubleField21)) return false; - if (StringField73 != other.StringField73) return false; - if (StringField74 != other.StringField74) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField22, other.DoubleField22)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField69, other.DoubleField69)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField70, other.DoubleField70)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField71, other.DoubleField71)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField72, other.DoubleField72)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField25, other.DoubleField25)) return false; - if (Int64Field26 != other.Int64Field26) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField68, other.DoubleField68)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField28, other.DoubleField28)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField106, other.DoubleField106)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField29, other.DoubleField29)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField30, other.DoubleField30)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField101, other.DoubleField101)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField102, other.DoubleField102)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField103, other.DoubleField103)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField104, other.DoubleField104)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField105, other.DoubleField105)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField31, other.DoubleField31)) return false; - if (Int64Field32 != other.Int64Field32) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField75, other.DoubleField75)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField129, other.DoubleField129)) return false; - if (EnumField80 != other.EnumField80) return false; - if (EnumField81 != other.EnumField81) return false; - if (Int64Field82 != other.Int64Field82) return false; - if (EnumField83 != other.EnumField83) return false; - if (Int64Field85 != other.Int64Field85) return false; - if (Int64Field86 != other.Int64Field86) return false; - if (Int64Field87 != other.Int64Field87) return false; - if (Int64Field125 != other.Int64Field125) return false; - if (Int64Field37 != other.Int64Field37) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField38, other.DoubleField38)) return false; - if (Interactions != other.Interactions) return false; - if(!repeatedIntField100_.Equals(other.repeatedIntField100_)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField40, other.DoubleField40)) return false; - if (Int64Field41 != other.Int64Field41) return false; - if (Int64Field126 != other.Int64Field126) return false; - if (Int64Field127 != other.Int64Field127) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField128, other.DoubleField128)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField109, other.DoubleField109)) return false; - if (Int64Field110 != other.Int64Field110) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField111, other.DoubleField111)) return false; - if (Int64Field112 != other.Int64Field112) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField113, other.DoubleField113)) return false; - if (Int64Field114 != other.Int64Field114) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField42, other.DoubleField42)) return false; - if (Int64Field43 != other.Int64Field43) return false; - if (Int64Field44 != other.Int64Field44) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField45, other.DoubleField45)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField46, other.DoubleField46)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField78, other.DoubleField78)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField88, other.DoubleField88)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField47, other.DoubleField47)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField89, other.DoubleField89)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField48, other.DoubleField48)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField49, other.DoubleField49)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField50, other.DoubleField50)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField90, other.DoubleField90)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField51, other.DoubleField51)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField91, other.DoubleField91)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField92, other.DoubleField92)) return false; - if (Int64Field107 != other.Int64Field107) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField93, other.DoubleField93)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField108, other.DoubleField108)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField52, other.DoubleField52)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField53, other.DoubleField53)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField94, other.DoubleField94)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField54, other.DoubleField54)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField55, other.DoubleField55)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField56, other.DoubleField56)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField57, other.DoubleField57)) return false; - if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(DoubleField58, other.DoubleField58)) return false; - if (Int64Field59 != other.Int64Field59) return false; - if (Int64Field60 != other.Int64Field60) return false; - return Equals(_unknownFields, other._unknownFields); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override int GetHashCode() { - int hash = 1; - if (DoubleField95 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField95); - if (DoubleField1 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField1); - if (DoubleField79 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField79); - if (Int64Field2 != 0L) hash ^= Int64Field2.GetHashCode(); - if (DoubleField96 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField96); - if (Int64Field3 != 0L) hash ^= Int64Field3.GetHashCode(); - if (Int64Field4 != 0L) hash ^= Int64Field4.GetHashCode(); - if (DoubleField97 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField97); - if (DoubleField65 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField65); - if (DoubleField66 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField66); - if (DoubleField7 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField7); - if (DoubleField62 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField62); - if (DoubleField118 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField118); - if (DoubleField119 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField119); - if (DoubleField67 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField67); - if (DoubleField120 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField120); - if (DoubleField121 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField121); - if (DoubleField122 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField122); - if (DoubleField123 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField123); - if (DoubleField124 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField124); - if (DoubleField8 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField8); - if (DoubleField9 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField9); - if (DoubleField98 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField98); - if (DoubleField10 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField10); - if (DoubleField11 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField11); - if (DoubleField99 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField99); - if (DoubleField84 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField84); - if (DoubleField14 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField14); - if (DoubleField77 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField77); - if (DoubleField15 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField15); - if (Int64Field19 != 0L) hash ^= Int64Field19.GetHashCode(); - if (Int64Field115 != 0L) hash ^= Int64Field115.GetHashCode(); - if (DoubleField116 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField116); - if (Int64Field117 != 0L) hash ^= Int64Field117.GetHashCode(); - if (DoubleField20 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField20); - if (DoubleField21 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField21); - if (StringField73.Length != 0) hash ^= StringField73.GetHashCode(); - if (StringField74.Length != 0) hash ^= StringField74.GetHashCode(); - if (DoubleField22 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField22); - if (DoubleField69 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField69); - if (DoubleField70 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField70); - if (DoubleField71 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField71); - if (DoubleField72 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField72); - if (DoubleField25 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField25); - if (Int64Field26 != 0L) hash ^= Int64Field26.GetHashCode(); - if (DoubleField68 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField68); - if (DoubleField28 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField28); - if (DoubleField106 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField106); - if (DoubleField29 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField29); - if (DoubleField30 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField30); - if (DoubleField101 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField101); - if (DoubleField102 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField102); - if (DoubleField103 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField103); - if (DoubleField104 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField104); - if (DoubleField105 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField105); - if (DoubleField31 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField31); - if (Int64Field32 != 0L) hash ^= Int64Field32.GetHashCode(); - if (DoubleField75 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField75); - if (DoubleField129 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField129); - if (EnumField80 != 0) hash ^= EnumField80.GetHashCode(); - if (EnumField81 != 0) hash ^= EnumField81.GetHashCode(); - if (Int64Field82 != 0L) hash ^= Int64Field82.GetHashCode(); - if (EnumField83 != 0) hash ^= EnumField83.GetHashCode(); - if (Int64Field85 != 0L) hash ^= Int64Field85.GetHashCode(); - if (Int64Field86 != 0L) hash ^= Int64Field86.GetHashCode(); - if (Int64Field87 != 0L) hash ^= Int64Field87.GetHashCode(); - if (Int64Field125 != 0L) hash ^= Int64Field125.GetHashCode(); - if (Int64Field37 != 0L) hash ^= Int64Field37.GetHashCode(); - if (DoubleField38 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField38); - if (Interactions != 0L) hash ^= Interactions.GetHashCode(); - hash ^= repeatedIntField100_.GetHashCode(); - if (DoubleField40 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField40); - if (Int64Field41 != 0L) hash ^= Int64Field41.GetHashCode(); - if (Int64Field126 != 0L) hash ^= Int64Field126.GetHashCode(); - if (Int64Field127 != 0L) hash ^= Int64Field127.GetHashCode(); - if (DoubleField128 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField128); - if (DoubleField109 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField109); - if (Int64Field110 != 0L) hash ^= Int64Field110.GetHashCode(); - if (DoubleField111 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField111); - if (Int64Field112 != 0L) hash ^= Int64Field112.GetHashCode(); - if (DoubleField113 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField113); - if (Int64Field114 != 0L) hash ^= Int64Field114.GetHashCode(); - if (DoubleField42 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField42); - if (Int64Field43 != 0L) hash ^= Int64Field43.GetHashCode(); - if (Int64Field44 != 0L) hash ^= Int64Field44.GetHashCode(); - if (DoubleField45 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField45); - if (DoubleField46 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField46); - if (DoubleField78 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField78); - if (DoubleField88 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField88); - if (DoubleField47 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField47); - if (DoubleField89 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField89); - if (DoubleField48 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField48); - if (DoubleField49 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField49); - if (DoubleField50 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField50); - if (DoubleField90 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField90); - if (DoubleField51 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField51); - if (DoubleField91 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField91); - if (DoubleField92 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField92); - if (Int64Field107 != 0L) hash ^= Int64Field107.GetHashCode(); - if (DoubleField93 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField93); - if (DoubleField108 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField108); - if (DoubleField52 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField52); - if (DoubleField53 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField53); - if (DoubleField94 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField94); - if (DoubleField54 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField54); - if (DoubleField55 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField55); - if (DoubleField56 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField56); - if (DoubleField57 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField57); - if (DoubleField58 != 0D) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(DoubleField58); - if (Int64Field59 != 0L) hash ^= Int64Field59.GetHashCode(); - if (Int64Field60 != 0L) hash ^= Int64Field60.GetHashCode(); if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); + _unknownFields.WriteTo(output); } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { if (DoubleField1 != 0D) { output.WriteRawTag(9); output.WriteDouble(DoubleField1); @@ -6027,7 +7619,7 @@ public sealed partial class ManyPrimitiveFieldsMessage : pb::IMessage + /// Benchmark that tests writing performance for various messages. + /// + [MemoryDiagnoser] + public class WriteMessagesBenchmark + { + const int MaxMessages = 100; + + SubTest manyWrapperFieldsTest = new SubTest(ParseMessagesBenchmark.CreateManyWrapperFieldsMessage(), MaxMessages); + SubTest manyPrimitiveFieldsTest = new SubTest(ParseMessagesBenchmark.CreateManyPrimitiveFieldsMessage(), MaxMessages); + SubTest emptyMessageTest = new SubTest(new Empty(), MaxMessages); + + public IEnumerable MessageCountValues => new[] { 10, 100 }; + + [GlobalSetup] + public void GlobalSetup() + { + } + + [Benchmark] + public byte[] ManyWrapperFieldsMessage_ToByteArray() + { + return manyWrapperFieldsTest.ToByteArray(); + } + + [Benchmark] + public byte[] ManyWrapperFieldsMessage_WriteToCodedOutputStream() + { + return manyWrapperFieldsTest.WriteToCodedOutputStream_PreAllocatedBuffer(); + } + + [Benchmark] + public byte[] ManyWrapperFieldsMessage_WriteToSpan() + { + return manyWrapperFieldsTest.WriteToSpan_PreAllocatedBuffer(); + } + + + [Benchmark] + public byte[] ManyPrimitiveFieldsMessage_ToByteArray() + { + return manyPrimitiveFieldsTest.ToByteArray(); + } + + [Benchmark] + public byte[] ManyPrimitiveFieldsMessage_WriteToCodedOutputStream() + { + return manyPrimitiveFieldsTest.WriteToCodedOutputStream_PreAllocatedBuffer(); + } + + [Benchmark] + public byte[] ManyPrimitiveFieldsMessage_WriteToSpan() + { + return manyPrimitiveFieldsTest.WriteToSpan_PreAllocatedBuffer(); + } + + [Benchmark] + public byte[] EmptyMessage_ToByteArray() + { + return emptyMessageTest.ToByteArray(); + } + + [Benchmark] + public byte[] EmptyMessage_WriteToCodedOutputStream() + { + return emptyMessageTest.WriteToCodedOutputStream_PreAllocatedBuffer(); + } + + [Benchmark] + public byte[] EmptyMessage_WriteToSpan() + { + return emptyMessageTest.WriteToSpan_PreAllocatedBuffer(); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyWrapperFieldsMessage_WriteDelimitedMessagesToCodedOutputStream(int messageCount) + { + manyWrapperFieldsTest.WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyWrapperFieldsMessage_WriteDelimitedMessagesToSpan(int messageCount) + { + manyWrapperFieldsTest.WriteDelimitedMessagesToSpan_PreAllocatedBuffer(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyPrimitiveFieldsMessage_WriteDelimitedMessagesToCodedOutputStream(int messageCount) + { + manyPrimitiveFieldsTest.WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(messageCount); + } + + [Benchmark] + [ArgumentsSource(nameof(MessageCountValues))] + public void ManyPrimitiveFieldsMessage_WriteDelimitedMessagesToSpan(int messageCount) + { + manyPrimitiveFieldsTest.WriteDelimitedMessagesToSpan_PreAllocatedBuffer(messageCount); + } + + private class SubTest + { + private readonly IMessage message; + private readonly byte[] outputBuffer; + private readonly byte[] multipleMessagesOutputBuffer; + + public SubTest(IMessage message, int maxMessageCount) + { + this.message = message; + + int messageSize = message.CalculateSize(); + this.outputBuffer = new byte[messageSize]; + this.multipleMessagesOutputBuffer = new byte[maxMessageCount * (messageSize + CodedOutputStream.ComputeLengthSize(messageSize))]; + } + + public byte[] ToByteArray() => message.ToByteArray(); + + public byte[] WriteToCodedOutputStream_PreAllocatedBuffer() + { + var cos = new CodedOutputStream(outputBuffer); // use pre-existing output buffer + message.WriteTo(cos); + return outputBuffer; + } + + public byte[] WriteToSpan_PreAllocatedBuffer() + { + var span = new Span(outputBuffer); // use pre-existing output buffer + message.WriteTo(span); + return outputBuffer; + } + + public byte[] WriteDelimitedMessagesToCodedOutputStream_PreAllocatedBuffer(int messageCount) + { + var cos = new CodedOutputStream(multipleMessagesOutputBuffer); // use pre-existing output buffer + for (int i = 0; i < messageCount; i++) + { + cos.WriteMessage(message); + } + return multipleMessagesOutputBuffer; + } + + public byte[] WriteDelimitedMessagesToSpan_PreAllocatedBuffer(int messageCount) + { + var span = new Span(multipleMessagesOutputBuffer); // use pre-existing output buffer + WriteContext.Initialize(ref span, out WriteContext ctx); + for (int i = 0; i < messageCount; i++) + { + ctx.WriteMessage(message); + } + return multipleMessagesOutputBuffer; + } + } + } +} diff --git a/csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs b/csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs new file mode 100644 index 000000000000..66b6b4a02828 --- /dev/null +++ b/csharp/src/Google.Protobuf.Benchmarks/WriteRawPrimitivesBenchmark.cs @@ -0,0 +1,519 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2019 Google Inc. All rights reserved. +// https://github.com/protocolbuffers/protobuf +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using BenchmarkDotNet.Attributes; +using System; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Buffers; +using System.Text; + +namespace Google.Protobuf.Benchmarks +{ + /// + /// Benchmarks throughput when writing raw primitives. + /// + [MemoryDiagnoser] + public class WriteRawPrimitivesBenchmark + { + // key is the encodedSize of varint values + Dictionary varint32Values; + Dictionary varint64Values; + + double[] doubleValues; + float[] floatValues; + + // key is the encodedSize of string values + Dictionary stringValues; + + // key is the encodedSize of string values + Dictionary nonAsciiStringValues; + + // key is the encodedSize of string values + Dictionary byteStringValues; + + // the buffer to which all the data will be written + byte[] outputBuffer; + + Random random = new Random(417384220); // random but deterministic seed + + public IEnumerable StringEncodedSizes => new[] { 1, 4, 10, 105, 10080 }; + + public IEnumerable NonAsciiStringEncodedSizes => new[] { 4, 10, 105, 10080 }; + + [GlobalSetup] + public void GlobalSetup() + { + outputBuffer = new byte[BytesToWrite]; + + varint32Values = new Dictionary(); + varint64Values = new Dictionary(); + for (int encodedSize = 1; encodedSize <= 10; encodedSize++) + { + if (encodedSize <= 5) + { + varint32Values.Add(encodedSize, CreateRandomVarints32(random, BytesToWrite / encodedSize, encodedSize)); + } + varint64Values.Add(encodedSize, CreateRandomVarints64(random, BytesToWrite / encodedSize, encodedSize)); + } + + doubleValues = CreateRandomDoubles(random, BytesToWrite / sizeof(double)); + floatValues = CreateRandomFloats(random, BytesToWrite / sizeof(float)); + + stringValues = new Dictionary(); + + byteStringValues = new Dictionary(); + foreach(var encodedSize in StringEncodedSizes) + { + stringValues.Add(encodedSize, CreateStrings(BytesToWrite / encodedSize, encodedSize)); + byteStringValues.Add(encodedSize, CreateByteStrings(BytesToWrite / encodedSize, encodedSize)); + } + + nonAsciiStringValues = new Dictionary(); + foreach(var encodedSize in NonAsciiStringEncodedSizes) + { + nonAsciiStringValues.Add(encodedSize, CreateNonAsciiStrings(BytesToWrite / encodedSize, encodedSize)); + } + } + + // Total number of bytes that each benchmark will write. + // Measuring the time taken to write buffer of given size makes it easier to compare parsing speed for different + // types and makes it easy to calculate the througput (in MB/s) + // 10800 bytes is chosen because it is divisible by all possible encoded sizes for all primitive types {1..10} + [Params(10080)] + public int BytesToWrite { get; set; } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + public void WriteRawVarint32_CodedOutputStream(int encodedSize) + { + var values = varint32Values[encodedSize]; + var cos = new CodedOutputStream(outputBuffer); + for (int i = 0; i < values.Length; i++) + { + cos.WriteRawVarint32(values[i]); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + public void WriteRawVarint32_WriteContext(int encodedSize) + { + var values = varint32Values[encodedSize]; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + for (int i = 0; i < values.Length; i++) + { + ctx.WriteUInt32(values[i]); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + [Arguments(6)] + [Arguments(7)] + [Arguments(8)] + [Arguments(9)] + [Arguments(10)] + public void WriteRawVarint64_CodedOutputStream(int encodedSize) + { + var values = varint64Values[encodedSize]; + var cos = new CodedOutputStream(outputBuffer); + for (int i = 0; i < values.Length; i++) + { + cos.WriteRawVarint64(values[i]); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + [Arguments(1)] + [Arguments(2)] + [Arguments(3)] + [Arguments(4)] + [Arguments(5)] + [Arguments(6)] + [Arguments(7)] + [Arguments(8)] + [Arguments(9)] + [Arguments(10)] + public void WriteRawVarint64_WriteContext(int encodedSize) + { + var values = varint64Values[encodedSize]; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + for (int i = 0; i < values.Length; i++) + { + ctx.WriteUInt64(values[i]); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteFixed32_CodedOutputStream() + { + const int encodedSize = sizeof(uint); + var cos = new CodedOutputStream(outputBuffer); + for (int i = 0; i < BytesToWrite / encodedSize; i++) + { + cos.WriteFixed32(12345); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteFixed32_WriteContext() + { + const int encodedSize = sizeof(uint); + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + for (uint i = 0; i < BytesToWrite / encodedSize; i++) + { + ctx.WriteFixed32(12345); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteFixed64_CodedOutputStream() + { + const int encodedSize = sizeof(ulong); + var cos = new CodedOutputStream(outputBuffer); + for(int i = 0; i < BytesToWrite / encodedSize; i++) + { + cos.WriteFixed64(123456789); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteFixed64_WriteContext() + { + const int encodedSize = sizeof(ulong); + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + for (uint i = 0; i < BytesToWrite / encodedSize; i++) + { + ctx.WriteFixed64(123456789); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteRawTag_OneByte_WriteContext() + { + const int encodedSize = 1; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + for (uint i = 0; i < BytesToWrite / encodedSize; i++) + { + ctx.WriteRawTag(16); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteRawTag_TwoBytes_WriteContext() + { + const int encodedSize = 2; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + for (uint i = 0; i < BytesToWrite / encodedSize; i++) + { + ctx.WriteRawTag(137, 6); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteRawTag_ThreeBytes_WriteContext() + { + const int encodedSize = 3; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + for (uint i = 0; i < BytesToWrite / encodedSize; i++) + { + ctx.WriteRawTag(160, 131, 1); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void Baseline_WriteContext() + { + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + ctx.state.position = outputBuffer.Length; + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteRawFloat_CodedOutputStream() + { + var cos = new CodedOutputStream(outputBuffer); + foreach (var value in floatValues) + { + cos.WriteFloat(value); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteRawFloat_WriteContext() + { + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + foreach (var value in floatValues) + { + ctx.WriteFloat(value); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteRawDouble_CodedOutputStream() + { + var cos = new CodedOutputStream(outputBuffer); + foreach (var value in doubleValues) + { + cos.WriteDouble(value); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + public void WriteRawDouble_WriteContext() + { + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + foreach (var value in doubleValues) + { + ctx.WriteDouble(value); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public void WriteString_CodedOutputStream(int encodedSize) + { + var values = stringValues[encodedSize]; + var cos = new CodedOutputStream(outputBuffer); + foreach (var value in values) + { + cos.WriteString(value); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public void WriteString_WriteContext(int encodedSize) + { + var values = stringValues[encodedSize]; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + foreach (var value in values) + { + ctx.WriteString(value); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + [ArgumentsSource(nameof(NonAsciiStringEncodedSizes))] + public void WriteNonAsciiString_CodedOutputStream(int encodedSize) + { + var values = nonAsciiStringValues[encodedSize]; + var cos = new CodedOutputStream(outputBuffer); + foreach (var value in values) + { + cos.WriteString(value); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + [ArgumentsSource(nameof(NonAsciiStringEncodedSizes))] + public void WriteNonAsciiString_WriteContext(int encodedSize) + { + var values = nonAsciiStringValues[encodedSize]; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + foreach (var value in values) + { + ctx.WriteString(value); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public void WriteBytes_CodedOutputStream(int encodedSize) + { + var values = byteStringValues[encodedSize]; + var cos = new CodedOutputStream(outputBuffer); + foreach (var value in values) + { + cos.WriteBytes(value); + } + cos.Flush(); + cos.CheckNoSpaceLeft(); + } + + [Benchmark] + [ArgumentsSource(nameof(StringEncodedSizes))] + public void WriteBytes_WriteContext(int encodedSize) + { + var values = byteStringValues[encodedSize]; + var span = new Span(outputBuffer); + WriteContext.Initialize(ref span, out WriteContext ctx); + foreach (var value in values) + { + ctx.WriteBytes(value); + } + ctx.Flush(); + ctx.CheckNoSpaceLeft(); + } + + private static uint[] CreateRandomVarints32(Random random, int valueCount, int encodedSize) + { + var result = new uint[valueCount]; + for (int i = 0; i < valueCount; i++) + { + result[i] = (uint) ParseRawPrimitivesBenchmark.RandomUnsignedVarint(random, encodedSize, true); + } + return result; + } + + private static ulong[] CreateRandomVarints64(Random random, int valueCount, int encodedSize) + { + var result = new ulong[valueCount]; + for (int i = 0; i < valueCount; i++) + { + result[i] = ParseRawPrimitivesBenchmark.RandomUnsignedVarint(random, encodedSize, false); + } + return result; + } + + private static float[] CreateRandomFloats(Random random, int valueCount) + { + var result = new float[valueCount]; + for (int i = 0; i < valueCount; i++) + { + result[i] = (float)random.NextDouble(); + } + return result; + } + + private static double[] CreateRandomDoubles(Random random, int valueCount) + { + var result = new double[valueCount]; + for (int i = 0; i < valueCount; i++) + { + result[i] = random.NextDouble(); + } + return result; + } + + private static string[] CreateStrings(int valueCount, int encodedSize) + { + var str = ParseRawPrimitivesBenchmark.CreateStringWithEncodedSize(encodedSize); + + var result = new string[valueCount]; + for (int i = 0; i < valueCount; i++) + { + result[i] = str; + } + return result; + } + + private static string[] CreateNonAsciiStrings(int valueCount, int encodedSize) + { + var str = ParseRawPrimitivesBenchmark.CreateNonAsciiStringWithEncodedSize(encodedSize); + + var result = new string[valueCount]; + for (int i = 0; i < valueCount; i++) + { + result[i] = str; + } + return result; + } + + private static ByteString[] CreateByteStrings(int valueCount, int encodedSize) + { + var str = ParseRawPrimitivesBenchmark.CreateStringWithEncodedSize(encodedSize); + + var result = new ByteString[valueCount]; + for (int i = 0; i < valueCount; i++) + { + result[i] = ByteString.CopyFrom(Encoding.UTF8.GetBytes(str)); + } + return result; + } + } +} diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs index 23894ad3ba4c..06b61ea8bd6e 100644 --- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs +++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs @@ -82,7 +82,7 @@ public enum TestCategory { [pbr::OriginalName("JSON_TEST")] JsonTest = 2, /// /// Similar to JSON_TEST. However, during parsing json, testee should ignore - /// unknown fields. This feature is optional. Each implementation can descide + /// unknown fields. This feature is optional. Each implementation can decide /// whether to support it. See /// https://developers.google.com/protocol-buffers/docs/proto3#json_options /// for more detail. @@ -107,7 +107,11 @@ public enum TestCategory { /// This will be known by message_type == "conformance.FailureSet", a conformance /// test should return a serialized FailureSet in protobuf_payload. /// - public sealed partial class FailureSet : pb::IMessage { + public sealed partial class FailureSet : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FailureSet()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -185,12 +189,26 @@ public sealed partial class FailureSet : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else failure_.WriteTo(output, _repeated_failure_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + failure_.WriteTo(ref output, _repeated_failure_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -212,6 +230,9 @@ public sealed partial class FailureSet : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -224,8 +245,27 @@ public sealed partial class FailureSet : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + failure_.AddEntriesFrom(ref input, _repeated_failure_codec); + break; + } + } + } + } + #endif + } /// @@ -235,7 +275,11 @@ public sealed partial class FailureSet : pb::IMessage { /// 2. parse the protobuf or JSON payload in "payload" (which may fail) /// 3. if the parse succeeded, serialize the message in the requested format. /// - public sealed partial class ConformanceRequest : pb::IMessage { + public sealed partial class ConformanceRequest : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ConformanceRequest()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -370,7 +414,7 @@ public sealed partial class ConformanceRequest : pb::IMessage /// Each test is given a specific test category. Some category may need - /// spedific support in testee programs. Refer to the definition of TestCategory + /// specific support in testee programs. Refer to the definition of TestCategory /// for more information. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -483,6 +527,9 @@ public enum PayloadOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (payloadCase_ == PayloadOneofCase.ProtobufPayload) { output.WriteRawTag(10); output.WriteBytes(ProtobufPayload); @@ -522,8 +569,54 @@ public enum PayloadOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (payloadCase_ == PayloadOneofCase.ProtobufPayload) { + output.WriteRawTag(10); + output.WriteBytes(ProtobufPayload); + } + if (payloadCase_ == PayloadOneofCase.JsonPayload) { + output.WriteRawTag(18); + output.WriteString(JsonPayload); + } + if (RequestedOutputFormat != global::Conformance.WireFormat.Unspecified) { + output.WriteRawTag(24); + output.WriteEnum((int) RequestedOutputFormat); + } + if (MessageType.Length != 0) { + output.WriteRawTag(34); + output.WriteString(MessageType); + } + if (TestCategory != global::Conformance.TestCategory.UnspecifiedTest) { + output.WriteRawTag(40); + output.WriteEnum((int) TestCategory); + } + if (jspbEncodingOptions_ != null) { + output.WriteRawTag(50); + output.WriteMessage(JspbEncodingOptions); + } + if (payloadCase_ == PayloadOneofCase.JspbPayload) { + output.WriteRawTag(58); + output.WriteString(JspbPayload); + } + if (payloadCase_ == PayloadOneofCase.TextPayload) { + output.WriteRawTag(66); + output.WriteString(TextPayload); + } + if (PrintUnknownFields != false) { + output.WriteRawTag(72); + output.WriteBool(PrintUnknownFields); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -603,6 +696,9 @@ public enum PayloadOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -650,14 +746,72 @@ public enum PayloadOneofCase { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + ProtobufPayload = input.ReadBytes(); + break; + } + case 18: { + JsonPayload = input.ReadString(); + break; + } + case 24: { + RequestedOutputFormat = (global::Conformance.WireFormat) input.ReadEnum(); + break; + } + case 34: { + MessageType = input.ReadString(); + break; + } + case 40: { + TestCategory = (global::Conformance.TestCategory) input.ReadEnum(); + break; + } + case 50: { + if (jspbEncodingOptions_ == null) { + JspbEncodingOptions = new global::Conformance.JspbEncodingConfig(); + } + input.ReadMessage(JspbEncodingOptions); + break; + } + case 58: { + JspbPayload = input.ReadString(); + break; + } + case 66: { + TextPayload = input.ReadString(); + break; + } + case 72: { + PrintUnknownFields = input.ReadBool(); + break; + } + } + } } + #endif } /// /// Represents a single test case's output. /// - public sealed partial class ConformanceResponse : pb::IMessage { + public sealed partial class ConformanceResponse : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ConformanceResponse()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -918,6 +1072,9 @@ public enum ResultOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (resultCase_ == ResultOneofCase.ParseError) { output.WriteRawTag(10); output.WriteString(ParseError); @@ -953,8 +1110,50 @@ public enum ResultOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (resultCase_ == ResultOneofCase.ParseError) { + output.WriteRawTag(10); + output.WriteString(ParseError); + } + if (resultCase_ == ResultOneofCase.RuntimeError) { + output.WriteRawTag(18); + output.WriteString(RuntimeError); + } + if (resultCase_ == ResultOneofCase.ProtobufPayload) { + output.WriteRawTag(26); + output.WriteBytes(ProtobufPayload); + } + if (resultCase_ == ResultOneofCase.JsonPayload) { + output.WriteRawTag(34); + output.WriteString(JsonPayload); + } + if (resultCase_ == ResultOneofCase.Skipped) { + output.WriteRawTag(42); + output.WriteString(Skipped); + } + if (resultCase_ == ResultOneofCase.SerializeError) { + output.WriteRawTag(50); + output.WriteString(SerializeError); + } + if (resultCase_ == ResultOneofCase.JspbPayload) { + output.WriteRawTag(58); + output.WriteString(JspbPayload); + } + if (resultCase_ == ResultOneofCase.TextPayload) { + output.WriteRawTag(66); + output.WriteString(TextPayload); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -1025,6 +1224,9 @@ public enum ResultOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1065,14 +1267,65 @@ public enum ResultOneofCase { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + ParseError = input.ReadString(); + break; + } + case 18: { + RuntimeError = input.ReadString(); + break; + } + case 26: { + ProtobufPayload = input.ReadBytes(); + break; + } + case 34: { + JsonPayload = input.ReadString(); + break; + } + case 42: { + Skipped = input.ReadString(); + break; + } + case 50: { + SerializeError = input.ReadString(); + break; + } + case 58: { + JspbPayload = input.ReadString(); + break; + } + case 66: { + TextPayload = input.ReadString(); + break; + } + } + } + } + #endif + } /// /// Encoding options for jspb format. /// - public sealed partial class JspbEncodingConfig : pb::IMessage { + public sealed partial class JspbEncodingConfig : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new JspbEncodingConfig()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1154,6 +1407,9 @@ public sealed partial class JspbEncodingConfig : pb::IMessage(request.JsonPayload); - break; - case ConformanceRequest.PayloadOneofCase.ProtobufPayload: - { - if (request.MessageType.Equals("protobuf_test_messages.proto3.TestAllTypesProto3")) + switch (request.MessageType) { - message = ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload); + case "protobuf_test_messages.proto3.TestAllTypesProto3": + message = parser.Parse(request.JsonPayload); + break; + case "protobuf_test_messages.proto2.TestAllTypesProto2": + message = parser.Parse(request.JsonPayload); + break; + default: + throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"); } - else if (request.MessageType.Equals("protobuf_test_messages.proto2.TestAllTypesProto2")) - { - ExtensionRegistry registry = new ExtensionRegistry() - { - ProtobufTestMessages.Proto2.TestMessagesProto2Extensions.ExtensionInt32, - ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1.Extensions.MessageSetExtension, - ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension2.Extensions.MessageSetExtension - }; - message = ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser.WithExtensionRegistry(registry).ParseFrom(request.ProtobufPayload); - } - else + break; + case ConformanceRequest.PayloadOneofCase.ProtobufPayload: + switch (request.MessageType) { - throw new Exception(" Protobuf request doesn't have specific payload type"); + case "protobuf_test_messages.proto3.TestAllTypesProto3": + message = ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser.ParseFrom(request.ProtobufPayload); + break; + case "protobuf_test_messages.proto2.TestAllTypesProto2": + message = ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser + .WithExtensionRegistry(proto2ExtensionRegistry) + .ParseFrom(request.ProtobufPayload); + break; + default: + throw new Exception($" Protobuf request doesn't have specific payload type ({request.MessageType})"); } break; - } case ConformanceRequest.PayloadOneofCase.TextPayload: - { return new ConformanceResponse { Skipped = "CSharp doesn't support text format" }; - } default: throw new Exception("Unsupported request payload: " + request.PayloadCase); } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/Google.Protobuf.Test.TestProtos.csproj b/csharp/src/Google.Protobuf.Test.TestProtos/Google.Protobuf.Test.TestProtos.csproj index 5b705804aa27..1af85e0a5479 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/Google.Protobuf.Test.TestProtos.csproj +++ b/csharp/src/Google.Protobuf.Test.TestProtos/Google.Protobuf.Test.TestProtos.csproj @@ -6,7 +6,7 @@ and without the internal visibility from the test project (all of which have caused issues in the past). --> - net45;netstandard1.0;netstandard2.0 + net45;netstandard1.1;netstandard2.0 3.0 ../../keys/Google.Protobuf.snk true diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs index 197b197d0ea4..bbf0061f880b 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/MapUnittestProto3.cs @@ -176,7 +176,11 @@ public enum MapEnum { /// /// Tests maps. /// - public sealed partial class TestMap : pb::IMessage { + public sealed partial class TestMap : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMap()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -462,6 +466,9 @@ public sealed partial class TestMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else mapInt32Int32_.WriteTo(output, _map_mapInt32Int32_codec); mapInt64Int64_.WriteTo(output, _map_mapInt64Int64_codec); mapUint32Uint32_.WriteTo(output, _map_mapUint32Uint32_codec); @@ -482,7 +489,34 @@ public sealed partial class TestMap : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec); + mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec); + mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec); + mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec); + mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec); + mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec); + mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec); + mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec); + mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec); + mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec); + mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec); + mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec); + mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec); + mapStringString_.WriteTo(ref output, _map_mapStringString_codec); + mapInt32Bytes_.WriteTo(ref output, _map_mapInt32Bytes_codec); + mapInt32Enum_.WriteTo(ref output, _map_mapInt32Enum_codec); + mapInt32ForeignMessage_.WriteTo(ref output, _map_mapInt32ForeignMessage_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -537,6 +571,9 @@ public sealed partial class TestMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -613,11 +650,98 @@ public sealed partial class TestMap : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + mapInt32Int32_.AddEntriesFrom(ref input, _map_mapInt32Int32_codec); + break; + } + case 18: { + mapInt64Int64_.AddEntriesFrom(ref input, _map_mapInt64Int64_codec); + break; + } + case 26: { + mapUint32Uint32_.AddEntriesFrom(ref input, _map_mapUint32Uint32_codec); + break; + } + case 34: { + mapUint64Uint64_.AddEntriesFrom(ref input, _map_mapUint64Uint64_codec); + break; + } + case 42: { + mapSint32Sint32_.AddEntriesFrom(ref input, _map_mapSint32Sint32_codec); + break; + } + case 50: { + mapSint64Sint64_.AddEntriesFrom(ref input, _map_mapSint64Sint64_codec); + break; + } + case 58: { + mapFixed32Fixed32_.AddEntriesFrom(ref input, _map_mapFixed32Fixed32_codec); + break; + } + case 66: { + mapFixed64Fixed64_.AddEntriesFrom(ref input, _map_mapFixed64Fixed64_codec); + break; + } + case 74: { + mapSfixed32Sfixed32_.AddEntriesFrom(ref input, _map_mapSfixed32Sfixed32_codec); + break; + } + case 82: { + mapSfixed64Sfixed64_.AddEntriesFrom(ref input, _map_mapSfixed64Sfixed64_codec); + break; + } + case 90: { + mapInt32Float_.AddEntriesFrom(ref input, _map_mapInt32Float_codec); + break; + } + case 98: { + mapInt32Double_.AddEntriesFrom(ref input, _map_mapInt32Double_codec); + break; + } + case 106: { + mapBoolBool_.AddEntriesFrom(ref input, _map_mapBoolBool_codec); + break; + } + case 114: { + mapStringString_.AddEntriesFrom(ref input, _map_mapStringString_codec); + break; + } + case 122: { + mapInt32Bytes_.AddEntriesFrom(ref input, _map_mapInt32Bytes_codec); + break; + } + case 130: { + mapInt32Enum_.AddEntriesFrom(ref input, _map_mapInt32Enum_codec); + break; + } + case 138: { + mapInt32ForeignMessage_.AddEntriesFrom(ref input, _map_mapInt32ForeignMessage_codec); + break; + } + } + } + } + #endif + } - public sealed partial class TestMapSubmessage : pb::IMessage { + public sealed partial class TestMapSubmessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMapSubmessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -696,6 +820,9 @@ public sealed partial class TestMapSubmessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (testMap_ != null) { output.WriteRawTag(10); output.WriteMessage(TestMap); @@ -703,7 +830,21 @@ public sealed partial class TestMapSubmessage : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (testMap_ != null) { + output.WriteRawTag(10); + output.WriteMessage(TestMap); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -733,6 +874,9 @@ public sealed partial class TestMapSubmessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -748,11 +892,37 @@ public sealed partial class TestMapSubmessage : pb::IMessage } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (testMap_ == null) { + TestMap = new global::Google.Protobuf.TestProtos.TestMap(); + } + input.ReadMessage(TestMap); + break; + } + } + } + } + #endif + } - public sealed partial class TestMessageMap : pb::IMessage { + public sealed partial class TestMessageMap : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMessageMap()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -830,11 +1000,25 @@ public sealed partial class TestMessageMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else mapInt32Message_.WriteTo(output, _map_mapInt32Message_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + mapInt32Message_.WriteTo(ref output, _map_mapInt32Message_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -857,6 +1041,9 @@ public sealed partial class TestMessageMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -869,14 +1056,37 @@ public sealed partial class TestMessageMap : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + mapInt32Message_.AddEntriesFrom(ref input, _map_mapInt32Message_codec); + break; + } + } + } + } + #endif + } /// /// Two map fields share the same entry default instance. /// - public sealed partial class TestSameTypeMap : pb::IMessage { + public sealed partial class TestSameTypeMap : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestSameTypeMap()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -967,13 +1177,28 @@ public sealed partial class TestSameTypeMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else map1_.WriteTo(output, _map_map1_codec); map2_.WriteTo(output, _map_map2_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + map1_.WriteTo(ref output, _map_map1_codec); + map2_.WriteTo(ref output, _map_map2_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -997,6 +1222,9 @@ public sealed partial class TestSameTypeMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1013,11 +1241,38 @@ public sealed partial class TestSameTypeMap : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + map1_.AddEntriesFrom(ref input, _map_map1_codec); + break; + } + case 18: { + map2_.AddEntriesFrom(ref input, _map_map2_codec); + break; + } + } + } } + #endif } - public sealed partial class TestArenaMap : pb::IMessage { + public sealed partial class TestArenaMap : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestArenaMap()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1277,6 +1532,9 @@ public sealed partial class TestArenaMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else mapInt32Int32_.WriteTo(output, _map_mapInt32Int32_codec); mapInt64Int64_.WriteTo(output, _map_mapInt64Int64_codec); mapUint32Uint32_.WriteTo(output, _map_mapUint32Uint32_codec); @@ -1295,7 +1553,32 @@ public sealed partial class TestArenaMap : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec); + mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec); + mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec); + mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec); + mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec); + mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec); + mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec); + mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec); + mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec); + mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec); + mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec); + mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec); + mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec); + mapInt32Enum_.WriteTo(ref output, _map_mapInt32Enum_codec); + mapInt32ForeignMessage_.WriteTo(ref output, _map_mapInt32ForeignMessage_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1346,6 +1629,9 @@ public sealed partial class TestArenaMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1414,7 +1700,82 @@ public sealed partial class TestArenaMap : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + mapInt32Int32_.AddEntriesFrom(ref input, _map_mapInt32Int32_codec); + break; + } + case 18: { + mapInt64Int64_.AddEntriesFrom(ref input, _map_mapInt64Int64_codec); + break; + } + case 26: { + mapUint32Uint32_.AddEntriesFrom(ref input, _map_mapUint32Uint32_codec); + break; + } + case 34: { + mapUint64Uint64_.AddEntriesFrom(ref input, _map_mapUint64Uint64_codec); + break; + } + case 42: { + mapSint32Sint32_.AddEntriesFrom(ref input, _map_mapSint32Sint32_codec); + break; + } + case 50: { + mapSint64Sint64_.AddEntriesFrom(ref input, _map_mapSint64Sint64_codec); + break; + } + case 58: { + mapFixed32Fixed32_.AddEntriesFrom(ref input, _map_mapFixed32Fixed32_codec); + break; + } + case 66: { + mapFixed64Fixed64_.AddEntriesFrom(ref input, _map_mapFixed64Fixed64_codec); + break; + } + case 74: { + mapSfixed32Sfixed32_.AddEntriesFrom(ref input, _map_mapSfixed32Sfixed32_codec); + break; + } + case 82: { + mapSfixed64Sfixed64_.AddEntriesFrom(ref input, _map_mapSfixed64Sfixed64_codec); + break; + } + case 90: { + mapInt32Float_.AddEntriesFrom(ref input, _map_mapInt32Float_codec); + break; + } + case 98: { + mapInt32Double_.AddEntriesFrom(ref input, _map_mapInt32Double_codec); + break; + } + case 106: { + mapBoolBool_.AddEntriesFrom(ref input, _map_mapBoolBool_codec); + break; + } + case 114: { + mapInt32Enum_.AddEntriesFrom(ref input, _map_mapInt32Enum_codec); + break; + } + case 122: { + mapInt32ForeignMessage_.AddEntriesFrom(ref input, _map_mapInt32ForeignMessage_codec); + break; + } + } + } } + #endif } @@ -1422,7 +1783,11 @@ public sealed partial class TestArenaMap : pb::IMessage { /// Previously, message containing enum called Type cannot be used as value of /// map field. /// - public sealed partial class MessageContainingEnumCalledType : pb::IMessage { + public sealed partial class MessageContainingEnumCalledType : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageContainingEnumCalledType()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1500,11 +1865,25 @@ public sealed partial class MessageContainingEnumCalledType : pb::IMessageContainer for nested types declared in the MessageContainingEnumCalledType message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1557,7 +1958,11 @@ public enum Type { /// /// Previously, message cannot contain map field called "entry". /// - public sealed partial class MessageContainingMapCalledEntry : pb::IMessage { + public sealed partial class MessageContainingMapCalledEntry : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageContainingMapCalledEntry()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1635,11 +2040,25 @@ public sealed partial class MessageContainingMapCalledEntry : pb::IMessage - public sealed partial class TestAllTypesProto2 : pb::IExtendableMessage { + public sealed partial class TestAllTypesProto2 : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestAllTypesProto2()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -290,13 +294,13 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the optional_nested_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalNestedMessage { - get { return optionalNestedMessage_ != null; } - } - /// Clears the value of the optional_nested_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalNestedMessage() { - optionalNestedMessage_ = null; - } /// Field number for the "optional_foreign_message" field. public const int OptionalForeignMessageFieldNumber = 19; @@ -815,16 +809,6 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the optional_foreign_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalForeignMessage { - get { return optionalForeignMessage_ != null; } - } - /// Clears the value of the optional_foreign_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalForeignMessage() { - optionalForeignMessage_ = null; - } /// Field number for the "optional_nested_enum" field. public const int OptionalNestedEnumFieldNumber = 21; @@ -930,16 +914,6 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the recursive_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasRecursiveMessage { - get { return recursiveMessage_ != null; } - } - /// Clears the value of the recursive_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearRecursiveMessage() { - recursiveMessage_ = null; - } /// Field number for the "repeated_int32" field. public const int RepeatedInt32FieldNumber = 31; @@ -1660,24 +1634,12 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "oneof_nested_message" field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOneofNestedMessage { - get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; } - } - /// Clears the value of the oneof if it's currently set to "oneof_nested_message" - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOneofNestedMessage() { - if (HasOneofNestedMessage) { - ClearOneofField(); - } - } /// Field number for the "oneof_string" field. public const int OneofStringFieldNumber = 113; @@ -1872,21 +1834,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int Fieldname1 { - get { if ((_hasBits0 & 2097152) != 0) { return fieldname1_; } else { return Fieldname1DefaultValue; } } + get { if ((_hasBits0 & 32768) != 0) { return fieldname1_; } else { return Fieldname1DefaultValue; } } set { - _hasBits0 |= 2097152; + _hasBits0 |= 32768; fieldname1_ = value; } } /// Gets whether the "fieldname1" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldname1 { - get { return (_hasBits0 & 2097152) != 0; } + get { return (_hasBits0 & 32768) != 0; } } /// Clears the value of the "fieldname1" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldname1() { - _hasBits0 &= ~2097152; + _hasBits0 &= ~32768; } /// Field number for the "field_name2" field. @@ -1896,21 +1858,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field_name2" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName2 { - get { return (_hasBits0 & 4194304) != 0; } + get { return (_hasBits0 & 65536) != 0; } } /// Clears the value of the "field_name2" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName2() { - _hasBits0 &= ~4194304; + _hasBits0 &= ~65536; } /// Field number for the "_field_name3" field. @@ -1920,21 +1882,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "_field_name3" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName3 { - get { return (_hasBits0 & 8388608) != 0; } + get { return (_hasBits0 & 131072) != 0; } } /// Clears the value of the "_field_name3" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName3() { - _hasBits0 &= ~8388608; + _hasBits0 &= ~131072; } /// Field number for the "field__name4_" field. @@ -1944,21 +1906,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field__name4_" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName4 { - get { return (_hasBits0 & 16777216) != 0; } + get { return (_hasBits0 & 262144) != 0; } } /// Clears the value of the "field__name4_" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName4() { - _hasBits0 &= ~16777216; + _hasBits0 &= ~262144; } /// Field number for the "field0name5" field. @@ -1968,21 +1930,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field0name5" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasField0Name5 { - get { return (_hasBits0 & 33554432) != 0; } + get { return (_hasBits0 & 524288) != 0; } } /// Clears the value of the "field0name5" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearField0Name5() { - _hasBits0 &= ~33554432; + _hasBits0 &= ~524288; } /// Field number for the "field_0_name6" field. @@ -1992,21 +1954,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field_0_name6" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasField0Name6 { - get { return (_hasBits0 & 67108864) != 0; } + get { return (_hasBits0 & 1048576) != 0; } } /// Clears the value of the "field_0_name6" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearField0Name6() { - _hasBits0 &= ~67108864; + _hasBits0 &= ~1048576; } /// Field number for the "fieldName7" field. @@ -2016,21 +1978,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "fieldName7" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName7 { - get { return (_hasBits0 & 134217728) != 0; } + get { return (_hasBits0 & 2097152) != 0; } } /// Clears the value of the "fieldName7" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName7() { - _hasBits0 &= ~134217728; + _hasBits0 &= ~2097152; } /// Field number for the "FieldName8" field. @@ -2040,21 +2002,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "FieldName8" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName8 { - get { return (_hasBits0 & 268435456) != 0; } + get { return (_hasBits0 & 4194304) != 0; } } /// Clears the value of the "FieldName8" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName8() { - _hasBits0 &= ~268435456; + _hasBits0 &= ~4194304; } /// Field number for the "field_Name9" field. @@ -2064,21 +2026,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field_Name9" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName9 { - get { return (_hasBits0 & 536870912) != 0; } + get { return (_hasBits0 & 8388608) != 0; } } /// Clears the value of the "field_Name9" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName9() { - _hasBits0 &= ~536870912; + _hasBits0 &= ~8388608; } /// Field number for the "Field_Name10" field. @@ -2088,21 +2050,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "Field_Name10" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName10 { - get { return (_hasBits0 & 1073741824) != 0; } + get { return (_hasBits0 & 16777216) != 0; } } /// Clears the value of the "Field_Name10" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName10() { - _hasBits0 &= ~1073741824; + _hasBits0 &= ~16777216; } /// Field number for the "FIELD_NAME11" field. @@ -2112,21 +2074,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "FIELD_NAME11" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFIELDNAME11 { - get { return (_hasBits0 & -2147483648) != 0; } + get { return (_hasBits0 & 33554432) != 0; } } /// Clears the value of the "FIELD_NAME11" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFIELDNAME11() { - _hasBits0 &= ~-2147483648; + _hasBits0 &= ~33554432; } /// Field number for the "FIELD_name12" field. @@ -2136,21 +2098,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "FIELD_name12" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFIELDName12 { - get { return (_hasBits1 & 1) != 0; } + get { return (_hasBits0 & 67108864) != 0; } } /// Clears the value of the "FIELD_name12" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFIELDName12() { - _hasBits1 &= ~1; + _hasBits0 &= ~67108864; } /// Field number for the "__field_name13" field. @@ -2160,21 +2122,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "__field_name13" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName13 { - get { return (_hasBits1 & 2) != 0; } + get { return (_hasBits0 & 134217728) != 0; } } /// Clears the value of the "__field_name13" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName13() { - _hasBits1 &= ~2; + _hasBits0 &= ~134217728; } /// Field number for the "__Field_name14" field. @@ -2184,21 +2146,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "__Field_name14" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName14 { - get { return (_hasBits1 & 4) != 0; } + get { return (_hasBits0 & 268435456) != 0; } } /// Clears the value of the "__Field_name14" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName14() { - _hasBits1 &= ~4; + _hasBits0 &= ~268435456; } /// Field number for the "field__name15" field. @@ -2208,21 +2170,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field__name15" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName15 { - get { return (_hasBits1 & 8) != 0; } + get { return (_hasBits0 & 536870912) != 0; } } /// Clears the value of the "field__name15" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName15() { - _hasBits1 &= ~8; + _hasBits0 &= ~536870912; } /// Field number for the "field__Name16" field. @@ -2232,21 +2194,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field__Name16" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName16 { - get { return (_hasBits1 & 16) != 0; } + get { return (_hasBits0 & 1073741824) != 0; } } /// Clears the value of the "field__Name16" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName16() { - _hasBits1 &= ~16; + _hasBits0 &= ~1073741824; } /// Field number for the "field_name17__" field. @@ -2256,21 +2218,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "field_name17__" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName17 { - get { return (_hasBits1 & 32) != 0; } + get { return (_hasBits0 & -2147483648) != 0; } } /// Clears the value of the "field_name17__" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName17() { - _hasBits1 &= ~32; + _hasBits0 &= ~-2147483648; } /// Field number for the "Field_name18__" field. @@ -2280,21 +2242,21 @@ public sealed partial class TestAllTypesProto2 : pb::IExtendableMessageGets whether the "Field_name18__" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasFieldName18 { - get { return (_hasBits1 & 64) != 0; } + get { return (_hasBits1 & 1) != 0; } } /// Clears the value of the "Field_name18__" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearFieldName18() { - _hasBits1 &= ~64; + _hasBits1 &= ~1; } private object oneofField_; @@ -2479,13 +2441,13 @@ public enum OneofFieldOneofCase { if (HasOptionalBool) hash ^= OptionalBool.GetHashCode(); if (HasOptionalString) hash ^= OptionalString.GetHashCode(); if (HasOptionalBytes) hash ^= OptionalBytes.GetHashCode(); - if (HasOptionalNestedMessage) hash ^= OptionalNestedMessage.GetHashCode(); - if (HasOptionalForeignMessage) hash ^= OptionalForeignMessage.GetHashCode(); + if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode(); + if (optionalForeignMessage_ != null) hash ^= OptionalForeignMessage.GetHashCode(); if (HasOptionalNestedEnum) hash ^= OptionalNestedEnum.GetHashCode(); if (HasOptionalForeignEnum) hash ^= OptionalForeignEnum.GetHashCode(); if (HasOptionalStringPiece) hash ^= OptionalStringPiece.GetHashCode(); if (HasOptionalCord) hash ^= OptionalCord.GetHashCode(); - if (HasRecursiveMessage) hash ^= RecursiveMessage.GetHashCode(); + if (recursiveMessage_ != null) hash ^= RecursiveMessage.GetHashCode(); hash ^= repeatedInt32_.GetHashCode(); hash ^= repeatedInt64_.GetHashCode(); hash ^= repeatedUint32_.GetHashCode(); @@ -2555,7 +2517,7 @@ public enum OneofFieldOneofCase { hash ^= MapStringNestedEnum.GetHashCode(); hash ^= MapStringForeignEnum.GetHashCode(); if (HasOneofUint32) hash ^= OneofUint32.GetHashCode(); - if (HasOneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode(); if (HasOneofString) hash ^= OneofString.GetHashCode(); if (HasOneofBytes) hash ^= OneofBytes.GetHashCode(); if (HasOneofBool) hash ^= OneofBool.GetHashCode(); @@ -2599,6 +2561,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasOptionalInt32) { output.WriteRawTag(8); output.WriteInt32(OptionalInt32); @@ -2659,11 +2624,11 @@ public enum OneofFieldOneofCase { output.WriteRawTag(122); output.WriteBytes(OptionalBytes); } - if (HasOptionalNestedMessage) { + if (optionalNestedMessage_ != null) { output.WriteRawTag(146, 1); output.WriteMessage(OptionalNestedMessage); } - if (HasOptionalForeignMessage) { + if (optionalForeignMessage_ != null) { output.WriteRawTag(154, 1); output.WriteMessage(OptionalForeignMessage); } @@ -2683,7 +2648,7 @@ public enum OneofFieldOneofCase { output.WriteRawTag(202, 1); output.WriteString(OptionalCord); } - if (HasRecursiveMessage) { + if (recursiveMessage_ != null) { output.WriteRawTag(218, 1); output.WriteMessage(RecursiveMessage); } @@ -2759,7 +2724,7 @@ public enum OneofFieldOneofCase { output.WriteRawTag(248, 6); output.WriteUInt32(OneofUint32); } - if (HasOneofNestedMessage) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { output.WriteRawTag(130, 7); output.WriteMessage(OneofNestedMessage); } @@ -2874,176 +2839,458 @@ public enum OneofFieldOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { if (HasOptionalInt32) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32); + output.WriteRawTag(8); + output.WriteInt32(OptionalInt32); } if (HasOptionalInt64) { - size += 1 + pb::CodedOutputStream.ComputeInt64Size(OptionalInt64); + output.WriteRawTag(16); + output.WriteInt64(OptionalInt64); } if (HasOptionalUint32) { - size += 1 + pb::CodedOutputStream.ComputeUInt32Size(OptionalUint32); + output.WriteRawTag(24); + output.WriteUInt32(OptionalUint32); } if (HasOptionalUint64) { - size += 1 + pb::CodedOutputStream.ComputeUInt64Size(OptionalUint64); + output.WriteRawTag(32); + output.WriteUInt64(OptionalUint64); } if (HasOptionalSint32) { - size += 1 + pb::CodedOutputStream.ComputeSInt32Size(OptionalSint32); + output.WriteRawTag(40); + output.WriteSInt32(OptionalSint32); } if (HasOptionalSint64) { - size += 1 + pb::CodedOutputStream.ComputeSInt64Size(OptionalSint64); + output.WriteRawTag(48); + output.WriteSInt64(OptionalSint64); } if (HasOptionalFixed32) { - size += 1 + 4; + output.WriteRawTag(61); + output.WriteFixed32(OptionalFixed32); } if (HasOptionalFixed64) { - size += 1 + 8; + output.WriteRawTag(65); + output.WriteFixed64(OptionalFixed64); } if (HasOptionalSfixed32) { - size += 1 + 4; + output.WriteRawTag(77); + output.WriteSFixed32(OptionalSfixed32); } if (HasOptionalSfixed64) { - size += 1 + 8; + output.WriteRawTag(81); + output.WriteSFixed64(OptionalSfixed64); } if (HasOptionalFloat) { - size += 1 + 4; + output.WriteRawTag(93); + output.WriteFloat(OptionalFloat); } if (HasOptionalDouble) { - size += 1 + 8; + output.WriteRawTag(97); + output.WriteDouble(OptionalDouble); } if (HasOptionalBool) { - size += 1 + 1; + output.WriteRawTag(104); + output.WriteBool(OptionalBool); } if (HasOptionalString) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalString); + output.WriteRawTag(114); + output.WriteString(OptionalString); } if (HasOptionalBytes) { - size += 1 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes); + output.WriteRawTag(122); + output.WriteBytes(OptionalBytes); } - if (HasOptionalNestedMessage) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage); + if (optionalNestedMessage_ != null) { + output.WriteRawTag(146, 1); + output.WriteMessage(OptionalNestedMessage); } - if (HasOptionalForeignMessage) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage); + if (optionalForeignMessage_ != null) { + output.WriteRawTag(154, 1); + output.WriteMessage(OptionalForeignMessage); } if (HasOptionalNestedEnum) { - size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum); + output.WriteRawTag(168, 1); + output.WriteEnum((int) OptionalNestedEnum); } if (HasOptionalForeignEnum) { - size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalForeignEnum); + output.WriteRawTag(176, 1); + output.WriteEnum((int) OptionalForeignEnum); } if (HasOptionalStringPiece) { - size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalStringPiece); + output.WriteRawTag(194, 1); + output.WriteString(OptionalStringPiece); } if (HasOptionalCord) { - size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord); + output.WriteRawTag(202, 1); + output.WriteString(OptionalCord); } - if (HasRecursiveMessage) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(RecursiveMessage); + if (recursiveMessage_ != null) { + output.WriteRawTag(218, 1); + output.WriteMessage(RecursiveMessage); } - size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec); - size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec); - size += repeatedUint32_.CalculateSize(_repeated_repeatedUint32_codec); - size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec); - size += repeatedSint32_.CalculateSize(_repeated_repeatedSint32_codec); - size += repeatedSint64_.CalculateSize(_repeated_repeatedSint64_codec); - size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec); - size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec); - size += repeatedSfixed32_.CalculateSize(_repeated_repeatedSfixed32_codec); - size += repeatedSfixed64_.CalculateSize(_repeated_repeatedSfixed64_codec); - size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec); - size += repeatedDouble_.CalculateSize(_repeated_repeatedDouble_codec); - size += repeatedBool_.CalculateSize(_repeated_repeatedBool_codec); - size += repeatedString_.CalculateSize(_repeated_repeatedString_codec); - size += repeatedBytes_.CalculateSize(_repeated_repeatedBytes_codec); - size += repeatedNestedMessage_.CalculateSize(_repeated_repeatedNestedMessage_codec); - size += repeatedForeignMessage_.CalculateSize(_repeated_repeatedForeignMessage_codec); - size += repeatedNestedEnum_.CalculateSize(_repeated_repeatedNestedEnum_codec); - size += repeatedForeignEnum_.CalculateSize(_repeated_repeatedForeignEnum_codec); - size += repeatedStringPiece_.CalculateSize(_repeated_repeatedStringPiece_codec); - size += repeatedCord_.CalculateSize(_repeated_repeatedCord_codec); - size += packedInt32_.CalculateSize(_repeated_packedInt32_codec); - size += packedInt64_.CalculateSize(_repeated_packedInt64_codec); - size += packedUint32_.CalculateSize(_repeated_packedUint32_codec); - size += packedUint64_.CalculateSize(_repeated_packedUint64_codec); - size += packedSint32_.CalculateSize(_repeated_packedSint32_codec); - size += packedSint64_.CalculateSize(_repeated_packedSint64_codec); - size += packedFixed32_.CalculateSize(_repeated_packedFixed32_codec); - size += packedFixed64_.CalculateSize(_repeated_packedFixed64_codec); - size += packedSfixed32_.CalculateSize(_repeated_packedSfixed32_codec); - size += packedSfixed64_.CalculateSize(_repeated_packedSfixed64_codec); - size += packedFloat_.CalculateSize(_repeated_packedFloat_codec); - size += packedDouble_.CalculateSize(_repeated_packedDouble_codec); - size += packedBool_.CalculateSize(_repeated_packedBool_codec); - size += packedNestedEnum_.CalculateSize(_repeated_packedNestedEnum_codec); - size += unpackedInt32_.CalculateSize(_repeated_unpackedInt32_codec); - size += unpackedInt64_.CalculateSize(_repeated_unpackedInt64_codec); - size += unpackedUint32_.CalculateSize(_repeated_unpackedUint32_codec); - size += unpackedUint64_.CalculateSize(_repeated_unpackedUint64_codec); - size += unpackedSint32_.CalculateSize(_repeated_unpackedSint32_codec); - size += unpackedSint64_.CalculateSize(_repeated_unpackedSint64_codec); - size += unpackedFixed32_.CalculateSize(_repeated_unpackedFixed32_codec); - size += unpackedFixed64_.CalculateSize(_repeated_unpackedFixed64_codec); - size += unpackedSfixed32_.CalculateSize(_repeated_unpackedSfixed32_codec); - size += unpackedSfixed64_.CalculateSize(_repeated_unpackedSfixed64_codec); - size += unpackedFloat_.CalculateSize(_repeated_unpackedFloat_codec); - size += unpackedDouble_.CalculateSize(_repeated_unpackedDouble_codec); - size += unpackedBool_.CalculateSize(_repeated_unpackedBool_codec); - size += unpackedNestedEnum_.CalculateSize(_repeated_unpackedNestedEnum_codec); - size += mapInt32Int32_.CalculateSize(_map_mapInt32Int32_codec); - size += mapInt64Int64_.CalculateSize(_map_mapInt64Int64_codec); - size += mapUint32Uint32_.CalculateSize(_map_mapUint32Uint32_codec); - size += mapUint64Uint64_.CalculateSize(_map_mapUint64Uint64_codec); - size += mapSint32Sint32_.CalculateSize(_map_mapSint32Sint32_codec); - size += mapSint64Sint64_.CalculateSize(_map_mapSint64Sint64_codec); - size += mapFixed32Fixed32_.CalculateSize(_map_mapFixed32Fixed32_codec); - size += mapFixed64Fixed64_.CalculateSize(_map_mapFixed64Fixed64_codec); - size += mapSfixed32Sfixed32_.CalculateSize(_map_mapSfixed32Sfixed32_codec); - size += mapSfixed64Sfixed64_.CalculateSize(_map_mapSfixed64Sfixed64_codec); - size += mapInt32Float_.CalculateSize(_map_mapInt32Float_codec); - size += mapInt32Double_.CalculateSize(_map_mapInt32Double_codec); - size += mapBoolBool_.CalculateSize(_map_mapBoolBool_codec); - size += mapStringString_.CalculateSize(_map_mapStringString_codec); - size += mapStringBytes_.CalculateSize(_map_mapStringBytes_codec); - size += mapStringNestedMessage_.CalculateSize(_map_mapStringNestedMessage_codec); - size += mapStringForeignMessage_.CalculateSize(_map_mapStringForeignMessage_codec); - size += mapStringNestedEnum_.CalculateSize(_map_mapStringNestedEnum_codec); - size += mapStringForeignEnum_.CalculateSize(_map_mapStringForeignEnum_codec); + repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec); + repeatedInt64_.WriteTo(ref output, _repeated_repeatedInt64_codec); + repeatedUint32_.WriteTo(ref output, _repeated_repeatedUint32_codec); + repeatedUint64_.WriteTo(ref output, _repeated_repeatedUint64_codec); + repeatedSint32_.WriteTo(ref output, _repeated_repeatedSint32_codec); + repeatedSint64_.WriteTo(ref output, _repeated_repeatedSint64_codec); + repeatedFixed32_.WriteTo(ref output, _repeated_repeatedFixed32_codec); + repeatedFixed64_.WriteTo(ref output, _repeated_repeatedFixed64_codec); + repeatedSfixed32_.WriteTo(ref output, _repeated_repeatedSfixed32_codec); + repeatedSfixed64_.WriteTo(ref output, _repeated_repeatedSfixed64_codec); + repeatedFloat_.WriteTo(ref output, _repeated_repeatedFloat_codec); + repeatedDouble_.WriteTo(ref output, _repeated_repeatedDouble_codec); + repeatedBool_.WriteTo(ref output, _repeated_repeatedBool_codec); + repeatedString_.WriteTo(ref output, _repeated_repeatedString_codec); + repeatedBytes_.WriteTo(ref output, _repeated_repeatedBytes_codec); + repeatedNestedMessage_.WriteTo(ref output, _repeated_repeatedNestedMessage_codec); + repeatedForeignMessage_.WriteTo(ref output, _repeated_repeatedForeignMessage_codec); + repeatedNestedEnum_.WriteTo(ref output, _repeated_repeatedNestedEnum_codec); + repeatedForeignEnum_.WriteTo(ref output, _repeated_repeatedForeignEnum_codec); + repeatedStringPiece_.WriteTo(ref output, _repeated_repeatedStringPiece_codec); + repeatedCord_.WriteTo(ref output, _repeated_repeatedCord_codec); + mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec); + mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec); + mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec); + mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec); + mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec); + mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec); + mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec); + mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec); + mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec); + mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec); + mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec); + mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec); + mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec); + mapStringString_.WriteTo(ref output, _map_mapStringString_codec); + mapStringBytes_.WriteTo(ref output, _map_mapStringBytes_codec); + mapStringNestedMessage_.WriteTo(ref output, _map_mapStringNestedMessage_codec); + mapStringForeignMessage_.WriteTo(ref output, _map_mapStringForeignMessage_codec); + mapStringNestedEnum_.WriteTo(ref output, _map_mapStringNestedEnum_codec); + mapStringForeignEnum_.WriteTo(ref output, _map_mapStringForeignEnum_codec); + packedInt32_.WriteTo(ref output, _repeated_packedInt32_codec); + packedInt64_.WriteTo(ref output, _repeated_packedInt64_codec); + packedUint32_.WriteTo(ref output, _repeated_packedUint32_codec); + packedUint64_.WriteTo(ref output, _repeated_packedUint64_codec); + packedSint32_.WriteTo(ref output, _repeated_packedSint32_codec); + packedSint64_.WriteTo(ref output, _repeated_packedSint64_codec); + packedFixed32_.WriteTo(ref output, _repeated_packedFixed32_codec); + packedFixed64_.WriteTo(ref output, _repeated_packedFixed64_codec); + packedSfixed32_.WriteTo(ref output, _repeated_packedSfixed32_codec); + packedSfixed64_.WriteTo(ref output, _repeated_packedSfixed64_codec); + packedFloat_.WriteTo(ref output, _repeated_packedFloat_codec); + packedDouble_.WriteTo(ref output, _repeated_packedDouble_codec); + packedBool_.WriteTo(ref output, _repeated_packedBool_codec); + packedNestedEnum_.WriteTo(ref output, _repeated_packedNestedEnum_codec); + unpackedInt32_.WriteTo(ref output, _repeated_unpackedInt32_codec); + unpackedInt64_.WriteTo(ref output, _repeated_unpackedInt64_codec); + unpackedUint32_.WriteTo(ref output, _repeated_unpackedUint32_codec); + unpackedUint64_.WriteTo(ref output, _repeated_unpackedUint64_codec); + unpackedSint32_.WriteTo(ref output, _repeated_unpackedSint32_codec); + unpackedSint64_.WriteTo(ref output, _repeated_unpackedSint64_codec); + unpackedFixed32_.WriteTo(ref output, _repeated_unpackedFixed32_codec); + unpackedFixed64_.WriteTo(ref output, _repeated_unpackedFixed64_codec); + unpackedSfixed32_.WriteTo(ref output, _repeated_unpackedSfixed32_codec); + unpackedSfixed64_.WriteTo(ref output, _repeated_unpackedSfixed64_codec); + unpackedFloat_.WriteTo(ref output, _repeated_unpackedFloat_codec); + unpackedDouble_.WriteTo(ref output, _repeated_unpackedDouble_codec); + unpackedBool_.WriteTo(ref output, _repeated_unpackedBool_codec); + unpackedNestedEnum_.WriteTo(ref output, _repeated_unpackedNestedEnum_codec); if (HasOneofUint32) { - size += 2 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32); + output.WriteRawTag(248, 6); + output.WriteUInt32(OneofUint32); } - if (HasOneofNestedMessage) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OneofNestedMessage); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + output.WriteRawTag(130, 7); + output.WriteMessage(OneofNestedMessage); } if (HasOneofString) { - size += 2 + pb::CodedOutputStream.ComputeStringSize(OneofString); + output.WriteRawTag(138, 7); + output.WriteString(OneofString); } if (HasOneofBytes) { - size += 2 + pb::CodedOutputStream.ComputeBytesSize(OneofBytes); + output.WriteRawTag(146, 7); + output.WriteBytes(OneofBytes); } if (HasOneofBool) { - size += 2 + 1; + output.WriteRawTag(152, 7); + output.WriteBool(OneofBool); } if (HasOneofUint64) { - size += 2 + pb::CodedOutputStream.ComputeUInt64Size(OneofUint64); + output.WriteRawTag(160, 7); + output.WriteUInt64(OneofUint64); } if (HasOneofFloat) { - size += 2 + 4; + output.WriteRawTag(173, 7); + output.WriteFloat(OneofFloat); } if (HasOneofDouble) { - size += 2 + 8; + output.WriteRawTag(177, 7); + output.WriteDouble(OneofDouble); } if (HasOneofEnum) { - size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OneofEnum); + output.WriteRawTag(184, 7); + output.WriteEnum((int) OneofEnum); } if (HasData) { - size += 4 + pb::CodedOutputStream.ComputeGroupSize(Data); - } - if (HasFieldname1) { + output.WriteRawTag(203, 12); + output.WriteGroup(Data); + output.WriteRawTag(204, 12); + } + if (HasFieldname1) { + output.WriteRawTag(136, 25); + output.WriteInt32(Fieldname1); + } + if (HasFieldName2) { + output.WriteRawTag(144, 25); + output.WriteInt32(FieldName2); + } + if (HasFieldName3) { + output.WriteRawTag(152, 25); + output.WriteInt32(FieldName3); + } + if (HasFieldName4) { + output.WriteRawTag(160, 25); + output.WriteInt32(FieldName4); + } + if (HasField0Name5) { + output.WriteRawTag(168, 25); + output.WriteInt32(Field0Name5); + } + if (HasField0Name6) { + output.WriteRawTag(176, 25); + output.WriteInt32(Field0Name6); + } + if (HasFieldName7) { + output.WriteRawTag(184, 25); + output.WriteInt32(FieldName7); + } + if (HasFieldName8) { + output.WriteRawTag(192, 25); + output.WriteInt32(FieldName8); + } + if (HasFieldName9) { + output.WriteRawTag(200, 25); + output.WriteInt32(FieldName9); + } + if (HasFieldName10) { + output.WriteRawTag(208, 25); + output.WriteInt32(FieldName10); + } + if (HasFIELDNAME11) { + output.WriteRawTag(216, 25); + output.WriteInt32(FIELDNAME11); + } + if (HasFIELDName12) { + output.WriteRawTag(224, 25); + output.WriteInt32(FIELDName12); + } + if (HasFieldName13) { + output.WriteRawTag(232, 25); + output.WriteInt32(FieldName13); + } + if (HasFieldName14) { + output.WriteRawTag(240, 25); + output.WriteInt32(FieldName14); + } + if (HasFieldName15) { + output.WriteRawTag(248, 25); + output.WriteInt32(FieldName15); + } + if (HasFieldName16) { + output.WriteRawTag(128, 26); + output.WriteInt32(FieldName16); + } + if (HasFieldName17) { + output.WriteRawTag(136, 26); + output.WriteInt32(FieldName17); + } + if (HasFieldName18) { + output.WriteRawTag(144, 26); + output.WriteInt32(FieldName18); + } + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (HasOptionalInt32) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32); + } + if (HasOptionalInt64) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(OptionalInt64); + } + if (HasOptionalUint32) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(OptionalUint32); + } + if (HasOptionalUint64) { + size += 1 + pb::CodedOutputStream.ComputeUInt64Size(OptionalUint64); + } + if (HasOptionalSint32) { + size += 1 + pb::CodedOutputStream.ComputeSInt32Size(OptionalSint32); + } + if (HasOptionalSint64) { + size += 1 + pb::CodedOutputStream.ComputeSInt64Size(OptionalSint64); + } + if (HasOptionalFixed32) { + size += 1 + 4; + } + if (HasOptionalFixed64) { + size += 1 + 8; + } + if (HasOptionalSfixed32) { + size += 1 + 4; + } + if (HasOptionalSfixed64) { + size += 1 + 8; + } + if (HasOptionalFloat) { + size += 1 + 4; + } + if (HasOptionalDouble) { + size += 1 + 8; + } + if (HasOptionalBool) { + size += 1 + 1; + } + if (HasOptionalString) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalString); + } + if (HasOptionalBytes) { + size += 1 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes); + } + if (optionalNestedMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage); + } + if (optionalForeignMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage); + } + if (HasOptionalNestedEnum) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum); + } + if (HasOptionalForeignEnum) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalForeignEnum); + } + if (HasOptionalStringPiece) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalStringPiece); + } + if (HasOptionalCord) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord); + } + if (recursiveMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(RecursiveMessage); + } + size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec); + size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec); + size += repeatedUint32_.CalculateSize(_repeated_repeatedUint32_codec); + size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec); + size += repeatedSint32_.CalculateSize(_repeated_repeatedSint32_codec); + size += repeatedSint64_.CalculateSize(_repeated_repeatedSint64_codec); + size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec); + size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec); + size += repeatedSfixed32_.CalculateSize(_repeated_repeatedSfixed32_codec); + size += repeatedSfixed64_.CalculateSize(_repeated_repeatedSfixed64_codec); + size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec); + size += repeatedDouble_.CalculateSize(_repeated_repeatedDouble_codec); + size += repeatedBool_.CalculateSize(_repeated_repeatedBool_codec); + size += repeatedString_.CalculateSize(_repeated_repeatedString_codec); + size += repeatedBytes_.CalculateSize(_repeated_repeatedBytes_codec); + size += repeatedNestedMessage_.CalculateSize(_repeated_repeatedNestedMessage_codec); + size += repeatedForeignMessage_.CalculateSize(_repeated_repeatedForeignMessage_codec); + size += repeatedNestedEnum_.CalculateSize(_repeated_repeatedNestedEnum_codec); + size += repeatedForeignEnum_.CalculateSize(_repeated_repeatedForeignEnum_codec); + size += repeatedStringPiece_.CalculateSize(_repeated_repeatedStringPiece_codec); + size += repeatedCord_.CalculateSize(_repeated_repeatedCord_codec); + size += packedInt32_.CalculateSize(_repeated_packedInt32_codec); + size += packedInt64_.CalculateSize(_repeated_packedInt64_codec); + size += packedUint32_.CalculateSize(_repeated_packedUint32_codec); + size += packedUint64_.CalculateSize(_repeated_packedUint64_codec); + size += packedSint32_.CalculateSize(_repeated_packedSint32_codec); + size += packedSint64_.CalculateSize(_repeated_packedSint64_codec); + size += packedFixed32_.CalculateSize(_repeated_packedFixed32_codec); + size += packedFixed64_.CalculateSize(_repeated_packedFixed64_codec); + size += packedSfixed32_.CalculateSize(_repeated_packedSfixed32_codec); + size += packedSfixed64_.CalculateSize(_repeated_packedSfixed64_codec); + size += packedFloat_.CalculateSize(_repeated_packedFloat_codec); + size += packedDouble_.CalculateSize(_repeated_packedDouble_codec); + size += packedBool_.CalculateSize(_repeated_packedBool_codec); + size += packedNestedEnum_.CalculateSize(_repeated_packedNestedEnum_codec); + size += unpackedInt32_.CalculateSize(_repeated_unpackedInt32_codec); + size += unpackedInt64_.CalculateSize(_repeated_unpackedInt64_codec); + size += unpackedUint32_.CalculateSize(_repeated_unpackedUint32_codec); + size += unpackedUint64_.CalculateSize(_repeated_unpackedUint64_codec); + size += unpackedSint32_.CalculateSize(_repeated_unpackedSint32_codec); + size += unpackedSint64_.CalculateSize(_repeated_unpackedSint64_codec); + size += unpackedFixed32_.CalculateSize(_repeated_unpackedFixed32_codec); + size += unpackedFixed64_.CalculateSize(_repeated_unpackedFixed64_codec); + size += unpackedSfixed32_.CalculateSize(_repeated_unpackedSfixed32_codec); + size += unpackedSfixed64_.CalculateSize(_repeated_unpackedSfixed64_codec); + size += unpackedFloat_.CalculateSize(_repeated_unpackedFloat_codec); + size += unpackedDouble_.CalculateSize(_repeated_unpackedDouble_codec); + size += unpackedBool_.CalculateSize(_repeated_unpackedBool_codec); + size += unpackedNestedEnum_.CalculateSize(_repeated_unpackedNestedEnum_codec); + size += mapInt32Int32_.CalculateSize(_map_mapInt32Int32_codec); + size += mapInt64Int64_.CalculateSize(_map_mapInt64Int64_codec); + size += mapUint32Uint32_.CalculateSize(_map_mapUint32Uint32_codec); + size += mapUint64Uint64_.CalculateSize(_map_mapUint64Uint64_codec); + size += mapSint32Sint32_.CalculateSize(_map_mapSint32Sint32_codec); + size += mapSint64Sint64_.CalculateSize(_map_mapSint64Sint64_codec); + size += mapFixed32Fixed32_.CalculateSize(_map_mapFixed32Fixed32_codec); + size += mapFixed64Fixed64_.CalculateSize(_map_mapFixed64Fixed64_codec); + size += mapSfixed32Sfixed32_.CalculateSize(_map_mapSfixed32Sfixed32_codec); + size += mapSfixed64Sfixed64_.CalculateSize(_map_mapSfixed64Sfixed64_codec); + size += mapInt32Float_.CalculateSize(_map_mapInt32Float_codec); + size += mapInt32Double_.CalculateSize(_map_mapInt32Double_codec); + size += mapBoolBool_.CalculateSize(_map_mapBoolBool_codec); + size += mapStringString_.CalculateSize(_map_mapStringString_codec); + size += mapStringBytes_.CalculateSize(_map_mapStringBytes_codec); + size += mapStringNestedMessage_.CalculateSize(_map_mapStringNestedMessage_codec); + size += mapStringForeignMessage_.CalculateSize(_map_mapStringForeignMessage_codec); + size += mapStringNestedEnum_.CalculateSize(_map_mapStringNestedEnum_codec); + size += mapStringForeignEnum_.CalculateSize(_map_mapStringForeignEnum_codec); + if (HasOneofUint32) { + size += 2 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32); + } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OneofNestedMessage); + } + if (HasOneofString) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(OneofString); + } + if (HasOneofBytes) { + size += 2 + pb::CodedOutputStream.ComputeBytesSize(OneofBytes); + } + if (HasOneofBool) { + size += 2 + 1; + } + if (HasOneofUint64) { + size += 2 + pb::CodedOutputStream.ComputeUInt64Size(OneofUint64); + } + if (HasOneofFloat) { + size += 2 + 4; + } + if (HasOneofDouble) { + size += 2 + 8; + } + if (HasOneofEnum) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OneofEnum); + } + if (HasData) { + size += 4 + pb::CodedOutputStream.ComputeGroupSize(Data); + } + if (HasFieldname1) { size += 2 + pb::CodedOutputStream.ComputeInt32Size(Fieldname1); } if (HasFieldName2) { @@ -3156,14 +3403,14 @@ public enum OneofFieldOneofCase { if (other.HasOptionalBytes) { OptionalBytes = other.OptionalBytes; } - if (other.HasOptionalNestedMessage) { - if (!HasOptionalNestedMessage) { + if (other.optionalNestedMessage_ != null) { + if (optionalNestedMessage_ == null) { OptionalNestedMessage = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage(); } OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage); } - if (other.HasOptionalForeignMessage) { - if (!HasOptionalForeignMessage) { + if (other.optionalForeignMessage_ != null) { + if (optionalForeignMessage_ == null) { OptionalForeignMessage = new global::ProtobufTestMessages.Proto2.ForeignMessageProto2(); } OptionalForeignMessage.MergeFrom(other.OptionalForeignMessage); @@ -3180,8 +3427,8 @@ public enum OneofFieldOneofCase { if (other.HasOptionalCord) { OptionalCord = other.OptionalCord; } - if (other.HasRecursiveMessage) { - if (!HasRecursiveMessage) { + if (other.recursiveMessage_ != null) { + if (recursiveMessage_ == null) { RecursiveMessage = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2(); } RecursiveMessage.MergeFrom(other.RecursiveMessage); @@ -3353,6 +3600,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -3422,14 +3672,14 @@ public enum OneofFieldOneofCase { break; } case 146: { - if (!HasOptionalNestedMessage) { + if (optionalNestedMessage_ == null) { OptionalNestedMessage = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage(); } input.ReadMessage(OptionalNestedMessage); break; } case 154: { - if (!HasOptionalForeignMessage) { + if (optionalForeignMessage_ == null) { OptionalForeignMessage = new global::ProtobufTestMessages.Proto2.ForeignMessageProto2(); } input.ReadMessage(OptionalForeignMessage); @@ -3452,7 +3702,7 @@ public enum OneofFieldOneofCase { break; } case 218: { - if (!HasRecursiveMessage) { + if (recursiveMessage_ == null) { RecursiveMessage = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2(); } input.ReadMessage(RecursiveMessage); @@ -3740,37 +3990,586 @@ public enum OneofFieldOneofCase { } case 770: case 769: { - unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec); + unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec); + break; + } + case 778: + case 781: { + unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec); + break; + } + case 786: + case 785: { + unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec); + break; + } + case 794: + case 797: { + unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec); + break; + } + case 802: + case 801: { + unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec); + break; + } + case 810: + case 808: { + unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec); + break; + } + case 818: + case 816: { + unpackedNestedEnum_.AddEntriesFrom(input, _repeated_unpackedNestedEnum_codec); + break; + } + case 888: { + OneofUint32 = input.ReadUInt32(); + break; + } + case 898: { + global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage subBuilder = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + subBuilder.MergeFrom(OneofNestedMessage); + } + input.ReadMessage(subBuilder); + OneofNestedMessage = subBuilder; + break; + } + case 906: { + OneofString = input.ReadString(); + break; + } + case 914: { + OneofBytes = input.ReadBytes(); + break; + } + case 920: { + OneofBool = input.ReadBool(); + break; + } + case 928: { + OneofUint64 = input.ReadUInt64(); + break; + } + case 941: { + OneofFloat = input.ReadFloat(); + break; + } + case 945: { + OneofDouble = input.ReadDouble(); + break; + } + case 952: { + oneofField_ = input.ReadEnum(); + oneofFieldCase_ = OneofFieldOneofCase.OneofEnum; + break; + } + case 1611: { + if (!HasData) { + Data = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.Data(); + } + input.ReadGroup(Data); + break; + } + case 3208: { + Fieldname1 = input.ReadInt32(); + break; + } + case 3216: { + FieldName2 = input.ReadInt32(); + break; + } + case 3224: { + FieldName3 = input.ReadInt32(); + break; + } + case 3232: { + FieldName4 = input.ReadInt32(); + break; + } + case 3240: { + Field0Name5 = input.ReadInt32(); + break; + } + case 3248: { + Field0Name6 = input.ReadInt32(); + break; + } + case 3256: { + FieldName7 = input.ReadInt32(); + break; + } + case 3264: { + FieldName8 = input.ReadInt32(); + break; + } + case 3272: { + FieldName9 = input.ReadInt32(); + break; + } + case 3280: { + FieldName10 = input.ReadInt32(); + break; + } + case 3288: { + FIELDNAME11 = input.ReadInt32(); + break; + } + case 3296: { + FIELDName12 = input.ReadInt32(); + break; + } + case 3304: { + FieldName13 = input.ReadInt32(); + break; + } + case 3312: { + FieldName14 = input.ReadInt32(); + break; + } + case 3320: { + FieldName15 = input.ReadInt32(); + break; + } + case 3328: { + FieldName16 = input.ReadInt32(); + break; + } + case 3336: { + FieldName17 = input.ReadInt32(); + break; + } + case 3344: { + FieldName18 = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + case 8: { + OptionalInt32 = input.ReadInt32(); + break; + } + case 16: { + OptionalInt64 = input.ReadInt64(); + break; + } + case 24: { + OptionalUint32 = input.ReadUInt32(); + break; + } + case 32: { + OptionalUint64 = input.ReadUInt64(); + break; + } + case 40: { + OptionalSint32 = input.ReadSInt32(); + break; + } + case 48: { + OptionalSint64 = input.ReadSInt64(); + break; + } + case 61: { + OptionalFixed32 = input.ReadFixed32(); + break; + } + case 65: { + OptionalFixed64 = input.ReadFixed64(); + break; + } + case 77: { + OptionalSfixed32 = input.ReadSFixed32(); + break; + } + case 81: { + OptionalSfixed64 = input.ReadSFixed64(); + break; + } + case 93: { + OptionalFloat = input.ReadFloat(); + break; + } + case 97: { + OptionalDouble = input.ReadDouble(); + break; + } + case 104: { + OptionalBool = input.ReadBool(); + break; + } + case 114: { + OptionalString = input.ReadString(); + break; + } + case 122: { + OptionalBytes = input.ReadBytes(); + break; + } + case 146: { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage(); + } + input.ReadMessage(OptionalNestedMessage); + break; + } + case 154: { + if (optionalForeignMessage_ == null) { + OptionalForeignMessage = new global::ProtobufTestMessages.Proto2.ForeignMessageProto2(); + } + input.ReadMessage(OptionalForeignMessage); + break; + } + case 168: { + OptionalNestedEnum = (global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedEnum) input.ReadEnum(); + break; + } + case 176: { + OptionalForeignEnum = (global::ProtobufTestMessages.Proto2.ForeignEnumProto2) input.ReadEnum(); + break; + } + case 194: { + OptionalStringPiece = input.ReadString(); + break; + } + case 202: { + OptionalCord = input.ReadString(); + break; + } + case 218: { + if (recursiveMessage_ == null) { + RecursiveMessage = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2(); + } + input.ReadMessage(RecursiveMessage); + break; + } + case 250: + case 248: { + repeatedInt32_.AddEntriesFrom(ref input, _repeated_repeatedInt32_codec); + break; + } + case 258: + case 256: { + repeatedInt64_.AddEntriesFrom(ref input, _repeated_repeatedInt64_codec); + break; + } + case 266: + case 264: { + repeatedUint32_.AddEntriesFrom(ref input, _repeated_repeatedUint32_codec); + break; + } + case 274: + case 272: { + repeatedUint64_.AddEntriesFrom(ref input, _repeated_repeatedUint64_codec); + break; + } + case 282: + case 280: { + repeatedSint32_.AddEntriesFrom(ref input, _repeated_repeatedSint32_codec); + break; + } + case 290: + case 288: { + repeatedSint64_.AddEntriesFrom(ref input, _repeated_repeatedSint64_codec); + break; + } + case 298: + case 301: { + repeatedFixed32_.AddEntriesFrom(ref input, _repeated_repeatedFixed32_codec); + break; + } + case 306: + case 305: { + repeatedFixed64_.AddEntriesFrom(ref input, _repeated_repeatedFixed64_codec); + break; + } + case 314: + case 317: { + repeatedSfixed32_.AddEntriesFrom(ref input, _repeated_repeatedSfixed32_codec); + break; + } + case 322: + case 321: { + repeatedSfixed64_.AddEntriesFrom(ref input, _repeated_repeatedSfixed64_codec); + break; + } + case 330: + case 333: { + repeatedFloat_.AddEntriesFrom(ref input, _repeated_repeatedFloat_codec); + break; + } + case 338: + case 337: { + repeatedDouble_.AddEntriesFrom(ref input, _repeated_repeatedDouble_codec); + break; + } + case 346: + case 344: { + repeatedBool_.AddEntriesFrom(ref input, _repeated_repeatedBool_codec); + break; + } + case 354: { + repeatedString_.AddEntriesFrom(ref input, _repeated_repeatedString_codec); + break; + } + case 362: { + repeatedBytes_.AddEntriesFrom(ref input, _repeated_repeatedBytes_codec); + break; + } + case 386: { + repeatedNestedMessage_.AddEntriesFrom(ref input, _repeated_repeatedNestedMessage_codec); + break; + } + case 394: { + repeatedForeignMessage_.AddEntriesFrom(ref input, _repeated_repeatedForeignMessage_codec); + break; + } + case 410: + case 408: { + repeatedNestedEnum_.AddEntriesFrom(ref input, _repeated_repeatedNestedEnum_codec); + break; + } + case 418: + case 416: { + repeatedForeignEnum_.AddEntriesFrom(ref input, _repeated_repeatedForeignEnum_codec); + break; + } + case 434: { + repeatedStringPiece_.AddEntriesFrom(ref input, _repeated_repeatedStringPiece_codec); + break; + } + case 442: { + repeatedCord_.AddEntriesFrom(ref input, _repeated_repeatedCord_codec); + break; + } + case 450: { + mapInt32Int32_.AddEntriesFrom(ref input, _map_mapInt32Int32_codec); + break; + } + case 458: { + mapInt64Int64_.AddEntriesFrom(ref input, _map_mapInt64Int64_codec); + break; + } + case 466: { + mapUint32Uint32_.AddEntriesFrom(ref input, _map_mapUint32Uint32_codec); + break; + } + case 474: { + mapUint64Uint64_.AddEntriesFrom(ref input, _map_mapUint64Uint64_codec); + break; + } + case 482: { + mapSint32Sint32_.AddEntriesFrom(ref input, _map_mapSint32Sint32_codec); + break; + } + case 490: { + mapSint64Sint64_.AddEntriesFrom(ref input, _map_mapSint64Sint64_codec); + break; + } + case 498: { + mapFixed32Fixed32_.AddEntriesFrom(ref input, _map_mapFixed32Fixed32_codec); + break; + } + case 506: { + mapFixed64Fixed64_.AddEntriesFrom(ref input, _map_mapFixed64Fixed64_codec); + break; + } + case 514: { + mapSfixed32Sfixed32_.AddEntriesFrom(ref input, _map_mapSfixed32Sfixed32_codec); + break; + } + case 522: { + mapSfixed64Sfixed64_.AddEntriesFrom(ref input, _map_mapSfixed64Sfixed64_codec); + break; + } + case 530: { + mapInt32Float_.AddEntriesFrom(ref input, _map_mapInt32Float_codec); + break; + } + case 538: { + mapInt32Double_.AddEntriesFrom(ref input, _map_mapInt32Double_codec); + break; + } + case 546: { + mapBoolBool_.AddEntriesFrom(ref input, _map_mapBoolBool_codec); + break; + } + case 554: { + mapStringString_.AddEntriesFrom(ref input, _map_mapStringString_codec); + break; + } + case 562: { + mapStringBytes_.AddEntriesFrom(ref input, _map_mapStringBytes_codec); + break; + } + case 570: { + mapStringNestedMessage_.AddEntriesFrom(ref input, _map_mapStringNestedMessage_codec); + break; + } + case 578: { + mapStringForeignMessage_.AddEntriesFrom(ref input, _map_mapStringForeignMessage_codec); + break; + } + case 586: { + mapStringNestedEnum_.AddEntriesFrom(ref input, _map_mapStringNestedEnum_codec); + break; + } + case 594: { + mapStringForeignEnum_.AddEntriesFrom(ref input, _map_mapStringForeignEnum_codec); + break; + } + case 602: + case 600: { + packedInt32_.AddEntriesFrom(ref input, _repeated_packedInt32_codec); + break; + } + case 610: + case 608: { + packedInt64_.AddEntriesFrom(ref input, _repeated_packedInt64_codec); + break; + } + case 618: + case 616: { + packedUint32_.AddEntriesFrom(ref input, _repeated_packedUint32_codec); + break; + } + case 626: + case 624: { + packedUint64_.AddEntriesFrom(ref input, _repeated_packedUint64_codec); + break; + } + case 634: + case 632: { + packedSint32_.AddEntriesFrom(ref input, _repeated_packedSint32_codec); + break; + } + case 642: + case 640: { + packedSint64_.AddEntriesFrom(ref input, _repeated_packedSint64_codec); + break; + } + case 650: + case 653: { + packedFixed32_.AddEntriesFrom(ref input, _repeated_packedFixed32_codec); + break; + } + case 658: + case 657: { + packedFixed64_.AddEntriesFrom(ref input, _repeated_packedFixed64_codec); + break; + } + case 666: + case 669: { + packedSfixed32_.AddEntriesFrom(ref input, _repeated_packedSfixed32_codec); + break; + } + case 674: + case 673: { + packedSfixed64_.AddEntriesFrom(ref input, _repeated_packedSfixed64_codec); + break; + } + case 682: + case 685: { + packedFloat_.AddEntriesFrom(ref input, _repeated_packedFloat_codec); + break; + } + case 690: + case 689: { + packedDouble_.AddEntriesFrom(ref input, _repeated_packedDouble_codec); + break; + } + case 698: + case 696: { + packedBool_.AddEntriesFrom(ref input, _repeated_packedBool_codec); + break; + } + case 706: + case 704: { + packedNestedEnum_.AddEntriesFrom(ref input, _repeated_packedNestedEnum_codec); + break; + } + case 714: + case 712: { + unpackedInt32_.AddEntriesFrom(ref input, _repeated_unpackedInt32_codec); + break; + } + case 722: + case 720: { + unpackedInt64_.AddEntriesFrom(ref input, _repeated_unpackedInt64_codec); + break; + } + case 730: + case 728: { + unpackedUint32_.AddEntriesFrom(ref input, _repeated_unpackedUint32_codec); + break; + } + case 738: + case 736: { + unpackedUint64_.AddEntriesFrom(ref input, _repeated_unpackedUint64_codec); + break; + } + case 746: + case 744: { + unpackedSint32_.AddEntriesFrom(ref input, _repeated_unpackedSint32_codec); + break; + } + case 754: + case 752: { + unpackedSint64_.AddEntriesFrom(ref input, _repeated_unpackedSint64_codec); + break; + } + case 762: + case 765: { + unpackedFixed32_.AddEntriesFrom(ref input, _repeated_unpackedFixed32_codec); + break; + } + case 770: + case 769: { + unpackedFixed64_.AddEntriesFrom(ref input, _repeated_unpackedFixed64_codec); break; } case 778: case 781: { - unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec); + unpackedSfixed32_.AddEntriesFrom(ref input, _repeated_unpackedSfixed32_codec); break; } case 786: case 785: { - unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec); + unpackedSfixed64_.AddEntriesFrom(ref input, _repeated_unpackedSfixed64_codec); break; } case 794: case 797: { - unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec); + unpackedFloat_.AddEntriesFrom(ref input, _repeated_unpackedFloat_codec); break; } case 802: case 801: { - unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec); + unpackedDouble_.AddEntriesFrom(ref input, _repeated_unpackedDouble_codec); break; } case 810: case 808: { - unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec); + unpackedBool_.AddEntriesFrom(ref input, _repeated_unpackedBool_codec); break; } case 818: case 816: { - unpackedNestedEnum_.AddEntriesFrom(input, _repeated_unpackedNestedEnum_codec); + unpackedNestedEnum_.AddEntriesFrom(ref input, _repeated_unpackedNestedEnum_codec); break; } case 888: { @@ -3779,7 +4578,7 @@ public enum OneofFieldOneofCase { } case 898: { global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage subBuilder = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.NestedMessage(); - if (HasOneofNestedMessage) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { subBuilder.MergeFrom(OneofNestedMessage); } input.ReadMessage(subBuilder); @@ -3897,6 +4696,7 @@ public enum OneofFieldOneofCase { } } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -3934,7 +4734,11 @@ public enum NestedEnum { [pbr::OriginalName("NEG")] Neg = -1, } - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -3962,7 +4766,7 @@ public sealed partial class NestedMessage : pb::IMessage { public NestedMessage(NestedMessage other) : this() { _hasBits0 = other._hasBits0; a_ = other.a_; - corecursive_ = other.HasCorecursive ? other.corecursive_.Clone() : null; + corecursive_ = other.corecursive_ != null ? other.corecursive_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -4005,16 +4809,6 @@ public sealed partial class NestedMessage : pb::IMessage { corecursive_ = value; } } - /// Gets whether the corecursive field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasCorecursive { - get { return corecursive_ != null; } - } - /// Clears the value of the corecursive field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearCorecursive() { - corecursive_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -4038,7 +4832,7 @@ public sealed partial class NestedMessage : pb::IMessage { public override int GetHashCode() { int hash = 1; if (HasA) hash ^= A.GetHashCode(); - if (HasCorecursive) hash ^= Corecursive.GetHashCode(); + if (corecursive_ != null) hash ^= Corecursive.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -4052,18 +4846,39 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(8); output.WriteInt32(A); } - if (HasCorecursive) { + if (corecursive_ != null) { output.WriteRawTag(18); output.WriteMessage(Corecursive); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(8); + output.WriteInt32(A); + } + if (corecursive_ != null) { + output.WriteRawTag(18); + output.WriteMessage(Corecursive); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4071,7 +4886,7 @@ public sealed partial class NestedMessage : pb::IMessage { if (HasA) { size += 1 + pb::CodedOutputStream.ComputeInt32Size(A); } - if (HasCorecursive) { + if (corecursive_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Corecursive); } if (_unknownFields != null) { @@ -4088,8 +4903,8 @@ public sealed partial class NestedMessage : pb::IMessage { if (other.HasA) { A = other.A; } - if (other.HasCorecursive) { - if (!HasCorecursive) { + if (other.corecursive_ != null) { + if (corecursive_ == null) { Corecursive = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2(); } Corecursive.MergeFrom(other.Corecursive); @@ -4099,6 +4914,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4110,7 +4928,32 @@ public sealed partial class NestedMessage : pb::IMessage { break; } case 18: { - if (!HasCorecursive) { + if (corecursive_ == null) { + Corecursive = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2(); + } + input.ReadMessage(Corecursive); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + A = input.ReadInt32(); + break; + } + case 18: { + if (corecursive_ == null) { Corecursive = new global::ProtobufTestMessages.Proto2.TestAllTypesProto2(); } input.ReadMessage(Corecursive); @@ -4119,13 +4962,18 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif } /// /// groups /// - public sealed partial class Data : pb::IMessage { + public sealed partial class Data : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Data()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4246,6 +5094,9 @@ public sealed partial class Data : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasGroupInt32) { output.WriteRawTag(208, 12); output.WriteInt32(GroupInt32); @@ -4257,7 +5108,25 @@ public sealed partial class Data : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasGroupInt32) { + output.WriteRawTag(208, 12); + output.WriteInt32(GroupInt32); + } + if (HasGroupUint32) { + output.WriteRawTag(216, 12); + output.WriteUInt32(GroupUint32); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4290,6 +5159,9 @@ public sealed partial class Data : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4308,14 +5180,43 @@ public sealed partial class Data : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 1612: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 1616: { + GroupInt32 = input.ReadInt32(); + break; + } + case 1624: { + GroupUint32 = input.ReadUInt32(); + break; + } + } + } } + #endif } /// /// message_set test case. /// - public sealed partial class MessageSetCorrect : pb::IExtendableMessage { + public sealed partial class MessageSetCorrect : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageSetCorrect()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -4389,13 +5290,29 @@ public sealed partial class MessageSetCorrect : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -4456,7 +5393,11 @@ public sealed partial class MessageSetCorrect : pb::IExtendableMessage { + public sealed partial class MessageSetCorrectExtension1 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageSetCorrectExtension1()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4547,6 +5488,9 @@ public sealed partial class MessageSetCorrectExtension1 : pb::IMessageContainer for extensions for other messages declared in the MessageSetCorrectExtension1 message type. @@ -4606,7 +5586,11 @@ public static partial class Extensions { } - public sealed partial class MessageSetCorrectExtension2 : pb::IMessage { + public sealed partial class MessageSetCorrectExtension2 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageSetCorrectExtension2()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4700,6 +5684,9 @@ public sealed partial class MessageSetCorrectExtension2 : pb::IMessageContainer for extensions for other messages declared in the MessageSetCorrectExtension2 message type. @@ -4764,7 +5787,11 @@ public static partial class Extensions { } - public sealed partial class ForeignMessageProto2 : pb::IMessage { + public sealed partial class ForeignMessageProto2 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ForeignMessageProto2()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4858,6 +5885,9 @@ public sealed partial class ForeignMessageProto2 : pb::IMessage { + public sealed partial class UnknownToTestAllTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new UnknownToTestAllTypes()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4937,7 +6007,7 @@ public sealed partial class UnknownToTestAllTypes : pb::IMessageGets whether the nested_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasNestedMessage { - get { return nestedMessage_ != null; } - } - /// Clears the value of the nested_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearNestedMessage() { - nestedMessage_ = null; - } /// Field number for the "optionalgroup" field. public const int OptionalGroupFieldNumber = 1004; @@ -5099,7 +6159,7 @@ public sealed partial class UnknownToTestAllTypes : pb::IMessageContainer for nested types declared in the UnknownToTestAllTypes message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class OptionalGroup : pb::IMessage { + public sealed partial class OptionalGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OptionalGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -5339,6 +6487,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(8); output.WriteInt32(A); @@ -5346,7 +6497,21 @@ public sealed partial class OptionalGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(8); + output.WriteInt32(A); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5373,6 +6538,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5387,7 +6555,28 @@ public sealed partial class OptionalGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 8036: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + A = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs index 064d0c0acec0..6f915cb79bf9 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto3.cs @@ -29,7 +29,7 @@ public static partial class TestMessagesProto3Reflection { "dWYvYW55LnByb3RvGh5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8a", "IGdvb2dsZS9wcm90b2J1Zi9maWVsZF9tYXNrLnByb3RvGhxnb29nbGUvcHJv", "dG9idWYvc3RydWN0LnByb3RvGh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1w", - "LnByb3RvGh5nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8iv0QKElRl", + "LnByb3RvGh5nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8isUUKElRl", "c3RBbGxUeXBlc1Byb3RvMxIWCg5vcHRpb25hbF9pbnQzMhgBIAEoBRIWCg5v", "cHRpb25hbF9pbnQ2NBgCIAEoAxIXCg9vcHRpb25hbF91aW50MzIYAyABKA0S", "FwoPb3B0aW9uYWxfdWludDY0GAQgASgEEhcKD29wdGlvbmFsX3NpbnQzMhgF", @@ -140,99 +140,101 @@ public static partial class TestMessagesProto3Reflection { "IAEoBEgAEhUKC29uZW9mX2Zsb2F0GHUgASgCSAASFgoMb25lb2ZfZG91Ymxl", "GHYgASgBSAASUgoKb25lb2ZfZW51bRh3IAEoDjI8LnByb3RvYnVmX3Rlc3Rf", "bWVzc2FnZXMucHJvdG8zLlRlc3RBbGxUeXBlc1Byb3RvMy5OZXN0ZWRFbnVt", - "SAASOgoVb3B0aW9uYWxfYm9vbF93cmFwcGVyGMkBIAEoCzIaLmdvb2dsZS5w", - "cm90b2J1Zi5Cb29sVmFsdWUSPAoWb3B0aW9uYWxfaW50MzJfd3JhcHBlchjK", - "ASABKAsyGy5nb29nbGUucHJvdG9idWYuSW50MzJWYWx1ZRI8ChZvcHRpb25h", - "bF9pbnQ2NF93cmFwcGVyGMsBIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2", - "NFZhbHVlEj4KF29wdGlvbmFsX3VpbnQzMl93cmFwcGVyGMwBIAEoCzIcLmdv", - "b2dsZS5wcm90b2J1Zi5VSW50MzJWYWx1ZRI+ChdvcHRpb25hbF91aW50NjRf", - "d3JhcHBlchjNASABKAsyHC5nb29nbGUucHJvdG9idWYuVUludDY0VmFsdWUS", - "PAoWb3B0aW9uYWxfZmxvYXRfd3JhcHBlchjOASABKAsyGy5nb29nbGUucHJv", - "dG9idWYuRmxvYXRWYWx1ZRI+ChdvcHRpb25hbF9kb3VibGVfd3JhcHBlchjP", - "ASABKAsyHC5nb29nbGUucHJvdG9idWYuRG91YmxlVmFsdWUSPgoXb3B0aW9u", - "YWxfc3RyaW5nX3dyYXBwZXIY0AEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlN0", - "cmluZ1ZhbHVlEjwKFm9wdGlvbmFsX2J5dGVzX3dyYXBwZXIY0QEgASgLMhsu", - "Z29vZ2xlLnByb3RvYnVmLkJ5dGVzVmFsdWUSOgoVcmVwZWF0ZWRfYm9vbF93", - "cmFwcGVyGNMBIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5Cb29sVmFsdWUSPAoW", - "cmVwZWF0ZWRfaW50MzJfd3JhcHBlchjUASADKAsyGy5nb29nbGUucHJvdG9i", - "dWYuSW50MzJWYWx1ZRI8ChZyZXBlYXRlZF9pbnQ2NF93cmFwcGVyGNUBIAMo", - "CzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQ2NFZhbHVlEj4KF3JlcGVhdGVkX3Vp", - "bnQzMl93cmFwcGVyGNYBIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50MzJW", - "YWx1ZRI+ChdyZXBlYXRlZF91aW50NjRfd3JhcHBlchjXASADKAsyHC5nb29n", - "bGUucHJvdG9idWYuVUludDY0VmFsdWUSPAoWcmVwZWF0ZWRfZmxvYXRfd3Jh", - "cHBlchjYASADKAsyGy5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZRI+Chdy", - "ZXBlYXRlZF9kb3VibGVfd3JhcHBlchjZASADKAsyHC5nb29nbGUucHJvdG9i", - "dWYuRG91YmxlVmFsdWUSPgoXcmVwZWF0ZWRfc3RyaW5nX3dyYXBwZXIY2gEg", - "AygLMhwuZ29vZ2xlLnByb3RvYnVmLlN0cmluZ1ZhbHVlEjwKFnJlcGVhdGVk", - "X2J5dGVzX3dyYXBwZXIY2wEgAygLMhsuZ29vZ2xlLnByb3RvYnVmLkJ5dGVz", - "VmFsdWUSNQoRb3B0aW9uYWxfZHVyYXRpb24YrQIgASgLMhkuZ29vZ2xlLnBy", - "b3RvYnVmLkR1cmF0aW9uEjcKEm9wdGlvbmFsX3RpbWVzdGFtcBiuAiABKAsy", - "Gi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjgKE29wdGlvbmFsX2ZpZWxk", - "X21hc2sYrwIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFzaxIxCg9v", - "cHRpb25hbF9zdHJ1Y3QYsAIgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVj", - "dBIrCgxvcHRpb25hbF9hbnkYsQIgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFu", - "eRIvCg5vcHRpb25hbF92YWx1ZRiyAiABKAsyFi5nb29nbGUucHJvdG9idWYu", - "VmFsdWUSNQoRcmVwZWF0ZWRfZHVyYXRpb24YtwIgAygLMhkuZ29vZ2xlLnBy", - "b3RvYnVmLkR1cmF0aW9uEjcKEnJlcGVhdGVkX3RpbWVzdGFtcBi4AiADKAsy", - "Gi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjcKEnJlcGVhdGVkX2ZpZWxk", - "bWFzaxi5AiADKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrEjEKD3Jl", - "cGVhdGVkX3N0cnVjdBjEAiADKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0", - "EisKDHJlcGVhdGVkX2FueRi7AiADKAsyFC5nb29nbGUucHJvdG9idWYuQW55", - "Ei8KDnJlcGVhdGVkX3ZhbHVlGLwCIAMoCzIWLmdvb2dsZS5wcm90b2J1Zi5W", - "YWx1ZRI4ChNyZXBlYXRlZF9saXN0X3ZhbHVlGL0CIAMoCzIaLmdvb2dsZS5w", - "cm90b2J1Zi5MaXN0VmFsdWUSEwoKZmllbGRuYW1lMRiRAyABKAUSFAoLZmll", - "bGRfbmFtZTIYkgMgASgFEhUKDF9maWVsZF9uYW1lMxiTAyABKAUSFgoNZmll", - "bGRfX25hbWU0XxiUAyABKAUSFAoLZmllbGQwbmFtZTUYlQMgASgFEhYKDWZp", - "ZWxkXzBfbmFtZTYYlgMgASgFEhMKCmZpZWxkTmFtZTcYlwMgASgFEhMKCkZp", - "ZWxkTmFtZTgYmAMgASgFEhQKC2ZpZWxkX05hbWU5GJkDIAEoBRIVCgxGaWVs", - "ZF9OYW1lMTAYmgMgASgFEhUKDEZJRUxEX05BTUUxMRibAyABKAUSFQoMRklF", - "TERfbmFtZTEyGJwDIAEoBRIXCg5fX2ZpZWxkX25hbWUxMxidAyABKAUSFwoO", - "X19GaWVsZF9uYW1lMTQYngMgASgFEhYKDWZpZWxkX19uYW1lMTUYnwMgASgF", - "EhYKDWZpZWxkX19OYW1lMTYYoAMgASgFEhcKDmZpZWxkX25hbWUxN19fGKED", - "IAEoBRIXCg5GaWVsZF9uYW1lMThfXxiiAyABKAUaYgoNTmVzdGVkTWVzc2Fn", - "ZRIJCgFhGAEgASgFEkYKC2NvcmVjdXJzaXZlGAIgASgLMjEucHJvdG9idWZf", - "dGVzdF9tZXNzYWdlcy5wcm90bzMuVGVzdEFsbFR5cGVzUHJvdG8zGjQKEk1h", - "cEludDMySW50MzJFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6", - "AjgBGjQKEk1hcEludDY0SW50NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFs", - "dWUYAiABKAM6AjgBGjYKFE1hcFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgB", - "IAEoDRINCgV2YWx1ZRgCIAEoDToCOAEaNgoUTWFwVWludDY0VWludDY0RW50", - "cnkSCwoDa2V5GAEgASgEEg0KBXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50", - "MzJTaW50MzJFbnRyeRILCgNrZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgB", - "GjYKFE1hcFNpbnQ2NFNpbnQ2NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1", - "ZRgCIAEoEjoCOAEaOAoWTWFwRml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkY", - "ASABKAcSDQoFdmFsdWUYAiABKAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0", - "RW50cnkSCwoDa2V5GAEgASgGEg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBT", - "Zml4ZWQzMlNmaXhlZDMyRW50cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIg", - "ASgPOgI4ARo6ChhNYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEg", - "ASgQEg0KBXZhbHVlGAIgASgQOgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkS", - "CwoDa2V5GAEgASgFEg0KBXZhbHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRv", - "dWJsZUVudHJ5EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQ", - "TWFwQm9vbEJvb2xFbnRyeRILCgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6", - "AjgBGjYKFE1hcFN0cmluZ1N0cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2", - "YWx1ZRgCIAEoCToCOAEaNQoTTWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkY", - "ASABKAkSDQoFdmFsdWUYAiABKAw6AjgBGn4KG01hcFN0cmluZ05lc3RlZE1l", - "c3NhZ2VFbnRyeRILCgNrZXkYASABKAkSTgoFdmFsdWUYAiABKAsyPy5wcm90", - "b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvMy5UZXN0QWxsVHlwZXNQcm90bzMu", - "TmVzdGVkTWVzc2FnZToCOAEabQocTWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VF", - "bnRyeRILCgNrZXkYASABKAkSPAoFdmFsdWUYAiABKAsyLS5wcm90b2J1Zl90", - "ZXN0X21lc3NhZ2VzLnByb3RvMy5Gb3JlaWduTWVzc2FnZToCOAEaeAoYTWFw", - "U3RyaW5nTmVzdGVkRW51bUVudHJ5EgsKA2tleRgBIAEoCRJLCgV2YWx1ZRgC", - "IAEoDjI8LnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8zLlRlc3RBbGxU", - "eXBlc1Byb3RvMy5OZXN0ZWRFbnVtOgI4ARpnChlNYXBTdHJpbmdGb3JlaWdu", - "RW51bUVudHJ5EgsKA2tleRgBIAEoCRI5CgV2YWx1ZRgCIAEoDjIqLnByb3Rv", - "YnVmX3Rlc3RfbWVzc2FnZXMucHJvdG8zLkZvcmVpZ25FbnVtOgI4ASI5CgpO", - "ZXN0ZWRFbnVtEgcKA0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD/", - "//////////8BIlkKC0FsaWFzZWRFbnVtEg0KCUFMSUFTX0ZPTxAAEg0KCUFM", - "SUFTX0JBUhABEg0KCUFMSUFTX0JBWhACEgcKA1FVWBACEgcKA3F1eBACEgcK", - "A2JBehACGgIQAUINCgtvbmVvZl9maWVsZEoGCPUDEP8DIhsKDkZvcmVpZ25N", - "ZXNzYWdlEgkKAWMYASABKAUqQAoLRm9yZWlnbkVudW0SDwoLRk9SRUlHTl9G", - "T08QABIPCgtGT1JFSUdOX0JBUhABEg8KC0ZPUkVJR05fQkFaEAJCOAooY29t", - "Lmdvb2dsZS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvM0gB+AEBogIG", - "UHJvdG8zYgZwcm90bzM=")); + "SAASNgoQb25lb2ZfbnVsbF92YWx1ZRh4IAEoDjIaLmdvb2dsZS5wcm90b2J1", + "Zi5OdWxsVmFsdWVIABI6ChVvcHRpb25hbF9ib29sX3dyYXBwZXIYyQEgASgL", + "MhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRI8ChZvcHRpb25hbF9pbnQz", + "Ml93cmFwcGVyGMoBIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVl", + "EjwKFm9wdGlvbmFsX2ludDY0X3dyYXBwZXIYywEgASgLMhsuZ29vZ2xlLnBy", + "b3RvYnVmLkludDY0VmFsdWUSPgoXb3B0aW9uYWxfdWludDMyX3dyYXBwZXIY", + "zAEgASgLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlEj4KF29wdGlv", + "bmFsX3VpbnQ2NF93cmFwcGVyGM0BIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5V", + "SW50NjRWYWx1ZRI8ChZvcHRpb25hbF9mbG9hdF93cmFwcGVyGM4BIAEoCzIb", + "Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlEj4KF29wdGlvbmFsX2RvdWJs", + "ZV93cmFwcGVyGM8BIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1", + "ZRI+ChdvcHRpb25hbF9zdHJpbmdfd3JhcHBlchjQASABKAsyHC5nb29nbGUu", + "cHJvdG9idWYuU3RyaW5nVmFsdWUSPAoWb3B0aW9uYWxfYnl0ZXNfd3JhcHBl", + "chjRASABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZRI6ChVyZXBl", + "YXRlZF9ib29sX3dyYXBwZXIY0wEgAygLMhouZ29vZ2xlLnByb3RvYnVmLkJv", + "b2xWYWx1ZRI8ChZyZXBlYXRlZF9pbnQzMl93cmFwcGVyGNQBIAMoCzIbLmdv", + "b2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjwKFnJlcGVhdGVkX2ludDY0X3dy", + "YXBwZXIY1QEgAygLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSPgoX", + "cmVwZWF0ZWRfdWludDMyX3dyYXBwZXIY1gEgAygLMhwuZ29vZ2xlLnByb3Rv", + "YnVmLlVJbnQzMlZhbHVlEj4KF3JlcGVhdGVkX3VpbnQ2NF93cmFwcGVyGNcB", + "IAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZRI8ChZyZXBlYXRl", + "ZF9mbG9hdF93cmFwcGVyGNgBIAMoCzIbLmdvb2dsZS5wcm90b2J1Zi5GbG9h", + "dFZhbHVlEj4KF3JlcGVhdGVkX2RvdWJsZV93cmFwcGVyGNkBIAMoCzIcLmdv", + "b2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZRI+ChdyZXBlYXRlZF9zdHJpbmdf", + "d3JhcHBlchjaASADKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUS", + "PAoWcmVwZWF0ZWRfYnl0ZXNfd3JhcHBlchjbASADKAsyGy5nb29nbGUucHJv", + "dG9idWYuQnl0ZXNWYWx1ZRI1ChFvcHRpb25hbF9kdXJhdGlvbhitAiABKAsy", + "GS5nb29nbGUucHJvdG9idWYuRHVyYXRpb24SNwoSb3B0aW9uYWxfdGltZXN0", + "YW1wGK4CIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASOAoTb3B0", + "aW9uYWxfZmllbGRfbWFzaxivAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmll", + "bGRNYXNrEjEKD29wdGlvbmFsX3N0cnVjdBiwAiABKAsyFy5nb29nbGUucHJv", + "dG9idWYuU3RydWN0EisKDG9wdGlvbmFsX2FueRixAiABKAsyFC5nb29nbGUu", + "cHJvdG9idWYuQW55Ei8KDm9wdGlvbmFsX3ZhbHVlGLICIAEoCzIWLmdvb2ds", + "ZS5wcm90b2J1Zi5WYWx1ZRI4ChNvcHRpb25hbF9udWxsX3ZhbHVlGLMCIAEo", + "DjIaLmdvb2dsZS5wcm90b2J1Zi5OdWxsVmFsdWUSNQoRcmVwZWF0ZWRfZHVy", + "YXRpb24YtwIgAygLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uEjcKEnJl", + "cGVhdGVkX3RpbWVzdGFtcBi4AiADKAsyGi5nb29nbGUucHJvdG9idWYuVGlt", + "ZXN0YW1wEjcKEnJlcGVhdGVkX2ZpZWxkbWFzaxi5AiADKAsyGi5nb29nbGUu", + "cHJvdG9idWYuRmllbGRNYXNrEjEKD3JlcGVhdGVkX3N0cnVjdBjEAiADKAsy", + "Fy5nb29nbGUucHJvdG9idWYuU3RydWN0EisKDHJlcGVhdGVkX2FueRi7AiAD", + "KAsyFC5nb29nbGUucHJvdG9idWYuQW55Ei8KDnJlcGVhdGVkX3ZhbHVlGLwC", + "IAMoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZRI4ChNyZXBlYXRlZF9saXN0", + "X3ZhbHVlGL0CIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5MaXN0VmFsdWUSEwoK", + "ZmllbGRuYW1lMRiRAyABKAUSFAoLZmllbGRfbmFtZTIYkgMgASgFEhUKDF9m", + "aWVsZF9uYW1lMxiTAyABKAUSFgoNZmllbGRfX25hbWU0XxiUAyABKAUSFAoL", + "ZmllbGQwbmFtZTUYlQMgASgFEhYKDWZpZWxkXzBfbmFtZTYYlgMgASgFEhMK", + "CmZpZWxkTmFtZTcYlwMgASgFEhMKCkZpZWxkTmFtZTgYmAMgASgFEhQKC2Zp", + "ZWxkX05hbWU5GJkDIAEoBRIVCgxGaWVsZF9OYW1lMTAYmgMgASgFEhUKDEZJ", + "RUxEX05BTUUxMRibAyABKAUSFQoMRklFTERfbmFtZTEyGJwDIAEoBRIXCg5f", + "X2ZpZWxkX25hbWUxMxidAyABKAUSFwoOX19GaWVsZF9uYW1lMTQYngMgASgF", + "EhYKDWZpZWxkX19uYW1lMTUYnwMgASgFEhYKDWZpZWxkX19OYW1lMTYYoAMg", + "ASgFEhcKDmZpZWxkX25hbWUxN19fGKEDIAEoBRIXCg5GaWVsZF9uYW1lMThf", + "XxiiAyABKAUaYgoNTmVzdGVkTWVzc2FnZRIJCgFhGAEgASgFEkYKC2NvcmVj", + "dXJzaXZlGAIgASgLMjEucHJvdG9idWZfdGVzdF9tZXNzYWdlcy5wcm90bzMu", + "VGVzdEFsbFR5cGVzUHJvdG8zGjQKEk1hcEludDMySW50MzJFbnRyeRILCgNr", + "ZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1hcEludDY0SW50NjRF", + "bnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6AjgBGjYKFE1hcFVp", + "bnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2YWx1ZRgCIAEoDToC", + "OAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5GAEgASgEEg0KBXZh", + "bHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJFbnRyeRILCgNrZXkY", + "ASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNpbnQ2NFNpbnQ2NEVu", + "dHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoCOAEaOAoWTWFwRml4", + "ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoFdmFsdWUYAiABKAc6", + "AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoDa2V5GAEgASgGEg0K", + "BXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNmaXhlZDMyRW50cnkS", + "CwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6ChhNYXBTZml4ZWQ2", + "NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZhbHVlGAIgASgQOgI4", + "ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEgASgFEg0KBXZhbHVl", + "GAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5EgsKA2tleRgBIAEo", + "BRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJvb2xFbnRyeRILCgNr", + "ZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1hcFN0cmluZ1N0cmlu", + "Z0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaNQoTTWFw", + "U3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6", + "AjgBGn4KG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRILCgNrZXkYASAB", + "KAkSTgoFdmFsdWUYAiABKAsyPy5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnBy", + "b3RvMy5UZXN0QWxsVHlwZXNQcm90bzMuTmVzdGVkTWVzc2FnZToCOAEabQoc", + "TWFwU3RyaW5nRm9yZWlnbk1lc3NhZ2VFbnRyeRILCgNrZXkYASABKAkSPAoF", + "dmFsdWUYAiABKAsyLS5wcm90b2J1Zl90ZXN0X21lc3NhZ2VzLnByb3RvMy5G", + "b3JlaWduTWVzc2FnZToCOAEaeAoYTWFwU3RyaW5nTmVzdGVkRW51bUVudHJ5", + "EgsKA2tleRgBIAEoCRJLCgV2YWx1ZRgCIAEoDjI8LnByb3RvYnVmX3Rlc3Rf", + "bWVzc2FnZXMucHJvdG8zLlRlc3RBbGxUeXBlc1Byb3RvMy5OZXN0ZWRFbnVt", + "OgI4ARpnChlNYXBTdHJpbmdGb3JlaWduRW51bUVudHJ5EgsKA2tleRgBIAEo", + "CRI5CgV2YWx1ZRgCIAEoDjIqLnByb3RvYnVmX3Rlc3RfbWVzc2FnZXMucHJv", + "dG8zLkZvcmVpZ25FbnVtOgI4ASI5CgpOZXN0ZWRFbnVtEgcKA0ZPTxAAEgcK", + "A0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8BIlkKC0FsaWFzZWRF", + "bnVtEg0KCUFMSUFTX0ZPTxAAEg0KCUFMSUFTX0JBUhABEg0KCUFMSUFTX0JB", + "WhACEgcKA1FVWBACEgcKA3F1eBACEgcKA2JBehACGgIQAUINCgtvbmVvZl9m", + "aWVsZEoGCPUDEP8DIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUqQAoL", + "Rm9yZWlnbkVudW0SDwoLRk9SRUlHTl9GT08QABIPCgtGT1JFSUdOX0JBUhAB", + "Eg8KC0ZPUkVJR05fQkFaEAJCOAooY29tLmdvb2dsZS5wcm90b2J1Zl90ZXN0", + "X21lc3NhZ2VzLnByb3RvM0gB+AEBogIGUHJvdG8zYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::ProtobufTestMessages.Proto3.ForeignEnum), }, null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalAliasedEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedNestedEnum", "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedNestedEnum", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OneofBool", "OneofUint64", "OneofFloat", "OneofDouble", "OneofEnum", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "RepeatedListValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum), typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalAliasedEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedNestedEnum", "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedNestedEnum", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OneofBool", "OneofUint64", "OneofFloat", "OneofDouble", "OneofEnum", "OneofNullValue", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "OptionalNullValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "RepeatedListValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12", "FieldName13", "FieldName14", "FieldName15", "FieldName16", "FieldName17", "FieldName18" }, new[]{ "OneofField" }, new[]{ typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum), typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage), global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null, null), null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }), new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufTestMessages.Proto3.ForeignMessage), global::ProtobufTestMessages.Proto3.ForeignMessage.Parser, new[]{ "C" }, null, null, null, null) })); @@ -259,7 +261,11 @@ public enum ForeignEnum { /// could trigger bugs that occur in any message type in this file. We verify /// this stays true in a unit test. /// - public sealed partial class TestAllTypesProto3 : pb::IMessage { + public sealed partial class TestAllTypesProto3 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestAllTypesProto3()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -399,6 +405,7 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "oneof_null_value" field. + public const int OneofNullValueFieldNumber = 120; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Google.Protobuf.WellKnownTypes.NullValue OneofNullValue { + get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) oneofField_ : global::Google.Protobuf.WellKnownTypes.NullValue.NullValue; } + set { + oneofField_ = value; + oneofFieldCase_ = OneofFieldOneofCase.OneofNullValue; + } + } + /// Field number for the "optional_bool_wrapper" field. public const int OptionalBoolWrapperFieldNumber = 201; private static readonly pb::FieldCodec _single_optionalBoolWrapper_codec = pb::FieldCodec.ForStructWrapper(1610); @@ -1785,6 +1806,17 @@ public sealed partial class TestAllTypesProto3 : pb::IMessageField number for the "optional_null_value" field. + public const int OptionalNullValueFieldNumber = 307; + private global::Google.Protobuf.WellKnownTypes.NullValue optionalNullValue_ = global::Google.Protobuf.WellKnownTypes.NullValue.NullValue; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Google.Protobuf.WellKnownTypes.NullValue OptionalNullValue { + get { return optionalNullValue_; } + set { + optionalNullValue_ = value; + } + } + /// Field number for the "repeated_duration" field. public const int RepeatedDurationFieldNumber = 311; private static readonly pb::FieldCodec _repeated_repeatedDuration_codec @@ -2070,6 +2102,7 @@ public enum OneofFieldOneofCase { OneofFloat = 117, OneofDouble = 118, OneofEnum = 119, + OneofNullValue = 120, } private OneofFieldOneofCase oneofFieldCase_ = OneofFieldOneofCase.None; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2196,6 +2229,7 @@ public enum OneofFieldOneofCase { if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(OneofFloat, other.OneofFloat)) return false; if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(OneofDouble, other.OneofDouble)) return false; if (OneofEnum != other.OneofEnum) return false; + if (OneofNullValue != other.OneofNullValue) return false; if (OptionalBoolWrapper != other.OptionalBoolWrapper) return false; if (OptionalInt32Wrapper != other.OptionalInt32Wrapper) return false; if (OptionalInt64Wrapper != other.OptionalInt64Wrapper) return false; @@ -2220,6 +2254,7 @@ public enum OneofFieldOneofCase { if (!object.Equals(OptionalStruct, other.OptionalStruct)) return false; if (!object.Equals(OptionalAny, other.OptionalAny)) return false; if (!object.Equals(OptionalValue, other.OptionalValue)) return false; + if (OptionalNullValue != other.OptionalNullValue) return false; if(!repeatedDuration_.Equals(other.repeatedDuration_)) return false; if(!repeatedTimestamp_.Equals(other.repeatedTimestamp_)) return false; if(!repeatedFieldmask_.Equals(other.repeatedFieldmask_)) return false; @@ -2352,6 +2387,7 @@ public enum OneofFieldOneofCase { if (oneofFieldCase_ == OneofFieldOneofCase.OneofFloat) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(OneofFloat); if (oneofFieldCase_ == OneofFieldOneofCase.OneofDouble) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OneofDouble); if (oneofFieldCase_ == OneofFieldOneofCase.OneofEnum) hash ^= OneofEnum.GetHashCode(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) hash ^= OneofNullValue.GetHashCode(); if (optionalBoolWrapper_ != null) hash ^= OptionalBoolWrapper.GetHashCode(); if (optionalInt32Wrapper_ != null) hash ^= OptionalInt32Wrapper.GetHashCode(); if (optionalInt64Wrapper_ != null) hash ^= OptionalInt64Wrapper.GetHashCode(); @@ -2376,6 +2412,7 @@ public enum OneofFieldOneofCase { if (optionalStruct_ != null) hash ^= OptionalStruct.GetHashCode(); if (optionalAny_ != null) hash ^= OptionalAny.GetHashCode(); if (optionalValue_ != null) hash ^= OptionalValue.GetHashCode(); + if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) hash ^= OptionalNullValue.GetHashCode(); hash ^= repeatedDuration_.GetHashCode(); hash ^= repeatedTimestamp_.GetHashCode(); hash ^= repeatedFieldmask_.GetHashCode(); @@ -2415,6 +2452,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (OptionalInt32 != 0) { output.WriteRawTag(8); output.WriteInt32(OptionalInt32); @@ -2611,6 +2651,10 @@ public enum OneofFieldOneofCase { output.WriteRawTag(184, 7); output.WriteEnum((int) OneofEnum); } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) { + output.WriteRawTag(192, 7); + output.WriteEnum((int) OneofNullValue); + } if (optionalBoolWrapper_ != null) { _single_optionalBoolWrapper_codec.WriteTagAndValue(output, OptionalBoolWrapper); } @@ -2671,6 +2715,10 @@ public enum OneofFieldOneofCase { output.WriteRawTag(146, 19); output.WriteMessage(OptionalValue); } + if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + output.WriteRawTag(152, 19); + output.WriteEnum((int) OptionalNullValue); + } repeatedDuration_.WriteTo(output, _repeated_repeatedDuration_codec); repeatedTimestamp_.WriteTo(output, _repeated_repeatedTimestamp_codec); repeatedFieldmask_.WriteTo(output, _repeated_repeatedFieldmask_codec); @@ -2753,641 +2801,1731 @@ public enum OneofFieldOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public int CalculateSize() { - int size = 0; + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { if (OptionalInt32 != 0) { - size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32); + output.WriteRawTag(8); + output.WriteInt32(OptionalInt32); } if (OptionalInt64 != 0L) { - size += 1 + pb::CodedOutputStream.ComputeInt64Size(OptionalInt64); + output.WriteRawTag(16); + output.WriteInt64(OptionalInt64); } if (OptionalUint32 != 0) { - size += 1 + pb::CodedOutputStream.ComputeUInt32Size(OptionalUint32); + output.WriteRawTag(24); + output.WriteUInt32(OptionalUint32); } if (OptionalUint64 != 0UL) { - size += 1 + pb::CodedOutputStream.ComputeUInt64Size(OptionalUint64); + output.WriteRawTag(32); + output.WriteUInt64(OptionalUint64); } if (OptionalSint32 != 0) { - size += 1 + pb::CodedOutputStream.ComputeSInt32Size(OptionalSint32); + output.WriteRawTag(40); + output.WriteSInt32(OptionalSint32); } if (OptionalSint64 != 0L) { - size += 1 + pb::CodedOutputStream.ComputeSInt64Size(OptionalSint64); + output.WriteRawTag(48); + output.WriteSInt64(OptionalSint64); } if (OptionalFixed32 != 0) { - size += 1 + 4; + output.WriteRawTag(61); + output.WriteFixed32(OptionalFixed32); } if (OptionalFixed64 != 0UL) { - size += 1 + 8; + output.WriteRawTag(65); + output.WriteFixed64(OptionalFixed64); } if (OptionalSfixed32 != 0) { - size += 1 + 4; + output.WriteRawTag(77); + output.WriteSFixed32(OptionalSfixed32); } if (OptionalSfixed64 != 0L) { - size += 1 + 8; + output.WriteRawTag(81); + output.WriteSFixed64(OptionalSfixed64); } if (OptionalFloat != 0F) { - size += 1 + 4; + output.WriteRawTag(93); + output.WriteFloat(OptionalFloat); } if (OptionalDouble != 0D) { - size += 1 + 8; + output.WriteRawTag(97); + output.WriteDouble(OptionalDouble); } if (OptionalBool != false) { - size += 1 + 1; + output.WriteRawTag(104); + output.WriteBool(OptionalBool); } if (OptionalString.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalString); + output.WriteRawTag(114); + output.WriteString(OptionalString); } if (OptionalBytes.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes); + output.WriteRawTag(122); + output.WriteBytes(OptionalBytes); } if (optionalNestedMessage_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage); + output.WriteRawTag(146, 1); + output.WriteMessage(OptionalNestedMessage); } if (optionalForeignMessage_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage); + output.WriteRawTag(154, 1); + output.WriteMessage(OptionalForeignMessage); } if (OptionalNestedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum.Foo) { - size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum); + output.WriteRawTag(168, 1); + output.WriteEnum((int) OptionalNestedEnum); } if (OptionalForeignEnum != global::ProtobufTestMessages.Proto3.ForeignEnum.ForeignFoo) { - size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalForeignEnum); + output.WriteRawTag(176, 1); + output.WriteEnum((int) OptionalForeignEnum); } if (OptionalAliasedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum.AliasFoo) { - size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalAliasedEnum); + output.WriteRawTag(184, 1); + output.WriteEnum((int) OptionalAliasedEnum); } if (OptionalStringPiece.Length != 0) { - size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalStringPiece); + output.WriteRawTag(194, 1); + output.WriteString(OptionalStringPiece); } if (OptionalCord.Length != 0) { - size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord); + output.WriteRawTag(202, 1); + output.WriteString(OptionalCord); } if (recursiveMessage_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(RecursiveMessage); + output.WriteRawTag(218, 1); + output.WriteMessage(RecursiveMessage); } - size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec); - size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec); - size += repeatedUint32_.CalculateSize(_repeated_repeatedUint32_codec); - size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec); - size += repeatedSint32_.CalculateSize(_repeated_repeatedSint32_codec); - size += repeatedSint64_.CalculateSize(_repeated_repeatedSint64_codec); - size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec); - size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec); - size += repeatedSfixed32_.CalculateSize(_repeated_repeatedSfixed32_codec); - size += repeatedSfixed64_.CalculateSize(_repeated_repeatedSfixed64_codec); - size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec); - size += repeatedDouble_.CalculateSize(_repeated_repeatedDouble_codec); - size += repeatedBool_.CalculateSize(_repeated_repeatedBool_codec); - size += repeatedString_.CalculateSize(_repeated_repeatedString_codec); - size += repeatedBytes_.CalculateSize(_repeated_repeatedBytes_codec); - size += repeatedNestedMessage_.CalculateSize(_repeated_repeatedNestedMessage_codec); - size += repeatedForeignMessage_.CalculateSize(_repeated_repeatedForeignMessage_codec); - size += repeatedNestedEnum_.CalculateSize(_repeated_repeatedNestedEnum_codec); - size += repeatedForeignEnum_.CalculateSize(_repeated_repeatedForeignEnum_codec); - size += repeatedStringPiece_.CalculateSize(_repeated_repeatedStringPiece_codec); - size += repeatedCord_.CalculateSize(_repeated_repeatedCord_codec); - size += packedInt32_.CalculateSize(_repeated_packedInt32_codec); - size += packedInt64_.CalculateSize(_repeated_packedInt64_codec); - size += packedUint32_.CalculateSize(_repeated_packedUint32_codec); - size += packedUint64_.CalculateSize(_repeated_packedUint64_codec); - size += packedSint32_.CalculateSize(_repeated_packedSint32_codec); - size += packedSint64_.CalculateSize(_repeated_packedSint64_codec); - size += packedFixed32_.CalculateSize(_repeated_packedFixed32_codec); - size += packedFixed64_.CalculateSize(_repeated_packedFixed64_codec); - size += packedSfixed32_.CalculateSize(_repeated_packedSfixed32_codec); - size += packedSfixed64_.CalculateSize(_repeated_packedSfixed64_codec); - size += packedFloat_.CalculateSize(_repeated_packedFloat_codec); - size += packedDouble_.CalculateSize(_repeated_packedDouble_codec); - size += packedBool_.CalculateSize(_repeated_packedBool_codec); - size += packedNestedEnum_.CalculateSize(_repeated_packedNestedEnum_codec); - size += unpackedInt32_.CalculateSize(_repeated_unpackedInt32_codec); - size += unpackedInt64_.CalculateSize(_repeated_unpackedInt64_codec); - size += unpackedUint32_.CalculateSize(_repeated_unpackedUint32_codec); - size += unpackedUint64_.CalculateSize(_repeated_unpackedUint64_codec); - size += unpackedSint32_.CalculateSize(_repeated_unpackedSint32_codec); - size += unpackedSint64_.CalculateSize(_repeated_unpackedSint64_codec); - size += unpackedFixed32_.CalculateSize(_repeated_unpackedFixed32_codec); - size += unpackedFixed64_.CalculateSize(_repeated_unpackedFixed64_codec); - size += unpackedSfixed32_.CalculateSize(_repeated_unpackedSfixed32_codec); - size += unpackedSfixed64_.CalculateSize(_repeated_unpackedSfixed64_codec); - size += unpackedFloat_.CalculateSize(_repeated_unpackedFloat_codec); - size += unpackedDouble_.CalculateSize(_repeated_unpackedDouble_codec); - size += unpackedBool_.CalculateSize(_repeated_unpackedBool_codec); - size += unpackedNestedEnum_.CalculateSize(_repeated_unpackedNestedEnum_codec); - size += mapInt32Int32_.CalculateSize(_map_mapInt32Int32_codec); - size += mapInt64Int64_.CalculateSize(_map_mapInt64Int64_codec); - size += mapUint32Uint32_.CalculateSize(_map_mapUint32Uint32_codec); - size += mapUint64Uint64_.CalculateSize(_map_mapUint64Uint64_codec); - size += mapSint32Sint32_.CalculateSize(_map_mapSint32Sint32_codec); - size += mapSint64Sint64_.CalculateSize(_map_mapSint64Sint64_codec); - size += mapFixed32Fixed32_.CalculateSize(_map_mapFixed32Fixed32_codec); - size += mapFixed64Fixed64_.CalculateSize(_map_mapFixed64Fixed64_codec); - size += mapSfixed32Sfixed32_.CalculateSize(_map_mapSfixed32Sfixed32_codec); - size += mapSfixed64Sfixed64_.CalculateSize(_map_mapSfixed64Sfixed64_codec); - size += mapInt32Float_.CalculateSize(_map_mapInt32Float_codec); - size += mapInt32Double_.CalculateSize(_map_mapInt32Double_codec); - size += mapBoolBool_.CalculateSize(_map_mapBoolBool_codec); - size += mapStringString_.CalculateSize(_map_mapStringString_codec); - size += mapStringBytes_.CalculateSize(_map_mapStringBytes_codec); - size += mapStringNestedMessage_.CalculateSize(_map_mapStringNestedMessage_codec); - size += mapStringForeignMessage_.CalculateSize(_map_mapStringForeignMessage_codec); - size += mapStringNestedEnum_.CalculateSize(_map_mapStringNestedEnum_codec); - size += mapStringForeignEnum_.CalculateSize(_map_mapStringForeignEnum_codec); + repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec); + repeatedInt64_.WriteTo(ref output, _repeated_repeatedInt64_codec); + repeatedUint32_.WriteTo(ref output, _repeated_repeatedUint32_codec); + repeatedUint64_.WriteTo(ref output, _repeated_repeatedUint64_codec); + repeatedSint32_.WriteTo(ref output, _repeated_repeatedSint32_codec); + repeatedSint64_.WriteTo(ref output, _repeated_repeatedSint64_codec); + repeatedFixed32_.WriteTo(ref output, _repeated_repeatedFixed32_codec); + repeatedFixed64_.WriteTo(ref output, _repeated_repeatedFixed64_codec); + repeatedSfixed32_.WriteTo(ref output, _repeated_repeatedSfixed32_codec); + repeatedSfixed64_.WriteTo(ref output, _repeated_repeatedSfixed64_codec); + repeatedFloat_.WriteTo(ref output, _repeated_repeatedFloat_codec); + repeatedDouble_.WriteTo(ref output, _repeated_repeatedDouble_codec); + repeatedBool_.WriteTo(ref output, _repeated_repeatedBool_codec); + repeatedString_.WriteTo(ref output, _repeated_repeatedString_codec); + repeatedBytes_.WriteTo(ref output, _repeated_repeatedBytes_codec); + repeatedNestedMessage_.WriteTo(ref output, _repeated_repeatedNestedMessage_codec); + repeatedForeignMessage_.WriteTo(ref output, _repeated_repeatedForeignMessage_codec); + repeatedNestedEnum_.WriteTo(ref output, _repeated_repeatedNestedEnum_codec); + repeatedForeignEnum_.WriteTo(ref output, _repeated_repeatedForeignEnum_codec); + repeatedStringPiece_.WriteTo(ref output, _repeated_repeatedStringPiece_codec); + repeatedCord_.WriteTo(ref output, _repeated_repeatedCord_codec); + mapInt32Int32_.WriteTo(ref output, _map_mapInt32Int32_codec); + mapInt64Int64_.WriteTo(ref output, _map_mapInt64Int64_codec); + mapUint32Uint32_.WriteTo(ref output, _map_mapUint32Uint32_codec); + mapUint64Uint64_.WriteTo(ref output, _map_mapUint64Uint64_codec); + mapSint32Sint32_.WriteTo(ref output, _map_mapSint32Sint32_codec); + mapSint64Sint64_.WriteTo(ref output, _map_mapSint64Sint64_codec); + mapFixed32Fixed32_.WriteTo(ref output, _map_mapFixed32Fixed32_codec); + mapFixed64Fixed64_.WriteTo(ref output, _map_mapFixed64Fixed64_codec); + mapSfixed32Sfixed32_.WriteTo(ref output, _map_mapSfixed32Sfixed32_codec); + mapSfixed64Sfixed64_.WriteTo(ref output, _map_mapSfixed64Sfixed64_codec); + mapInt32Float_.WriteTo(ref output, _map_mapInt32Float_codec); + mapInt32Double_.WriteTo(ref output, _map_mapInt32Double_codec); + mapBoolBool_.WriteTo(ref output, _map_mapBoolBool_codec); + mapStringString_.WriteTo(ref output, _map_mapStringString_codec); + mapStringBytes_.WriteTo(ref output, _map_mapStringBytes_codec); + mapStringNestedMessage_.WriteTo(ref output, _map_mapStringNestedMessage_codec); + mapStringForeignMessage_.WriteTo(ref output, _map_mapStringForeignMessage_codec); + mapStringNestedEnum_.WriteTo(ref output, _map_mapStringNestedEnum_codec); + mapStringForeignEnum_.WriteTo(ref output, _map_mapStringForeignEnum_codec); + packedInt32_.WriteTo(ref output, _repeated_packedInt32_codec); + packedInt64_.WriteTo(ref output, _repeated_packedInt64_codec); + packedUint32_.WriteTo(ref output, _repeated_packedUint32_codec); + packedUint64_.WriteTo(ref output, _repeated_packedUint64_codec); + packedSint32_.WriteTo(ref output, _repeated_packedSint32_codec); + packedSint64_.WriteTo(ref output, _repeated_packedSint64_codec); + packedFixed32_.WriteTo(ref output, _repeated_packedFixed32_codec); + packedFixed64_.WriteTo(ref output, _repeated_packedFixed64_codec); + packedSfixed32_.WriteTo(ref output, _repeated_packedSfixed32_codec); + packedSfixed64_.WriteTo(ref output, _repeated_packedSfixed64_codec); + packedFloat_.WriteTo(ref output, _repeated_packedFloat_codec); + packedDouble_.WriteTo(ref output, _repeated_packedDouble_codec); + packedBool_.WriteTo(ref output, _repeated_packedBool_codec); + packedNestedEnum_.WriteTo(ref output, _repeated_packedNestedEnum_codec); + unpackedInt32_.WriteTo(ref output, _repeated_unpackedInt32_codec); + unpackedInt64_.WriteTo(ref output, _repeated_unpackedInt64_codec); + unpackedUint32_.WriteTo(ref output, _repeated_unpackedUint32_codec); + unpackedUint64_.WriteTo(ref output, _repeated_unpackedUint64_codec); + unpackedSint32_.WriteTo(ref output, _repeated_unpackedSint32_codec); + unpackedSint64_.WriteTo(ref output, _repeated_unpackedSint64_codec); + unpackedFixed32_.WriteTo(ref output, _repeated_unpackedFixed32_codec); + unpackedFixed64_.WriteTo(ref output, _repeated_unpackedFixed64_codec); + unpackedSfixed32_.WriteTo(ref output, _repeated_unpackedSfixed32_codec); + unpackedSfixed64_.WriteTo(ref output, _repeated_unpackedSfixed64_codec); + unpackedFloat_.WriteTo(ref output, _repeated_unpackedFloat_codec); + unpackedDouble_.WriteTo(ref output, _repeated_unpackedDouble_codec); + unpackedBool_.WriteTo(ref output, _repeated_unpackedBool_codec); + unpackedNestedEnum_.WriteTo(ref output, _repeated_unpackedNestedEnum_codec); if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) { - size += 2 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32); + output.WriteRawTag(248, 6); + output.WriteUInt32(OneofUint32); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OneofNestedMessage); + output.WriteRawTag(130, 7); + output.WriteMessage(OneofNestedMessage); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) { - size += 2 + pb::CodedOutputStream.ComputeStringSize(OneofString); + output.WriteRawTag(138, 7); + output.WriteString(OneofString); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) { - size += 2 + pb::CodedOutputStream.ComputeBytesSize(OneofBytes); + output.WriteRawTag(146, 7); + output.WriteBytes(OneofBytes); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofBool) { - size += 2 + 1; + output.WriteRawTag(152, 7); + output.WriteBool(OneofBool); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint64) { - size += 2 + pb::CodedOutputStream.ComputeUInt64Size(OneofUint64); + output.WriteRawTag(160, 7); + output.WriteUInt64(OneofUint64); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofFloat) { - size += 2 + 4; + output.WriteRawTag(173, 7); + output.WriteFloat(OneofFloat); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofDouble) { - size += 2 + 8; + output.WriteRawTag(177, 7); + output.WriteDouble(OneofDouble); } if (oneofFieldCase_ == OneofFieldOneofCase.OneofEnum) { - size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OneofEnum); + output.WriteRawTag(184, 7); + output.WriteEnum((int) OneofEnum); + } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) { + output.WriteRawTag(192, 7); + output.WriteEnum((int) OneofNullValue); } if (optionalBoolWrapper_ != null) { - size += _single_optionalBoolWrapper_codec.CalculateSizeWithTag(OptionalBoolWrapper); + _single_optionalBoolWrapper_codec.WriteTagAndValue(ref output, OptionalBoolWrapper); } if (optionalInt32Wrapper_ != null) { - size += _single_optionalInt32Wrapper_codec.CalculateSizeWithTag(OptionalInt32Wrapper); + _single_optionalInt32Wrapper_codec.WriteTagAndValue(ref output, OptionalInt32Wrapper); } if (optionalInt64Wrapper_ != null) { - size += _single_optionalInt64Wrapper_codec.CalculateSizeWithTag(OptionalInt64Wrapper); + _single_optionalInt64Wrapper_codec.WriteTagAndValue(ref output, OptionalInt64Wrapper); } if (optionalUint32Wrapper_ != null) { - size += _single_optionalUint32Wrapper_codec.CalculateSizeWithTag(OptionalUint32Wrapper); + _single_optionalUint32Wrapper_codec.WriteTagAndValue(ref output, OptionalUint32Wrapper); } if (optionalUint64Wrapper_ != null) { - size += _single_optionalUint64Wrapper_codec.CalculateSizeWithTag(OptionalUint64Wrapper); + _single_optionalUint64Wrapper_codec.WriteTagAndValue(ref output, OptionalUint64Wrapper); } if (optionalFloatWrapper_ != null) { - size += _single_optionalFloatWrapper_codec.CalculateSizeWithTag(OptionalFloatWrapper); + _single_optionalFloatWrapper_codec.WriteTagAndValue(ref output, OptionalFloatWrapper); } if (optionalDoubleWrapper_ != null) { - size += _single_optionalDoubleWrapper_codec.CalculateSizeWithTag(OptionalDoubleWrapper); + _single_optionalDoubleWrapper_codec.WriteTagAndValue(ref output, OptionalDoubleWrapper); } if (optionalStringWrapper_ != null) { - size += _single_optionalStringWrapper_codec.CalculateSizeWithTag(OptionalStringWrapper); + _single_optionalStringWrapper_codec.WriteTagAndValue(ref output, OptionalStringWrapper); } if (optionalBytesWrapper_ != null) { - size += _single_optionalBytesWrapper_codec.CalculateSizeWithTag(OptionalBytesWrapper); - } - size += repeatedBoolWrapper_.CalculateSize(_repeated_repeatedBoolWrapper_codec); - size += repeatedInt32Wrapper_.CalculateSize(_repeated_repeatedInt32Wrapper_codec); - size += repeatedInt64Wrapper_.CalculateSize(_repeated_repeatedInt64Wrapper_codec); - size += repeatedUint32Wrapper_.CalculateSize(_repeated_repeatedUint32Wrapper_codec); - size += repeatedUint64Wrapper_.CalculateSize(_repeated_repeatedUint64Wrapper_codec); - size += repeatedFloatWrapper_.CalculateSize(_repeated_repeatedFloatWrapper_codec); - size += repeatedDoubleWrapper_.CalculateSize(_repeated_repeatedDoubleWrapper_codec); - size += repeatedStringWrapper_.CalculateSize(_repeated_repeatedStringWrapper_codec); - size += repeatedBytesWrapper_.CalculateSize(_repeated_repeatedBytesWrapper_codec); + _single_optionalBytesWrapper_codec.WriteTagAndValue(ref output, OptionalBytesWrapper); + } + repeatedBoolWrapper_.WriteTo(ref output, _repeated_repeatedBoolWrapper_codec); + repeatedInt32Wrapper_.WriteTo(ref output, _repeated_repeatedInt32Wrapper_codec); + repeatedInt64Wrapper_.WriteTo(ref output, _repeated_repeatedInt64Wrapper_codec); + repeatedUint32Wrapper_.WriteTo(ref output, _repeated_repeatedUint32Wrapper_codec); + repeatedUint64Wrapper_.WriteTo(ref output, _repeated_repeatedUint64Wrapper_codec); + repeatedFloatWrapper_.WriteTo(ref output, _repeated_repeatedFloatWrapper_codec); + repeatedDoubleWrapper_.WriteTo(ref output, _repeated_repeatedDoubleWrapper_codec); + repeatedStringWrapper_.WriteTo(ref output, _repeated_repeatedStringWrapper_codec); + repeatedBytesWrapper_.WriteTo(ref output, _repeated_repeatedBytesWrapper_codec); if (optionalDuration_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalDuration); + output.WriteRawTag(234, 18); + output.WriteMessage(OptionalDuration); } if (optionalTimestamp_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalTimestamp); + output.WriteRawTag(242, 18); + output.WriteMessage(OptionalTimestamp); } if (optionalFieldMask_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalFieldMask); + output.WriteRawTag(250, 18); + output.WriteMessage(OptionalFieldMask); } if (optionalStruct_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalStruct); + output.WriteRawTag(130, 19); + output.WriteMessage(OptionalStruct); } if (optionalAny_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalAny); + output.WriteRawTag(138, 19); + output.WriteMessage(OptionalAny); } if (optionalValue_ != null) { - size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalValue); + output.WriteRawTag(146, 19); + output.WriteMessage(OptionalValue); } - size += repeatedDuration_.CalculateSize(_repeated_repeatedDuration_codec); - size += repeatedTimestamp_.CalculateSize(_repeated_repeatedTimestamp_codec); - size += repeatedFieldmask_.CalculateSize(_repeated_repeatedFieldmask_codec); - size += repeatedStruct_.CalculateSize(_repeated_repeatedStruct_codec); - size += repeatedAny_.CalculateSize(_repeated_repeatedAny_codec); - size += repeatedValue_.CalculateSize(_repeated_repeatedValue_codec); - size += repeatedListValue_.CalculateSize(_repeated_repeatedListValue_codec); + if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + output.WriteRawTag(152, 19); + output.WriteEnum((int) OptionalNullValue); + } + repeatedDuration_.WriteTo(ref output, _repeated_repeatedDuration_codec); + repeatedTimestamp_.WriteTo(ref output, _repeated_repeatedTimestamp_codec); + repeatedFieldmask_.WriteTo(ref output, _repeated_repeatedFieldmask_codec); + repeatedAny_.WriteTo(ref output, _repeated_repeatedAny_codec); + repeatedValue_.WriteTo(ref output, _repeated_repeatedValue_codec); + repeatedListValue_.WriteTo(ref output, _repeated_repeatedListValue_codec); + repeatedStruct_.WriteTo(ref output, _repeated_repeatedStruct_codec); if (Fieldname1 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(Fieldname1); + output.WriteRawTag(136, 25); + output.WriteInt32(Fieldname1); } if (FieldName2 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName2); + output.WriteRawTag(144, 25); + output.WriteInt32(FieldName2); } if (FieldName3 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName3); + output.WriteRawTag(152, 25); + output.WriteInt32(FieldName3); } if (FieldName4 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName4); + output.WriteRawTag(160, 25); + output.WriteInt32(FieldName4); } if (Field0Name5 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name5); + output.WriteRawTag(168, 25); + output.WriteInt32(Field0Name5); } if (Field0Name6 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name6); + output.WriteRawTag(176, 25); + output.WriteInt32(Field0Name6); } if (FieldName7 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName7); + output.WriteRawTag(184, 25); + output.WriteInt32(FieldName7); } if (FieldName8 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName8); + output.WriteRawTag(192, 25); + output.WriteInt32(FieldName8); } if (FieldName9 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName9); + output.WriteRawTag(200, 25); + output.WriteInt32(FieldName9); } if (FieldName10 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName10); - } + output.WriteRawTag(208, 25); + output.WriteInt32(FieldName10); + } if (FIELDNAME11 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDNAME11); + output.WriteRawTag(216, 25); + output.WriteInt32(FIELDNAME11); } if (FIELDName12 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDName12); + output.WriteRawTag(224, 25); + output.WriteInt32(FIELDName12); } if (FieldName13 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName13); + output.WriteRawTag(232, 25); + output.WriteInt32(FieldName13); } if (FieldName14 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName14); + output.WriteRawTag(240, 25); + output.WriteInt32(FieldName14); } if (FieldName15 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName15); + output.WriteRawTag(248, 25); + output.WriteInt32(FieldName15); } if (FieldName16 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName16); + output.WriteRawTag(128, 26); + output.WriteInt32(FieldName16); } if (FieldName17 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName17); + output.WriteRawTag(136, 26); + output.WriteInt32(FieldName17); } if (FieldName18 != 0) { - size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName18); + output.WriteRawTag(144, 26); + output.WriteInt32(FieldName18); } if (_unknownFields != null) { - size += _unknownFields.CalculateSize(); + _unknownFields.WriteTo(ref output); } - return size; } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(TestAllTypesProto3 other) { - if (other == null) { - return; + public int CalculateSize() { + int size = 0; + if (OptionalInt32 != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32); } - if (other.OptionalInt32 != 0) { - OptionalInt32 = other.OptionalInt32; + if (OptionalInt64 != 0L) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(OptionalInt64); } - if (other.OptionalInt64 != 0L) { - OptionalInt64 = other.OptionalInt64; + if (OptionalUint32 != 0) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(OptionalUint32); } - if (other.OptionalUint32 != 0) { - OptionalUint32 = other.OptionalUint32; + if (OptionalUint64 != 0UL) { + size += 1 + pb::CodedOutputStream.ComputeUInt64Size(OptionalUint64); } - if (other.OptionalUint64 != 0UL) { - OptionalUint64 = other.OptionalUint64; + if (OptionalSint32 != 0) { + size += 1 + pb::CodedOutputStream.ComputeSInt32Size(OptionalSint32); } - if (other.OptionalSint32 != 0) { - OptionalSint32 = other.OptionalSint32; + if (OptionalSint64 != 0L) { + size += 1 + pb::CodedOutputStream.ComputeSInt64Size(OptionalSint64); } - if (other.OptionalSint64 != 0L) { - OptionalSint64 = other.OptionalSint64; + if (OptionalFixed32 != 0) { + size += 1 + 4; } - if (other.OptionalFixed32 != 0) { - OptionalFixed32 = other.OptionalFixed32; + if (OptionalFixed64 != 0UL) { + size += 1 + 8; } - if (other.OptionalFixed64 != 0UL) { - OptionalFixed64 = other.OptionalFixed64; + if (OptionalSfixed32 != 0) { + size += 1 + 4; } - if (other.OptionalSfixed32 != 0) { - OptionalSfixed32 = other.OptionalSfixed32; + if (OptionalSfixed64 != 0L) { + size += 1 + 8; } - if (other.OptionalSfixed64 != 0L) { - OptionalSfixed64 = other.OptionalSfixed64; + if (OptionalFloat != 0F) { + size += 1 + 4; } - if (other.OptionalFloat != 0F) { - OptionalFloat = other.OptionalFloat; + if (OptionalDouble != 0D) { + size += 1 + 8; } - if (other.OptionalDouble != 0D) { - OptionalDouble = other.OptionalDouble; + if (OptionalBool != false) { + size += 1 + 1; } - if (other.OptionalBool != false) { - OptionalBool = other.OptionalBool; + if (OptionalString.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalString); } - if (other.OptionalString.Length != 0) { - OptionalString = other.OptionalString; + if (OptionalBytes.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes); } - if (other.OptionalBytes.Length != 0) { - OptionalBytes = other.OptionalBytes; + if (optionalNestedMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage); } - if (other.optionalNestedMessage_ != null) { - if (optionalNestedMessage_ == null) { - OptionalNestedMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage(); - } - OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage); + if (optionalForeignMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage); } - if (other.optionalForeignMessage_ != null) { - if (optionalForeignMessage_ == null) { - OptionalForeignMessage = new global::ProtobufTestMessages.Proto3.ForeignMessage(); - } - OptionalForeignMessage.MergeFrom(other.OptionalForeignMessage); + if (OptionalNestedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum.Foo) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum); } - if (other.OptionalNestedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum.Foo) { - OptionalNestedEnum = other.OptionalNestedEnum; + if (OptionalForeignEnum != global::ProtobufTestMessages.Proto3.ForeignEnum.ForeignFoo) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalForeignEnum); } - if (other.OptionalForeignEnum != global::ProtobufTestMessages.Proto3.ForeignEnum.ForeignFoo) { - OptionalForeignEnum = other.OptionalForeignEnum; + if (OptionalAliasedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum.AliasFoo) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalAliasedEnum); } - if (other.OptionalAliasedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum.AliasFoo) { - OptionalAliasedEnum = other.OptionalAliasedEnum; + if (OptionalStringPiece.Length != 0) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalStringPiece); } - if (other.OptionalStringPiece.Length != 0) { - OptionalStringPiece = other.OptionalStringPiece; + if (OptionalCord.Length != 0) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord); } - if (other.OptionalCord.Length != 0) { - OptionalCord = other.OptionalCord; + if (recursiveMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(RecursiveMessage); } - if (other.recursiveMessage_ != null) { - if (recursiveMessage_ == null) { - RecursiveMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3(); - } - RecursiveMessage.MergeFrom(other.RecursiveMessage); + size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec); + size += repeatedInt64_.CalculateSize(_repeated_repeatedInt64_codec); + size += repeatedUint32_.CalculateSize(_repeated_repeatedUint32_codec); + size += repeatedUint64_.CalculateSize(_repeated_repeatedUint64_codec); + size += repeatedSint32_.CalculateSize(_repeated_repeatedSint32_codec); + size += repeatedSint64_.CalculateSize(_repeated_repeatedSint64_codec); + size += repeatedFixed32_.CalculateSize(_repeated_repeatedFixed32_codec); + size += repeatedFixed64_.CalculateSize(_repeated_repeatedFixed64_codec); + size += repeatedSfixed32_.CalculateSize(_repeated_repeatedSfixed32_codec); + size += repeatedSfixed64_.CalculateSize(_repeated_repeatedSfixed64_codec); + size += repeatedFloat_.CalculateSize(_repeated_repeatedFloat_codec); + size += repeatedDouble_.CalculateSize(_repeated_repeatedDouble_codec); + size += repeatedBool_.CalculateSize(_repeated_repeatedBool_codec); + size += repeatedString_.CalculateSize(_repeated_repeatedString_codec); + size += repeatedBytes_.CalculateSize(_repeated_repeatedBytes_codec); + size += repeatedNestedMessage_.CalculateSize(_repeated_repeatedNestedMessage_codec); + size += repeatedForeignMessage_.CalculateSize(_repeated_repeatedForeignMessage_codec); + size += repeatedNestedEnum_.CalculateSize(_repeated_repeatedNestedEnum_codec); + size += repeatedForeignEnum_.CalculateSize(_repeated_repeatedForeignEnum_codec); + size += repeatedStringPiece_.CalculateSize(_repeated_repeatedStringPiece_codec); + size += repeatedCord_.CalculateSize(_repeated_repeatedCord_codec); + size += packedInt32_.CalculateSize(_repeated_packedInt32_codec); + size += packedInt64_.CalculateSize(_repeated_packedInt64_codec); + size += packedUint32_.CalculateSize(_repeated_packedUint32_codec); + size += packedUint64_.CalculateSize(_repeated_packedUint64_codec); + size += packedSint32_.CalculateSize(_repeated_packedSint32_codec); + size += packedSint64_.CalculateSize(_repeated_packedSint64_codec); + size += packedFixed32_.CalculateSize(_repeated_packedFixed32_codec); + size += packedFixed64_.CalculateSize(_repeated_packedFixed64_codec); + size += packedSfixed32_.CalculateSize(_repeated_packedSfixed32_codec); + size += packedSfixed64_.CalculateSize(_repeated_packedSfixed64_codec); + size += packedFloat_.CalculateSize(_repeated_packedFloat_codec); + size += packedDouble_.CalculateSize(_repeated_packedDouble_codec); + size += packedBool_.CalculateSize(_repeated_packedBool_codec); + size += packedNestedEnum_.CalculateSize(_repeated_packedNestedEnum_codec); + size += unpackedInt32_.CalculateSize(_repeated_unpackedInt32_codec); + size += unpackedInt64_.CalculateSize(_repeated_unpackedInt64_codec); + size += unpackedUint32_.CalculateSize(_repeated_unpackedUint32_codec); + size += unpackedUint64_.CalculateSize(_repeated_unpackedUint64_codec); + size += unpackedSint32_.CalculateSize(_repeated_unpackedSint32_codec); + size += unpackedSint64_.CalculateSize(_repeated_unpackedSint64_codec); + size += unpackedFixed32_.CalculateSize(_repeated_unpackedFixed32_codec); + size += unpackedFixed64_.CalculateSize(_repeated_unpackedFixed64_codec); + size += unpackedSfixed32_.CalculateSize(_repeated_unpackedSfixed32_codec); + size += unpackedSfixed64_.CalculateSize(_repeated_unpackedSfixed64_codec); + size += unpackedFloat_.CalculateSize(_repeated_unpackedFloat_codec); + size += unpackedDouble_.CalculateSize(_repeated_unpackedDouble_codec); + size += unpackedBool_.CalculateSize(_repeated_unpackedBool_codec); + size += unpackedNestedEnum_.CalculateSize(_repeated_unpackedNestedEnum_codec); + size += mapInt32Int32_.CalculateSize(_map_mapInt32Int32_codec); + size += mapInt64Int64_.CalculateSize(_map_mapInt64Int64_codec); + size += mapUint32Uint32_.CalculateSize(_map_mapUint32Uint32_codec); + size += mapUint64Uint64_.CalculateSize(_map_mapUint64Uint64_codec); + size += mapSint32Sint32_.CalculateSize(_map_mapSint32Sint32_codec); + size += mapSint64Sint64_.CalculateSize(_map_mapSint64Sint64_codec); + size += mapFixed32Fixed32_.CalculateSize(_map_mapFixed32Fixed32_codec); + size += mapFixed64Fixed64_.CalculateSize(_map_mapFixed64Fixed64_codec); + size += mapSfixed32Sfixed32_.CalculateSize(_map_mapSfixed32Sfixed32_codec); + size += mapSfixed64Sfixed64_.CalculateSize(_map_mapSfixed64Sfixed64_codec); + size += mapInt32Float_.CalculateSize(_map_mapInt32Float_codec); + size += mapInt32Double_.CalculateSize(_map_mapInt32Double_codec); + size += mapBoolBool_.CalculateSize(_map_mapBoolBool_codec); + size += mapStringString_.CalculateSize(_map_mapStringString_codec); + size += mapStringBytes_.CalculateSize(_map_mapStringBytes_codec); + size += mapStringNestedMessage_.CalculateSize(_map_mapStringNestedMessage_codec); + size += mapStringForeignMessage_.CalculateSize(_map_mapStringForeignMessage_codec); + size += mapStringNestedEnum_.CalculateSize(_map_mapStringNestedEnum_codec); + size += mapStringForeignEnum_.CalculateSize(_map_mapStringForeignEnum_codec); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) { + size += 2 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32); } - repeatedInt32_.Add(other.repeatedInt32_); - repeatedInt64_.Add(other.repeatedInt64_); - repeatedUint32_.Add(other.repeatedUint32_); - repeatedUint64_.Add(other.repeatedUint64_); - repeatedSint32_.Add(other.repeatedSint32_); - repeatedSint64_.Add(other.repeatedSint64_); - repeatedFixed32_.Add(other.repeatedFixed32_); - repeatedFixed64_.Add(other.repeatedFixed64_); - repeatedSfixed32_.Add(other.repeatedSfixed32_); - repeatedSfixed64_.Add(other.repeatedSfixed64_); - repeatedFloat_.Add(other.repeatedFloat_); - repeatedDouble_.Add(other.repeatedDouble_); - repeatedBool_.Add(other.repeatedBool_); - repeatedString_.Add(other.repeatedString_); - repeatedBytes_.Add(other.repeatedBytes_); - repeatedNestedMessage_.Add(other.repeatedNestedMessage_); - repeatedForeignMessage_.Add(other.repeatedForeignMessage_); - repeatedNestedEnum_.Add(other.repeatedNestedEnum_); - repeatedForeignEnum_.Add(other.repeatedForeignEnum_); - repeatedStringPiece_.Add(other.repeatedStringPiece_); - repeatedCord_.Add(other.repeatedCord_); - packedInt32_.Add(other.packedInt32_); - packedInt64_.Add(other.packedInt64_); - packedUint32_.Add(other.packedUint32_); - packedUint64_.Add(other.packedUint64_); - packedSint32_.Add(other.packedSint32_); - packedSint64_.Add(other.packedSint64_); - packedFixed32_.Add(other.packedFixed32_); - packedFixed64_.Add(other.packedFixed64_); - packedSfixed32_.Add(other.packedSfixed32_); - packedSfixed64_.Add(other.packedSfixed64_); - packedFloat_.Add(other.packedFloat_); - packedDouble_.Add(other.packedDouble_); - packedBool_.Add(other.packedBool_); - packedNestedEnum_.Add(other.packedNestedEnum_); - unpackedInt32_.Add(other.unpackedInt32_); - unpackedInt64_.Add(other.unpackedInt64_); - unpackedUint32_.Add(other.unpackedUint32_); - unpackedUint64_.Add(other.unpackedUint64_); - unpackedSint32_.Add(other.unpackedSint32_); - unpackedSint64_.Add(other.unpackedSint64_); - unpackedFixed32_.Add(other.unpackedFixed32_); - unpackedFixed64_.Add(other.unpackedFixed64_); - unpackedSfixed32_.Add(other.unpackedSfixed32_); - unpackedSfixed64_.Add(other.unpackedSfixed64_); - unpackedFloat_.Add(other.unpackedFloat_); - unpackedDouble_.Add(other.unpackedDouble_); - unpackedBool_.Add(other.unpackedBool_); - unpackedNestedEnum_.Add(other.unpackedNestedEnum_); - mapInt32Int32_.Add(other.mapInt32Int32_); - mapInt64Int64_.Add(other.mapInt64Int64_); - mapUint32Uint32_.Add(other.mapUint32Uint32_); - mapUint64Uint64_.Add(other.mapUint64Uint64_); - mapSint32Sint32_.Add(other.mapSint32Sint32_); - mapSint64Sint64_.Add(other.mapSint64Sint64_); - mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_); - mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_); - mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_); - mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_); - mapInt32Float_.Add(other.mapInt32Float_); - mapInt32Double_.Add(other.mapInt32Double_); - mapBoolBool_.Add(other.mapBoolBool_); - mapStringString_.Add(other.mapStringString_); - mapStringBytes_.Add(other.mapStringBytes_); - mapStringNestedMessage_.Add(other.mapStringNestedMessage_); - mapStringForeignMessage_.Add(other.mapStringForeignMessage_); - mapStringNestedEnum_.Add(other.mapStringNestedEnum_); - mapStringForeignEnum_.Add(other.mapStringForeignEnum_); - if (other.optionalBoolWrapper_ != null) { - if (optionalBoolWrapper_ == null || other.OptionalBoolWrapper != false) { - OptionalBoolWrapper = other.OptionalBoolWrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OneofNestedMessage); } - if (other.optionalInt32Wrapper_ != null) { - if (optionalInt32Wrapper_ == null || other.OptionalInt32Wrapper != 0) { - OptionalInt32Wrapper = other.OptionalInt32Wrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(OneofString); } - if (other.optionalInt64Wrapper_ != null) { - if (optionalInt64Wrapper_ == null || other.OptionalInt64Wrapper != 0L) { - OptionalInt64Wrapper = other.OptionalInt64Wrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) { + size += 2 + pb::CodedOutputStream.ComputeBytesSize(OneofBytes); } - if (other.optionalUint32Wrapper_ != null) { - if (optionalUint32Wrapper_ == null || other.OptionalUint32Wrapper != 0) { - OptionalUint32Wrapper = other.OptionalUint32Wrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofBool) { + size += 2 + 1; } - if (other.optionalUint64Wrapper_ != null) { - if (optionalUint64Wrapper_ == null || other.OptionalUint64Wrapper != 0UL) { - OptionalUint64Wrapper = other.OptionalUint64Wrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint64) { + size += 2 + pb::CodedOutputStream.ComputeUInt64Size(OneofUint64); } - if (other.optionalFloatWrapper_ != null) { - if (optionalFloatWrapper_ == null || other.OptionalFloatWrapper != 0F) { - OptionalFloatWrapper = other.OptionalFloatWrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofFloat) { + size += 2 + 4; } - if (other.optionalDoubleWrapper_ != null) { - if (optionalDoubleWrapper_ == null || other.OptionalDoubleWrapper != 0D) { - OptionalDoubleWrapper = other.OptionalDoubleWrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofDouble) { + size += 2 + 8; } - if (other.optionalStringWrapper_ != null) { - if (optionalStringWrapper_ == null || other.OptionalStringWrapper != "") { - OptionalStringWrapper = other.OptionalStringWrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofEnum) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OneofEnum); } - if (other.optionalBytesWrapper_ != null) { - if (optionalBytesWrapper_ == null || other.OptionalBytesWrapper != pb::ByteString.Empty) { - OptionalBytesWrapper = other.OptionalBytesWrapper; - } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNullValue) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OneofNullValue); } - repeatedBoolWrapper_.Add(other.repeatedBoolWrapper_); - repeatedInt32Wrapper_.Add(other.repeatedInt32Wrapper_); - repeatedInt64Wrapper_.Add(other.repeatedInt64Wrapper_); - repeatedUint32Wrapper_.Add(other.repeatedUint32Wrapper_); - repeatedUint64Wrapper_.Add(other.repeatedUint64Wrapper_); - repeatedFloatWrapper_.Add(other.repeatedFloatWrapper_); - repeatedDoubleWrapper_.Add(other.repeatedDoubleWrapper_); - repeatedStringWrapper_.Add(other.repeatedStringWrapper_); - repeatedBytesWrapper_.Add(other.repeatedBytesWrapper_); - if (other.optionalDuration_ != null) { - if (optionalDuration_ == null) { - OptionalDuration = new global::Google.Protobuf.WellKnownTypes.Duration(); - } - OptionalDuration.MergeFrom(other.OptionalDuration); + if (optionalBoolWrapper_ != null) { + size += _single_optionalBoolWrapper_codec.CalculateSizeWithTag(OptionalBoolWrapper); } - if (other.optionalTimestamp_ != null) { - if (optionalTimestamp_ == null) { - OptionalTimestamp = new global::Google.Protobuf.WellKnownTypes.Timestamp(); - } - OptionalTimestamp.MergeFrom(other.OptionalTimestamp); + if (optionalInt32Wrapper_ != null) { + size += _single_optionalInt32Wrapper_codec.CalculateSizeWithTag(OptionalInt32Wrapper); } - if (other.optionalFieldMask_ != null) { - if (optionalFieldMask_ == null) { - OptionalFieldMask = new global::Google.Protobuf.WellKnownTypes.FieldMask(); - } - OptionalFieldMask.MergeFrom(other.OptionalFieldMask); + if (optionalInt64Wrapper_ != null) { + size += _single_optionalInt64Wrapper_codec.CalculateSizeWithTag(OptionalInt64Wrapper); } - if (other.optionalStruct_ != null) { - if (optionalStruct_ == null) { - OptionalStruct = new global::Google.Protobuf.WellKnownTypes.Struct(); - } - OptionalStruct.MergeFrom(other.OptionalStruct); + if (optionalUint32Wrapper_ != null) { + size += _single_optionalUint32Wrapper_codec.CalculateSizeWithTag(OptionalUint32Wrapper); } - if (other.optionalAny_ != null) { - if (optionalAny_ == null) { - OptionalAny = new global::Google.Protobuf.WellKnownTypes.Any(); - } - OptionalAny.MergeFrom(other.OptionalAny); + if (optionalUint64Wrapper_ != null) { + size += _single_optionalUint64Wrapper_codec.CalculateSizeWithTag(OptionalUint64Wrapper); } - if (other.optionalValue_ != null) { - if (optionalValue_ == null) { - OptionalValue = new global::Google.Protobuf.WellKnownTypes.Value(); - } - OptionalValue.MergeFrom(other.OptionalValue); + if (optionalFloatWrapper_ != null) { + size += _single_optionalFloatWrapper_codec.CalculateSizeWithTag(OptionalFloatWrapper); } - repeatedDuration_.Add(other.repeatedDuration_); - repeatedTimestamp_.Add(other.repeatedTimestamp_); - repeatedFieldmask_.Add(other.repeatedFieldmask_); - repeatedStruct_.Add(other.repeatedStruct_); - repeatedAny_.Add(other.repeatedAny_); - repeatedValue_.Add(other.repeatedValue_); - repeatedListValue_.Add(other.repeatedListValue_); - if (other.Fieldname1 != 0) { - Fieldname1 = other.Fieldname1; + if (optionalDoubleWrapper_ != null) { + size += _single_optionalDoubleWrapper_codec.CalculateSizeWithTag(OptionalDoubleWrapper); } - if (other.FieldName2 != 0) { - FieldName2 = other.FieldName2; + if (optionalStringWrapper_ != null) { + size += _single_optionalStringWrapper_codec.CalculateSizeWithTag(OptionalStringWrapper); } - if (other.FieldName3 != 0) { - FieldName3 = other.FieldName3; + if (optionalBytesWrapper_ != null) { + size += _single_optionalBytesWrapper_codec.CalculateSizeWithTag(OptionalBytesWrapper); } - if (other.FieldName4 != 0) { - FieldName4 = other.FieldName4; + size += repeatedBoolWrapper_.CalculateSize(_repeated_repeatedBoolWrapper_codec); + size += repeatedInt32Wrapper_.CalculateSize(_repeated_repeatedInt32Wrapper_codec); + size += repeatedInt64Wrapper_.CalculateSize(_repeated_repeatedInt64Wrapper_codec); + size += repeatedUint32Wrapper_.CalculateSize(_repeated_repeatedUint32Wrapper_codec); + size += repeatedUint64Wrapper_.CalculateSize(_repeated_repeatedUint64Wrapper_codec); + size += repeatedFloatWrapper_.CalculateSize(_repeated_repeatedFloatWrapper_codec); + size += repeatedDoubleWrapper_.CalculateSize(_repeated_repeatedDoubleWrapper_codec); + size += repeatedStringWrapper_.CalculateSize(_repeated_repeatedStringWrapper_codec); + size += repeatedBytesWrapper_.CalculateSize(_repeated_repeatedBytesWrapper_codec); + if (optionalDuration_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalDuration); } - if (other.Field0Name5 != 0) { - Field0Name5 = other.Field0Name5; + if (optionalTimestamp_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalTimestamp); } - if (other.Field0Name6 != 0) { - Field0Name6 = other.Field0Name6; + if (optionalFieldMask_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalFieldMask); } - if (other.FieldName7 != 0) { - FieldName7 = other.FieldName7; + if (optionalStruct_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalStruct); } - if (other.FieldName8 != 0) { - FieldName8 = other.FieldName8; + if (optionalAny_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalAny); } - if (other.FieldName9 != 0) { - FieldName9 = other.FieldName9; + if (optionalValue_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalValue); } - if (other.FieldName10 != 0) { - FieldName10 = other.FieldName10; + if (OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNullValue); } - if (other.FIELDNAME11 != 0) { - FIELDNAME11 = other.FIELDNAME11; + size += repeatedDuration_.CalculateSize(_repeated_repeatedDuration_codec); + size += repeatedTimestamp_.CalculateSize(_repeated_repeatedTimestamp_codec); + size += repeatedFieldmask_.CalculateSize(_repeated_repeatedFieldmask_codec); + size += repeatedStruct_.CalculateSize(_repeated_repeatedStruct_codec); + size += repeatedAny_.CalculateSize(_repeated_repeatedAny_codec); + size += repeatedValue_.CalculateSize(_repeated_repeatedValue_codec); + size += repeatedListValue_.CalculateSize(_repeated_repeatedListValue_codec); + if (Fieldname1 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(Fieldname1); } - if (other.FIELDName12 != 0) { - FIELDName12 = other.FIELDName12; + if (FieldName2 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName2); } - if (other.FieldName13 != 0) { - FieldName13 = other.FieldName13; + if (FieldName3 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName3); } - if (other.FieldName14 != 0) { - FieldName14 = other.FieldName14; + if (FieldName4 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName4); } - if (other.FieldName15 != 0) { - FieldName15 = other.FieldName15; + if (Field0Name5 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name5); } - if (other.FieldName16 != 0) { - FieldName16 = other.FieldName16; + if (Field0Name6 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name6); } - if (other.FieldName17 != 0) { - FieldName17 = other.FieldName17; + if (FieldName7 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName7); } - if (other.FieldName18 != 0) { - FieldName18 = other.FieldName18; + if (FieldName8 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName8); } - switch (other.OneofFieldCase) { - case OneofFieldOneofCase.OneofUint32: - OneofUint32 = other.OneofUint32; - break; - case OneofFieldOneofCase.OneofNestedMessage: - if (OneofNestedMessage == null) { - OneofNestedMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage(); + if (FieldName9 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName9); + } + if (FieldName10 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName10); + } + if (FIELDNAME11 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDNAME11); + } + if (FIELDName12 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDName12); + } + if (FieldName13 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName13); + } + if (FieldName14 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName14); + } + if (FieldName15 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName15); + } + if (FieldName16 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName16); + } + if (FieldName17 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName17); + } + if (FieldName18 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName18); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(TestAllTypesProto3 other) { + if (other == null) { + return; + } + if (other.OptionalInt32 != 0) { + OptionalInt32 = other.OptionalInt32; + } + if (other.OptionalInt64 != 0L) { + OptionalInt64 = other.OptionalInt64; + } + if (other.OptionalUint32 != 0) { + OptionalUint32 = other.OptionalUint32; + } + if (other.OptionalUint64 != 0UL) { + OptionalUint64 = other.OptionalUint64; + } + if (other.OptionalSint32 != 0) { + OptionalSint32 = other.OptionalSint32; + } + if (other.OptionalSint64 != 0L) { + OptionalSint64 = other.OptionalSint64; + } + if (other.OptionalFixed32 != 0) { + OptionalFixed32 = other.OptionalFixed32; + } + if (other.OptionalFixed64 != 0UL) { + OptionalFixed64 = other.OptionalFixed64; + } + if (other.OptionalSfixed32 != 0) { + OptionalSfixed32 = other.OptionalSfixed32; + } + if (other.OptionalSfixed64 != 0L) { + OptionalSfixed64 = other.OptionalSfixed64; + } + if (other.OptionalFloat != 0F) { + OptionalFloat = other.OptionalFloat; + } + if (other.OptionalDouble != 0D) { + OptionalDouble = other.OptionalDouble; + } + if (other.OptionalBool != false) { + OptionalBool = other.OptionalBool; + } + if (other.OptionalString.Length != 0) { + OptionalString = other.OptionalString; + } + if (other.OptionalBytes.Length != 0) { + OptionalBytes = other.OptionalBytes; + } + if (other.optionalNestedMessage_ != null) { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage(); + } + OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage); + } + if (other.optionalForeignMessage_ != null) { + if (optionalForeignMessage_ == null) { + OptionalForeignMessage = new global::ProtobufTestMessages.Proto3.ForeignMessage(); + } + OptionalForeignMessage.MergeFrom(other.OptionalForeignMessage); + } + if (other.OptionalNestedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum.Foo) { + OptionalNestedEnum = other.OptionalNestedEnum; + } + if (other.OptionalForeignEnum != global::ProtobufTestMessages.Proto3.ForeignEnum.ForeignFoo) { + OptionalForeignEnum = other.OptionalForeignEnum; + } + if (other.OptionalAliasedEnum != global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum.AliasFoo) { + OptionalAliasedEnum = other.OptionalAliasedEnum; + } + if (other.OptionalStringPiece.Length != 0) { + OptionalStringPiece = other.OptionalStringPiece; + } + if (other.OptionalCord.Length != 0) { + OptionalCord = other.OptionalCord; + } + if (other.recursiveMessage_ != null) { + if (recursiveMessage_ == null) { + RecursiveMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3(); + } + RecursiveMessage.MergeFrom(other.RecursiveMessage); + } + repeatedInt32_.Add(other.repeatedInt32_); + repeatedInt64_.Add(other.repeatedInt64_); + repeatedUint32_.Add(other.repeatedUint32_); + repeatedUint64_.Add(other.repeatedUint64_); + repeatedSint32_.Add(other.repeatedSint32_); + repeatedSint64_.Add(other.repeatedSint64_); + repeatedFixed32_.Add(other.repeatedFixed32_); + repeatedFixed64_.Add(other.repeatedFixed64_); + repeatedSfixed32_.Add(other.repeatedSfixed32_); + repeatedSfixed64_.Add(other.repeatedSfixed64_); + repeatedFloat_.Add(other.repeatedFloat_); + repeatedDouble_.Add(other.repeatedDouble_); + repeatedBool_.Add(other.repeatedBool_); + repeatedString_.Add(other.repeatedString_); + repeatedBytes_.Add(other.repeatedBytes_); + repeatedNestedMessage_.Add(other.repeatedNestedMessage_); + repeatedForeignMessage_.Add(other.repeatedForeignMessage_); + repeatedNestedEnum_.Add(other.repeatedNestedEnum_); + repeatedForeignEnum_.Add(other.repeatedForeignEnum_); + repeatedStringPiece_.Add(other.repeatedStringPiece_); + repeatedCord_.Add(other.repeatedCord_); + packedInt32_.Add(other.packedInt32_); + packedInt64_.Add(other.packedInt64_); + packedUint32_.Add(other.packedUint32_); + packedUint64_.Add(other.packedUint64_); + packedSint32_.Add(other.packedSint32_); + packedSint64_.Add(other.packedSint64_); + packedFixed32_.Add(other.packedFixed32_); + packedFixed64_.Add(other.packedFixed64_); + packedSfixed32_.Add(other.packedSfixed32_); + packedSfixed64_.Add(other.packedSfixed64_); + packedFloat_.Add(other.packedFloat_); + packedDouble_.Add(other.packedDouble_); + packedBool_.Add(other.packedBool_); + packedNestedEnum_.Add(other.packedNestedEnum_); + unpackedInt32_.Add(other.unpackedInt32_); + unpackedInt64_.Add(other.unpackedInt64_); + unpackedUint32_.Add(other.unpackedUint32_); + unpackedUint64_.Add(other.unpackedUint64_); + unpackedSint32_.Add(other.unpackedSint32_); + unpackedSint64_.Add(other.unpackedSint64_); + unpackedFixed32_.Add(other.unpackedFixed32_); + unpackedFixed64_.Add(other.unpackedFixed64_); + unpackedSfixed32_.Add(other.unpackedSfixed32_); + unpackedSfixed64_.Add(other.unpackedSfixed64_); + unpackedFloat_.Add(other.unpackedFloat_); + unpackedDouble_.Add(other.unpackedDouble_); + unpackedBool_.Add(other.unpackedBool_); + unpackedNestedEnum_.Add(other.unpackedNestedEnum_); + mapInt32Int32_.Add(other.mapInt32Int32_); + mapInt64Int64_.Add(other.mapInt64Int64_); + mapUint32Uint32_.Add(other.mapUint32Uint32_); + mapUint64Uint64_.Add(other.mapUint64Uint64_); + mapSint32Sint32_.Add(other.mapSint32Sint32_); + mapSint64Sint64_.Add(other.mapSint64Sint64_); + mapFixed32Fixed32_.Add(other.mapFixed32Fixed32_); + mapFixed64Fixed64_.Add(other.mapFixed64Fixed64_); + mapSfixed32Sfixed32_.Add(other.mapSfixed32Sfixed32_); + mapSfixed64Sfixed64_.Add(other.mapSfixed64Sfixed64_); + mapInt32Float_.Add(other.mapInt32Float_); + mapInt32Double_.Add(other.mapInt32Double_); + mapBoolBool_.Add(other.mapBoolBool_); + mapStringString_.Add(other.mapStringString_); + mapStringBytes_.Add(other.mapStringBytes_); + mapStringNestedMessage_.Add(other.mapStringNestedMessage_); + mapStringForeignMessage_.Add(other.mapStringForeignMessage_); + mapStringNestedEnum_.Add(other.mapStringNestedEnum_); + mapStringForeignEnum_.Add(other.mapStringForeignEnum_); + if (other.optionalBoolWrapper_ != null) { + if (optionalBoolWrapper_ == null || other.OptionalBoolWrapper != false) { + OptionalBoolWrapper = other.OptionalBoolWrapper; + } + } + if (other.optionalInt32Wrapper_ != null) { + if (optionalInt32Wrapper_ == null || other.OptionalInt32Wrapper != 0) { + OptionalInt32Wrapper = other.OptionalInt32Wrapper; + } + } + if (other.optionalInt64Wrapper_ != null) { + if (optionalInt64Wrapper_ == null || other.OptionalInt64Wrapper != 0L) { + OptionalInt64Wrapper = other.OptionalInt64Wrapper; + } + } + if (other.optionalUint32Wrapper_ != null) { + if (optionalUint32Wrapper_ == null || other.OptionalUint32Wrapper != 0) { + OptionalUint32Wrapper = other.OptionalUint32Wrapper; + } + } + if (other.optionalUint64Wrapper_ != null) { + if (optionalUint64Wrapper_ == null || other.OptionalUint64Wrapper != 0UL) { + OptionalUint64Wrapper = other.OptionalUint64Wrapper; + } + } + if (other.optionalFloatWrapper_ != null) { + if (optionalFloatWrapper_ == null || other.OptionalFloatWrapper != 0F) { + OptionalFloatWrapper = other.OptionalFloatWrapper; + } + } + if (other.optionalDoubleWrapper_ != null) { + if (optionalDoubleWrapper_ == null || other.OptionalDoubleWrapper != 0D) { + OptionalDoubleWrapper = other.OptionalDoubleWrapper; + } + } + if (other.optionalStringWrapper_ != null) { + if (optionalStringWrapper_ == null || other.OptionalStringWrapper != "") { + OptionalStringWrapper = other.OptionalStringWrapper; + } + } + if (other.optionalBytesWrapper_ != null) { + if (optionalBytesWrapper_ == null || other.OptionalBytesWrapper != pb::ByteString.Empty) { + OptionalBytesWrapper = other.OptionalBytesWrapper; + } + } + repeatedBoolWrapper_.Add(other.repeatedBoolWrapper_); + repeatedInt32Wrapper_.Add(other.repeatedInt32Wrapper_); + repeatedInt64Wrapper_.Add(other.repeatedInt64Wrapper_); + repeatedUint32Wrapper_.Add(other.repeatedUint32Wrapper_); + repeatedUint64Wrapper_.Add(other.repeatedUint64Wrapper_); + repeatedFloatWrapper_.Add(other.repeatedFloatWrapper_); + repeatedDoubleWrapper_.Add(other.repeatedDoubleWrapper_); + repeatedStringWrapper_.Add(other.repeatedStringWrapper_); + repeatedBytesWrapper_.Add(other.repeatedBytesWrapper_); + if (other.optionalDuration_ != null) { + if (optionalDuration_ == null) { + OptionalDuration = new global::Google.Protobuf.WellKnownTypes.Duration(); + } + OptionalDuration.MergeFrom(other.OptionalDuration); + } + if (other.optionalTimestamp_ != null) { + if (optionalTimestamp_ == null) { + OptionalTimestamp = new global::Google.Protobuf.WellKnownTypes.Timestamp(); + } + OptionalTimestamp.MergeFrom(other.OptionalTimestamp); + } + if (other.optionalFieldMask_ != null) { + if (optionalFieldMask_ == null) { + OptionalFieldMask = new global::Google.Protobuf.WellKnownTypes.FieldMask(); + } + OptionalFieldMask.MergeFrom(other.OptionalFieldMask); + } + if (other.optionalStruct_ != null) { + if (optionalStruct_ == null) { + OptionalStruct = new global::Google.Protobuf.WellKnownTypes.Struct(); + } + OptionalStruct.MergeFrom(other.OptionalStruct); + } + if (other.optionalAny_ != null) { + if (optionalAny_ == null) { + OptionalAny = new global::Google.Protobuf.WellKnownTypes.Any(); + } + OptionalAny.MergeFrom(other.OptionalAny); + } + if (other.optionalValue_ != null) { + if (optionalValue_ == null) { + OptionalValue = new global::Google.Protobuf.WellKnownTypes.Value(); + } + OptionalValue.MergeFrom(other.OptionalValue); + } + if (other.OptionalNullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + OptionalNullValue = other.OptionalNullValue; + } + repeatedDuration_.Add(other.repeatedDuration_); + repeatedTimestamp_.Add(other.repeatedTimestamp_); + repeatedFieldmask_.Add(other.repeatedFieldmask_); + repeatedStruct_.Add(other.repeatedStruct_); + repeatedAny_.Add(other.repeatedAny_); + repeatedValue_.Add(other.repeatedValue_); + repeatedListValue_.Add(other.repeatedListValue_); + if (other.Fieldname1 != 0) { + Fieldname1 = other.Fieldname1; + } + if (other.FieldName2 != 0) { + FieldName2 = other.FieldName2; + } + if (other.FieldName3 != 0) { + FieldName3 = other.FieldName3; + } + if (other.FieldName4 != 0) { + FieldName4 = other.FieldName4; + } + if (other.Field0Name5 != 0) { + Field0Name5 = other.Field0Name5; + } + if (other.Field0Name6 != 0) { + Field0Name6 = other.Field0Name6; + } + if (other.FieldName7 != 0) { + FieldName7 = other.FieldName7; + } + if (other.FieldName8 != 0) { + FieldName8 = other.FieldName8; + } + if (other.FieldName9 != 0) { + FieldName9 = other.FieldName9; + } + if (other.FieldName10 != 0) { + FieldName10 = other.FieldName10; + } + if (other.FIELDNAME11 != 0) { + FIELDNAME11 = other.FIELDNAME11; + } + if (other.FIELDName12 != 0) { + FIELDName12 = other.FIELDName12; + } + if (other.FieldName13 != 0) { + FieldName13 = other.FieldName13; + } + if (other.FieldName14 != 0) { + FieldName14 = other.FieldName14; + } + if (other.FieldName15 != 0) { + FieldName15 = other.FieldName15; + } + if (other.FieldName16 != 0) { + FieldName16 = other.FieldName16; + } + if (other.FieldName17 != 0) { + FieldName17 = other.FieldName17; + } + if (other.FieldName18 != 0) { + FieldName18 = other.FieldName18; + } + switch (other.OneofFieldCase) { + case OneofFieldOneofCase.OneofUint32: + OneofUint32 = other.OneofUint32; + break; + case OneofFieldOneofCase.OneofNestedMessage: + if (OneofNestedMessage == null) { + OneofNestedMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage(); + } + OneofNestedMessage.MergeFrom(other.OneofNestedMessage); + break; + case OneofFieldOneofCase.OneofString: + OneofString = other.OneofString; + break; + case OneofFieldOneofCase.OneofBytes: + OneofBytes = other.OneofBytes; + break; + case OneofFieldOneofCase.OneofBool: + OneofBool = other.OneofBool; + break; + case OneofFieldOneofCase.OneofUint64: + OneofUint64 = other.OneofUint64; + break; + case OneofFieldOneofCase.OneofFloat: + OneofFloat = other.OneofFloat; + break; + case OneofFieldOneofCase.OneofDouble: + OneofDouble = other.OneofDouble; + break; + case OneofFieldOneofCase.OneofEnum: + OneofEnum = other.OneofEnum; + break; + case OneofFieldOneofCase.OneofNullValue: + OneofNullValue = other.OneofNullValue; + break; + } + + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + OptionalInt32 = input.ReadInt32(); + break; + } + case 16: { + OptionalInt64 = input.ReadInt64(); + break; + } + case 24: { + OptionalUint32 = input.ReadUInt32(); + break; + } + case 32: { + OptionalUint64 = input.ReadUInt64(); + break; + } + case 40: { + OptionalSint32 = input.ReadSInt32(); + break; + } + case 48: { + OptionalSint64 = input.ReadSInt64(); + break; + } + case 61: { + OptionalFixed32 = input.ReadFixed32(); + break; + } + case 65: { + OptionalFixed64 = input.ReadFixed64(); + break; + } + case 77: { + OptionalSfixed32 = input.ReadSFixed32(); + break; + } + case 81: { + OptionalSfixed64 = input.ReadSFixed64(); + break; + } + case 93: { + OptionalFloat = input.ReadFloat(); + break; + } + case 97: { + OptionalDouble = input.ReadDouble(); + break; + } + case 104: { + OptionalBool = input.ReadBool(); + break; + } + case 114: { + OptionalString = input.ReadString(); + break; + } + case 122: { + OptionalBytes = input.ReadBytes(); + break; + } + case 146: { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage(); + } + input.ReadMessage(OptionalNestedMessage); + break; + } + case 154: { + if (optionalForeignMessage_ == null) { + OptionalForeignMessage = new global::ProtobufTestMessages.Proto3.ForeignMessage(); + } + input.ReadMessage(OptionalForeignMessage); + break; + } + case 168: { + OptionalNestedEnum = (global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedEnum) input.ReadEnum(); + break; + } + case 176: { + OptionalForeignEnum = (global::ProtobufTestMessages.Proto3.ForeignEnum) input.ReadEnum(); + break; + } + case 184: { + OptionalAliasedEnum = (global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.AliasedEnum) input.ReadEnum(); + break; + } + case 194: { + OptionalStringPiece = input.ReadString(); + break; + } + case 202: { + OptionalCord = input.ReadString(); + break; + } + case 218: { + if (recursiveMessage_ == null) { + RecursiveMessage = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3(); + } + input.ReadMessage(RecursiveMessage); + break; + } + case 250: + case 248: { + repeatedInt32_.AddEntriesFrom(input, _repeated_repeatedInt32_codec); + break; + } + case 258: + case 256: { + repeatedInt64_.AddEntriesFrom(input, _repeated_repeatedInt64_codec); + break; + } + case 266: + case 264: { + repeatedUint32_.AddEntriesFrom(input, _repeated_repeatedUint32_codec); + break; + } + case 274: + case 272: { + repeatedUint64_.AddEntriesFrom(input, _repeated_repeatedUint64_codec); + break; + } + case 282: + case 280: { + repeatedSint32_.AddEntriesFrom(input, _repeated_repeatedSint32_codec); + break; + } + case 290: + case 288: { + repeatedSint64_.AddEntriesFrom(input, _repeated_repeatedSint64_codec); + break; + } + case 298: + case 301: { + repeatedFixed32_.AddEntriesFrom(input, _repeated_repeatedFixed32_codec); + break; + } + case 306: + case 305: { + repeatedFixed64_.AddEntriesFrom(input, _repeated_repeatedFixed64_codec); + break; + } + case 314: + case 317: { + repeatedSfixed32_.AddEntriesFrom(input, _repeated_repeatedSfixed32_codec); + break; + } + case 322: + case 321: { + repeatedSfixed64_.AddEntriesFrom(input, _repeated_repeatedSfixed64_codec); + break; + } + case 330: + case 333: { + repeatedFloat_.AddEntriesFrom(input, _repeated_repeatedFloat_codec); + break; + } + case 338: + case 337: { + repeatedDouble_.AddEntriesFrom(input, _repeated_repeatedDouble_codec); + break; + } + case 346: + case 344: { + repeatedBool_.AddEntriesFrom(input, _repeated_repeatedBool_codec); + break; + } + case 354: { + repeatedString_.AddEntriesFrom(input, _repeated_repeatedString_codec); + break; + } + case 362: { + repeatedBytes_.AddEntriesFrom(input, _repeated_repeatedBytes_codec); + break; + } + case 386: { + repeatedNestedMessage_.AddEntriesFrom(input, _repeated_repeatedNestedMessage_codec); + break; + } + case 394: { + repeatedForeignMessage_.AddEntriesFrom(input, _repeated_repeatedForeignMessage_codec); + break; + } + case 410: + case 408: { + repeatedNestedEnum_.AddEntriesFrom(input, _repeated_repeatedNestedEnum_codec); + break; + } + case 418: + case 416: { + repeatedForeignEnum_.AddEntriesFrom(input, _repeated_repeatedForeignEnum_codec); + break; + } + case 434: { + repeatedStringPiece_.AddEntriesFrom(input, _repeated_repeatedStringPiece_codec); + break; + } + case 442: { + repeatedCord_.AddEntriesFrom(input, _repeated_repeatedCord_codec); + break; + } + case 450: { + mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec); + break; + } + case 458: { + mapInt64Int64_.AddEntriesFrom(input, _map_mapInt64Int64_codec); + break; + } + case 466: { + mapUint32Uint32_.AddEntriesFrom(input, _map_mapUint32Uint32_codec); + break; + } + case 474: { + mapUint64Uint64_.AddEntriesFrom(input, _map_mapUint64Uint64_codec); + break; + } + case 482: { + mapSint32Sint32_.AddEntriesFrom(input, _map_mapSint32Sint32_codec); + break; + } + case 490: { + mapSint64Sint64_.AddEntriesFrom(input, _map_mapSint64Sint64_codec); + break; + } + case 498: { + mapFixed32Fixed32_.AddEntriesFrom(input, _map_mapFixed32Fixed32_codec); + break; + } + case 506: { + mapFixed64Fixed64_.AddEntriesFrom(input, _map_mapFixed64Fixed64_codec); + break; + } + case 514: { + mapSfixed32Sfixed32_.AddEntriesFrom(input, _map_mapSfixed32Sfixed32_codec); + break; + } + case 522: { + mapSfixed64Sfixed64_.AddEntriesFrom(input, _map_mapSfixed64Sfixed64_codec); + break; + } + case 530: { + mapInt32Float_.AddEntriesFrom(input, _map_mapInt32Float_codec); + break; + } + case 538: { + mapInt32Double_.AddEntriesFrom(input, _map_mapInt32Double_codec); + break; + } + case 546: { + mapBoolBool_.AddEntriesFrom(input, _map_mapBoolBool_codec); + break; + } + case 554: { + mapStringString_.AddEntriesFrom(input, _map_mapStringString_codec); + break; + } + case 562: { + mapStringBytes_.AddEntriesFrom(input, _map_mapStringBytes_codec); + break; + } + case 570: { + mapStringNestedMessage_.AddEntriesFrom(input, _map_mapStringNestedMessage_codec); + break; + } + case 578: { + mapStringForeignMessage_.AddEntriesFrom(input, _map_mapStringForeignMessage_codec); + break; + } + case 586: { + mapStringNestedEnum_.AddEntriesFrom(input, _map_mapStringNestedEnum_codec); + break; + } + case 594: { + mapStringForeignEnum_.AddEntriesFrom(input, _map_mapStringForeignEnum_codec); + break; + } + case 602: + case 600: { + packedInt32_.AddEntriesFrom(input, _repeated_packedInt32_codec); + break; + } + case 610: + case 608: { + packedInt64_.AddEntriesFrom(input, _repeated_packedInt64_codec); + break; + } + case 618: + case 616: { + packedUint32_.AddEntriesFrom(input, _repeated_packedUint32_codec); + break; + } + case 626: + case 624: { + packedUint64_.AddEntriesFrom(input, _repeated_packedUint64_codec); + break; + } + case 634: + case 632: { + packedSint32_.AddEntriesFrom(input, _repeated_packedSint32_codec); + break; + } + case 642: + case 640: { + packedSint64_.AddEntriesFrom(input, _repeated_packedSint64_codec); + break; + } + case 650: + case 653: { + packedFixed32_.AddEntriesFrom(input, _repeated_packedFixed32_codec); + break; + } + case 658: + case 657: { + packedFixed64_.AddEntriesFrom(input, _repeated_packedFixed64_codec); + break; + } + case 666: + case 669: { + packedSfixed32_.AddEntriesFrom(input, _repeated_packedSfixed32_codec); + break; + } + case 674: + case 673: { + packedSfixed64_.AddEntriesFrom(input, _repeated_packedSfixed64_codec); + break; + } + case 682: + case 685: { + packedFloat_.AddEntriesFrom(input, _repeated_packedFloat_codec); + break; + } + case 690: + case 689: { + packedDouble_.AddEntriesFrom(input, _repeated_packedDouble_codec); + break; + } + case 698: + case 696: { + packedBool_.AddEntriesFrom(input, _repeated_packedBool_codec); + break; + } + case 706: + case 704: { + packedNestedEnum_.AddEntriesFrom(input, _repeated_packedNestedEnum_codec); + break; + } + case 714: + case 712: { + unpackedInt32_.AddEntriesFrom(input, _repeated_unpackedInt32_codec); + break; + } + case 722: + case 720: { + unpackedInt64_.AddEntriesFrom(input, _repeated_unpackedInt64_codec); + break; + } + case 730: + case 728: { + unpackedUint32_.AddEntriesFrom(input, _repeated_unpackedUint32_codec); + break; + } + case 738: + case 736: { + unpackedUint64_.AddEntriesFrom(input, _repeated_unpackedUint64_codec); + break; + } + case 746: + case 744: { + unpackedSint32_.AddEntriesFrom(input, _repeated_unpackedSint32_codec); + break; + } + case 754: + case 752: { + unpackedSint64_.AddEntriesFrom(input, _repeated_unpackedSint64_codec); + break; + } + case 762: + case 765: { + unpackedFixed32_.AddEntriesFrom(input, _repeated_unpackedFixed32_codec); + break; + } + case 770: + case 769: { + unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec); + break; + } + case 778: + case 781: { + unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec); + break; + } + case 786: + case 785: { + unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec); + break; + } + case 794: + case 797: { + unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec); + break; + } + case 802: + case 801: { + unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec); + break; + } + case 810: + case 808: { + unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec); + break; + } + case 818: + case 816: { + unpackedNestedEnum_.AddEntriesFrom(input, _repeated_unpackedNestedEnum_codec); + break; + } + case 888: { + OneofUint32 = input.ReadUInt32(); + break; + } + case 898: { + global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage subBuilder = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3.Types.NestedMessage(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + subBuilder.MergeFrom(OneofNestedMessage); + } + input.ReadMessage(subBuilder); + OneofNestedMessage = subBuilder; + break; + } + case 906: { + OneofString = input.ReadString(); + break; + } + case 914: { + OneofBytes = input.ReadBytes(); + break; + } + case 920: { + OneofBool = input.ReadBool(); + break; + } + case 928: { + OneofUint64 = input.ReadUInt64(); + break; + } + case 941: { + OneofFloat = input.ReadFloat(); + break; + } + case 945: { + OneofDouble = input.ReadDouble(); + break; + } + case 952: { + oneofField_ = input.ReadEnum(); + oneofFieldCase_ = OneofFieldOneofCase.OneofEnum; + break; + } + case 960: { + oneofField_ = input.ReadEnum(); + oneofFieldCase_ = OneofFieldOneofCase.OneofNullValue; + break; + } + case 1610: { + bool? value = _single_optionalBoolWrapper_codec.Read(input); + if (optionalBoolWrapper_ == null || value != false) { + OptionalBoolWrapper = value; + } + break; + } + case 1618: { + int? value = _single_optionalInt32Wrapper_codec.Read(input); + if (optionalInt32Wrapper_ == null || value != 0) { + OptionalInt32Wrapper = value; + } + break; + } + case 1626: { + long? value = _single_optionalInt64Wrapper_codec.Read(input); + if (optionalInt64Wrapper_ == null || value != 0L) { + OptionalInt64Wrapper = value; + } + break; + } + case 1634: { + uint? value = _single_optionalUint32Wrapper_codec.Read(input); + if (optionalUint32Wrapper_ == null || value != 0) { + OptionalUint32Wrapper = value; + } + break; + } + case 1642: { + ulong? value = _single_optionalUint64Wrapper_codec.Read(input); + if (optionalUint64Wrapper_ == null || value != 0UL) { + OptionalUint64Wrapper = value; + } + break; + } + case 1650: { + float? value = _single_optionalFloatWrapper_codec.Read(input); + if (optionalFloatWrapper_ == null || value != 0F) { + OptionalFloatWrapper = value; + } + break; + } + case 1658: { + double? value = _single_optionalDoubleWrapper_codec.Read(input); + if (optionalDoubleWrapper_ == null || value != 0D) { + OptionalDoubleWrapper = value; + } + break; + } + case 1666: { + string value = _single_optionalStringWrapper_codec.Read(input); + if (optionalStringWrapper_ == null || value != "") { + OptionalStringWrapper = value; + } + break; + } + case 1674: { + pb::ByteString value = _single_optionalBytesWrapper_codec.Read(input); + if (optionalBytesWrapper_ == null || value != pb::ByteString.Empty) { + OptionalBytesWrapper = value; + } + break; + } + case 1690: { + repeatedBoolWrapper_.AddEntriesFrom(input, _repeated_repeatedBoolWrapper_codec); + break; + } + case 1698: { + repeatedInt32Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt32Wrapper_codec); + break; + } + case 1706: { + repeatedInt64Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt64Wrapper_codec); + break; + } + case 1714: { + repeatedUint32Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint32Wrapper_codec); + break; + } + case 1722: { + repeatedUint64Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint64Wrapper_codec); + break; + } + case 1730: { + repeatedFloatWrapper_.AddEntriesFrom(input, _repeated_repeatedFloatWrapper_codec); + break; + } + case 1738: { + repeatedDoubleWrapper_.AddEntriesFrom(input, _repeated_repeatedDoubleWrapper_codec); + break; + } + case 1746: { + repeatedStringWrapper_.AddEntriesFrom(input, _repeated_repeatedStringWrapper_codec); + break; + } + case 1754: { + repeatedBytesWrapper_.AddEntriesFrom(input, _repeated_repeatedBytesWrapper_codec); + break; + } + case 2410: { + if (optionalDuration_ == null) { + OptionalDuration = new global::Google.Protobuf.WellKnownTypes.Duration(); + } + input.ReadMessage(OptionalDuration); + break; + } + case 2418: { + if (optionalTimestamp_ == null) { + OptionalTimestamp = new global::Google.Protobuf.WellKnownTypes.Timestamp(); + } + input.ReadMessage(OptionalTimestamp); + break; + } + case 2426: { + if (optionalFieldMask_ == null) { + OptionalFieldMask = new global::Google.Protobuf.WellKnownTypes.FieldMask(); + } + input.ReadMessage(OptionalFieldMask); + break; + } + case 2434: { + if (optionalStruct_ == null) { + OptionalStruct = new global::Google.Protobuf.WellKnownTypes.Struct(); + } + input.ReadMessage(OptionalStruct); + break; + } + case 2442: { + if (optionalAny_ == null) { + OptionalAny = new global::Google.Protobuf.WellKnownTypes.Any(); + } + input.ReadMessage(OptionalAny); + break; + } + case 2450: { + if (optionalValue_ == null) { + OptionalValue = new global::Google.Protobuf.WellKnownTypes.Value(); + } + input.ReadMessage(OptionalValue); + break; + } + case 2456: { + OptionalNullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum(); + break; + } + case 2490: { + repeatedDuration_.AddEntriesFrom(input, _repeated_repeatedDuration_codec); + break; + } + case 2498: { + repeatedTimestamp_.AddEntriesFrom(input, _repeated_repeatedTimestamp_codec); + break; + } + case 2506: { + repeatedFieldmask_.AddEntriesFrom(input, _repeated_repeatedFieldmask_codec); + break; + } + case 2522: { + repeatedAny_.AddEntriesFrom(input, _repeated_repeatedAny_codec); + break; + } + case 2530: { + repeatedValue_.AddEntriesFrom(input, _repeated_repeatedValue_codec); + break; + } + case 2538: { + repeatedListValue_.AddEntriesFrom(input, _repeated_repeatedListValue_codec); + break; + } + case 2594: { + repeatedStruct_.AddEntriesFrom(input, _repeated_repeatedStruct_codec); + break; } - OneofNestedMessage.MergeFrom(other.OneofNestedMessage); - break; - case OneofFieldOneofCase.OneofString: - OneofString = other.OneofString; - break; - case OneofFieldOneofCase.OneofBytes: - OneofBytes = other.OneofBytes; - break; - case OneofFieldOneofCase.OneofBool: - OneofBool = other.OneofBool; - break; - case OneofFieldOneofCase.OneofUint64: - OneofUint64 = other.OneofUint64; - break; - case OneofFieldOneofCase.OneofFloat: - OneofFloat = other.OneofFloat; - break; - case OneofFieldOneofCase.OneofDouble: - OneofDouble = other.OneofDouble; - break; - case OneofFieldOneofCase.OneofEnum: - OneofEnum = other.OneofEnum; - break; + case 3208: { + Fieldname1 = input.ReadInt32(); + break; + } + case 3216: { + FieldName2 = input.ReadInt32(); + break; + } + case 3224: { + FieldName3 = input.ReadInt32(); + break; + } + case 3232: { + FieldName4 = input.ReadInt32(); + break; + } + case 3240: { + Field0Name5 = input.ReadInt32(); + break; + } + case 3248: { + Field0Name6 = input.ReadInt32(); + break; + } + case 3256: { + FieldName7 = input.ReadInt32(); + break; + } + case 3264: { + FieldName8 = input.ReadInt32(); + break; + } + case 3272: { + FieldName9 = input.ReadInt32(); + break; + } + case 3280: { + FieldName10 = input.ReadInt32(); + break; + } + case 3288: { + FIELDNAME11 = input.ReadInt32(); + break; + } + case 3296: { + FIELDName12 = input.ReadInt32(); + break; + } + case 3304: { + FieldName13 = input.ReadInt32(); + break; + } + case 3312: { + FieldName14 = input.ReadInt32(); + break; + } + case 3320: { + FieldName15 = input.ReadInt32(); + break; + } + case 3328: { + FieldName16 = input.ReadInt32(); + break; + } + case 3336: { + FieldName17 = input.ReadInt32(); + break; + } + case 3344: { + FieldName18 = input.ReadInt32(); + break; + } + } } - - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 8: { OptionalInt32 = input.ReadInt32(); @@ -3492,317 +4630,317 @@ public enum OneofFieldOneofCase { } case 250: case 248: { - repeatedInt32_.AddEntriesFrom(input, _repeated_repeatedInt32_codec); + repeatedInt32_.AddEntriesFrom(ref input, _repeated_repeatedInt32_codec); break; } case 258: case 256: { - repeatedInt64_.AddEntriesFrom(input, _repeated_repeatedInt64_codec); + repeatedInt64_.AddEntriesFrom(ref input, _repeated_repeatedInt64_codec); break; } case 266: case 264: { - repeatedUint32_.AddEntriesFrom(input, _repeated_repeatedUint32_codec); + repeatedUint32_.AddEntriesFrom(ref input, _repeated_repeatedUint32_codec); break; } case 274: case 272: { - repeatedUint64_.AddEntriesFrom(input, _repeated_repeatedUint64_codec); + repeatedUint64_.AddEntriesFrom(ref input, _repeated_repeatedUint64_codec); break; } case 282: case 280: { - repeatedSint32_.AddEntriesFrom(input, _repeated_repeatedSint32_codec); + repeatedSint32_.AddEntriesFrom(ref input, _repeated_repeatedSint32_codec); break; } case 290: case 288: { - repeatedSint64_.AddEntriesFrom(input, _repeated_repeatedSint64_codec); + repeatedSint64_.AddEntriesFrom(ref input, _repeated_repeatedSint64_codec); break; } case 298: case 301: { - repeatedFixed32_.AddEntriesFrom(input, _repeated_repeatedFixed32_codec); + repeatedFixed32_.AddEntriesFrom(ref input, _repeated_repeatedFixed32_codec); break; } case 306: case 305: { - repeatedFixed64_.AddEntriesFrom(input, _repeated_repeatedFixed64_codec); + repeatedFixed64_.AddEntriesFrom(ref input, _repeated_repeatedFixed64_codec); break; } case 314: case 317: { - repeatedSfixed32_.AddEntriesFrom(input, _repeated_repeatedSfixed32_codec); + repeatedSfixed32_.AddEntriesFrom(ref input, _repeated_repeatedSfixed32_codec); break; } case 322: case 321: { - repeatedSfixed64_.AddEntriesFrom(input, _repeated_repeatedSfixed64_codec); + repeatedSfixed64_.AddEntriesFrom(ref input, _repeated_repeatedSfixed64_codec); break; } case 330: case 333: { - repeatedFloat_.AddEntriesFrom(input, _repeated_repeatedFloat_codec); + repeatedFloat_.AddEntriesFrom(ref input, _repeated_repeatedFloat_codec); break; } case 338: case 337: { - repeatedDouble_.AddEntriesFrom(input, _repeated_repeatedDouble_codec); + repeatedDouble_.AddEntriesFrom(ref input, _repeated_repeatedDouble_codec); break; } case 346: case 344: { - repeatedBool_.AddEntriesFrom(input, _repeated_repeatedBool_codec); + repeatedBool_.AddEntriesFrom(ref input, _repeated_repeatedBool_codec); break; } case 354: { - repeatedString_.AddEntriesFrom(input, _repeated_repeatedString_codec); + repeatedString_.AddEntriesFrom(ref input, _repeated_repeatedString_codec); break; } case 362: { - repeatedBytes_.AddEntriesFrom(input, _repeated_repeatedBytes_codec); + repeatedBytes_.AddEntriesFrom(ref input, _repeated_repeatedBytes_codec); break; } case 386: { - repeatedNestedMessage_.AddEntriesFrom(input, _repeated_repeatedNestedMessage_codec); + repeatedNestedMessage_.AddEntriesFrom(ref input, _repeated_repeatedNestedMessage_codec); break; } case 394: { - repeatedForeignMessage_.AddEntriesFrom(input, _repeated_repeatedForeignMessage_codec); + repeatedForeignMessage_.AddEntriesFrom(ref input, _repeated_repeatedForeignMessage_codec); break; } case 410: case 408: { - repeatedNestedEnum_.AddEntriesFrom(input, _repeated_repeatedNestedEnum_codec); + repeatedNestedEnum_.AddEntriesFrom(ref input, _repeated_repeatedNestedEnum_codec); break; } case 418: case 416: { - repeatedForeignEnum_.AddEntriesFrom(input, _repeated_repeatedForeignEnum_codec); + repeatedForeignEnum_.AddEntriesFrom(ref input, _repeated_repeatedForeignEnum_codec); break; } case 434: { - repeatedStringPiece_.AddEntriesFrom(input, _repeated_repeatedStringPiece_codec); + repeatedStringPiece_.AddEntriesFrom(ref input, _repeated_repeatedStringPiece_codec); break; } case 442: { - repeatedCord_.AddEntriesFrom(input, _repeated_repeatedCord_codec); + repeatedCord_.AddEntriesFrom(ref input, _repeated_repeatedCord_codec); break; } case 450: { - mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec); + mapInt32Int32_.AddEntriesFrom(ref input, _map_mapInt32Int32_codec); break; } case 458: { - mapInt64Int64_.AddEntriesFrom(input, _map_mapInt64Int64_codec); + mapInt64Int64_.AddEntriesFrom(ref input, _map_mapInt64Int64_codec); break; } case 466: { - mapUint32Uint32_.AddEntriesFrom(input, _map_mapUint32Uint32_codec); + mapUint32Uint32_.AddEntriesFrom(ref input, _map_mapUint32Uint32_codec); break; } case 474: { - mapUint64Uint64_.AddEntriesFrom(input, _map_mapUint64Uint64_codec); + mapUint64Uint64_.AddEntriesFrom(ref input, _map_mapUint64Uint64_codec); break; } case 482: { - mapSint32Sint32_.AddEntriesFrom(input, _map_mapSint32Sint32_codec); + mapSint32Sint32_.AddEntriesFrom(ref input, _map_mapSint32Sint32_codec); break; } case 490: { - mapSint64Sint64_.AddEntriesFrom(input, _map_mapSint64Sint64_codec); + mapSint64Sint64_.AddEntriesFrom(ref input, _map_mapSint64Sint64_codec); break; } case 498: { - mapFixed32Fixed32_.AddEntriesFrom(input, _map_mapFixed32Fixed32_codec); + mapFixed32Fixed32_.AddEntriesFrom(ref input, _map_mapFixed32Fixed32_codec); break; } case 506: { - mapFixed64Fixed64_.AddEntriesFrom(input, _map_mapFixed64Fixed64_codec); + mapFixed64Fixed64_.AddEntriesFrom(ref input, _map_mapFixed64Fixed64_codec); break; } case 514: { - mapSfixed32Sfixed32_.AddEntriesFrom(input, _map_mapSfixed32Sfixed32_codec); + mapSfixed32Sfixed32_.AddEntriesFrom(ref input, _map_mapSfixed32Sfixed32_codec); break; } case 522: { - mapSfixed64Sfixed64_.AddEntriesFrom(input, _map_mapSfixed64Sfixed64_codec); + mapSfixed64Sfixed64_.AddEntriesFrom(ref input, _map_mapSfixed64Sfixed64_codec); break; } case 530: { - mapInt32Float_.AddEntriesFrom(input, _map_mapInt32Float_codec); + mapInt32Float_.AddEntriesFrom(ref input, _map_mapInt32Float_codec); break; } case 538: { - mapInt32Double_.AddEntriesFrom(input, _map_mapInt32Double_codec); + mapInt32Double_.AddEntriesFrom(ref input, _map_mapInt32Double_codec); break; } case 546: { - mapBoolBool_.AddEntriesFrom(input, _map_mapBoolBool_codec); + mapBoolBool_.AddEntriesFrom(ref input, _map_mapBoolBool_codec); break; } case 554: { - mapStringString_.AddEntriesFrom(input, _map_mapStringString_codec); + mapStringString_.AddEntriesFrom(ref input, _map_mapStringString_codec); break; } case 562: { - mapStringBytes_.AddEntriesFrom(input, _map_mapStringBytes_codec); + mapStringBytes_.AddEntriesFrom(ref input, _map_mapStringBytes_codec); break; } case 570: { - mapStringNestedMessage_.AddEntriesFrom(input, _map_mapStringNestedMessage_codec); + mapStringNestedMessage_.AddEntriesFrom(ref input, _map_mapStringNestedMessage_codec); break; } case 578: { - mapStringForeignMessage_.AddEntriesFrom(input, _map_mapStringForeignMessage_codec); + mapStringForeignMessage_.AddEntriesFrom(ref input, _map_mapStringForeignMessage_codec); break; } case 586: { - mapStringNestedEnum_.AddEntriesFrom(input, _map_mapStringNestedEnum_codec); + mapStringNestedEnum_.AddEntriesFrom(ref input, _map_mapStringNestedEnum_codec); break; } case 594: { - mapStringForeignEnum_.AddEntriesFrom(input, _map_mapStringForeignEnum_codec); + mapStringForeignEnum_.AddEntriesFrom(ref input, _map_mapStringForeignEnum_codec); break; } case 602: case 600: { - packedInt32_.AddEntriesFrom(input, _repeated_packedInt32_codec); + packedInt32_.AddEntriesFrom(ref input, _repeated_packedInt32_codec); break; } case 610: case 608: { - packedInt64_.AddEntriesFrom(input, _repeated_packedInt64_codec); + packedInt64_.AddEntriesFrom(ref input, _repeated_packedInt64_codec); break; } case 618: case 616: { - packedUint32_.AddEntriesFrom(input, _repeated_packedUint32_codec); + packedUint32_.AddEntriesFrom(ref input, _repeated_packedUint32_codec); break; } case 626: case 624: { - packedUint64_.AddEntriesFrom(input, _repeated_packedUint64_codec); + packedUint64_.AddEntriesFrom(ref input, _repeated_packedUint64_codec); break; } case 634: case 632: { - packedSint32_.AddEntriesFrom(input, _repeated_packedSint32_codec); + packedSint32_.AddEntriesFrom(ref input, _repeated_packedSint32_codec); break; } case 642: case 640: { - packedSint64_.AddEntriesFrom(input, _repeated_packedSint64_codec); + packedSint64_.AddEntriesFrom(ref input, _repeated_packedSint64_codec); break; } case 650: case 653: { - packedFixed32_.AddEntriesFrom(input, _repeated_packedFixed32_codec); + packedFixed32_.AddEntriesFrom(ref input, _repeated_packedFixed32_codec); break; } case 658: case 657: { - packedFixed64_.AddEntriesFrom(input, _repeated_packedFixed64_codec); + packedFixed64_.AddEntriesFrom(ref input, _repeated_packedFixed64_codec); break; } case 666: case 669: { - packedSfixed32_.AddEntriesFrom(input, _repeated_packedSfixed32_codec); + packedSfixed32_.AddEntriesFrom(ref input, _repeated_packedSfixed32_codec); break; } case 674: case 673: { - packedSfixed64_.AddEntriesFrom(input, _repeated_packedSfixed64_codec); + packedSfixed64_.AddEntriesFrom(ref input, _repeated_packedSfixed64_codec); break; } case 682: case 685: { - packedFloat_.AddEntriesFrom(input, _repeated_packedFloat_codec); + packedFloat_.AddEntriesFrom(ref input, _repeated_packedFloat_codec); break; } case 690: case 689: { - packedDouble_.AddEntriesFrom(input, _repeated_packedDouble_codec); + packedDouble_.AddEntriesFrom(ref input, _repeated_packedDouble_codec); break; } case 698: case 696: { - packedBool_.AddEntriesFrom(input, _repeated_packedBool_codec); + packedBool_.AddEntriesFrom(ref input, _repeated_packedBool_codec); break; } case 706: case 704: { - packedNestedEnum_.AddEntriesFrom(input, _repeated_packedNestedEnum_codec); + packedNestedEnum_.AddEntriesFrom(ref input, _repeated_packedNestedEnum_codec); break; } case 714: case 712: { - unpackedInt32_.AddEntriesFrom(input, _repeated_unpackedInt32_codec); + unpackedInt32_.AddEntriesFrom(ref input, _repeated_unpackedInt32_codec); break; } case 722: case 720: { - unpackedInt64_.AddEntriesFrom(input, _repeated_unpackedInt64_codec); + unpackedInt64_.AddEntriesFrom(ref input, _repeated_unpackedInt64_codec); break; } case 730: case 728: { - unpackedUint32_.AddEntriesFrom(input, _repeated_unpackedUint32_codec); + unpackedUint32_.AddEntriesFrom(ref input, _repeated_unpackedUint32_codec); break; } case 738: case 736: { - unpackedUint64_.AddEntriesFrom(input, _repeated_unpackedUint64_codec); + unpackedUint64_.AddEntriesFrom(ref input, _repeated_unpackedUint64_codec); break; } case 746: case 744: { - unpackedSint32_.AddEntriesFrom(input, _repeated_unpackedSint32_codec); + unpackedSint32_.AddEntriesFrom(ref input, _repeated_unpackedSint32_codec); break; } case 754: case 752: { - unpackedSint64_.AddEntriesFrom(input, _repeated_unpackedSint64_codec); + unpackedSint64_.AddEntriesFrom(ref input, _repeated_unpackedSint64_codec); break; } case 762: case 765: { - unpackedFixed32_.AddEntriesFrom(input, _repeated_unpackedFixed32_codec); + unpackedFixed32_.AddEntriesFrom(ref input, _repeated_unpackedFixed32_codec); break; } case 770: case 769: { - unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec); + unpackedFixed64_.AddEntriesFrom(ref input, _repeated_unpackedFixed64_codec); break; } case 778: case 781: { - unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec); + unpackedSfixed32_.AddEntriesFrom(ref input, _repeated_unpackedSfixed32_codec); break; } case 786: case 785: { - unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec); + unpackedSfixed64_.AddEntriesFrom(ref input, _repeated_unpackedSfixed64_codec); break; } case 794: case 797: { - unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec); + unpackedFloat_.AddEntriesFrom(ref input, _repeated_unpackedFloat_codec); break; } case 802: case 801: { - unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec); + unpackedDouble_.AddEntriesFrom(ref input, _repeated_unpackedDouble_codec); break; } case 810: case 808: { - unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec); + unpackedBool_.AddEntriesFrom(ref input, _repeated_unpackedBool_codec); break; } case 818: case 816: { - unpackedNestedEnum_.AddEntriesFrom(input, _repeated_unpackedNestedEnum_codec); + unpackedNestedEnum_.AddEntriesFrom(ref input, _repeated_unpackedNestedEnum_codec); break; } case 888: { @@ -3847,103 +4985,108 @@ public enum OneofFieldOneofCase { oneofFieldCase_ = OneofFieldOneofCase.OneofEnum; break; } + case 960: { + oneofField_ = input.ReadEnum(); + oneofFieldCase_ = OneofFieldOneofCase.OneofNullValue; + break; + } case 1610: { - bool? value = _single_optionalBoolWrapper_codec.Read(input); + bool? value = _single_optionalBoolWrapper_codec.Read(ref input); if (optionalBoolWrapper_ == null || value != false) { OptionalBoolWrapper = value; } break; } case 1618: { - int? value = _single_optionalInt32Wrapper_codec.Read(input); + int? value = _single_optionalInt32Wrapper_codec.Read(ref input); if (optionalInt32Wrapper_ == null || value != 0) { OptionalInt32Wrapper = value; } break; } case 1626: { - long? value = _single_optionalInt64Wrapper_codec.Read(input); + long? value = _single_optionalInt64Wrapper_codec.Read(ref input); if (optionalInt64Wrapper_ == null || value != 0L) { OptionalInt64Wrapper = value; } break; } case 1634: { - uint? value = _single_optionalUint32Wrapper_codec.Read(input); + uint? value = _single_optionalUint32Wrapper_codec.Read(ref input); if (optionalUint32Wrapper_ == null || value != 0) { OptionalUint32Wrapper = value; } break; } case 1642: { - ulong? value = _single_optionalUint64Wrapper_codec.Read(input); + ulong? value = _single_optionalUint64Wrapper_codec.Read(ref input); if (optionalUint64Wrapper_ == null || value != 0UL) { OptionalUint64Wrapper = value; } break; } case 1650: { - float? value = _single_optionalFloatWrapper_codec.Read(input); + float? value = _single_optionalFloatWrapper_codec.Read(ref input); if (optionalFloatWrapper_ == null || value != 0F) { OptionalFloatWrapper = value; } break; } case 1658: { - double? value = _single_optionalDoubleWrapper_codec.Read(input); + double? value = _single_optionalDoubleWrapper_codec.Read(ref input); if (optionalDoubleWrapper_ == null || value != 0D) { OptionalDoubleWrapper = value; } break; } case 1666: { - string value = _single_optionalStringWrapper_codec.Read(input); + string value = _single_optionalStringWrapper_codec.Read(ref input); if (optionalStringWrapper_ == null || value != "") { OptionalStringWrapper = value; } break; } case 1674: { - pb::ByteString value = _single_optionalBytesWrapper_codec.Read(input); + pb::ByteString value = _single_optionalBytesWrapper_codec.Read(ref input); if (optionalBytesWrapper_ == null || value != pb::ByteString.Empty) { OptionalBytesWrapper = value; } break; } case 1690: { - repeatedBoolWrapper_.AddEntriesFrom(input, _repeated_repeatedBoolWrapper_codec); + repeatedBoolWrapper_.AddEntriesFrom(ref input, _repeated_repeatedBoolWrapper_codec); break; } case 1698: { - repeatedInt32Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt32Wrapper_codec); + repeatedInt32Wrapper_.AddEntriesFrom(ref input, _repeated_repeatedInt32Wrapper_codec); break; } case 1706: { - repeatedInt64Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt64Wrapper_codec); + repeatedInt64Wrapper_.AddEntriesFrom(ref input, _repeated_repeatedInt64Wrapper_codec); break; } case 1714: { - repeatedUint32Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint32Wrapper_codec); + repeatedUint32Wrapper_.AddEntriesFrom(ref input, _repeated_repeatedUint32Wrapper_codec); break; } case 1722: { - repeatedUint64Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint64Wrapper_codec); + repeatedUint64Wrapper_.AddEntriesFrom(ref input, _repeated_repeatedUint64Wrapper_codec); break; } case 1730: { - repeatedFloatWrapper_.AddEntriesFrom(input, _repeated_repeatedFloatWrapper_codec); + repeatedFloatWrapper_.AddEntriesFrom(ref input, _repeated_repeatedFloatWrapper_codec); break; } case 1738: { - repeatedDoubleWrapper_.AddEntriesFrom(input, _repeated_repeatedDoubleWrapper_codec); + repeatedDoubleWrapper_.AddEntriesFrom(ref input, _repeated_repeatedDoubleWrapper_codec); break; } case 1746: { - repeatedStringWrapper_.AddEntriesFrom(input, _repeated_repeatedStringWrapper_codec); + repeatedStringWrapper_.AddEntriesFrom(ref input, _repeated_repeatedStringWrapper_codec); break; } case 1754: { - repeatedBytesWrapper_.AddEntriesFrom(input, _repeated_repeatedBytesWrapper_codec); + repeatedBytesWrapper_.AddEntriesFrom(ref input, _repeated_repeatedBytesWrapper_codec); break; } case 2410: { @@ -3988,32 +5131,36 @@ public enum OneofFieldOneofCase { input.ReadMessage(OptionalValue); break; } + case 2456: { + OptionalNullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum(); + break; + } case 2490: { - repeatedDuration_.AddEntriesFrom(input, _repeated_repeatedDuration_codec); + repeatedDuration_.AddEntriesFrom(ref input, _repeated_repeatedDuration_codec); break; } case 2498: { - repeatedTimestamp_.AddEntriesFrom(input, _repeated_repeatedTimestamp_codec); + repeatedTimestamp_.AddEntriesFrom(ref input, _repeated_repeatedTimestamp_codec); break; } case 2506: { - repeatedFieldmask_.AddEntriesFrom(input, _repeated_repeatedFieldmask_codec); + repeatedFieldmask_.AddEntriesFrom(ref input, _repeated_repeatedFieldmask_codec); break; } case 2522: { - repeatedAny_.AddEntriesFrom(input, _repeated_repeatedAny_codec); + repeatedAny_.AddEntriesFrom(ref input, _repeated_repeatedAny_codec); break; } case 2530: { - repeatedValue_.AddEntriesFrom(input, _repeated_repeatedValue_codec); + repeatedValue_.AddEntriesFrom(ref input, _repeated_repeatedValue_codec); break; } case 2538: { - repeatedListValue_.AddEntriesFrom(input, _repeated_repeatedListValue_codec); + repeatedListValue_.AddEntriesFrom(ref input, _repeated_repeatedListValue_codec); break; } case 2594: { - repeatedStruct_.AddEntriesFrom(input, _repeated_repeatedStruct_codec); + repeatedStruct_.AddEntriesFrom(ref input, _repeated_repeatedStruct_codec); break; } case 3208: { @@ -4091,6 +5238,7 @@ public enum OneofFieldOneofCase { } } } + #endif #region Nested types /// Container for nested types declared in the TestAllTypesProto3 message type. @@ -4115,7 +5263,11 @@ public enum AliasedEnum { [pbr::OriginalName("bAz", PreferredAlias = false)] BAz = 2, } - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4208,6 +5360,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (A != 0) { output.WriteRawTag(8); output.WriteInt32(A); @@ -4219,7 +5374,25 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (A != 0) { + output.WriteRawTag(8); + output.WriteInt32(A); + } + if (corecursive_ != null) { + output.WriteRawTag(18); + output.WriteMessage(Corecursive); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4255,6 +5428,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4274,7 +5450,33 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + A = input.ReadInt32(); + break; + } + case 18: { + if (corecursive_ == null) { + Corecursive = new global::ProtobufTestMessages.Proto3.TestAllTypesProto3(); + } + input.ReadMessage(Corecursive); + break; + } + } + } } + #endif } @@ -4283,7 +5485,11 @@ public sealed partial class NestedMessage : pb::IMessage { } - public sealed partial class ForeignMessage : pb::IMessage { + public sealed partial class ForeignMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ForeignMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4362,6 +5568,9 @@ public sealed partial class ForeignMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (C != 0) { output.WriteRawTag(8); output.WriteInt32(C); @@ -4369,7 +5578,21 @@ public sealed partial class ForeignMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (C != 0) { + output.WriteRawTag(8); + output.WriteInt32(C); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4396,6 +5619,9 @@ public sealed partial class ForeignMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4408,7 +5634,26 @@ public sealed partial class ForeignMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + C = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs b/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs index e55df12f2ec8..a843c4ae8baf 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs @@ -1120,7 +1120,11 @@ public enum VeryLargeEnum { /// This proto includes every type of field in both singular and repeated /// forms. /// - public sealed partial class TestAllTypes : pb::IMessage { + public sealed partial class TestAllTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestAllTypes()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -1165,16 +1169,16 @@ public sealed partial class TestAllTypes : pb::IMessage { optionalString_ = other.optionalString_; optionalBytes_ = other.optionalBytes_; optionalGroup_ = other.HasOptionalGroup ? other.optionalGroup_.Clone() : null; - optionalNestedMessage_ = other.HasOptionalNestedMessage ? other.optionalNestedMessage_.Clone() : null; - optionalForeignMessage_ = other.HasOptionalForeignMessage ? other.optionalForeignMessage_.Clone() : null; - optionalImportMessage_ = other.HasOptionalImportMessage ? other.optionalImportMessage_.Clone() : null; + optionalNestedMessage_ = other.optionalNestedMessage_ != null ? other.optionalNestedMessage_.Clone() : null; + optionalForeignMessage_ = other.optionalForeignMessage_ != null ? other.optionalForeignMessage_.Clone() : null; + optionalImportMessage_ = other.optionalImportMessage_ != null ? other.optionalImportMessage_.Clone() : null; optionalNestedEnum_ = other.optionalNestedEnum_; optionalForeignEnum_ = other.optionalForeignEnum_; optionalImportEnum_ = other.optionalImportEnum_; optionalStringPiece_ = other.optionalStringPiece_; optionalCord_ = other.optionalCord_; - optionalPublicImportMessage_ = other.HasOptionalPublicImportMessage ? other.optionalPublicImportMessage_.Clone() : null; - optionalLazyMessage_ = other.HasOptionalLazyMessage ? other.optionalLazyMessage_.Clone() : null; + optionalPublicImportMessage_ = other.optionalPublicImportMessage_ != null ? other.optionalPublicImportMessage_.Clone() : null; + optionalLazyMessage_ = other.optionalLazyMessage_ != null ? other.optionalLazyMessage_.Clone() : null; repeatedInt32_ = other.repeatedInt32_.Clone(); repeatedInt64_ = other.repeatedInt64_.Clone(); repeatedUint32_ = other.repeatedUint32_.Clone(); @@ -1635,16 +1639,6 @@ public sealed partial class TestAllTypes : pb::IMessage { optionalNestedMessage_ = value; } } - /// Gets whether the optional_nested_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalNestedMessage { - get { return optionalNestedMessage_ != null; } - } - /// Clears the value of the optional_nested_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalNestedMessage() { - optionalNestedMessage_ = null; - } /// Field number for the "optional_foreign_message" field. public const int OptionalForeignMessageFieldNumber = 19; @@ -1656,16 +1650,6 @@ public sealed partial class TestAllTypes : pb::IMessage { optionalForeignMessage_ = value; } } - /// Gets whether the optional_foreign_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalForeignMessage { - get { return optionalForeignMessage_ != null; } - } - /// Clears the value of the optional_foreign_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalForeignMessage() { - optionalForeignMessage_ = null; - } /// Field number for the "optional_import_message" field. public const int OptionalImportMessageFieldNumber = 20; @@ -1677,16 +1661,6 @@ public sealed partial class TestAllTypes : pb::IMessage { optionalImportMessage_ = value; } } - /// Gets whether the optional_import_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalImportMessage { - get { return optionalImportMessage_ != null; } - } - /// Clears the value of the optional_import_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalImportMessage() { - optionalImportMessage_ = null; - } /// Field number for the "optional_nested_enum" field. public const int OptionalNestedEnumFieldNumber = 21; @@ -1819,16 +1793,6 @@ public sealed partial class TestAllTypes : pb::IMessage { optionalPublicImportMessage_ = value; } } - /// Gets whether the optional_public_import_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalPublicImportMessage { - get { return optionalPublicImportMessage_ != null; } - } - /// Clears the value of the optional_public_import_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalPublicImportMessage() { - optionalPublicImportMessage_ = null; - } /// Field number for the "optional_lazy_message" field. public const int OptionalLazyMessageFieldNumber = 27; @@ -1840,16 +1804,6 @@ public sealed partial class TestAllTypes : pb::IMessage { optionalLazyMessage_ = value; } } - /// Gets whether the optional_lazy_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalLazyMessage { - get { return optionalLazyMessage_ != null; } - } - /// Clears the value of the optional_lazy_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalLazyMessage() { - optionalLazyMessage_ = null; - } /// Field number for the "repeated_int32" field. public const int RepeatedInt32FieldNumber = 31; @@ -2610,24 +2564,12 @@ public sealed partial class TestAllTypes : pb::IMessage { public const int OneofNestedMessageFieldNumber = 112; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage OneofNestedMessage { - get { return HasOneofNestedMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage) oneofField_ : null; } + get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage) oneofField_ : null; } set { oneofField_ = value; oneofFieldCase_ = value == null ? OneofFieldOneofCase.None : OneofFieldOneofCase.OneofNestedMessage; } } - /// Gets whether the "oneof_nested_message" field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOneofNestedMessage { - get { return oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; } - } - /// Clears the value of the oneof if it's currently set to "oneof_nested_message" - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOneofNestedMessage() { - if (HasOneofNestedMessage) { - ClearOneofField(); - } - } /// Field number for the "oneof_string" field. public const int OneofStringFieldNumber = 113; @@ -2807,16 +2749,16 @@ public enum OneofFieldOneofCase { if (HasOptionalString) hash ^= OptionalString.GetHashCode(); if (HasOptionalBytes) hash ^= OptionalBytes.GetHashCode(); if (HasOptionalGroup) hash ^= OptionalGroup.GetHashCode(); - if (HasOptionalNestedMessage) hash ^= OptionalNestedMessage.GetHashCode(); - if (HasOptionalForeignMessage) hash ^= OptionalForeignMessage.GetHashCode(); - if (HasOptionalImportMessage) hash ^= OptionalImportMessage.GetHashCode(); + if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode(); + if (optionalForeignMessage_ != null) hash ^= OptionalForeignMessage.GetHashCode(); + if (optionalImportMessage_ != null) hash ^= OptionalImportMessage.GetHashCode(); if (HasOptionalNestedEnum) hash ^= OptionalNestedEnum.GetHashCode(); if (HasOptionalForeignEnum) hash ^= OptionalForeignEnum.GetHashCode(); if (HasOptionalImportEnum) hash ^= OptionalImportEnum.GetHashCode(); if (HasOptionalStringPiece) hash ^= OptionalStringPiece.GetHashCode(); if (HasOptionalCord) hash ^= OptionalCord.GetHashCode(); - if (HasOptionalPublicImportMessage) hash ^= OptionalPublicImportMessage.GetHashCode(); - if (HasOptionalLazyMessage) hash ^= OptionalLazyMessage.GetHashCode(); + if (optionalPublicImportMessage_ != null) hash ^= OptionalPublicImportMessage.GetHashCode(); + if (optionalLazyMessage_ != null) hash ^= OptionalLazyMessage.GetHashCode(); hash ^= repeatedInt32_.GetHashCode(); hash ^= repeatedInt64_.GetHashCode(); hash ^= repeatedUint32_.GetHashCode(); @@ -2863,7 +2805,7 @@ public enum OneofFieldOneofCase { if (HasDefaultStringPiece) hash ^= DefaultStringPiece.GetHashCode(); if (HasDefaultCord) hash ^= DefaultCord.GetHashCode(); if (HasOneofUint32) hash ^= OneofUint32.GetHashCode(); - if (HasOneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode(); if (HasOneofString) hash ^= OneofString.GetHashCode(); if (HasOneofBytes) hash ^= OneofBytes.GetHashCode(); hash ^= (int) oneofFieldCase_; @@ -2880,6 +2822,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasOptionalInt32) { output.WriteRawTag(8); output.WriteInt32(OptionalInt32); @@ -2945,15 +2890,15 @@ public enum OneofFieldOneofCase { output.WriteGroup(OptionalGroup); output.WriteRawTag(132, 1); } - if (HasOptionalNestedMessage) { + if (optionalNestedMessage_ != null) { output.WriteRawTag(146, 1); output.WriteMessage(OptionalNestedMessage); } - if (HasOptionalForeignMessage) { + if (optionalForeignMessage_ != null) { output.WriteRawTag(154, 1); output.WriteMessage(OptionalForeignMessage); } - if (HasOptionalImportMessage) { + if (optionalImportMessage_ != null) { output.WriteRawTag(162, 1); output.WriteMessage(OptionalImportMessage); } @@ -2977,11 +2922,11 @@ public enum OneofFieldOneofCase { output.WriteRawTag(202, 1); output.WriteString(OptionalCord); } - if (HasOptionalPublicImportMessage) { + if (optionalPublicImportMessage_ != null) { output.WriteRawTag(210, 1); output.WriteMessage(OptionalPublicImportMessage); } - if (HasOptionalLazyMessage) { + if (optionalLazyMessage_ != null) { output.WriteRawTag(218, 1); output.WriteMessage(OptionalLazyMessage); } @@ -3094,7 +3039,7 @@ public enum OneofFieldOneofCase { output.WriteRawTag(248, 6); output.WriteUInt32(OneofUint32); } - if (HasOneofNestedMessage) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { output.WriteRawTag(130, 7); output.WriteMessage(OneofNestedMessage); } @@ -3109,7 +3054,243 @@ public enum OneofFieldOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasOptionalInt32) { + output.WriteRawTag(8); + output.WriteInt32(OptionalInt32); + } + if (HasOptionalInt64) { + output.WriteRawTag(16); + output.WriteInt64(OptionalInt64); + } + if (HasOptionalUint32) { + output.WriteRawTag(24); + output.WriteUInt32(OptionalUint32); + } + if (HasOptionalUint64) { + output.WriteRawTag(32); + output.WriteUInt64(OptionalUint64); + } + if (HasOptionalSint32) { + output.WriteRawTag(40); + output.WriteSInt32(OptionalSint32); + } + if (HasOptionalSint64) { + output.WriteRawTag(48); + output.WriteSInt64(OptionalSint64); + } + if (HasOptionalFixed32) { + output.WriteRawTag(61); + output.WriteFixed32(OptionalFixed32); + } + if (HasOptionalFixed64) { + output.WriteRawTag(65); + output.WriteFixed64(OptionalFixed64); + } + if (HasOptionalSfixed32) { + output.WriteRawTag(77); + output.WriteSFixed32(OptionalSfixed32); + } + if (HasOptionalSfixed64) { + output.WriteRawTag(81); + output.WriteSFixed64(OptionalSfixed64); + } + if (HasOptionalFloat) { + output.WriteRawTag(93); + output.WriteFloat(OptionalFloat); + } + if (HasOptionalDouble) { + output.WriteRawTag(97); + output.WriteDouble(OptionalDouble); + } + if (HasOptionalBool) { + output.WriteRawTag(104); + output.WriteBool(OptionalBool); + } + if (HasOptionalString) { + output.WriteRawTag(114); + output.WriteString(OptionalString); + } + if (HasOptionalBytes) { + output.WriteRawTag(122); + output.WriteBytes(OptionalBytes); + } + if (HasOptionalGroup) { + output.WriteRawTag(131, 1); + output.WriteGroup(OptionalGroup); + output.WriteRawTag(132, 1); + } + if (optionalNestedMessage_ != null) { + output.WriteRawTag(146, 1); + output.WriteMessage(OptionalNestedMessage); + } + if (optionalForeignMessage_ != null) { + output.WriteRawTag(154, 1); + output.WriteMessage(OptionalForeignMessage); + } + if (optionalImportMessage_ != null) { + output.WriteRawTag(162, 1); + output.WriteMessage(OptionalImportMessage); + } + if (HasOptionalNestedEnum) { + output.WriteRawTag(168, 1); + output.WriteEnum((int) OptionalNestedEnum); + } + if (HasOptionalForeignEnum) { + output.WriteRawTag(176, 1); + output.WriteEnum((int) OptionalForeignEnum); + } + if (HasOptionalImportEnum) { + output.WriteRawTag(184, 1); + output.WriteEnum((int) OptionalImportEnum); + } + if (HasOptionalStringPiece) { + output.WriteRawTag(194, 1); + output.WriteString(OptionalStringPiece); + } + if (HasOptionalCord) { + output.WriteRawTag(202, 1); + output.WriteString(OptionalCord); + } + if (optionalPublicImportMessage_ != null) { + output.WriteRawTag(210, 1); + output.WriteMessage(OptionalPublicImportMessage); + } + if (optionalLazyMessage_ != null) { + output.WriteRawTag(218, 1); + output.WriteMessage(OptionalLazyMessage); + } + repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec); + repeatedInt64_.WriteTo(ref output, _repeated_repeatedInt64_codec); + repeatedUint32_.WriteTo(ref output, _repeated_repeatedUint32_codec); + repeatedUint64_.WriteTo(ref output, _repeated_repeatedUint64_codec); + repeatedSint32_.WriteTo(ref output, _repeated_repeatedSint32_codec); + repeatedSint64_.WriteTo(ref output, _repeated_repeatedSint64_codec); + repeatedFixed32_.WriteTo(ref output, _repeated_repeatedFixed32_codec); + repeatedFixed64_.WriteTo(ref output, _repeated_repeatedFixed64_codec); + repeatedSfixed32_.WriteTo(ref output, _repeated_repeatedSfixed32_codec); + repeatedSfixed64_.WriteTo(ref output, _repeated_repeatedSfixed64_codec); + repeatedFloat_.WriteTo(ref output, _repeated_repeatedFloat_codec); + repeatedDouble_.WriteTo(ref output, _repeated_repeatedDouble_codec); + repeatedBool_.WriteTo(ref output, _repeated_repeatedBool_codec); + repeatedString_.WriteTo(ref output, _repeated_repeatedString_codec); + repeatedBytes_.WriteTo(ref output, _repeated_repeatedBytes_codec); + repeatedGroup_.WriteTo(ref output, _repeated_repeatedGroup_codec); + repeatedNestedMessage_.WriteTo(ref output, _repeated_repeatedNestedMessage_codec); + repeatedForeignMessage_.WriteTo(ref output, _repeated_repeatedForeignMessage_codec); + repeatedImportMessage_.WriteTo(ref output, _repeated_repeatedImportMessage_codec); + repeatedNestedEnum_.WriteTo(ref output, _repeated_repeatedNestedEnum_codec); + repeatedForeignEnum_.WriteTo(ref output, _repeated_repeatedForeignEnum_codec); + repeatedImportEnum_.WriteTo(ref output, _repeated_repeatedImportEnum_codec); + repeatedStringPiece_.WriteTo(ref output, _repeated_repeatedStringPiece_codec); + repeatedCord_.WriteTo(ref output, _repeated_repeatedCord_codec); + repeatedLazyMessage_.WriteTo(ref output, _repeated_repeatedLazyMessage_codec); + if (HasDefaultInt32) { + output.WriteRawTag(232, 3); + output.WriteInt32(DefaultInt32); + } + if (HasDefaultInt64) { + output.WriteRawTag(240, 3); + output.WriteInt64(DefaultInt64); + } + if (HasDefaultUint32) { + output.WriteRawTag(248, 3); + output.WriteUInt32(DefaultUint32); + } + if (HasDefaultUint64) { + output.WriteRawTag(128, 4); + output.WriteUInt64(DefaultUint64); + } + if (HasDefaultSint32) { + output.WriteRawTag(136, 4); + output.WriteSInt32(DefaultSint32); + } + if (HasDefaultSint64) { + output.WriteRawTag(144, 4); + output.WriteSInt64(DefaultSint64); + } + if (HasDefaultFixed32) { + output.WriteRawTag(157, 4); + output.WriteFixed32(DefaultFixed32); + } + if (HasDefaultFixed64) { + output.WriteRawTag(161, 4); + output.WriteFixed64(DefaultFixed64); + } + if (HasDefaultSfixed32) { + output.WriteRawTag(173, 4); + output.WriteSFixed32(DefaultSfixed32); + } + if (HasDefaultSfixed64) { + output.WriteRawTag(177, 4); + output.WriteSFixed64(DefaultSfixed64); + } + if (HasDefaultFloat) { + output.WriteRawTag(189, 4); + output.WriteFloat(DefaultFloat); + } + if (HasDefaultDouble) { + output.WriteRawTag(193, 4); + output.WriteDouble(DefaultDouble); + } + if (HasDefaultBool) { + output.WriteRawTag(200, 4); + output.WriteBool(DefaultBool); + } + if (HasDefaultString) { + output.WriteRawTag(210, 4); + output.WriteString(DefaultString); + } + if (HasDefaultBytes) { + output.WriteRawTag(218, 4); + output.WriteBytes(DefaultBytes); + } + if (HasDefaultNestedEnum) { + output.WriteRawTag(136, 5); + output.WriteEnum((int) DefaultNestedEnum); + } + if (HasDefaultForeignEnum) { + output.WriteRawTag(144, 5); + output.WriteEnum((int) DefaultForeignEnum); + } + if (HasDefaultImportEnum) { + output.WriteRawTag(152, 5); + output.WriteEnum((int) DefaultImportEnum); + } + if (HasDefaultStringPiece) { + output.WriteRawTag(162, 5); + output.WriteString(DefaultStringPiece); + } + if (HasDefaultCord) { + output.WriteRawTag(170, 5); + output.WriteString(DefaultCord); + } + if (HasOneofUint32) { + output.WriteRawTag(248, 6); + output.WriteUInt32(OneofUint32); + } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + output.WriteRawTag(130, 7); + output.WriteMessage(OneofNestedMessage); + } + if (HasOneofString) { + output.WriteRawTag(138, 7); + output.WriteString(OneofString); + } + if (HasOneofBytes) { + output.WriteRawTag(146, 7); + output.WriteBytes(OneofBytes); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -3162,13 +3343,13 @@ public enum OneofFieldOneofCase { if (HasOptionalGroup) { size += 4 + pb::CodedOutputStream.ComputeGroupSize(OptionalGroup); } - if (HasOptionalNestedMessage) { + if (optionalNestedMessage_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage); } - if (HasOptionalForeignMessage) { + if (optionalForeignMessage_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage); } - if (HasOptionalImportMessage) { + if (optionalImportMessage_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalImportMessage); } if (HasOptionalNestedEnum) { @@ -3186,10 +3367,10 @@ public enum OneofFieldOneofCase { if (HasOptionalCord) { size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord); } - if (HasOptionalPublicImportMessage) { + if (optionalPublicImportMessage_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalPublicImportMessage); } - if (HasOptionalLazyMessage) { + if (optionalLazyMessage_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalLazyMessage); } size += repeatedInt32_.CalculateSize(_repeated_repeatedInt32_codec); @@ -3280,7 +3461,7 @@ public enum OneofFieldOneofCase { if (HasOneofUint32) { size += 2 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32); } - if (HasOneofNestedMessage) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(OneofNestedMessage); } if (HasOneofString) { @@ -3351,20 +3532,20 @@ public enum OneofFieldOneofCase { } OptionalGroup.MergeFrom(other.OptionalGroup); } - if (other.HasOptionalNestedMessage) { - if (!HasOptionalNestedMessage) { + if (other.optionalNestedMessage_ != null) { + if (optionalNestedMessage_ == null) { OptionalNestedMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); } OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage); } - if (other.HasOptionalForeignMessage) { - if (!HasOptionalForeignMessage) { + if (other.optionalForeignMessage_ != null) { + if (optionalForeignMessage_ == null) { OptionalForeignMessage = new global::Google.Protobuf.TestProtos.Proto2.ForeignMessage(); } OptionalForeignMessage.MergeFrom(other.OptionalForeignMessage); } - if (other.HasOptionalImportMessage) { - if (!HasOptionalImportMessage) { + if (other.optionalImportMessage_ != null) { + if (optionalImportMessage_ == null) { OptionalImportMessage = new global::Google.Protobuf.TestProtos.Proto2.ImportMessage(); } OptionalImportMessage.MergeFrom(other.OptionalImportMessage); @@ -3384,14 +3565,14 @@ public enum OneofFieldOneofCase { if (other.HasOptionalCord) { OptionalCord = other.OptionalCord; } - if (other.HasOptionalPublicImportMessage) { - if (!HasOptionalPublicImportMessage) { + if (other.optionalPublicImportMessage_ != null) { + if (optionalPublicImportMessage_ == null) { OptionalPublicImportMessage = new global::Google.Protobuf.TestProtos.Proto2.PublicImportMessage(); } OptionalPublicImportMessage.MergeFrom(other.OptionalPublicImportMessage); } - if (other.HasOptionalLazyMessage) { - if (!HasOptionalLazyMessage) { + if (other.optionalLazyMessage_ != null) { + if (optionalLazyMessage_ == null) { OptionalLazyMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); } OptionalLazyMessage.MergeFrom(other.OptionalLazyMessage); @@ -3504,6 +3685,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -3578,21 +3762,21 @@ public enum OneofFieldOneofCase { break; } case 146: { - if (!HasOptionalNestedMessage) { + if (optionalNestedMessage_ == null) { OptionalNestedMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); } input.ReadMessage(OptionalNestedMessage); break; } case 154: { - if (!HasOptionalForeignMessage) { + if (optionalForeignMessage_ == null) { OptionalForeignMessage = new global::Google.Protobuf.TestProtos.Proto2.ForeignMessage(); } input.ReadMessage(OptionalForeignMessage); break; } case 162: { - if (!HasOptionalImportMessage) { + if (optionalImportMessage_ == null) { OptionalImportMessage = new global::Google.Protobuf.TestProtos.Proto2.ImportMessage(); } input.ReadMessage(OptionalImportMessage); @@ -3619,14 +3803,14 @@ public enum OneofFieldOneofCase { break; } case 210: { - if (!HasOptionalPublicImportMessage) { + if (optionalPublicImportMessage_ == null) { OptionalPublicImportMessage = new global::Google.Protobuf.TestProtos.Proto2.PublicImportMessage(); } input.ReadMessage(OptionalPublicImportMessage); break; } case 218: { - if (!HasOptionalLazyMessage) { + if (optionalLazyMessage_ == null) { OptionalLazyMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); } input.ReadMessage(OptionalLazyMessage); @@ -3834,7 +4018,7 @@ public enum OneofFieldOneofCase { } case 898: { global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); - if (HasOneofNestedMessage) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { subBuilder.MergeFrom(OneofNestedMessage); } input.ReadMessage(subBuilder); @@ -3851,40 +4035,398 @@ public enum OneofFieldOneofCase { } } } + #endif } - #region Nested types - /// Container for nested types declared in the TestAllTypes message type. + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static partial class Types { - public enum NestedEnum { - [pbr::OriginalName("FOO")] Foo = 1, - [pbr::OriginalName("BAR")] Bar = 2, - [pbr::OriginalName("BAZ")] Baz = 3, - /// - /// Intentionally negative. - /// - [pbr::OriginalName("NEG")] Neg = -1, - } - - public sealed partial class NestedMessage : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); - private pb::UnknownFieldSet _unknownFields; - private int _hasBits0; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Descriptor.NestedTypes[0]; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + OptionalInt32 = input.ReadInt32(); + break; + } + case 16: { + OptionalInt64 = input.ReadInt64(); + break; + } + case 24: { + OptionalUint32 = input.ReadUInt32(); + break; + } + case 32: { + OptionalUint64 = input.ReadUInt64(); + break; + } + case 40: { + OptionalSint32 = input.ReadSInt32(); + break; + } + case 48: { + OptionalSint64 = input.ReadSInt64(); + break; + } + case 61: { + OptionalFixed32 = input.ReadFixed32(); + break; + } + case 65: { + OptionalFixed64 = input.ReadFixed64(); + break; + } + case 77: { + OptionalSfixed32 = input.ReadSFixed32(); + break; + } + case 81: { + OptionalSfixed64 = input.ReadSFixed64(); + break; + } + case 93: { + OptionalFloat = input.ReadFloat(); + break; + } + case 97: { + OptionalDouble = input.ReadDouble(); + break; + } + case 104: { + OptionalBool = input.ReadBool(); + break; + } + case 114: { + OptionalString = input.ReadString(); + break; + } + case 122: { + OptionalBytes = input.ReadBytes(); + break; + } + case 131: { + if (!HasOptionalGroup) { + OptionalGroup = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.OptionalGroup(); + } + input.ReadGroup(OptionalGroup); + break; + } + case 146: { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); + } + input.ReadMessage(OptionalNestedMessage); + break; + } + case 154: { + if (optionalForeignMessage_ == null) { + OptionalForeignMessage = new global::Google.Protobuf.TestProtos.Proto2.ForeignMessage(); + } + input.ReadMessage(OptionalForeignMessage); + break; + } + case 162: { + if (optionalImportMessage_ == null) { + OptionalImportMessage = new global::Google.Protobuf.TestProtos.Proto2.ImportMessage(); + } + input.ReadMessage(OptionalImportMessage); + break; + } + case 168: { + OptionalNestedEnum = (global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedEnum) input.ReadEnum(); + break; + } + case 176: { + OptionalForeignEnum = (global::Google.Protobuf.TestProtos.Proto2.ForeignEnum) input.ReadEnum(); + break; + } + case 184: { + OptionalImportEnum = (global::Google.Protobuf.TestProtos.Proto2.ImportEnum) input.ReadEnum(); + break; + } + case 194: { + OptionalStringPiece = input.ReadString(); + break; + } + case 202: { + OptionalCord = input.ReadString(); + break; + } + case 210: { + if (optionalPublicImportMessage_ == null) { + OptionalPublicImportMessage = new global::Google.Protobuf.TestProtos.Proto2.PublicImportMessage(); + } + input.ReadMessage(OptionalPublicImportMessage); + break; + } + case 218: { + if (optionalLazyMessage_ == null) { + OptionalLazyMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); + } + input.ReadMessage(OptionalLazyMessage); + break; + } + case 250: + case 248: { + repeatedInt32_.AddEntriesFrom(ref input, _repeated_repeatedInt32_codec); + break; + } + case 258: + case 256: { + repeatedInt64_.AddEntriesFrom(ref input, _repeated_repeatedInt64_codec); + break; + } + case 266: + case 264: { + repeatedUint32_.AddEntriesFrom(ref input, _repeated_repeatedUint32_codec); + break; + } + case 274: + case 272: { + repeatedUint64_.AddEntriesFrom(ref input, _repeated_repeatedUint64_codec); + break; + } + case 282: + case 280: { + repeatedSint32_.AddEntriesFrom(ref input, _repeated_repeatedSint32_codec); + break; + } + case 290: + case 288: { + repeatedSint64_.AddEntriesFrom(ref input, _repeated_repeatedSint64_codec); + break; + } + case 298: + case 301: { + repeatedFixed32_.AddEntriesFrom(ref input, _repeated_repeatedFixed32_codec); + break; + } + case 306: + case 305: { + repeatedFixed64_.AddEntriesFrom(ref input, _repeated_repeatedFixed64_codec); + break; + } + case 314: + case 317: { + repeatedSfixed32_.AddEntriesFrom(ref input, _repeated_repeatedSfixed32_codec); + break; + } + case 322: + case 321: { + repeatedSfixed64_.AddEntriesFrom(ref input, _repeated_repeatedSfixed64_codec); + break; + } + case 330: + case 333: { + repeatedFloat_.AddEntriesFrom(ref input, _repeated_repeatedFloat_codec); + break; + } + case 338: + case 337: { + repeatedDouble_.AddEntriesFrom(ref input, _repeated_repeatedDouble_codec); + break; + } + case 346: + case 344: { + repeatedBool_.AddEntriesFrom(ref input, _repeated_repeatedBool_codec); + break; + } + case 354: { + repeatedString_.AddEntriesFrom(ref input, _repeated_repeatedString_codec); + break; + } + case 362: { + repeatedBytes_.AddEntriesFrom(ref input, _repeated_repeatedBytes_codec); + break; + } + case 371: { + repeatedGroup_.AddEntriesFrom(ref input, _repeated_repeatedGroup_codec); + break; + } + case 386: { + repeatedNestedMessage_.AddEntriesFrom(ref input, _repeated_repeatedNestedMessage_codec); + break; + } + case 394: { + repeatedForeignMessage_.AddEntriesFrom(ref input, _repeated_repeatedForeignMessage_codec); + break; + } + case 402: { + repeatedImportMessage_.AddEntriesFrom(ref input, _repeated_repeatedImportMessage_codec); + break; + } + case 410: + case 408: { + repeatedNestedEnum_.AddEntriesFrom(ref input, _repeated_repeatedNestedEnum_codec); + break; + } + case 418: + case 416: { + repeatedForeignEnum_.AddEntriesFrom(ref input, _repeated_repeatedForeignEnum_codec); + break; + } + case 426: + case 424: { + repeatedImportEnum_.AddEntriesFrom(ref input, _repeated_repeatedImportEnum_codec); + break; + } + case 434: { + repeatedStringPiece_.AddEntriesFrom(ref input, _repeated_repeatedStringPiece_codec); + break; + } + case 442: { + repeatedCord_.AddEntriesFrom(ref input, _repeated_repeatedCord_codec); + break; + } + case 458: { + repeatedLazyMessage_.AddEntriesFrom(ref input, _repeated_repeatedLazyMessage_codec); + break; + } + case 488: { + DefaultInt32 = input.ReadInt32(); + break; + } + case 496: { + DefaultInt64 = input.ReadInt64(); + break; + } + case 504: { + DefaultUint32 = input.ReadUInt32(); + break; + } + case 512: { + DefaultUint64 = input.ReadUInt64(); + break; + } + case 520: { + DefaultSint32 = input.ReadSInt32(); + break; + } + case 528: { + DefaultSint64 = input.ReadSInt64(); + break; + } + case 541: { + DefaultFixed32 = input.ReadFixed32(); + break; + } + case 545: { + DefaultFixed64 = input.ReadFixed64(); + break; + } + case 557: { + DefaultSfixed32 = input.ReadSFixed32(); + break; + } + case 561: { + DefaultSfixed64 = input.ReadSFixed64(); + break; + } + case 573: { + DefaultFloat = input.ReadFloat(); + break; + } + case 577: { + DefaultDouble = input.ReadDouble(); + break; + } + case 584: { + DefaultBool = input.ReadBool(); + break; + } + case 594: { + DefaultString = input.ReadString(); + break; + } + case 602: { + DefaultBytes = input.ReadBytes(); + break; + } + case 648: { + DefaultNestedEnum = (global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedEnum) input.ReadEnum(); + break; + } + case 656: { + DefaultForeignEnum = (global::Google.Protobuf.TestProtos.Proto2.ForeignEnum) input.ReadEnum(); + break; + } + case 664: { + DefaultImportEnum = (global::Google.Protobuf.TestProtos.Proto2.ImportEnum) input.ReadEnum(); + break; + } + case 674: { + DefaultStringPiece = input.ReadString(); + break; + } + case 682: { + DefaultCord = input.ReadString(); + break; + } + case 888: { + OneofUint32 = input.ReadUInt32(); + break; + } + case 898: { + global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + subBuilder.MergeFrom(OneofNestedMessage); + } + input.ReadMessage(subBuilder); + OneofNestedMessage = subBuilder; + break; + } + case 906: { + OneofString = input.ReadString(); + break; + } + case 914: { + OneofBytes = input.ReadBytes(); + break; + } + } + } + } + #endif + + #region Nested types + /// Container for nested types declared in the TestAllTypes message type. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static partial class Types { + public enum NestedEnum { + [pbr::OriginalName("FOO")] Foo = 1, + [pbr::OriginalName("BAR")] Bar = 2, + [pbr::OriginalName("BAZ")] Baz = 3, + /// + /// Intentionally negative. + /// + [pbr::OriginalName("NEG")] Neg = -1, + } + + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); + private pb::UnknownFieldSet _unknownFields; + private int _hasBits0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Descriptor.NestedTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public NestedMessage() { OnConstruction(); } @@ -3966,6 +4508,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasBb) { output.WriteRawTag(8); output.WriteInt32(Bb); @@ -3973,7 +4518,21 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasBb) { + output.WriteRawTag(8); + output.WriteInt32(Bb); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4000,6 +4559,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4012,11 +4574,34 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Bb = input.ReadInt32(); + break; + } + } + } + } + #endif + } - public sealed partial class OptionalGroup : pb::IMessage { + public sealed partial class OptionalGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OptionalGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4110,6 +4695,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(136, 1); output.WriteInt32(A); @@ -4117,8 +4705,22 @@ public sealed partial class OptionalGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(136, 1); + output.WriteInt32(A); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -4144,6 +4746,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4158,11 +4763,36 @@ public sealed partial class OptionalGroup : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 132: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 136: { + A = input.ReadInt32(); + break; + } + } + } + } + #endif + } - public sealed partial class RepeatedGroup : pb::IMessage { + public sealed partial class RepeatedGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RepeatedGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4256,6 +4886,9 @@ public sealed partial class RepeatedGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(248, 2); output.WriteInt32(A); @@ -4263,8 +4896,22 @@ public sealed partial class RepeatedGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(248, 2); + output.WriteInt32(A); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -4290,6 +4937,9 @@ public sealed partial class RepeatedGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4304,7 +4954,28 @@ public sealed partial class RepeatedGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 372: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 376: { + A = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -4314,9 +4985,13 @@ public sealed partial class RepeatedGroup : pb::IMessage { } /// - /// This proto includes a recusively nested message. + /// This proto includes a recursively nested message. /// - public sealed partial class NestedTestAllTypes : pb::IMessage { + public sealed partial class NestedTestAllTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedTestAllTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4341,8 +5016,8 @@ public sealed partial class NestedTestAllTypes : pb::IMessageGets whether the child field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasChild { - get { return child_ != null; } - } - /// Clears the value of the child field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearChild() { - child_ = null; - } /// Field number for the "payload" field. public const int PayloadFieldNumber = 2; @@ -4383,16 +5048,6 @@ public sealed partial class NestedTestAllTypes : pb::IMessageGets whether the payload field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasPayload { - get { return payload_ != null; } - } - /// Clears the value of the payload field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearPayload() { - payload_ = null; - } /// Field number for the "repeated_child" field. public const int RepeatedChildFieldNumber = 3; @@ -4426,8 +5081,8 @@ public sealed partial class NestedTestAllTypes : pb::IMessage { + public sealed partial class TestDeprecatedFields : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestDeprecatedFields()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4676,6 +5393,9 @@ public enum OneofFieldsOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasDeprecatedInt32) { output.WriteRawTag(8); output.WriteInt32(DeprecatedInt32); @@ -4687,7 +5407,25 @@ public enum OneofFieldsOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasDeprecatedInt32) { + output.WriteRawTag(8); + output.WriteInt32(DeprecatedInt32); + } + if (HasDeprecatedInt32InOneof) { + output.WriteRawTag(16); + output.WriteInt32(DeprecatedInt32InOneof); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4723,6 +5461,9 @@ public enum OneofFieldsOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4739,12 +5480,39 @@ public enum OneofFieldsOneofCase { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + DeprecatedInt32 = input.ReadInt32(); + break; + } + case 16: { + DeprecatedInt32InOneof = input.ReadInt32(); + break; + } + } + } } + #endif } [global::System.ObsoleteAttribute] - public sealed partial class TestDeprecatedMessage : pb::IMessage { + public sealed partial class TestDeprecatedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestDeprecatedMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4809,11 +5577,24 @@ public sealed partial class TestDeprecatedMessage : pb::IMessage - public sealed partial class ForeignMessage : pb::IMessage { + public sealed partial class ForeignMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ForeignMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -4970,6 +5773,9 @@ public sealed partial class ForeignMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasC) { output.WriteRawTag(8); output.WriteInt32(C); @@ -4981,7 +5787,25 @@ public sealed partial class ForeignMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasC) { + output.WriteRawTag(8); + output.WriteInt32(C); + } + if (HasD) { + output.WriteRawTag(16); + output.WriteInt32(D); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5014,6 +5838,9 @@ public sealed partial class ForeignMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5030,11 +5857,38 @@ public sealed partial class ForeignMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + C = input.ReadInt32(); + break; + } + case 16: { + D = input.ReadInt32(); + break; + } + } + } } + #endif } - public sealed partial class TestReservedFields : pb::IMessage { + public sealed partial class TestReservedFields : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestReservedFields()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5099,10 +5953,23 @@ public sealed partial class TestReservedFields : pb::IMessage { + public sealed partial class TestAllExtensions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestAllExtensions()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -5209,13 +6098,29 @@ public sealed partial class TestAllExtensions : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -5276,7 +6201,11 @@ public sealed partial class TestAllExtensions : pb::IExtendableMessage { + public sealed partial class OptionalGroup_extension : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OptionalGroup_extension()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -5370,6 +6299,9 @@ public sealed partial class OptionalGroup_extension : pb::IMessage { + public sealed partial class RepeatedGroup_extension : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RepeatedGroup_extension()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -5516,6 +6490,9 @@ public sealed partial class RepeatedGroup_extension : pb::IMessage { + public sealed partial class TestGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -5686,6 +6705,9 @@ public sealed partial class TestGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasOptionalGroup) { output.WriteRawTag(131, 1); output.WriteGroup(OptionalGroup); @@ -5698,7 +6720,26 @@ public sealed partial class TestGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasOptionalGroup) { + output.WriteRawTag(131, 1); + output.WriteGroup(OptionalGroup); + output.WriteRawTag(132, 1); + } + if (HasOptionalForeignEnum) { + output.WriteRawTag(176, 1); + output.WriteEnum((int) OptionalForeignEnum); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5734,6 +6775,9 @@ public sealed partial class TestGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5753,13 +6797,43 @@ public sealed partial class TestGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 131: { + if (!HasOptionalGroup) { + OptionalGroup = new global::Google.Protobuf.TestProtos.Proto2.TestGroup.Types.OptionalGroup(); + } + input.ReadGroup(OptionalGroup); + break; + } + case 176: { + OptionalForeignEnum = (global::Google.Protobuf.TestProtos.Proto2.ForeignEnum) input.ReadEnum(); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the TestGroup message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class OptionalGroup : pb::IMessage { + public sealed partial class OptionalGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OptionalGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -5853,6 +6927,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(136, 1); output.WriteInt32(A); @@ -5860,7 +6937,21 @@ public sealed partial class OptionalGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(136, 1); + output.WriteInt32(A); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5882,18 +6973,41 @@ public sealed partial class OptionalGroup : pb::IMessage { if (other.HasA) { A = other.A; } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 132: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 136: { + A = input.ReadInt32(); + break; + } + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { case 132: return; default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 136: { A = input.ReadInt32(); @@ -5902,6 +7016,7 @@ public sealed partial class OptionalGroup : pb::IMessage { } } } + #endif } @@ -5910,7 +7025,11 @@ public sealed partial class OptionalGroup : pb::IMessage { } - public sealed partial class TestGroupExtension : pb::IExtendableMessage { + public sealed partial class TestGroupExtension : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestGroupExtension()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -5984,13 +7103,29 @@ public sealed partial class TestGroupExtension : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -6051,7 +7206,11 @@ public sealed partial class TestGroupExtension : pb::IExtendableMessage { + public sealed partial class TestNestedExtension : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestNestedExtension()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6116,10 +7275,23 @@ public sealed partial class TestNestedExtension : pb::IMessageContainer for nested types declared in the TestNestedExtension message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class OptionalGroup_extension : pb::IMessage { + public sealed partial class OptionalGroup_extension : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OptionalGroup_extension()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -6248,6 +7442,9 @@ public sealed partial class OptionalGroup_extension : pb::IMessage - public sealed partial class TestRequired : pb::IMessage { + public sealed partial class TestRequired : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRequired()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -7299,6 +8538,9 @@ public sealed partial class TestRequired : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(8); output.WriteInt32(A); @@ -7434,7 +8676,149 @@ public sealed partial class TestRequired : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(8); + output.WriteInt32(A); + } + if (HasDummy2) { + output.WriteRawTag(16); + output.WriteInt32(Dummy2); + } + if (HasB) { + output.WriteRawTag(24); + output.WriteInt32(B); + } + if (HasDummy4) { + output.WriteRawTag(32); + output.WriteInt32(Dummy4); + } + if (HasDummy5) { + output.WriteRawTag(40); + output.WriteInt32(Dummy5); + } + if (HasDummy6) { + output.WriteRawTag(48); + output.WriteInt32(Dummy6); + } + if (HasDummy7) { + output.WriteRawTag(56); + output.WriteInt32(Dummy7); + } + if (HasDummy8) { + output.WriteRawTag(64); + output.WriteInt32(Dummy8); + } + if (HasDummy9) { + output.WriteRawTag(72); + output.WriteInt32(Dummy9); + } + if (HasDummy10) { + output.WriteRawTag(80); + output.WriteInt32(Dummy10); + } + if (HasDummy11) { + output.WriteRawTag(88); + output.WriteInt32(Dummy11); + } + if (HasDummy12) { + output.WriteRawTag(96); + output.WriteInt32(Dummy12); + } + if (HasDummy13) { + output.WriteRawTag(104); + output.WriteInt32(Dummy13); + } + if (HasDummy14) { + output.WriteRawTag(112); + output.WriteInt32(Dummy14); + } + if (HasDummy15) { + output.WriteRawTag(120); + output.WriteInt32(Dummy15); + } + if (HasDummy16) { + output.WriteRawTag(128, 1); + output.WriteInt32(Dummy16); + } + if (HasDummy17) { + output.WriteRawTag(136, 1); + output.WriteInt32(Dummy17); + } + if (HasDummy18) { + output.WriteRawTag(144, 1); + output.WriteInt32(Dummy18); + } + if (HasDummy19) { + output.WriteRawTag(152, 1); + output.WriteInt32(Dummy19); + } + if (HasDummy20) { + output.WriteRawTag(160, 1); + output.WriteInt32(Dummy20); + } + if (HasDummy21) { + output.WriteRawTag(168, 1); + output.WriteInt32(Dummy21); + } + if (HasDummy22) { + output.WriteRawTag(176, 1); + output.WriteInt32(Dummy22); + } + if (HasDummy23) { + output.WriteRawTag(184, 1); + output.WriteInt32(Dummy23); + } + if (HasDummy24) { + output.WriteRawTag(192, 1); + output.WriteInt32(Dummy24); + } + if (HasDummy25) { + output.WriteRawTag(200, 1); + output.WriteInt32(Dummy25); + } + if (HasDummy26) { + output.WriteRawTag(208, 1); + output.WriteInt32(Dummy26); + } + if (HasDummy27) { + output.WriteRawTag(216, 1); + output.WriteInt32(Dummy27); + } + if (HasDummy28) { + output.WriteRawTag(224, 1); + output.WriteInt32(Dummy28); + } + if (HasDummy29) { + output.WriteRawTag(232, 1); + output.WriteInt32(Dummy29); + } + if (HasDummy30) { + output.WriteRawTag(240, 1); + output.WriteInt32(Dummy30); + } + if (HasDummy31) { + output.WriteRawTag(248, 1); + output.WriteInt32(Dummy31); + } + if (HasDummy32) { + output.WriteRawTag(128, 2); + output.WriteInt32(Dummy32); + } + if (HasC) { + output.WriteRawTag(136, 2); + output.WriteInt32(C); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7648,16 +9032,165 @@ public sealed partial class TestRequired : pb::IMessage { if (other.HasC) { C = other.C; } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + A = input.ReadInt32(); + break; + } + case 16: { + Dummy2 = input.ReadInt32(); + break; + } + case 24: { + B = input.ReadInt32(); + break; + } + case 32: { + Dummy4 = input.ReadInt32(); + break; + } + case 40: { + Dummy5 = input.ReadInt32(); + break; + } + case 48: { + Dummy6 = input.ReadInt32(); + break; + } + case 56: { + Dummy7 = input.ReadInt32(); + break; + } + case 64: { + Dummy8 = input.ReadInt32(); + break; + } + case 72: { + Dummy9 = input.ReadInt32(); + break; + } + case 80: { + Dummy10 = input.ReadInt32(); + break; + } + case 88: { + Dummy11 = input.ReadInt32(); + break; + } + case 96: { + Dummy12 = input.ReadInt32(); + break; + } + case 104: { + Dummy13 = input.ReadInt32(); + break; + } + case 112: { + Dummy14 = input.ReadInt32(); + break; + } + case 120: { + Dummy15 = input.ReadInt32(); + break; + } + case 128: { + Dummy16 = input.ReadInt32(); + break; + } + case 136: { + Dummy17 = input.ReadInt32(); + break; + } + case 144: { + Dummy18 = input.ReadInt32(); + break; + } + case 152: { + Dummy19 = input.ReadInt32(); + break; + } + case 160: { + Dummy20 = input.ReadInt32(); + break; + } + case 168: { + Dummy21 = input.ReadInt32(); + break; + } + case 176: { + Dummy22 = input.ReadInt32(); + break; + } + case 184: { + Dummy23 = input.ReadInt32(); + break; + } + case 192: { + Dummy24 = input.ReadInt32(); + break; + } + case 200: { + Dummy25 = input.ReadInt32(); + break; + } + case 208: { + Dummy26 = input.ReadInt32(); + break; + } + case 216: { + Dummy27 = input.ReadInt32(); + break; + } + case 224: { + Dummy28 = input.ReadInt32(); + break; + } + case 232: { + Dummy29 = input.ReadInt32(); + break; + } + case 240: { + Dummy30 = input.ReadInt32(); + break; + } + case 248: { + Dummy31 = input.ReadInt32(); + break; + } + case 256: { + Dummy32 = input.ReadInt32(); + break; + } + case 264: { + C = input.ReadInt32(); + break; + } + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 8: { A = input.ReadInt32(); @@ -7794,6 +9327,7 @@ public sealed partial class TestRequired : pb::IMessage { } } } + #endif #region Extensions /// Container for extensions for other messages declared in the TestRequired message type. @@ -7808,7 +9342,11 @@ public static partial class Extensions { } - public sealed partial class TestRequiredForeign : pb::IMessage { + public sealed partial class TestRequiredForeign : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRequiredForeign()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -7835,7 +9373,7 @@ public sealed partial class TestRequiredForeign : pb::IMessageGets whether the optional_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalMessage { - get { return optionalMessage_ != null; } - } - /// Clears the value of the optional_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalMessage() { - optionalMessage_ = null; - } /// Field number for the "repeated_message" field. public const int RepeatedMessageFieldNumber = 2; @@ -7923,7 +9451,7 @@ public sealed partial class TestRequiredForeign : pb::IMessage { + public sealed partial class TestRequiredMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRequiredMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -8041,9 +9628,9 @@ public sealed partial class TestRequiredMessage : pb::IMessageGets whether the optional_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalMessage { - get { return optionalMessage_ != null; } - } - /// Clears the value of the optional_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalMessage() { - optionalMessage_ = null; - } /// Field number for the "repeated_message" field. public const int RepeatedMessageFieldNumber = 2; @@ -8093,16 +9670,6 @@ public sealed partial class TestRequiredMessage : pb::IMessageGets whether the required_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasRequiredMessage { - get { return requiredMessage_ != null; } - } - /// Clears the value of the required_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearRequiredMessage() { - requiredMessage_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -8126,9 +9693,9 @@ public sealed partial class TestRequiredMessage : pb::IMessage /// Test that we can use NestedMessage from outside TestAllTypes. /// - public sealed partial class TestForeignNested : pb::IMessage { + public sealed partial class TestForeignNested : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestForeignNested()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -8253,7 +9882,7 @@ public sealed partial class TestForeignNested : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public TestForeignNested(TestForeignNested other) : this() { - foreignNested_ = other.HasForeignNested ? other.foreignNested_.Clone() : null; + foreignNested_ = other.foreignNested_ != null ? other.foreignNested_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -8272,16 +9901,6 @@ public sealed partial class TestForeignNested : pb::IMessage foreignNested_ = value; } } - /// Gets whether the foreign_nested field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasForeignNested { - get { return foreignNested_ != null; } - } - /// Clears the value of the foreign_nested field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearForeignNested() { - foreignNested_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -8303,7 +9922,7 @@ public sealed partial class TestForeignNested : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasForeignNested) hash ^= ForeignNested.GetHashCode(); + if (foreignNested_ != null) hash ^= ForeignNested.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -8317,19 +9936,36 @@ public sealed partial class TestForeignNested : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasForeignNested) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (foreignNested_ != null) { output.WriteRawTag(10); output.WriteMessage(ForeignNested); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (foreignNested_ != null) { + output.WriteRawTag(10); + output.WriteMessage(ForeignNested); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasForeignNested) { + if (foreignNested_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(ForeignNested); } if (_unknownFields != null) { @@ -8343,8 +9979,8 @@ public sealed partial class TestForeignNested : pb::IMessage if (other == null) { return; } - if (other.HasForeignNested) { - if (!HasForeignNested) { + if (other.foreignNested_ != null) { + if (foreignNested_ == null) { ForeignNested = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); } ForeignNested.MergeFrom(other.ForeignNested); @@ -8354,6 +9990,9 @@ public sealed partial class TestForeignNested : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -8361,7 +10000,28 @@ public sealed partial class TestForeignNested : pb::IMessage _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { - if (!HasForeignNested) { + if (foreignNested_ == null) { + ForeignNested = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); + } + input.ReadMessage(ForeignNested); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (foreignNested_ == null) { ForeignNested = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes.Types.NestedMessage(); } input.ReadMessage(ForeignNested); @@ -8370,13 +10030,18 @@ public sealed partial class TestForeignNested : pb::IMessage } } } + #endif } /// /// TestEmptyMessage is used to test unknown field support. /// - public sealed partial class TestEmptyMessage : pb::IMessage { + public sealed partial class TestEmptyMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestEmptyMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -8441,10 +10106,23 @@ public sealed partial class TestEmptyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -8465,6 +10143,9 @@ public sealed partial class TestEmptyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -8473,7 +10154,22 @@ public sealed partial class TestEmptyMessage : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } @@ -8481,7 +10177,11 @@ public sealed partial class TestEmptyMessage : pb::IMessage { /// Like above, but declare all field numbers as potential extensions. No /// actual extensions should ever be defined for this type. /// - public sealed partial class TestEmptyMessageWithExtensions : pb::IExtendableMessage { + public sealed partial class TestEmptyMessageWithExtensions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestEmptyMessageWithExtensions()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -8555,14 +10255,30 @@ public sealed partial class TestEmptyMessageWithExtensions : pb::IExtendableMess [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_extensions != null) { _extensions.WriteTo(output); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -8586,6 +10302,9 @@ public sealed partial class TestEmptyMessageWithExtensions : pb::IExtendableMess [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -8596,7 +10315,24 @@ public sealed partial class TestEmptyMessageWithExtensions : pb::IExtendableMess break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + } + } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -8622,7 +10358,11 @@ public sealed partial class TestEmptyMessageWithExtensions : pb::IExtendableMess } - public sealed partial class TestMultipleExtensionRanges : pb::IExtendableMessage { + public sealed partial class TestMultipleExtensionRanges : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMultipleExtensionRanges()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -8696,13 +10436,29 @@ public sealed partial class TestMultipleExtensionRanges : pb::IExtendableMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_extensions != null) { _extensions.WriteTo(output); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -8721,23 +10477,43 @@ public sealed partial class TestMultipleExtensionRanges : pb::IExtendableMessage if (other == null) { return; } - pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } + break; + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); } break; } } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -8766,7 +10542,11 @@ public sealed partial class TestMultipleExtensionRanges : pb::IExtendableMessage /// /// Test that really large tag numbers don't break anything. /// - public sealed partial class TestReallyLargeTagNumber : pb::IMessage { + public sealed partial class TestReallyLargeTagNumber : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestReallyLargeTagNumber()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -8891,6 +10671,9 @@ public sealed partial class TestReallyLargeTagNumber : pb::IMessage { + public sealed partial class TestRecursiveMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRecursiveMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -8982,7 +10813,7 @@ public sealed partial class TestRecursiveMessage : pb::IMessageGets whether the a field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasA { - get { return a_ != null; } - } - /// Clears the value of the a field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearA() { - a_ = null; - } /// Field number for the "i" field. public const int IFieldNumber = 2; @@ -9058,7 +10879,7 @@ public sealed partial class TestRecursiveMessage : pb::IMessage /// Test that mutual recursion works. /// - public sealed partial class TestMutualRecursionA : pb::IMessage { + public sealed partial class TestMutualRecursionA : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMutualRecursionA()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -9171,7 +11046,7 @@ public sealed partial class TestMutualRecursionA : pb::IMessageGets whether the bb field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasBb { - get { return bb_ != null; } - } - /// Clears the value of the bb field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearBb() { - bb_ = null; - } /// Field number for the "subgroup" field. public const int SubGroupFieldNumber = 2; @@ -9244,7 +11109,7 @@ public sealed partial class TestMutualRecursionA : pb::IMessageContainer for nested types declared in the TestMutualRecursionA message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class SubMessage : pb::IMessage { + public sealed partial class SubMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SubMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -9363,7 +11286,7 @@ public sealed partial class SubMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SubMessage(SubMessage other) : this() { - b_ = other.HasB ? other.b_.Clone() : null; + b_ = other.b_ != null ? other.b_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -9382,16 +11305,6 @@ public sealed partial class SubMessage : pb::IMessage { b_ = value; } } - /// Gets whether the b field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasB { - get { return b_ != null; } - } - /// Clears the value of the b field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearB() { - b_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -9413,7 +11326,7 @@ public sealed partial class SubMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasB) hash ^= B.GetHashCode(); + if (b_ != null) hash ^= B.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -9427,19 +11340,36 @@ public sealed partial class SubMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasB) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (b_ != null) { output.WriteRawTag(10); output.WriteMessage(B); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (b_ != null) { + output.WriteRawTag(10); + output.WriteMessage(B); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasB) { + if (b_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(B); } if (_unknownFields != null) { @@ -9453,8 +11383,8 @@ public sealed partial class SubMessage : pb::IMessage { if (other == null) { return; } - if (other.HasB) { - if (!HasB) { + if (other.b_ != null) { + if (b_ == null) { B = new global::Google.Protobuf.TestProtos.Proto2.TestMutualRecursionB(); } B.MergeFrom(other.B); @@ -9464,6 +11394,9 @@ public sealed partial class SubMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -9471,7 +11404,28 @@ public sealed partial class SubMessage : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { - if (!HasB) { + if (b_ == null) { + B = new global::Google.Protobuf.TestProtos.Proto2.TestMutualRecursionB(); + } + input.ReadMessage(B); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (b_ == null) { B = new global::Google.Protobuf.TestProtos.Proto2.TestMutualRecursionB(); } input.ReadMessage(B); @@ -9480,10 +11434,15 @@ public sealed partial class SubMessage : pb::IMessage { } } } + #endif } - public sealed partial class SubGroup : pb::IMessage { + public sealed partial class SubGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SubGroup()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -9508,8 +11467,8 @@ public sealed partial class SubGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public SubGroup(SubGroup other) : this() { - subMessage_ = other.HasSubMessage ? other.subMessage_.Clone() : null; - notInThisScc_ = other.HasNotInThisScc ? other.notInThisScc_.Clone() : null; + subMessage_ = other.subMessage_ != null ? other.subMessage_.Clone() : null; + notInThisScc_ = other.notInThisScc_ != null ? other.notInThisScc_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -9531,16 +11490,6 @@ public sealed partial class SubGroup : pb::IMessage { subMessage_ = value; } } - /// Gets whether the sub_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasSubMessage { - get { return subMessage_ != null; } - } - /// Clears the value of the sub_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearSubMessage() { - subMessage_ = null; - } /// Field number for the "not_in_this_scc" field. public const int NotInThisSccFieldNumber = 4; @@ -9552,16 +11501,6 @@ public sealed partial class SubGroup : pb::IMessage { notInThisScc_ = value; } } - /// Gets whether the not_in_this_scc field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasNotInThisScc { - get { return notInThisScc_ != null; } - } - /// Clears the value of the not_in_this_scc field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearNotInThisScc() { - notInThisScc_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -9584,8 +11523,8 @@ public sealed partial class SubGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasSubMessage) hash ^= SubMessage.GetHashCode(); - if (HasNotInThisScc) hash ^= NotInThisScc.GetHashCode(); + if (subMessage_ != null) hash ^= SubMessage.GetHashCode(); + if (notInThisScc_ != null) hash ^= NotInThisScc.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -9599,26 +11538,47 @@ public sealed partial class SubGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasSubMessage) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (subMessage_ != null) { output.WriteRawTag(26); output.WriteMessage(SubMessage); } - if (HasNotInThisScc) { + if (notInThisScc_ != null) { output.WriteRawTag(34); output.WriteMessage(NotInThisScc); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (subMessage_ != null) { + output.WriteRawTag(26); + output.WriteMessage(SubMessage); + } + if (notInThisScc_ != null) { + output.WriteRawTag(34); + output.WriteMessage(NotInThisScc); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasSubMessage) { + if (subMessage_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(SubMessage); } - if (HasNotInThisScc) { + if (notInThisScc_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(NotInThisScc); } if (_unknownFields != null) { @@ -9632,14 +11592,14 @@ public sealed partial class SubGroup : pb::IMessage { if (other == null) { return; } - if (other.HasSubMessage) { - if (!HasSubMessage) { + if (other.subMessage_ != null) { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestMutualRecursionA.Types.SubMessage(); } SubMessage.MergeFrom(other.SubMessage); } - if (other.HasNotInThisScc) { - if (!HasNotInThisScc) { + if (other.notInThisScc_ != null) { + if (notInThisScc_ == null) { NotInThisScc = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } NotInThisScc.MergeFrom(other.NotInThisScc); @@ -9649,6 +11609,9 @@ public sealed partial class SubGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -9658,14 +11621,44 @@ public sealed partial class SubGroup : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 26: { - if (!HasSubMessage) { + if (subMessage_ == null) { + SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestMutualRecursionA.Types.SubMessage(); + } + input.ReadMessage(SubMessage); + break; + } + case 34: { + if (notInThisScc_ == null) { + NotInThisScc = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + } + input.ReadMessage(NotInThisScc); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 20: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 26: { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestMutualRecursionA.Types.SubMessage(); } input.ReadMessage(SubMessage); break; } case 34: { - if (!HasNotInThisScc) { + if (notInThisScc_ == null) { NotInThisScc = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } input.ReadMessage(NotInThisScc); @@ -9674,6 +11667,7 @@ public sealed partial class SubGroup : pb::IMessage { } } } + #endif } @@ -9682,7 +11676,11 @@ public sealed partial class SubGroup : pb::IMessage { } - public sealed partial class TestMutualRecursionB : pb::IMessage { + public sealed partial class TestMutualRecursionB : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMutualRecursionB()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -9709,7 +11707,7 @@ public sealed partial class TestMutualRecursionB : pb::IMessageGets whether the a field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasA { - get { return a_ != null; } - } - /// Clears the value of the a field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearA() { - a_ = null; - } /// Field number for the "optional_int32" field. public const int OptionalInt32FieldNumber = 2; @@ -9785,7 +11773,7 @@ public sealed partial class TestMutualRecursionB : pb::IMessage { + public sealed partial class TestIsInitialized : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestIsInitialized()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -9895,7 +11937,7 @@ public sealed partial class TestIsInitialized : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public TestIsInitialized(TestIsInitialized other) : this() { - subMessage_ = other.HasSubMessage ? other.subMessage_.Clone() : null; + subMessage_ = other.subMessage_ != null ? other.subMessage_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -9911,18 +11953,8 @@ public sealed partial class TestIsInitialized : pb::IMessage public global::Google.Protobuf.TestProtos.Proto2.TestIsInitialized.Types.SubMessage SubMessage { get { return subMessage_; } set { - subMessage_ = value; - } - } - /// Gets whether the sub_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasSubMessage { - get { return subMessage_ != null; } - } - /// Clears the value of the sub_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearSubMessage() { - subMessage_ = null; + subMessage_ = value; + } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -9945,7 +11977,7 @@ public sealed partial class TestIsInitialized : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasSubMessage) hash ^= SubMessage.GetHashCode(); + if (subMessage_ != null) hash ^= SubMessage.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -9959,19 +11991,36 @@ public sealed partial class TestIsInitialized : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasSubMessage) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (subMessage_ != null) { output.WriteRawTag(10); output.WriteMessage(SubMessage); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (subMessage_ != null) { + output.WriteRawTag(10); + output.WriteMessage(SubMessage); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasSubMessage) { + if (subMessage_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(SubMessage); } if (_unknownFields != null) { @@ -9985,8 +12034,8 @@ public sealed partial class TestIsInitialized : pb::IMessage if (other == null) { return; } - if (other.HasSubMessage) { - if (!HasSubMessage) { + if (other.subMessage_ != null) { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestIsInitialized.Types.SubMessage(); } SubMessage.MergeFrom(other.SubMessage); @@ -9996,6 +12045,9 @@ public sealed partial class TestIsInitialized : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -10003,7 +12055,28 @@ public sealed partial class TestIsInitialized : pb::IMessage _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { - if (!HasSubMessage) { + if (subMessage_ == null) { + SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestIsInitialized.Types.SubMessage(); + } + input.ReadMessage(SubMessage); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestIsInitialized.Types.SubMessage(); } input.ReadMessage(SubMessage); @@ -10012,12 +12085,17 @@ public sealed partial class TestIsInitialized : pb::IMessage } } } + #endif #region Nested types /// Container for nested types declared in the TestIsInitialized message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class SubMessage : pb::IMessage { + public sealed partial class SubMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SubMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -10106,6 +12184,9 @@ public sealed partial class SubMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasSubGroup) { output.WriteRawTag(11); output.WriteGroup(SubGroup); @@ -10114,7 +12195,22 @@ public sealed partial class SubMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasSubGroup) { + output.WriteRawTag(11); + output.WriteGroup(SubGroup); + output.WriteRawTag(12); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -10144,6 +12240,9 @@ public sealed partial class SubMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -10159,13 +12258,39 @@ public sealed partial class SubMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 11: { + if (!HasSubGroup) { + SubGroup = new global::Google.Protobuf.TestProtos.Proto2.TestIsInitialized.Types.SubMessage.Types.SubGroup(); + } + input.ReadGroup(SubGroup); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the SubMessage message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class SubGroup : pb::IMessage { + public sealed partial class SubGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SubGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -10259,6 +12384,9 @@ public sealed partial class SubGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasI) { output.WriteRawTag(16); output.WriteInt32(I); @@ -10266,7 +12394,21 @@ public sealed partial class SubGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasI) { + output.WriteRawTag(16); + output.WriteInt32(I); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -10293,6 +12435,9 @@ public sealed partial class SubGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -10307,7 +12452,28 @@ public sealed partial class SubGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 12: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 16: { + I = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -10327,7 +12493,11 @@ public sealed partial class SubGroup : pb::IMessage { /// to compile with proto1, this will emit an error; so we only include it /// in protobuf_unittest_proto. /// - public sealed partial class TestDupFieldNumber : pb::IMessage { + public sealed partial class TestDupFieldNumber : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestDupFieldNumber()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -10472,6 +12642,9 @@ public sealed partial class TestDupFieldNumber : pb::IMessageContainer for nested types declared in the TestDupFieldNumber message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class Foo : pb::IMessage { + public sealed partial class Foo : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Foo()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -10660,6 +12897,9 @@ public sealed partial class Foo : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(8); output.WriteInt32(A); @@ -10667,7 +12907,21 @@ public sealed partial class Foo : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(8); + output.WriteInt32(A); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -10694,6 +12948,9 @@ public sealed partial class Foo : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -10708,11 +12965,36 @@ public sealed partial class Foo : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 20: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + A = input.ReadInt32(); + break; + } + } + } } + #endif } - public sealed partial class Bar : pb::IMessage { + public sealed partial class Bar : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Bar()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -10806,6 +13088,9 @@ public sealed partial class Bar : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(8); output.WriteInt32(A); @@ -10813,7 +13098,21 @@ public sealed partial class Bar : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(8); + output.WriteInt32(A); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -10840,6 +13139,9 @@ public sealed partial class Bar : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -10854,7 +13156,28 @@ public sealed partial class Bar : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 28: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + A = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -10866,7 +13189,11 @@ public sealed partial class Bar : pb::IMessage { /// /// Additional messages for testing lazy fields. /// - public sealed partial class TestEagerMessage : pb::IMessage { + public sealed partial class TestEagerMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestEagerMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -10891,7 +13218,7 @@ public sealed partial class TestEagerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public TestEagerMessage(TestEagerMessage other) : this() { - subMessage_ = other.HasSubMessage ? other.subMessage_.Clone() : null; + subMessage_ = other.subMessage_ != null ? other.subMessage_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -10910,16 +13237,6 @@ public sealed partial class TestEagerMessage : pb::IMessage { subMessage_ = value; } } - /// Gets whether the sub_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasSubMessage { - get { return subMessage_ != null; } - } - /// Clears the value of the sub_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearSubMessage() { - subMessage_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -10941,7 +13258,7 @@ public sealed partial class TestEagerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasSubMessage) hash ^= SubMessage.GetHashCode(); + if (subMessage_ != null) hash ^= SubMessage.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -10955,19 +13272,36 @@ public sealed partial class TestEagerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasSubMessage) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (subMessage_ != null) { output.WriteRawTag(10); output.WriteMessage(SubMessage); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (subMessage_ != null) { + output.WriteRawTag(10); + output.WriteMessage(SubMessage); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasSubMessage) { + if (subMessage_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(SubMessage); } if (_unknownFields != null) { @@ -10981,8 +13315,8 @@ public sealed partial class TestEagerMessage : pb::IMessage { if (other == null) { return; } - if (other.HasSubMessage) { - if (!HasSubMessage) { + if (other.subMessage_ != null) { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } SubMessage.MergeFrom(other.SubMessage); @@ -10992,6 +13326,9 @@ public sealed partial class TestEagerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -10999,7 +13336,28 @@ public sealed partial class TestEagerMessage : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { - if (!HasSubMessage) { + if (subMessage_ == null) { + SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + } + input.ReadMessage(SubMessage); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } input.ReadMessage(SubMessage); @@ -11008,10 +13366,15 @@ public sealed partial class TestEagerMessage : pb::IMessage { } } } + #endif } - public sealed partial class TestLazyMessage : pb::IMessage { + public sealed partial class TestLazyMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestLazyMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -11036,7 +13399,7 @@ public sealed partial class TestLazyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public TestLazyMessage(TestLazyMessage other) : this() { - subMessage_ = other.HasSubMessage ? other.subMessage_.Clone() : null; + subMessage_ = other.subMessage_ != null ? other.subMessage_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -11055,16 +13418,6 @@ public sealed partial class TestLazyMessage : pb::IMessage { subMessage_ = value; } } - /// Gets whether the sub_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasSubMessage { - get { return subMessage_ != null; } - } - /// Clears the value of the sub_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearSubMessage() { - subMessage_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -11086,7 +13439,7 @@ public sealed partial class TestLazyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasSubMessage) hash ^= SubMessage.GetHashCode(); + if (subMessage_ != null) hash ^= SubMessage.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -11100,19 +13453,36 @@ public sealed partial class TestLazyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasSubMessage) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (subMessage_ != null) { output.WriteRawTag(10); output.WriteMessage(SubMessage); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (subMessage_ != null) { + output.WriteRawTag(10); + output.WriteMessage(SubMessage); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasSubMessage) { + if (subMessage_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(SubMessage); } if (_unknownFields != null) { @@ -11126,8 +13496,8 @@ public sealed partial class TestLazyMessage : pb::IMessage { if (other == null) { return; } - if (other.HasSubMessage) { - if (!HasSubMessage) { + if (other.subMessage_ != null) { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } SubMessage.MergeFrom(other.SubMessage); @@ -11137,6 +13507,9 @@ public sealed partial class TestLazyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -11144,7 +13517,28 @@ public sealed partial class TestLazyMessage : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 10: { - if (!HasSubMessage) { + if (subMessage_ == null) { + SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + } + input.ReadMessage(SubMessage); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (subMessage_ == null) { SubMessage = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } input.ReadMessage(SubMessage); @@ -11153,13 +13547,18 @@ public sealed partial class TestLazyMessage : pb::IMessage { } } } + #endif } /// /// Needed for a Python test. /// - public sealed partial class TestNestedMessageHasBits : pb::IMessage { + public sealed partial class TestNestedMessageHasBits : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestNestedMessageHasBits()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -11184,7 +13583,7 @@ public sealed partial class TestNestedMessageHasBits : pb::IMessageGets whether the optional_nested_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalNestedMessage { - get { return optionalNestedMessage_ != null; } - } - /// Clears the value of the optional_nested_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalNestedMessage() { - optionalNestedMessage_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -11234,7 +13623,7 @@ public sealed partial class TestNestedMessageHasBits : pb::IMessageContainer for nested types declared in the TestNestedMessageHasBits message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -11397,12 +13832,27 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else nestedmessageRepeatedInt32_.WriteTo(output, _repeated_nestedmessageRepeatedInt32_codec); nestedmessageRepeatedForeignmessage_.WriteTo(output, _repeated_nestedmessageRepeatedForeignmessage_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + nestedmessageRepeatedInt32_.WriteTo(ref output, _repeated_nestedmessageRepeatedInt32_codec); + nestedmessageRepeatedForeignmessage_.WriteTo(ref output, _repeated_nestedmessageRepeatedForeignmessage_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -11427,6 +13877,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -11444,7 +13897,31 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: + case 8: { + nestedmessageRepeatedInt32_.AddEntriesFrom(ref input, _repeated_nestedmessageRepeatedInt32_codec); + break; + } + case 18: { + nestedmessageRepeatedForeignmessage_.AddEntriesFrom(ref input, _repeated_nestedmessageRepeatedForeignmessage_codec); + break; + } + } + } } + #endif } @@ -11457,7 +13934,11 @@ public sealed partial class NestedMessage : pb::IMessage { /// Test message with CamelCase field names. This violates Protocol Buffer /// standard style. /// - public sealed partial class TestCamelCaseFieldNames : pb::IMessage { + public sealed partial class TestCamelCaseFieldNames : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestCamelCaseFieldNames()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -11487,7 +13968,7 @@ public sealed partial class TestCamelCaseFieldNames : pb::IMessageGets whether the MessageField field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasMessageField { - get { return messageField_ != null; } - } - /// Clears the value of the MessageField field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearMessageField() { - messageField_ = null; - } /// Field number for the "StringPieceField" field. public const int StringPieceFieldFieldNumber = 5; @@ -11736,7 +14207,7 @@ public sealed partial class TestCamelCaseFieldNames : pb::IMessage - public sealed partial class TestFieldOrderings : pb::IExtendableMessage { + public sealed partial class TestFieldOrderings : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestFieldOrderings()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -11964,7 +14553,7 @@ public sealed partial class TestFieldOrderings : pb::IExtendableMessageGets whether the optional_nested_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalNestedMessage { - get { return optionalNestedMessage_ != null; } - } - /// Clears the value of the optional_nested_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalNestedMessage() { - optionalNestedMessage_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -12095,7 +14674,7 @@ public sealed partial class TestFieldOrderings : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -12243,7 +14893,11 @@ public sealed partial class TestFieldOrderings : pb::IExtendableMessageContainer for nested types declared in the TestFieldOrderings message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -12369,6 +15023,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasBb) { output.WriteRawTag(8); output.WriteInt32(Bb); @@ -12380,8 +15037,26 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasBb) { + output.WriteRawTag(8); + output.WriteInt32(Bb); + } + if (HasOo) { + output.WriteRawTag(16); + output.WriteInt64(Oo); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -12413,6 +15088,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -12429,7 +15107,30 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Bb = input.ReadInt32(); + break; + } + case 16: { + Oo = input.ReadInt64(); + break; + } + } + } } + #endif } @@ -12438,7 +15139,11 @@ public sealed partial class NestedMessage : pb::IMessage { } - public sealed partial class TestExtensionOrderings1 : pb::IMessage { + public sealed partial class TestExtensionOrderings1 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestExtensionOrderings1()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -12529,6 +15234,9 @@ public sealed partial class TestExtensionOrderings1 : pb::IMessageContainer for extensions for other messages declared in the TestExtensionOrderings1 message type. @@ -12588,7 +15332,11 @@ public static partial class Extensions { } - public sealed partial class TestExtensionOrderings2 : pb::IMessage { + public sealed partial class TestExtensionOrderings2 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestExtensionOrderings2()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -12679,6 +15427,9 @@ public sealed partial class TestExtensionOrderings2 : pb::IMessageContainer for nested types declared in the TestExtensionOrderings2 message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class TestExtensionOrderings3 : pb::IMessage { + public sealed partial class TestExtensionOrderings3 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestExtensionOrderings3()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -12822,6 +15613,9 @@ public sealed partial class TestExtensionOrderings3 : pb::IMessageContainer for extensions for other messages declared in the TestExtensionOrderings3 message type. @@ -12895,7 +15725,11 @@ public static partial class Extensions { } - public sealed partial class TestExtremeDefaultValues : pb::IMessage { + public sealed partial class TestExtremeDefaultValues : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestExtremeDefaultValues()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -13707,6 +16541,9 @@ public sealed partial class TestExtremeDefaultValues : pb::IMessage { + public sealed partial class SparseEnumMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SparseEnumMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -14215,6 +17300,9 @@ public sealed partial class SparseEnumMessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasSparseEnum) { output.WriteRawTag(8); output.WriteEnum((int) SparseEnum); @@ -14222,7 +17310,21 @@ public sealed partial class SparseEnumMessage : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasSparseEnum) { + output.WriteRawTag(8); + output.WriteEnum((int) SparseEnum); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -14249,6 +17351,9 @@ public sealed partial class SparseEnumMessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -14261,14 +17366,37 @@ public sealed partial class SparseEnumMessage : pb::IMessage } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + SparseEnum = (global::Google.Protobuf.TestProtos.Proto2.TestSparseEnum) input.ReadEnum(); + break; + } + } + } + } + #endif + } /// /// Test String and Bytes: string is for valid UTF-8 strings /// - public sealed partial class OneString : pb::IMessage { + public sealed partial class OneString : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneString()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14359,6 +17487,9 @@ public sealed partial class OneString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasData) { output.WriteRawTag(10); output.WriteString(Data); @@ -14366,7 +17497,21 @@ public sealed partial class OneString : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasData) { + output.WriteRawTag(10); + output.WriteString(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -14393,6 +17538,9 @@ public sealed partial class OneString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -14405,11 +17553,34 @@ public sealed partial class OneString : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Data = input.ReadString(); + break; + } + } + } } + #endif } - public sealed partial class MoreString : pb::IMessage { + public sealed partial class MoreString : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MoreString()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14487,11 +17658,25 @@ public sealed partial class MoreString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else data_.WriteTo(output, _repeated_data_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + data_.WriteTo(ref output, _repeated_data_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -14514,6 +17699,9 @@ public sealed partial class MoreString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -14526,11 +17714,34 @@ public sealed partial class MoreString : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + data_.AddEntriesFrom(ref input, _repeated_data_codec); + break; + } + } + } } + #endif } - public sealed partial class OneBytes : pb::IMessage { + public sealed partial class OneBytes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneBytes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14621,6 +17832,9 @@ public sealed partial class OneBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasData) { output.WriteRawTag(10); output.WriteBytes(Data); @@ -14628,7 +17842,21 @@ public sealed partial class OneBytes : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasData) { + output.WriteRawTag(10); + output.WriteBytes(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -14655,6 +17883,9 @@ public sealed partial class OneBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -14667,11 +17898,34 @@ public sealed partial class OneBytes : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Data = input.ReadBytes(); + break; + } + } + } + } + #endif + } - public sealed partial class MoreBytes : pb::IMessage { + public sealed partial class MoreBytes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MoreBytes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14749,11 +18003,25 @@ public sealed partial class MoreBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else data_.WriteTo(output, _repeated_data_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + data_.WriteTo(ref output, _repeated_data_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -14776,6 +18044,9 @@ public sealed partial class MoreBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -14788,14 +18059,37 @@ public sealed partial class MoreBytes : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + data_.AddEntriesFrom(ref input, _repeated_data_codec); + break; + } + } + } } + #endif } /// /// Test int32, uint32, int64, uint64, and bool are all compatible /// - public sealed partial class Int32Message : pb::IMessage { + public sealed partial class Int32Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int32Message()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -14889,6 +18183,9 @@ public sealed partial class Int32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasData) { output.WriteRawTag(8); output.WriteInt32(Data); @@ -14896,8 +18193,22 @@ public sealed partial class Int32Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasData) { + output.WriteRawTag(8); + output.WriteInt32(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -14923,6 +18234,9 @@ public sealed partial class Int32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -14935,11 +18249,34 @@ public sealed partial class Int32Message : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadInt32(); + break; + } + } + } } + #endif } - public sealed partial class Uint32Message : pb::IMessage { + public sealed partial class Uint32Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Uint32Message()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -15033,6 +18370,9 @@ public sealed partial class Uint32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasData) { output.WriteRawTag(8); output.WriteUInt32(Data); @@ -15040,7 +18380,21 @@ public sealed partial class Uint32Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasData) { + output.WriteRawTag(8); + output.WriteUInt32(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -15067,6 +18421,9 @@ public sealed partial class Uint32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -15079,11 +18436,34 @@ public sealed partial class Uint32Message : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadUInt32(); + break; + } + } + } + } + #endif + } - public sealed partial class Int64Message : pb::IMessage { + public sealed partial class Int64Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int64Message()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -15177,6 +18557,9 @@ public sealed partial class Int64Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasData) { output.WriteRawTag(8); output.WriteInt64(Data); @@ -15184,7 +18567,21 @@ public sealed partial class Int64Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasData) { + output.WriteRawTag(8); + output.WriteInt64(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -15211,6 +18608,9 @@ public sealed partial class Int64Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -15223,11 +18623,34 @@ public sealed partial class Int64Message : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadInt64(); + break; + } + } + } } + #endif } - public sealed partial class Uint64Message : pb::IMessage { + public sealed partial class Uint64Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Uint64Message()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -15321,6 +18744,9 @@ public sealed partial class Uint64Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasData) { output.WriteRawTag(8); output.WriteUInt64(Data); @@ -15328,7 +18754,21 @@ public sealed partial class Uint64Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasData) { + output.WriteRawTag(8); + output.WriteUInt64(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -15355,6 +18795,9 @@ public sealed partial class Uint64Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -15367,11 +18810,34 @@ public sealed partial class Uint64Message : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadUInt64(); + break; + } + } + } } + #endif } - public sealed partial class BoolMessage : pb::IMessage { + public sealed partial class BoolMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BoolMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -15465,6 +18931,9 @@ public sealed partial class BoolMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasData) { output.WriteRawTag(8); output.WriteBool(Data); @@ -15472,7 +18941,21 @@ public sealed partial class BoolMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasData) { + output.WriteRawTag(8); + output.WriteBool(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -15499,6 +18982,9 @@ public sealed partial class BoolMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -15511,17 +18997,39 @@ public sealed partial class BoolMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadBool(); + break; + } + } + } } + #endif } /// /// Test oneofs. /// - public sealed partial class TestOneof : pb::IMessage { + public sealed partial class TestOneof : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestOneof()); private pb::UnknownFieldSet _unknownFields; - private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -15544,7 +19052,6 @@ public sealed partial class TestOneof : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public TestOneof(TestOneof other) : this() { - _hasBits0 = other._hasBits0; switch (other.FooCase) { case FooOneofCase.FooInt: FooInt = other.FooInt; @@ -15618,24 +19125,12 @@ public sealed partial class TestOneof : pb::IMessage { public const int FooMessageFieldNumber = 3; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.Proto2.TestAllTypes FooMessage { - get { return HasFooMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestAllTypes) foo_ : null; } + get { return fooCase_ == FooOneofCase.FooMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestAllTypes) foo_ : null; } set { foo_ = value; fooCase_ = value == null ? FooOneofCase.None : FooOneofCase.FooMessage; } } - /// Gets whether the "foo_message" field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasFooMessage { - get { return fooCase_ == FooOneofCase.FooMessage; } - } - /// Clears the value of the oneof if it's currently set to "foo_message" - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearFooMessage() { - if (HasFooMessage) { - ClearFoo(); - } - } /// Field number for the "foogroup" field. public const int FooGroupFieldNumber = 4; @@ -15707,22 +19202,51 @@ public enum FooOneofCase { int hash = 1; if (HasFooInt) hash ^= FooInt.GetHashCode(); if (HasFooString) hash ^= FooString.GetHashCode(); - if (HasFooMessage) hash ^= FooMessage.GetHashCode(); + if (fooCase_ == FooOneofCase.FooMessage) hash ^= FooMessage.GetHashCode(); if (HasFooGroup) hash ^= FooGroup.GetHashCode(); hash ^= (int) fooCase_; if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasFooInt) { + output.WriteRawTag(8); + output.WriteInt32(FooInt); + } + if (HasFooString) { + output.WriteRawTag(18); + output.WriteString(FooString); + } + if (fooCase_ == FooOneofCase.FooMessage) { + output.WriteRawTag(26); + output.WriteMessage(FooMessage); + } + if (HasFooGroup) { + output.WriteRawTag(35); + output.WriteGroup(FooGroup); + output.WriteRawTag(36); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { if (HasFooInt) { output.WriteRawTag(8); output.WriteInt32(FooInt); @@ -15731,7 +19255,7 @@ public enum FooOneofCase { output.WriteRawTag(18); output.WriteString(FooString); } - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { output.WriteRawTag(26); output.WriteMessage(FooMessage); } @@ -15741,9 +19265,10 @@ public enum FooOneofCase { output.WriteRawTag(36); } if (_unknownFields != null) { - _unknownFields.WriteTo(output); + _unknownFields.WriteTo(ref output); } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -15754,7 +19279,7 @@ public enum FooOneofCase { if (HasFooString) { size += 1 + pb::CodedOutputStream.ComputeStringSize(FooString); } - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(FooMessage); } if (HasFooGroup) { @@ -15797,6 +19322,9 @@ public enum FooOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -15813,7 +19341,47 @@ public enum FooOneofCase { } case 26: { global::Google.Protobuf.TestProtos.Proto2.TestAllTypes subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { + subBuilder.MergeFrom(FooMessage); + } + input.ReadMessage(subBuilder); + FooMessage = subBuilder; + break; + } + case 35: { + global::Google.Protobuf.TestProtos.Proto2.TestOneof.Types.FooGroup subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestOneof.Types.FooGroup(); + if (HasFooGroup) { + subBuilder.MergeFrom(FooGroup); + } + input.ReadGroup(subBuilder); + FooGroup = subBuilder; + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + FooInt = input.ReadInt32(); + break; + } + case 18: { + FooString = input.ReadString(); + break; + } + case 26: { + global::Google.Protobuf.TestProtos.Proto2.TestAllTypes subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + if (fooCase_ == FooOneofCase.FooMessage) { subBuilder.MergeFrom(FooMessage); } input.ReadMessage(subBuilder); @@ -15832,12 +19400,17 @@ public enum FooOneofCase { } } } + #endif #region Nested types /// Container for nested types declared in the TestOneof message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class FooGroup : pb::IMessage { + public sealed partial class FooGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -15957,6 +19530,9 @@ public sealed partial class FooGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(40); output.WriteInt32(A); @@ -15968,7 +19544,25 @@ public sealed partial class FooGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(40); + output.WriteInt32(A); + } + if (HasB) { + output.WriteRawTag(50); + output.WriteString(B); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -16001,6 +19595,9 @@ public sealed partial class FooGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -16019,7 +19616,32 @@ public sealed partial class FooGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 36: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 40: { + A = input.ReadInt32(); + break; + } + case 50: { + B = input.ReadString(); + break; + } + } + } } + #endif } @@ -16028,7 +19650,11 @@ public sealed partial class FooGroup : pb::IMessage { } - public sealed partial class TestOneofBackwardsCompatible : pb::IMessage { + public sealed partial class TestOneofBackwardsCompatible : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestOneofBackwardsCompatible()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -16057,7 +19683,7 @@ public sealed partial class TestOneofBackwardsCompatible : pb::IMessageGets whether the foo_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasFooMessage { - get { return fooMessage_ != null; } - } - /// Clears the value of the foo_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearFooMessage() { - fooMessage_ = null; - } /// Field number for the "foogroup" field. public const int FooGroupFieldNumber = 4; @@ -16181,7 +19797,7 @@ public sealed partial class TestOneofBackwardsCompatible : pb::IMessageContainer for nested types declared in the TestOneofBackwardsCompatible message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class FooGroup : pb::IMessage { + public sealed partial class FooGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -16423,6 +20113,9 @@ public sealed partial class FooGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(40); output.WriteInt32(A); @@ -16434,7 +20127,25 @@ public sealed partial class FooGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(40); + output.WriteInt32(A); + } + if (HasB) { + output.WriteRawTag(50); + output.WriteString(B); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -16467,6 +20178,9 @@ public sealed partial class FooGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -16485,7 +20199,32 @@ public sealed partial class FooGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 36: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 40: { + A = input.ReadInt32(); + break; + } + case 50: { + B = input.ReadString(); + break; + } + } + } } + #endif } @@ -16494,7 +20233,11 @@ public sealed partial class FooGroup : pb::IMessage { } - public sealed partial class TestOneof2 : pb::IMessage { + public sealed partial class TestOneof2 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestOneof2()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -16724,24 +20467,12 @@ public sealed partial class TestOneof2 : pb::IMessage { public const int FooMessageFieldNumber = 7; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage FooMessage { - get { return HasFooMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage) foo_ : null; } + get { return fooCase_ == FooOneofCase.FooMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage) foo_ : null; } set { foo_ = value; fooCase_ = value == null ? FooOneofCase.None : FooOneofCase.FooMessage; } } - /// Gets whether the "foo_message" field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasFooMessage { - get { return fooCase_ == FooOneofCase.FooMessage; } - } - /// Clears the value of the oneof if it's currently set to "foo_message" - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearFooMessage() { - if (HasFooMessage) { - ClearFoo(); - } - } /// Field number for the "foogroup" field. public const int FooGroupFieldNumber = 8; @@ -16770,24 +20501,12 @@ public sealed partial class TestOneof2 : pb::IMessage { public const int FooLazyMessageFieldNumber = 11; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage FooLazyMessage { - get { return HasFooLazyMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage) foo_ : null; } + get { return fooCase_ == FooOneofCase.FooLazyMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage) foo_ : null; } set { foo_ = value; fooCase_ = value == null ? FooOneofCase.None : FooOneofCase.FooLazyMessage; } } - /// Gets whether the "foo_lazy_message" field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasFooLazyMessage { - get { return fooCase_ == FooOneofCase.FooLazyMessage; } - } - /// Clears the value of the oneof if it's currently set to "foo_lazy_message" - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearFooLazyMessage() { - if (HasFooLazyMessage) { - ClearFoo(); - } - } /// Field number for the "bar_int" field. public const int BarIntFieldNumber = 12; @@ -16934,21 +20653,21 @@ public sealed partial class TestOneof2 : pb::IMessage { private int bazInt_; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int BazInt { - get { if ((_hasBits0 & 16) != 0) { return bazInt_; } else { return BazIntDefaultValue; } } + get { if ((_hasBits0 & 1) != 0) { return bazInt_; } else { return BazIntDefaultValue; } } set { - _hasBits0 |= 16; + _hasBits0 |= 1; bazInt_ = value; } } /// Gets whether the "baz_int" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public bool HasBazInt { - get { return (_hasBits0 & 16) != 0; } + get { return (_hasBits0 & 1) != 0; } } /// Clears the value of the "baz_int" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void ClearBazInt() { - _hasBits0 &= ~16; + _hasBits0 &= ~1; } /// Field number for the "baz_string" field. @@ -17067,9 +20786,9 @@ public enum BarOneofCase { if (HasFooStringPiece) hash ^= FooStringPiece.GetHashCode(); if (HasFooBytes) hash ^= FooBytes.GetHashCode(); if (HasFooEnum) hash ^= FooEnum.GetHashCode(); - if (HasFooMessage) hash ^= FooMessage.GetHashCode(); + if (fooCase_ == FooOneofCase.FooMessage) hash ^= FooMessage.GetHashCode(); if (HasFooGroup) hash ^= FooGroup.GetHashCode(); - if (HasFooLazyMessage) hash ^= FooLazyMessage.GetHashCode(); + if (fooCase_ == FooOneofCase.FooLazyMessage) hash ^= FooLazyMessage.GetHashCode(); if (HasBarInt) hash ^= BarInt.GetHashCode(); if (HasBarString) hash ^= BarString.GetHashCode(); if (HasBarCord) hash ^= BarCord.GetHashCode(); @@ -17081,18 +20800,99 @@ public enum BarOneofCase { hash ^= (int) fooCase_; hash ^= (int) barCase_; if (_unknownFields != null) { - hash ^= _unknownFields.GetHashCode(); + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasFooInt) { + output.WriteRawTag(8); + output.WriteInt32(FooInt); + } + if (HasFooString) { + output.WriteRawTag(18); + output.WriteString(FooString); + } + if (HasFooCord) { + output.WriteRawTag(26); + output.WriteString(FooCord); + } + if (HasFooStringPiece) { + output.WriteRawTag(34); + output.WriteString(FooStringPiece); + } + if (HasFooBytes) { + output.WriteRawTag(42); + output.WriteBytes(FooBytes); + } + if (HasFooEnum) { + output.WriteRawTag(48); + output.WriteEnum((int) FooEnum); + } + if (fooCase_ == FooOneofCase.FooMessage) { + output.WriteRawTag(58); + output.WriteMessage(FooMessage); + } + if (HasFooGroup) { + output.WriteRawTag(67); + output.WriteGroup(FooGroup); + output.WriteRawTag(68); + } + if (fooCase_ == FooOneofCase.FooLazyMessage) { + output.WriteRawTag(90); + output.WriteMessage(FooLazyMessage); + } + if (HasBarInt) { + output.WriteRawTag(96); + output.WriteInt32(BarInt); + } + if (HasBarString) { + output.WriteRawTag(106); + output.WriteString(BarString); + } + if (HasBarCord) { + output.WriteRawTag(114); + output.WriteString(BarCord); + } + if (HasBarStringPiece) { + output.WriteRawTag(122); + output.WriteString(BarStringPiece); + } + if (HasBarBytes) { + output.WriteRawTag(130, 1); + output.WriteBytes(BarBytes); + } + if (HasBarEnum) { + output.WriteRawTag(136, 1); + output.WriteEnum((int) BarEnum); + } + if (HasBazInt) { + output.WriteRawTag(144, 1); + output.WriteInt32(BazInt); + } + if (HasBazString) { + output.WriteRawTag(154, 1); + output.WriteString(BazString); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); } - return hash; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public override string ToString() { - return pb::JsonFormatter.ToDiagnosticString(this); + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { if (HasFooInt) { output.WriteRawTag(8); output.WriteInt32(FooInt); @@ -17117,7 +20917,7 @@ public enum BarOneofCase { output.WriteRawTag(48); output.WriteEnum((int) FooEnum); } - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { output.WriteRawTag(58); output.WriteMessage(FooMessage); } @@ -17126,7 +20926,7 @@ public enum BarOneofCase { output.WriteGroup(FooGroup); output.WriteRawTag(68); } - if (HasFooLazyMessage) { + if (fooCase_ == FooOneofCase.FooLazyMessage) { output.WriteRawTag(90); output.WriteMessage(FooLazyMessage); } @@ -17163,9 +20963,10 @@ public enum BarOneofCase { output.WriteString(BazString); } if (_unknownFields != null) { - _unknownFields.WriteTo(output); + _unknownFields.WriteTo(ref output); } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -17188,13 +20989,13 @@ public enum BarOneofCase { if (HasFooEnum) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) FooEnum); } - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(FooMessage); } if (HasFooGroup) { size += 2 + pb::CodedOutputStream.ComputeGroupSize(FooGroup); } - if (HasFooLazyMessage) { + if (fooCase_ == FooOneofCase.FooLazyMessage) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(FooLazyMessage); } if (HasBarInt) { @@ -17303,6 +21104,9 @@ public enum BarOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -17336,7 +21140,106 @@ public enum BarOneofCase { } case 58: { global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage(); - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { + subBuilder.MergeFrom(FooMessage); + } + input.ReadMessage(subBuilder); + FooMessage = subBuilder; + break; + } + case 67: { + global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.FooGroup subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.FooGroup(); + if (HasFooGroup) { + subBuilder.MergeFrom(FooGroup); + } + input.ReadGroup(subBuilder); + FooGroup = subBuilder; + break; + } + case 90: { + global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage(); + if (fooCase_ == FooOneofCase.FooLazyMessage) { + subBuilder.MergeFrom(FooLazyMessage); + } + input.ReadMessage(subBuilder); + FooLazyMessage = subBuilder; + break; + } + case 96: { + BarInt = input.ReadInt32(); + break; + } + case 106: { + BarString = input.ReadString(); + break; + } + case 114: { + BarCord = input.ReadString(); + break; + } + case 122: { + BarStringPiece = input.ReadString(); + break; + } + case 130: { + BarBytes = input.ReadBytes(); + break; + } + case 136: { + bar_ = input.ReadEnum(); + barCase_ = BarOneofCase.BarEnum; + break; + } + case 144: { + BazInt = input.ReadInt32(); + break; + } + case 154: { + BazString = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + FooInt = input.ReadInt32(); + break; + } + case 18: { + FooString = input.ReadString(); + break; + } + case 26: { + FooCord = input.ReadString(); + break; + } + case 34: { + FooStringPiece = input.ReadString(); + break; + } + case 42: { + FooBytes = input.ReadBytes(); + break; + } + case 48: { + foo_ = input.ReadEnum(); + fooCase_ = FooOneofCase.FooEnum; + break; + } + case 58: { + global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage(); + if (fooCase_ == FooOneofCase.FooMessage) { subBuilder.MergeFrom(FooMessage); } input.ReadMessage(subBuilder); @@ -17354,7 +21257,7 @@ public enum BarOneofCase { } case 90: { global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestOneof2.Types.NestedMessage(); - if (HasFooLazyMessage) { + if (fooCase_ == FooOneofCase.FooLazyMessage) { subBuilder.MergeFrom(FooLazyMessage); } input.ReadMessage(subBuilder); @@ -17397,6 +21300,7 @@ public enum BarOneofCase { } } } + #endif #region Nested types /// Container for nested types declared in the TestOneof2 message type. @@ -17408,7 +21312,11 @@ public enum NestedEnum { [pbr::OriginalName("BAZ")] Baz = 3, } - public sealed partial class FooGroup : pb::IMessage { + public sealed partial class FooGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -17528,6 +21436,9 @@ public sealed partial class FooGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasA) { output.WriteRawTag(72); output.WriteInt32(A); @@ -17539,7 +21450,25 @@ public sealed partial class FooGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasA) { + output.WriteRawTag(72); + output.WriteInt32(A); + } + if (HasB) { + output.WriteRawTag(82); + output.WriteString(B); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -17572,6 +21501,9 @@ public sealed partial class FooGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -17590,11 +21522,40 @@ public sealed partial class FooGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 68: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 72: { + A = input.ReadInt32(); + break; + } + case 82: { + B = input.ReadString(); + break; + } + } + } } + #endif } - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -17701,6 +21662,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasQuxInt) { output.WriteRawTag(8); output.WriteInt64(QuxInt); @@ -17709,7 +21673,22 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasQuxInt) { + output.WriteRawTag(8); + output.WriteInt64(QuxInt); + } + corgeInt_.WriteTo(ref output, _repeated_corgeInt_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -17738,6 +21717,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -17755,7 +21737,31 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + QuxInt = input.ReadInt64(); + break; + } + case 18: + case 16: { + corgeInt_.AddEntriesFrom(ref input, _repeated_corgeInt_codec); + break; + } + } + } } + #endif } @@ -17764,10 +21770,13 @@ public sealed partial class NestedMessage : pb::IMessage { } - public sealed partial class TestRequiredOneof : pb::IMessage { + public sealed partial class TestRequiredOneof : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRequiredOneof()); private pb::UnknownFieldSet _unknownFields; - private int _hasBits0; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static pb::MessageParser Parser { get { return _parser; } } @@ -17790,7 +21799,6 @@ public sealed partial class TestRequiredOneof : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public TestRequiredOneof(TestRequiredOneof other) : this() { - _hasBits0 = other._hasBits0; switch (other.FooCase) { case FooOneofCase.FooInt: FooInt = other.FooInt; @@ -17861,24 +21869,12 @@ public sealed partial class TestRequiredOneof : pb::IMessage public const int FooMessageFieldNumber = 3; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public global::Google.Protobuf.TestProtos.Proto2.TestRequiredOneof.Types.NestedMessage FooMessage { - get { return HasFooMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestRequiredOneof.Types.NestedMessage) foo_ : null; } + get { return fooCase_ == FooOneofCase.FooMessage ? (global::Google.Protobuf.TestProtos.Proto2.TestRequiredOneof.Types.NestedMessage) foo_ : null; } set { foo_ = value; fooCase_ = value == null ? FooOneofCase.None : FooOneofCase.FooMessage; } } - /// Gets whether the "foo_message" field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasFooMessage { - get { return fooCase_ == FooOneofCase.FooMessage; } - } - /// Clears the value of the oneof if it's currently set to "foo_message" - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearFooMessage() { - if (HasFooMessage) { - ClearFoo(); - } - } private object foo_; /// Enum of possible cases for the "foo" oneof. @@ -17925,7 +21921,7 @@ public enum FooOneofCase { int hash = 1; if (HasFooInt) hash ^= FooInt.GetHashCode(); if (HasFooString) hash ^= FooString.GetHashCode(); - if (HasFooMessage) hash ^= FooMessage.GetHashCode(); + if (fooCase_ == FooOneofCase.FooMessage) hash ^= FooMessage.GetHashCode(); hash ^= (int) fooCase_; if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); @@ -17940,6 +21936,9 @@ public enum FooOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasFooInt) { output.WriteRawTag(8); output.WriteInt32(FooInt); @@ -17948,14 +21947,36 @@ public enum FooOneofCase { output.WriteRawTag(18); output.WriteString(FooString); } - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { output.WriteRawTag(26); output.WriteMessage(FooMessage); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasFooInt) { + output.WriteRawTag(8); + output.WriteInt32(FooInt); + } + if (HasFooString) { + output.WriteRawTag(18); + output.WriteString(FooString); + } + if (fooCase_ == FooOneofCase.FooMessage) { + output.WriteRawTag(26); + output.WriteMessage(FooMessage); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -17966,7 +21987,7 @@ public enum FooOneofCase { if (HasFooString) { size += 1 + pb::CodedOutputStream.ComputeStringSize(FooString); } - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(FooMessage); } if (_unknownFields != null) { @@ -18000,6 +22021,9 @@ public enum FooOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -18016,7 +22040,38 @@ public enum FooOneofCase { } case 26: { global::Google.Protobuf.TestProtos.Proto2.TestRequiredOneof.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestRequiredOneof.Types.NestedMessage(); - if (HasFooMessage) { + if (fooCase_ == FooOneofCase.FooMessage) { + subBuilder.MergeFrom(FooMessage); + } + input.ReadMessage(subBuilder); + FooMessage = subBuilder; + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + FooInt = input.ReadInt32(); + break; + } + case 18: { + FooString = input.ReadString(); + break; + } + case 26: { + global::Google.Protobuf.TestProtos.Proto2.TestRequiredOneof.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestRequiredOneof.Types.NestedMessage(); + if (fooCase_ == FooOneofCase.FooMessage) { subBuilder.MergeFrom(FooMessage); } input.ReadMessage(subBuilder); @@ -18026,12 +22081,17 @@ public enum FooOneofCase { } } } + #endif #region Nested types /// Container for nested types declared in the TestRequiredOneof message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -18125,6 +22185,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasRequiredDouble) { output.WriteRawTag(9); output.WriteDouble(RequiredDouble); @@ -18132,7 +22195,21 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasRequiredDouble) { + output.WriteRawTag(9); + output.WriteDouble(RequiredDouble); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -18154,16 +22231,37 @@ public sealed partial class NestedMessage : pb::IMessage { if (other.HasRequiredDouble) { RequiredDouble = other.RequiredDouble; } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 9: { + RequiredDouble = input.ReadDouble(); + break; + } + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 9: { RequiredDouble = input.ReadDouble(); @@ -18172,6 +22270,7 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif } @@ -18180,7 +22279,11 @@ public sealed partial class NestedMessage : pb::IMessage { } - public sealed partial class TestRequiredMap : pb::IMessage { + public sealed partial class TestRequiredMap : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRequiredMap()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -18258,11 +22361,25 @@ public sealed partial class TestRequiredMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else foo_.WriteTo(output, _map_foo_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + foo_.WriteTo(ref output, _map_foo_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -18285,6 +22402,9 @@ public sealed partial class TestRequiredMap : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -18297,13 +22417,36 @@ public sealed partial class TestRequiredMap : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + foo_.AddEntriesFrom(ref input, _map_foo_codec); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the TestRequiredMap message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -18397,6 +22540,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasRequiredInt32) { output.WriteRawTag(8); output.WriteInt32(RequiredInt32); @@ -18404,7 +22550,21 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasRequiredInt32) { + output.WriteRawTag(8); + output.WriteInt32(RequiredInt32); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -18431,6 +22591,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -18443,7 +22606,26 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + RequiredInt32 = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -18452,7 +22634,11 @@ public sealed partial class NestedMessage : pb::IMessage { } - public sealed partial class TestPackedTypes : pb::IMessage { + public sealed partial class TestPackedTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestPackedTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -18699,6 +22885,9 @@ public sealed partial class TestPackedTypes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else packedInt32_.WriteTo(output, _repeated_packedInt32_codec); packedInt64_.WriteTo(output, _repeated_packedInt64_codec); packedUint32_.WriteTo(output, _repeated_packedUint32_codec); @@ -18716,7 +22905,31 @@ public sealed partial class TestPackedTypes : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + packedInt32_.WriteTo(ref output, _repeated_packedInt32_codec); + packedInt64_.WriteTo(ref output, _repeated_packedInt64_codec); + packedUint32_.WriteTo(ref output, _repeated_packedUint32_codec); + packedUint64_.WriteTo(ref output, _repeated_packedUint64_codec); + packedSint32_.WriteTo(ref output, _repeated_packedSint32_codec); + packedSint64_.WriteTo(ref output, _repeated_packedSint64_codec); + packedFixed32_.WriteTo(ref output, _repeated_packedFixed32_codec); + packedFixed64_.WriteTo(ref output, _repeated_packedFixed64_codec); + packedSfixed32_.WriteTo(ref output, _repeated_packedSfixed32_codec); + packedSfixed64_.WriteTo(ref output, _repeated_packedSfixed64_codec); + packedFloat_.WriteTo(ref output, _repeated_packedFloat_codec); + packedDouble_.WriteTo(ref output, _repeated_packedDouble_codec); + packedBool_.WriteTo(ref output, _repeated_packedBool_codec); + packedEnum_.WriteTo(ref output, _repeated_packedEnum_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -18765,6 +22978,9 @@ public sealed partial class TestPackedTypes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -18843,7 +23059,92 @@ public sealed partial class TestPackedTypes : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 722: + case 720: { + packedInt32_.AddEntriesFrom(ref input, _repeated_packedInt32_codec); + break; + } + case 730: + case 728: { + packedInt64_.AddEntriesFrom(ref input, _repeated_packedInt64_codec); + break; + } + case 738: + case 736: { + packedUint32_.AddEntriesFrom(ref input, _repeated_packedUint32_codec); + break; + } + case 746: + case 744: { + packedUint64_.AddEntriesFrom(ref input, _repeated_packedUint64_codec); + break; + } + case 754: + case 752: { + packedSint32_.AddEntriesFrom(ref input, _repeated_packedSint32_codec); + break; + } + case 762: + case 760: { + packedSint64_.AddEntriesFrom(ref input, _repeated_packedSint64_codec); + break; + } + case 770: + case 773: { + packedFixed32_.AddEntriesFrom(ref input, _repeated_packedFixed32_codec); + break; + } + case 778: + case 777: { + packedFixed64_.AddEntriesFrom(ref input, _repeated_packedFixed64_codec); + break; + } + case 786: + case 789: { + packedSfixed32_.AddEntriesFrom(ref input, _repeated_packedSfixed32_codec); + break; + } + case 794: + case 793: { + packedSfixed64_.AddEntriesFrom(ref input, _repeated_packedSfixed64_codec); + break; + } + case 802: + case 805: { + packedFloat_.AddEntriesFrom(ref input, _repeated_packedFloat_codec); + break; + } + case 810: + case 809: { + packedDouble_.AddEntriesFrom(ref input, _repeated_packedDouble_codec); + break; + } + case 818: + case 816: { + packedBool_.AddEntriesFrom(ref input, _repeated_packedBool_codec); + break; + } + case 826: + case 824: { + packedEnum_.AddEntriesFrom(ref input, _repeated_packedEnum_codec); + break; + } + } + } } + #endif } @@ -18851,7 +23152,11 @@ public sealed partial class TestPackedTypes : pb::IMessage { /// A message with the same fields as TestPackedTypes, but without packing. Used /// to test packed <-> unpacked wire compatibility. /// - public sealed partial class TestUnpackedTypes : pb::IMessage { + public sealed partial class TestUnpackedTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestUnpackedTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -19098,6 +23403,9 @@ public sealed partial class TestUnpackedTypes : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else unpackedInt32_.WriteTo(output, _repeated_unpackedInt32_codec); unpackedInt64_.WriteTo(output, _repeated_unpackedInt64_codec); unpackedUint32_.WriteTo(output, _repeated_unpackedUint32_codec); @@ -19115,7 +23423,31 @@ public sealed partial class TestUnpackedTypes : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + unpackedInt32_.WriteTo(ref output, _repeated_unpackedInt32_codec); + unpackedInt64_.WriteTo(ref output, _repeated_unpackedInt64_codec); + unpackedUint32_.WriteTo(ref output, _repeated_unpackedUint32_codec); + unpackedUint64_.WriteTo(ref output, _repeated_unpackedUint64_codec); + unpackedSint32_.WriteTo(ref output, _repeated_unpackedSint32_codec); + unpackedSint64_.WriteTo(ref output, _repeated_unpackedSint64_codec); + unpackedFixed32_.WriteTo(ref output, _repeated_unpackedFixed32_codec); + unpackedFixed64_.WriteTo(ref output, _repeated_unpackedFixed64_codec); + unpackedSfixed32_.WriteTo(ref output, _repeated_unpackedSfixed32_codec); + unpackedSfixed64_.WriteTo(ref output, _repeated_unpackedSfixed64_codec); + unpackedFloat_.WriteTo(ref output, _repeated_unpackedFloat_codec); + unpackedDouble_.WriteTo(ref output, _repeated_unpackedDouble_codec); + unpackedBool_.WriteTo(ref output, _repeated_unpackedBool_codec); + unpackedEnum_.WriteTo(ref output, _repeated_unpackedEnum_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -19164,6 +23496,9 @@ public sealed partial class TestUnpackedTypes : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -19242,11 +23577,100 @@ public sealed partial class TestUnpackedTypes : pb::IMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 722: + case 720: { + unpackedInt32_.AddEntriesFrom(ref input, _repeated_unpackedInt32_codec); + break; + } + case 730: + case 728: { + unpackedInt64_.AddEntriesFrom(ref input, _repeated_unpackedInt64_codec); + break; + } + case 738: + case 736: { + unpackedUint32_.AddEntriesFrom(ref input, _repeated_unpackedUint32_codec); + break; + } + case 746: + case 744: { + unpackedUint64_.AddEntriesFrom(ref input, _repeated_unpackedUint64_codec); + break; + } + case 754: + case 752: { + unpackedSint32_.AddEntriesFrom(ref input, _repeated_unpackedSint32_codec); + break; + } + case 762: + case 760: { + unpackedSint64_.AddEntriesFrom(ref input, _repeated_unpackedSint64_codec); + break; + } + case 770: + case 773: { + unpackedFixed32_.AddEntriesFrom(ref input, _repeated_unpackedFixed32_codec); + break; + } + case 778: + case 777: { + unpackedFixed64_.AddEntriesFrom(ref input, _repeated_unpackedFixed64_codec); + break; + } + case 786: + case 789: { + unpackedSfixed32_.AddEntriesFrom(ref input, _repeated_unpackedSfixed32_codec); + break; + } + case 794: + case 793: { + unpackedSfixed64_.AddEntriesFrom(ref input, _repeated_unpackedSfixed64_codec); + break; + } + case 802: + case 805: { + unpackedFloat_.AddEntriesFrom(ref input, _repeated_unpackedFloat_codec); + break; + } + case 810: + case 809: { + unpackedDouble_.AddEntriesFrom(ref input, _repeated_unpackedDouble_codec); + break; + } + case 818: + case 816: { + unpackedBool_.AddEntriesFrom(ref input, _repeated_unpackedBool_codec); + break; + } + case 826: + case 824: { + unpackedEnum_.AddEntriesFrom(ref input, _repeated_unpackedEnum_codec); + break; + } + } + } } + #endif } - public sealed partial class TestPackedExtensions : pb::IExtendableMessage { + public sealed partial class TestPackedExtensions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestPackedExtensions()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -19320,13 +23744,29 @@ public sealed partial class TestPackedExtensions : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -19387,7 +23847,11 @@ public sealed partial class TestPackedExtensions : pb::IExtendableMessage { + public sealed partial class TestUnpackedExtensions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestUnpackedExtensions()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -19461,13 +23925,29 @@ public sealed partial class TestUnpackedExtensions : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -19533,7 +24033,11 @@ public sealed partial class TestUnpackedExtensions : pb::IExtendableMessage - public sealed partial class TestDynamicExtensions : pb::IMessage { + public sealed partial class TestDynamicExtensions : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestDynamicExtensions()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -19563,8 +24067,8 @@ public sealed partial class TestDynamicExtensions : pb::IMessageGets whether the message_extension field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasMessageExtension { - get { return messageExtension_ != null; } - } - /// Clears the value of the message_extension field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearMessageExtension() { - messageExtension_ = null; - } /// Field number for the "dynamic_message_extension" field. public const int DynamicMessageExtensionFieldNumber = 2004; @@ -19678,16 +24172,6 @@ public sealed partial class TestDynamicExtensions : pb::IMessageGets whether the dynamic_message_extension field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasDynamicMessageExtension { - get { return dynamicMessageExtension_ != null; } - } - /// Clears the value of the dynamic_message_extension field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearDynamicMessageExtension() { - dynamicMessageExtension_ = null; - } /// Field number for the "repeated_extension" field. public const int RepeatedExtensionFieldNumber = 2005; @@ -19738,23 +24222,57 @@ public sealed partial class TestDynamicExtensions : pb::IMessageContainer for nested types declared in the TestDynamicExtensions message type. @@ -19896,7 +24468,11 @@ public enum DynamicEnumType { [pbr::OriginalName("DYNAMIC_BAZ")] DynamicBaz = 2202, } - public sealed partial class DynamicMessageType : pb::IMessage { + public sealed partial class DynamicMessageType : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DynamicMessageType()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -19990,6 +24566,9 @@ public sealed partial class DynamicMessageType : pb::IMessage { + public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRepeatedScalarDifferentTagSizes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -20202,6 +24821,9 @@ public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage - public sealed partial class TestParsingMerge : pb::IExtendableMessage { + public sealed partial class TestParsingMerge : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestParsingMerge()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -20317,8 +25007,8 @@ public sealed partial class TestParsingMerge : pb::IExtendableMessageGets whether the required_all_types field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasRequiredAllTypes { - get { return requiredAllTypes_ != null; } - } - /// Clears the value of the required_all_types field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearRequiredAllTypes() { - requiredAllTypes_ = null; - } /// Field number for the "optional_all_types" field. public const int OptionalAllTypesFieldNumber = 2; @@ -20362,16 +25042,6 @@ public sealed partial class TestParsingMerge : pb::IExtendableMessageGets whether the optional_all_types field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalAllTypes { - get { return optionalAllTypes_ != null; } - } - /// Clears the value of the optional_all_types field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalAllTypes() { - optionalAllTypes_ = null; - } /// Field number for the "repeated_all_types" field. public const int RepeatedAllTypesFieldNumber = 3; @@ -20441,8 +25111,8 @@ public sealed partial class TestParsingMerge : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -20613,7 +25363,11 @@ public static partial class Types { /// Repeated fields in RepeatedFieldsGenerator are expected to be merged into /// the corresponding required/optional fields in TestParsingMerge. /// - public sealed partial class RepeatedFieldsGenerator : pb::IMessage { + public sealed partial class RepeatedFieldsGenerator : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RepeatedFieldsGenerator()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -20769,6 +25523,9 @@ public sealed partial class RepeatedFieldsGenerator : pb::IMessageContainer for nested types declared in the RepeatedFieldsGenerator message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class Group1 : pb::IMessage { + public sealed partial class Group1 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Group1()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -20881,7 +25705,7 @@ public sealed partial class Group1 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Group1(Group1 other) : this() { - field1_ = other.HasField1 ? other.field1_.Clone() : null; + field1_ = other.field1_ != null ? other.field1_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -20900,16 +25724,6 @@ public sealed partial class Group1 : pb::IMessage { field1_ = value; } } - /// Gets whether the field1 field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasField1 { - get { return field1_ != null; } - } - /// Clears the value of the field1 field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearField1() { - field1_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -20931,7 +25745,7 @@ public sealed partial class Group1 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasField1) hash ^= Field1.GetHashCode(); + if (field1_ != null) hash ^= Field1.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -20945,19 +25759,36 @@ public sealed partial class Group1 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasField1) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (field1_ != null) { output.WriteRawTag(90); output.WriteMessage(Field1); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (field1_ != null) { + output.WriteRawTag(90); + output.WriteMessage(Field1); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasField1) { + if (field1_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Field1); } if (_unknownFields != null) { @@ -20971,8 +25802,8 @@ public sealed partial class Group1 : pb::IMessage { if (other == null) { return; } - if (other.HasField1) { - if (!HasField1) { + if (other.field1_ != null) { + if (field1_ == null) { Field1 = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } Field1.MergeFrom(other.Field1); @@ -20982,6 +25813,9 @@ public sealed partial class Group1 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -20991,7 +25825,7 @@ public sealed partial class Group1 : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 90: { - if (!HasField1) { + if (field1_ == null) { Field1 = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } input.ReadMessage(Field1); @@ -20999,11 +25833,39 @@ public sealed partial class Group1 : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 84: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 90: { + if (field1_ == null) { + Field1 = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + } + input.ReadMessage(Field1); + break; + } + } + } + } + #endif + } - public sealed partial class Group2 : pb::IMessage { + public sealed partial class Group2 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Group2()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21028,7 +25890,7 @@ public sealed partial class Group2 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public Group2(Group2 other) : this() { - field1_ = other.HasField1 ? other.field1_.Clone() : null; + field1_ = other.field1_ != null ? other.field1_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -21047,16 +25909,6 @@ public sealed partial class Group2 : pb::IMessage { field1_ = value; } } - /// Gets whether the field1 field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasField1 { - get { return field1_ != null; } - } - /// Clears the value of the field1 field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearField1() { - field1_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -21078,7 +25930,7 @@ public sealed partial class Group2 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasField1) hash ^= Field1.GetHashCode(); + if (field1_ != null) hash ^= Field1.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -21091,20 +25943,37 @@ public sealed partial class Group2 : pb::IMessage { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void WriteTo(pb::CodedOutputStream output) { - if (HasField1) { + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (field1_ != null) { + output.WriteRawTag(170, 1); + output.WriteMessage(Field1); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (field1_ != null) { output.WriteRawTag(170, 1); output.WriteMessage(Field1); } if (_unknownFields != null) { - _unknownFields.WriteTo(output); + _unknownFields.WriteTo(ref output); } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasField1) { + if (field1_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(Field1); } if (_unknownFields != null) { @@ -21118,8 +25987,8 @@ public sealed partial class Group2 : pb::IMessage { if (other == null) { return; } - if (other.HasField1) { - if (!HasField1) { + if (other.field1_ != null) { + if (field1_ == null) { Field1 = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } Field1.MergeFrom(other.Field1); @@ -21129,6 +25998,9 @@ public sealed partial class Group2 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -21138,7 +26010,30 @@ public sealed partial class Group2 : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 170: { - if (!HasField1) { + if (field1_ == null) { + Field1 = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + } + input.ReadMessage(Field1); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 164: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 170: { + if (field1_ == null) { Field1 = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } input.ReadMessage(Field1); @@ -21147,6 +26042,7 @@ public sealed partial class Group2 : pb::IMessage { } } } + #endif } @@ -21155,7 +26051,11 @@ public sealed partial class Group2 : pb::IMessage { } - public sealed partial class OptionalGroup : pb::IMessage { + public sealed partial class OptionalGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OptionalGroup()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21180,7 +26080,7 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public OptionalGroup(OptionalGroup other) : this() { - optionalGroupAllTypes_ = other.HasOptionalGroupAllTypes ? other.optionalGroupAllTypes_.Clone() : null; + optionalGroupAllTypes_ = other.optionalGroupAllTypes_ != null ? other.optionalGroupAllTypes_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -21199,16 +26099,6 @@ public sealed partial class OptionalGroup : pb::IMessage { optionalGroupAllTypes_ = value; } } - /// Gets whether the optional_group_all_types field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalGroupAllTypes { - get { return optionalGroupAllTypes_ != null; } - } - /// Clears the value of the optional_group_all_types field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalGroupAllTypes() { - optionalGroupAllTypes_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -21230,7 +26120,7 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasOptionalGroupAllTypes) hash ^= OptionalGroupAllTypes.GetHashCode(); + if (optionalGroupAllTypes_ != null) hash ^= OptionalGroupAllTypes.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -21244,19 +26134,36 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasOptionalGroupAllTypes) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (optionalGroupAllTypes_ != null) { output.WriteRawTag(90); output.WriteMessage(OptionalGroupAllTypes); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (optionalGroupAllTypes_ != null) { + output.WriteRawTag(90); + output.WriteMessage(OptionalGroupAllTypes); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasOptionalGroupAllTypes) { + if (optionalGroupAllTypes_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(OptionalGroupAllTypes); } if (_unknownFields != null) { @@ -21270,8 +26177,8 @@ public sealed partial class OptionalGroup : pb::IMessage { if (other == null) { return; } - if (other.HasOptionalGroupAllTypes) { - if (!HasOptionalGroupAllTypes) { + if (other.optionalGroupAllTypes_ != null) { + if (optionalGroupAllTypes_ == null) { OptionalGroupAllTypes = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } OptionalGroupAllTypes.MergeFrom(other.OptionalGroupAllTypes); @@ -21281,6 +26188,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -21290,7 +26200,7 @@ public sealed partial class OptionalGroup : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 90: { - if (!HasOptionalGroupAllTypes) { + if (optionalGroupAllTypes_ == null) { OptionalGroupAllTypes = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } input.ReadMessage(OptionalGroupAllTypes); @@ -21298,11 +26208,39 @@ public sealed partial class OptionalGroup : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 84: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 90: { + if (optionalGroupAllTypes_ == null) { + OptionalGroupAllTypes = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + } + input.ReadMessage(OptionalGroupAllTypes); + break; + } + } + } + } + #endif + } - public sealed partial class RepeatedGroup : pb::IMessage { + public sealed partial class RepeatedGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RepeatedGroup()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21327,7 +26265,7 @@ public sealed partial class RepeatedGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public RepeatedGroup(RepeatedGroup other) : this() { - repeatedGroupAllTypes_ = other.HasRepeatedGroupAllTypes ? other.repeatedGroupAllTypes_.Clone() : null; + repeatedGroupAllTypes_ = other.repeatedGroupAllTypes_ != null ? other.repeatedGroupAllTypes_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -21346,16 +26284,6 @@ public sealed partial class RepeatedGroup : pb::IMessage { repeatedGroupAllTypes_ = value; } } - /// Gets whether the repeated_group_all_types field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasRepeatedGroupAllTypes { - get { return repeatedGroupAllTypes_ != null; } - } - /// Clears the value of the repeated_group_all_types field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearRepeatedGroupAllTypes() { - repeatedGroupAllTypes_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -21377,7 +26305,7 @@ public sealed partial class RepeatedGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override int GetHashCode() { int hash = 1; - if (HasRepeatedGroupAllTypes) hash ^= RepeatedGroupAllTypes.GetHashCode(); + if (repeatedGroupAllTypes_ != null) hash ^= RepeatedGroupAllTypes.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -21391,19 +26319,36 @@ public sealed partial class RepeatedGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { - if (HasRepeatedGroupAllTypes) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (repeatedGroupAllTypes_ != null) { output.WriteRawTag(170, 1); output.WriteMessage(RepeatedGroupAllTypes); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (repeatedGroupAllTypes_ != null) { + output.WriteRawTag(170, 1); + output.WriteMessage(RepeatedGroupAllTypes); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; - if (HasRepeatedGroupAllTypes) { + if (repeatedGroupAllTypes_ != null) { size += 2 + pb::CodedOutputStream.ComputeMessageSize(RepeatedGroupAllTypes); } if (_unknownFields != null) { @@ -21417,8 +26362,8 @@ public sealed partial class RepeatedGroup : pb::IMessage { if (other == null) { return; } - if (other.HasRepeatedGroupAllTypes) { - if (!HasRepeatedGroupAllTypes) { + if (other.repeatedGroupAllTypes_ != null) { + if (repeatedGroupAllTypes_ == null) { RepeatedGroupAllTypes = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } RepeatedGroupAllTypes.MergeFrom(other.RepeatedGroupAllTypes); @@ -21428,6 +26373,9 @@ public sealed partial class RepeatedGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -21437,7 +26385,30 @@ public sealed partial class RepeatedGroup : pb::IMessage { _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); break; case 170: { - if (!HasRepeatedGroupAllTypes) { + if (repeatedGroupAllTypes_ == null) { + RepeatedGroupAllTypes = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + } + input.ReadMessage(RepeatedGroupAllTypes); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 164: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 170: { + if (repeatedGroupAllTypes_ == null) { RepeatedGroupAllTypes = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); } input.ReadMessage(RepeatedGroupAllTypes); @@ -21446,6 +26417,7 @@ public sealed partial class RepeatedGroup : pb::IMessage { } } } + #endif } @@ -21465,7 +26437,11 @@ public static partial class Extensions { } - public sealed partial class TestCommentInjectionMessage : pb::IMessage { + public sealed partial class TestCommentInjectionMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestCommentInjectionMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21559,6 +26535,9 @@ public sealed partial class TestCommentInjectionMessage : pb::IMessage /// Test that RPC services work. /// - public sealed partial class FooRequest : pb::IMessage { + public sealed partial class FooRequest : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooRequest()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21677,10 +26696,23 @@ public sealed partial class FooRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -21701,6 +26733,9 @@ public sealed partial class FooRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -21709,11 +26744,30 @@ public sealed partial class FooRequest : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class FooResponse : pb::IMessage { + public sealed partial class FooResponse : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooResponse()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21778,10 +26832,23 @@ public sealed partial class FooResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -21802,6 +26869,9 @@ public sealed partial class FooResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -21810,11 +26880,30 @@ public sealed partial class FooResponse : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class FooClientMessage : pb::IMessage { + public sealed partial class FooClientMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooClientMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21879,10 +26968,23 @@ public sealed partial class FooClientMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -21903,6 +27005,9 @@ public sealed partial class FooClientMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -21911,11 +27016,30 @@ public sealed partial class FooClientMessage : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class FooServerMessage : pb::IMessage { + public sealed partial class FooServerMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooServerMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -21980,10 +27104,23 @@ public sealed partial class FooServerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -22004,6 +27141,9 @@ public sealed partial class FooServerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -22012,11 +27152,30 @@ public sealed partial class FooServerMessage : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class BarRequest : pb::IMessage { + public sealed partial class BarRequest : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BarRequest()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22081,10 +27240,23 @@ public sealed partial class BarRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -22105,6 +27277,9 @@ public sealed partial class BarRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -22113,11 +27288,30 @@ public sealed partial class BarRequest : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class BarResponse : pb::IMessage { + public sealed partial class BarResponse : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BarResponse()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -22182,10 +27376,23 @@ public sealed partial class BarResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -22206,6 +27413,9 @@ public sealed partial class BarResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -22214,11 +27424,30 @@ public sealed partial class BarResponse : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class TestJsonName : pb::IMessage { + public sealed partial class TestJsonName : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestJsonName()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -22447,6 +27676,9 @@ public sealed partial class TestJsonName : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasFieldName1) { output.WriteRawTag(8); output.WriteInt32(FieldName1); @@ -22474,7 +27706,41 @@ public sealed partial class TestJsonName : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasFieldName1) { + output.WriteRawTag(8); + output.WriteInt32(FieldName1); + } + if (HasFieldName2) { + output.WriteRawTag(16); + output.WriteInt32(FieldName2); + } + if (HasFieldName3) { + output.WriteRawTag(24); + output.WriteInt32(FieldName3); + } + if (HasFieldName4) { + output.WriteRawTag(32); + output.WriteInt32(FieldName4); + } + if (HasFIELDNAME5) { + output.WriteRawTag(40); + output.WriteInt32(FIELDNAME5); + } + if (HasFieldName6) { + output.WriteRawTag(48); + output.WriteInt32(FieldName6); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -22526,16 +27792,57 @@ public sealed partial class TestJsonName : pb::IMessage { if (other.HasFieldName6) { FieldName6 = other.FieldName6; } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + FieldName1 = input.ReadInt32(); + break; + } + case 16: { + FieldName2 = input.ReadInt32(); + break; + } + case 24: { + FieldName3 = input.ReadInt32(); + break; + } + case 32: { + FieldName4 = input.ReadInt32(); + break; + } + case 40: { + FIELDNAME5 = input.ReadInt32(); + break; + } + case 48: { + FieldName6 = input.ReadInt32(); + break; + } + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 8: { FieldName1 = input.ReadInt32(); @@ -22564,10 +27871,15 @@ public sealed partial class TestJsonName : pb::IMessage { } } } + #endif } - public sealed partial class TestHugeFieldNumbers : pb::IExtendableMessage { + public sealed partial class TestHugeFieldNumbers : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestHugeFieldNumbers()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -22603,7 +27915,7 @@ public sealed partial class TestHugeFieldNumbers : pb::IExtendableMessageGets whether the optional_message field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptionalMessage { - get { return optionalMessage_ != null; } - } - /// Clears the value of the optional_message field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptionalMessage() { - optionalMessage_ = null; - } /// Field number for the "optionalgroup" field. public const int OptionalGroupFieldNumber = 536870008; @@ -22847,24 +28149,12 @@ public sealed partial class TestHugeFieldNumbers : pb::IExtendableMessageGets whether the "oneof_test_all_types" field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOneofTestAllTypes { - get { return oneofFieldCase_ == OneofFieldOneofCase.OneofTestAllTypes; } - } - /// Clears the value of the oneof if it's currently set to "oneof_test_all_types" - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOneofTestAllTypes() { - if (HasOneofTestAllTypes) { - ClearOneofField(); - } - } /// Field number for the "oneof_string" field. public const int OneofStringFieldNumber = 536870013; @@ -22977,11 +28267,11 @@ public enum OneofFieldOneofCase { if (HasOptionalEnum) hash ^= OptionalEnum.GetHashCode(); if (HasOptionalString) hash ^= OptionalString.GetHashCode(); if (HasOptionalBytes) hash ^= OptionalBytes.GetHashCode(); - if (HasOptionalMessage) hash ^= OptionalMessage.GetHashCode(); + if (optionalMessage_ != null) hash ^= OptionalMessage.GetHashCode(); if (HasOptionalGroup) hash ^= OptionalGroup.GetHashCode(); hash ^= StringStringMap.GetHashCode(); if (HasOneofUint32) hash ^= OneofUint32.GetHashCode(); - if (HasOneofTestAllTypes) hash ^= OneofTestAllTypes.GetHashCode(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofTestAllTypes) hash ^= OneofTestAllTypes.GetHashCode(); if (HasOneofString) hash ^= OneofString.GetHashCode(); if (HasOneofBytes) hash ^= OneofBytes.GetHashCode(); hash ^= (int) oneofFieldCase_; @@ -23001,6 +28291,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasOptionalInt32) { output.WriteRawTag(128, 199, 255, 255, 15); output.WriteInt32(OptionalInt32); @@ -23023,7 +28316,7 @@ public enum OneofFieldOneofCase { output.WriteRawTag(178, 199, 255, 255, 15); output.WriteBytes(OptionalBytes); } - if (HasOptionalMessage) { + if (optionalMessage_ != null) { output.WriteRawTag(186, 199, 255, 255, 15); output.WriteMessage(OptionalMessage); } @@ -23037,7 +28330,7 @@ public enum OneofFieldOneofCase { output.WriteRawTag(216, 199, 255, 255, 15); output.WriteUInt32(OneofUint32); } - if (HasOneofTestAllTypes) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofTestAllTypes) { output.WriteRawTag(226, 199, 255, 255, 15); output.WriteMessage(OneofTestAllTypes); } @@ -23055,7 +28348,68 @@ public enum OneofFieldOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasOptionalInt32) { + output.WriteRawTag(128, 199, 255, 255, 15); + output.WriteInt32(OptionalInt32); + } + if (HasFixed32) { + output.WriteRawTag(136, 199, 255, 255, 15); + output.WriteInt32(Fixed32); + } + repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec); + packedInt32_.WriteTo(ref output, _repeated_packedInt32_codec); + if (HasOptionalEnum) { + output.WriteRawTag(160, 199, 255, 255, 15); + output.WriteEnum((int) OptionalEnum); + } + if (HasOptionalString) { + output.WriteRawTag(170, 199, 255, 255, 15); + output.WriteString(OptionalString); + } + if (HasOptionalBytes) { + output.WriteRawTag(178, 199, 255, 255, 15); + output.WriteBytes(OptionalBytes); + } + if (optionalMessage_ != null) { + output.WriteRawTag(186, 199, 255, 255, 15); + output.WriteMessage(OptionalMessage); + } + if (HasOptionalGroup) { + output.WriteRawTag(195, 199, 255, 255, 15); + output.WriteGroup(OptionalGroup); + output.WriteRawTag(196, 199, 255, 255, 15); + } + stringStringMap_.WriteTo(ref output, _map_stringStringMap_codec); + if (HasOneofUint32) { + output.WriteRawTag(216, 199, 255, 255, 15); + output.WriteUInt32(OneofUint32); + } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofTestAllTypes) { + output.WriteRawTag(226, 199, 255, 255, 15); + output.WriteMessage(OneofTestAllTypes); + } + if (HasOneofString) { + output.WriteRawTag(234, 199, 255, 255, 15); + output.WriteString(OneofString); + } + if (HasOneofBytes) { + output.WriteRawTag(242, 199, 255, 255, 15); + output.WriteBytes(OneofBytes); + } + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -23077,7 +28431,7 @@ public enum OneofFieldOneofCase { if (HasOptionalBytes) { size += 5 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes); } - if (HasOptionalMessage) { + if (optionalMessage_ != null) { size += 5 + pb::CodedOutputStream.ComputeMessageSize(OptionalMessage); } if (HasOptionalGroup) { @@ -23087,7 +28441,7 @@ public enum OneofFieldOneofCase { if (HasOneofUint32) { size += 5 + pb::CodedOutputStream.ComputeUInt32Size(OneofUint32); } - if (HasOneofTestAllTypes) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofTestAllTypes) { size += 5 + pb::CodedOutputStream.ComputeMessageSize(OneofTestAllTypes); } if (HasOneofString) { @@ -23127,8 +28481,8 @@ public enum OneofFieldOneofCase { if (other.HasOptionalBytes) { OptionalBytes = other.OptionalBytes; } - if (other.HasOptionalMessage) { - if (!HasOptionalMessage) { + if (other.optionalMessage_ != null) { + if (optionalMessage_ == null) { OptionalMessage = new global::Google.Protobuf.TestProtos.Proto2.ForeignMessage(); } OptionalMessage.MergeFrom(other.OptionalMessage); @@ -23164,6 +28518,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -23203,7 +28560,7 @@ public enum OneofFieldOneofCase { break; } case 4294960058: { - if (!HasOptionalMessage) { + if (optionalMessage_ == null) { OptionalMessage = new global::Google.Protobuf.TestProtos.Proto2.ForeignMessage(); } input.ReadMessage(OptionalMessage); @@ -23226,7 +28583,92 @@ public enum OneofFieldOneofCase { } case 4294960098: { global::Google.Protobuf.TestProtos.Proto2.TestAllTypes subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); - if (HasOneofTestAllTypes) { + if (oneofFieldCase_ == OneofFieldOneofCase.OneofTestAllTypes) { + subBuilder.MergeFrom(OneofTestAllTypes); + } + input.ReadMessage(subBuilder); + OneofTestAllTypes = subBuilder; + break; + } + case 4294960106: { + OneofString = input.ReadString(); + break; + } + case 4294960114: { + OneofBytes = input.ReadBytes(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + case 4294960000: { + OptionalInt32 = input.ReadInt32(); + break; + } + case 4294960008: { + Fixed32 = input.ReadInt32(); + break; + } + case 4294960018: + case 4294960016: { + repeatedInt32_.AddEntriesFrom(ref input, _repeated_repeatedInt32_codec); + break; + } + case 4294960026: + case 4294960024: { + packedInt32_.AddEntriesFrom(ref input, _repeated_packedInt32_codec); + break; + } + case 4294960032: { + OptionalEnum = (global::Google.Protobuf.TestProtos.Proto2.ForeignEnum) input.ReadEnum(); + break; + } + case 4294960042: { + OptionalString = input.ReadString(); + break; + } + case 4294960050: { + OptionalBytes = input.ReadBytes(); + break; + } + case 4294960058: { + if (optionalMessage_ == null) { + OptionalMessage = new global::Google.Protobuf.TestProtos.Proto2.ForeignMessage(); + } + input.ReadMessage(OptionalMessage); + break; + } + case 4294960067: { + if (!HasOptionalGroup) { + OptionalGroup = new global::Google.Protobuf.TestProtos.Proto2.TestHugeFieldNumbers.Types.OptionalGroup(); + } + input.ReadGroup(OptionalGroup); + break; + } + case 4294960082: { + stringStringMap_.AddEntriesFrom(ref input, _map_stringStringMap_codec); + break; + } + case 4294960088: { + OneofUint32 = input.ReadUInt32(); + break; + } + case 4294960098: { + global::Google.Protobuf.TestProtos.Proto2.TestAllTypes subBuilder = new global::Google.Protobuf.TestProtos.Proto2.TestAllTypes(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofTestAllTypes) { subBuilder.MergeFrom(OneofTestAllTypes); } input.ReadMessage(subBuilder); @@ -23244,6 +28686,7 @@ public enum OneofFieldOneofCase { } } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -23271,7 +28714,11 @@ public enum OneofFieldOneofCase { /// Container for nested types declared in the TestHugeFieldNumbers message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class OptionalGroup : pb::IMessage { + public sealed partial class OptionalGroup : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OptionalGroup()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -23365,6 +28812,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasGroupA) { output.WriteRawTag(200, 199, 255, 255, 15); output.WriteInt32(GroupA); @@ -23372,7 +28822,21 @@ public sealed partial class OptionalGroup : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasGroupA) { + output.WriteRawTag(200, 199, 255, 255, 15); + output.WriteInt32(GroupA); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -23399,6 +28863,9 @@ public sealed partial class OptionalGroup : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -23413,7 +28880,28 @@ public sealed partial class OptionalGroup : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + case 4294960068: + return; + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 4294960072: { + GroupA = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -23422,7 +28910,11 @@ public sealed partial class OptionalGroup : pb::IMessage { } - public sealed partial class TestExtensionInsideTable : pb::IExtendableMessage { + public sealed partial class TestExtensionInsideTable : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestExtensionInsideTable()); private pb::UnknownFieldSet _unknownFields; private pb::ExtensionSet _extensions; @@ -23741,6 +29233,9 @@ public sealed partial class TestExtensionInsideTable : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestCustomOptionsProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestCustomOptionsProto3.cs index cb5edf75472d..84a4a7eda20e 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestCustomOptionsProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestCustomOptionsProto3.cs @@ -257,7 +257,11 @@ public enum AggregateEnum { /// A test message with custom options at all possible locations (and also some /// regular options, to make sure they interact nicely). /// - public sealed partial class TestMessageWithCustomOptions : pb::IMessage { + public sealed partial class TestMessageWithCustomOptions : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMessageWithCustomOptions()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -375,6 +379,9 @@ public enum AnOneofOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Field1.Length != 0) { output.WriteRawTag(10); output.WriteString(Field1); @@ -386,8 +393,26 @@ public enum AnOneofOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Field1.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Field1); + } + if (anOneofCase_ == AnOneofOneofCase.OneofField) { + output.WriteRawTag(16); + output.WriteInt32(OneofField); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -422,6 +447,9 @@ public enum AnOneofOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -438,8 +466,31 @@ public enum AnOneofOneofCase { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Field1 = input.ReadString(); + break; + } + case 16: { + OneofField = input.ReadInt32(); + break; + } + } + } + } + #endif + #region Nested types /// Container for nested types declared in the TestMessageWithCustomOptions message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -459,7 +510,11 @@ public enum AnEnum { /// A test RPC service with custom options at all possible locations (and also /// some regular options, to make sure they interact nicely). /// - public sealed partial class CustomOptionFooRequest : pb::IMessage { + public sealed partial class CustomOptionFooRequest : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CustomOptionFooRequest()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -524,10 +579,23 @@ public sealed partial class CustomOptionFooRequest : pb::IMessage { + public sealed partial class CustomOptionFooResponse : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CustomOptionFooResponse()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -625,10 +715,23 @@ public sealed partial class CustomOptionFooResponse : pb::IMessage { + public sealed partial class CustomOptionFooClientMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CustomOptionFooClientMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -726,10 +851,23 @@ public sealed partial class CustomOptionFooClientMessage : pb::IMessage { + public sealed partial class CustomOptionFooServerMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CustomOptionFooServerMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -827,10 +987,23 @@ public sealed partial class CustomOptionFooServerMessage : pb::IMessage { + public sealed partial class DummyMessageContainingEnum : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DummyMessageContainingEnum()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -928,10 +1123,23 @@ public sealed partial class DummyMessageContainingEnum : pb::IMessageContainer for nested types declared in the DummyMessageContainingEnum message type. @@ -977,7 +1203,11 @@ public enum TestEnumType { } - public sealed partial class DummyMessageInvalidAsOptionType : pb::IMessage { + public sealed partial class DummyMessageInvalidAsOptionType : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DummyMessageInvalidAsOptionType()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1042,11 +1272,24 @@ public sealed partial class DummyMessageInvalidAsOptionType : pb::IMessage { + public sealed partial class CustomOptionMinIntegerValues : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CustomOptionMinIntegerValues()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1143,11 +1408,24 @@ public sealed partial class CustomOptionMinIntegerValues : pb::IMessage { + public sealed partial class CustomOptionMaxIntegerValues : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CustomOptionMaxIntegerValues()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1244,11 +1544,24 @@ public sealed partial class CustomOptionMaxIntegerValues : pb::IMessage { + public sealed partial class CustomOptionOtherValues : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CustomOptionOtherValues()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1345,10 +1680,23 @@ public sealed partial class CustomOptionOtherValues : pb::IMessage { + public sealed partial class SettingRealsFromPositiveInts : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SettingRealsFromPositiveInts()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1446,11 +1816,24 @@ public sealed partial class SettingRealsFromPositiveInts : pb::IMessage { + public sealed partial class SettingRealsFromNegativeInts : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SettingRealsFromNegativeInts()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1547,10 +1952,23 @@ public sealed partial class SettingRealsFromNegativeInts : pb::IMessage { + public sealed partial class ComplexOptionType1 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ComplexOptionType1()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1703,6 +2143,9 @@ public sealed partial class ComplexOptionType1 : pb::IMessage { + public sealed partial class ComplexOptionType2 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ComplexOptionType2()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1909,6 +2414,9 @@ public sealed partial class ComplexOptionType2 : pb::IMessageContainer for nested types declared in the ComplexOptionType2 message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class ComplexOptionType4 : pb::IMessage { + public sealed partial class ComplexOptionType4 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ComplexOptionType4()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2087,6 +2662,9 @@ public sealed partial class ComplexOptionType4 : pb::IMessageContainer for extensions for other messages declared in the ComplexOptionType4 message type. @@ -2151,7 +2765,11 @@ public static partial class Extensions { } - public sealed partial class ComplexOptionType3 : pb::IMessage { + public sealed partial class ComplexOptionType3 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ComplexOptionType3()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2230,6 +2848,9 @@ public sealed partial class ComplexOptionType3 : pb::IMessage /// Note that we try various different ways of naming the same extension. /// - public sealed partial class VariousComplexOptions : pb::IMessage { + public sealed partial class VariousComplexOptions : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new VariousComplexOptions()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2348,11 +3009,24 @@ public sealed partial class VariousComplexOptions : pb::IMessage /// A helper type used to test aggregate option parsing /// - public sealed partial class Aggregate : pb::IMessage { + public sealed partial class Aggregate : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Aggregate()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2497,6 +3193,9 @@ public sealed partial class Aggregate : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (I != 0) { output.WriteRawTag(8); output.WriteInt32(I); @@ -2512,7 +3211,29 @@ public sealed partial class Aggregate : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (I != 0) { + output.WriteRawTag(8); + output.WriteInt32(I); + } + if (S.Length != 0) { + output.WriteRawTag(18); + output.WriteString(S); + } + if (sub_ != null) { + output.WriteRawTag(26); + output.WriteMessage(Sub); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2554,6 +3275,9 @@ public sealed partial class Aggregate : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2577,11 +3301,45 @@ public sealed partial class Aggregate : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + I = input.ReadInt32(); + break; + } + case 18: { + S = input.ReadString(); + break; + } + case 26: { + if (sub_ == null) { + Sub = new global::UnitTest.Issues.TestProtos.Aggregate(); + } + input.ReadMessage(Sub); + break; + } + } + } } + #endif } - public sealed partial class AggregateMessage : pb::IMessage { + public sealed partial class AggregateMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new AggregateMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2660,6 +3418,9 @@ public sealed partial class AggregateMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Fieldname != 0) { output.WriteRawTag(8); output.WriteInt32(Fieldname); @@ -2667,7 +3428,21 @@ public sealed partial class AggregateMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Fieldname != 0) { + output.WriteRawTag(8); + output.WriteInt32(Fieldname); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2694,6 +3469,9 @@ public sealed partial class AggregateMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2706,14 +3484,37 @@ public sealed partial class AggregateMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Fieldname = input.ReadInt32(); + break; + } + } + } } + #endif } /// /// Test custom options for nested type. /// - public sealed partial class NestedOptionType : pb::IMessage { + public sealed partial class NestedOptionType : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedOptionType()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2778,10 +3579,23 @@ public sealed partial class NestedOptionType : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2802,6 +3616,9 @@ public sealed partial class NestedOptionType : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2810,7 +3627,22 @@ public sealed partial class NestedOptionType : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif #region Nested types /// Container for nested types declared in the NestedOptionType message type. @@ -2821,7 +3653,11 @@ public enum NestedEnum { [pbr::OriginalName("NESTED_ENUM_VALUE")] Value = 1, } - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2900,6 +3736,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (NestedField != 0) { output.WriteRawTag(8); output.WriteInt32(NestedField); @@ -2907,7 +3746,21 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (NestedField != 0) { + output.WriteRawTag(8); + output.WriteInt32(NestedField); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2934,6 +3787,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2946,7 +3802,26 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + NestedField = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImport.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImport.cs index d5f8589315e3..14b054ccbbae 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImport.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImport.cs @@ -59,7 +59,11 @@ public enum ImportEnumForMap { #endregion #region Messages - public sealed partial class ImportMessage : pb::IMessage { + public sealed partial class ImportMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ImportMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -153,6 +157,9 @@ public sealed partial class ImportMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasD) { output.WriteRawTag(8); output.WriteInt32(D); @@ -160,8 +167,22 @@ public sealed partial class ImportMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasD) { + output.WriteRawTag(8); + output.WriteInt32(D); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -187,6 +208,9 @@ public sealed partial class ImportMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -199,7 +223,26 @@ public sealed partial class ImportMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + D = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportProto3.cs index 19a1a34634f9..ecdf40979c2b 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportProto3.cs @@ -50,7 +50,11 @@ public enum ImportEnum { #endregion #region Messages - public sealed partial class ImportMessage : pb::IMessage { + public sealed partial class ImportMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ImportMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -129,6 +133,9 @@ public sealed partial class ImportMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (D != 0) { output.WriteRawTag(8); output.WriteInt32(D); @@ -136,8 +143,22 @@ public sealed partial class ImportMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (D != 0) { + output.WriteRawTag(8); + output.WriteInt32(D); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -163,6 +184,9 @@ public sealed partial class ImportMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -175,7 +199,26 @@ public sealed partial class ImportMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + D = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublic.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublic.cs index 77f212176035..24c29e970826 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublic.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestImportPublic.cs @@ -37,7 +37,11 @@ public static partial class UnittestImportPublicReflection { } #region Messages - public sealed partial class PublicImportMessage : pb::IMessage { + public sealed partial class PublicImportMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PublicImportMessage()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -131,6 +135,9 @@ public sealed partial class PublicImportMessage : pb::IMessage { + public sealed partial class PublicImportMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new PublicImportMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -117,6 +121,9 @@ public sealed partial class PublicImportMessage : pb::IMessage { + public sealed partial class Foo : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Foo()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -102,11 +106,24 @@ public sealed partial class Foo : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -126,6 +143,9 @@ public sealed partial class Foo : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -134,7 +154,22 @@ public sealed partial class Foo : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936C.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936C.cs index a8a73f6cb6ec..21d36300f87c 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936C.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssue6936C.cs @@ -39,7 +39,11 @@ public static partial class UnittestIssue6936CReflection { } #region Messages - public sealed partial class Bar : pb::IMessage { + public sealed partial class Bar : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Bar()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -118,6 +122,9 @@ public sealed partial class Bar : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (foo_ != null) { output.WriteRawTag(10); output.WriteMessage(Foo); @@ -125,8 +132,22 @@ public sealed partial class Bar : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (foo_ != null) { + output.WriteRawTag(10); + output.WriteMessage(Foo); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -155,6 +176,9 @@ public sealed partial class Bar : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -170,7 +194,29 @@ public sealed partial class Bar : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (foo_ == null) { + Foo = new global::UnitTest.Issues.TestProtos.Foo(); + } + input.ReadMessage(Foo); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs index f3f40c6a70cf..4377cf3a19cf 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestIssues.cs @@ -24,36 +24,43 @@ public static partial class UnittestIssuesReflection { static UnittestIssuesReflection() { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( - "ChV1bml0dGVzdF9pc3N1ZXMucHJvdG8SD3VuaXR0ZXN0X2lzc3VlcyInCghJ", - "c3N1ZTMwNxobCgpOZXN0ZWRPbmNlGg0KC05lc3RlZFR3aWNlIrABChNOZWdh", - "dGl2ZUVudW1NZXNzYWdlEiwKBXZhbHVlGAEgASgOMh0udW5pdHRlc3RfaXNz", - "dWVzLk5lZ2F0aXZlRW51bRIxCgZ2YWx1ZXMYAiADKA4yHS51bml0dGVzdF9p", - "c3N1ZXMuTmVnYXRpdmVFbnVtQgIQABI4Cg1wYWNrZWRfdmFsdWVzGAMgAygO", - "Mh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51bUICEAEiEQoPRGVwcmVj", - "YXRlZENoaWxkIrkCChdEZXByZWNhdGVkRmllbGRzTWVzc2FnZRIaCg5Qcmlt", - "aXRpdmVWYWx1ZRgBIAEoBUICGAESGgoOUHJpbWl0aXZlQXJyYXkYAiADKAVC", - "AhgBEjoKDE1lc3NhZ2VWYWx1ZRgDIAEoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5E", - "ZXByZWNhdGVkQ2hpbGRCAhgBEjoKDE1lc3NhZ2VBcnJheRgEIAMoCzIgLnVu", - "aXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRCAhgBEjYKCUVudW1WYWx1", - "ZRgFIAEoDjIfLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAES", - "NgoJRW51bUFycmF5GAYgAygOMh8udW5pdHRlc3RfaXNzdWVzLkRlcHJlY2F0", - "ZWRFbnVtQgIYASIZCglJdGVtRmllbGQSDAoEaXRlbRgBIAEoBSJECg1SZXNl", - "cnZlZE5hbWVzEg0KBXR5cGVzGAEgASgFEhIKCmRlc2NyaXB0b3IYAiABKAUa", - "EAoOU29tZU5lc3RlZFR5cGUioAEKFVRlc3RKc29uRmllbGRPcmRlcmluZxIT", - "CgtwbGFpbl9pbnQzMhgEIAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghv", - "MV9pbnQzMhgFIAEoBUgAEhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9p", - "bnQzMhgGIAEoBUgBEhMKCW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8y", - "IksKDFRlc3RKc29uTmFtZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9u", - "GAIgASgJUgRkZXNjEhIKBGd1aWQYAyABKAlSBGV4aWQifwoMT25lb2ZNZXJn", - "aW5nEg4KBHRleHQYASABKAlIABI2CgZuZXN0ZWQYAiABKAsyJC51bml0dGVz", - "dF9pc3N1ZXMuT25lb2ZNZXJnaW5nLk5lc3RlZEgAGh4KBk5lc3RlZBIJCgF4", - "GAEgASgFEgkKAXkYAiABKAVCBwoFdmFsdWUqVQoMTmVnYXRpdmVFbnVtEhYK", - "Ek5FR0FUSVZFX0VOVU1fWkVSTxAAEhYKCUZpdmVCZWxvdxD7//////////8B", - "EhUKCE1pbnVzT25lEP///////////wEqLgoORGVwcmVjYXRlZEVudW0SEwoP", - "REVQUkVDQVRFRF9aRVJPEAASBwoDb25lEAFCHaoCGlVuaXRUZXN0Lklzc3Vl", - "cy5UZXN0UHJvdG9zYgZwcm90bzM=")); + "ChV1bml0dGVzdF9pc3N1ZXMucHJvdG8SD3VuaXR0ZXN0X2lzc3VlcxocZ29v", + "Z2xlL3Byb3RvYnVmL3N0cnVjdC5wcm90byInCghJc3N1ZTMwNxobCgpOZXN0", + "ZWRPbmNlGg0KC05lc3RlZFR3aWNlIrABChNOZWdhdGl2ZUVudW1NZXNzYWdl", + "EiwKBXZhbHVlGAEgASgOMh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51", + "bRIxCgZ2YWx1ZXMYAiADKA4yHS51bml0dGVzdF9pc3N1ZXMuTmVnYXRpdmVF", + "bnVtQgIQABI4Cg1wYWNrZWRfdmFsdWVzGAMgAygOMh0udW5pdHRlc3RfaXNz", + "dWVzLk5lZ2F0aXZlRW51bUICEAEiEQoPRGVwcmVjYXRlZENoaWxkIrkCChdE", + "ZXByZWNhdGVkRmllbGRzTWVzc2FnZRIaCg5QcmltaXRpdmVWYWx1ZRgBIAEo", + "BUICGAESGgoOUHJpbWl0aXZlQXJyYXkYAiADKAVCAhgBEjoKDE1lc3NhZ2VW", + "YWx1ZRgDIAEoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRC", + "AhgBEjoKDE1lc3NhZ2VBcnJheRgEIAMoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5E", + "ZXByZWNhdGVkQ2hpbGRCAhgBEjYKCUVudW1WYWx1ZRgFIAEoDjIfLnVuaXR0", + "ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAESNgoJRW51bUFycmF5GAYg", + "AygOMh8udW5pdHRlc3RfaXNzdWVzLkRlcHJlY2F0ZWRFbnVtQgIYASIZCglJ", + "dGVtRmllbGQSDAoEaXRlbRgBIAEoBSJECg1SZXNlcnZlZE5hbWVzEg0KBXR5", + "cGVzGAEgASgFEhIKCmRlc2NyaXB0b3IYAiABKAUaEAoOU29tZU5lc3RlZFR5", + "cGUioAEKFVRlc3RKc29uRmllbGRPcmRlcmluZxITCgtwbGFpbl9pbnQzMhgE", + "IAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghvMV9pbnQzMhgFIAEoBUgA", + "EhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9pbnQzMhgGIAEoBUgBEhMK", + "CW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8yIksKDFRlc3RKc29uTmFt", + "ZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9uGAIgASgJUgRkZXNjEhIK", + "BGd1aWQYAyABKAlSBGV4aWQifwoMT25lb2ZNZXJnaW5nEg4KBHRleHQYASAB", + "KAlIABI2CgZuZXN0ZWQYAiABKAsyJC51bml0dGVzdF9pc3N1ZXMuT25lb2ZN", + "ZXJnaW5nLk5lc3RlZEgAGh4KBk5lc3RlZBIJCgF4GAEgASgFEgkKAXkYAiAB", + "KAVCBwoFdmFsdWUiawoWTnVsbFZhbHVlT3V0c2lkZVN0cnVjdBIWCgxzdHJp", + "bmdfdmFsdWUYASABKAlIABIwCgpudWxsX3ZhbHVlGAIgASgOMhouZ29vZ2xl", + "LnByb3RvYnVmLk51bGxWYWx1ZUgAQgcKBXZhbHVlIkUKE051bGxWYWx1ZU5v", + "dEluT25lb2YSLgoKbnVsbF92YWx1ZRgCIAEoDjIaLmdvb2dsZS5wcm90b2J1", + "Zi5OdWxsVmFsdWUiYAoXTWl4ZWRSZWd1bGFyQW5kT3B0aW9uYWwSFQoNcmVn", + "dWxhcl9maWVsZBgBIAEoCRIbCg5vcHRpb25hbF9maWVsZBgCIAEoCUgAiAEB", + "QhEKD19vcHRpb25hbF9maWVsZCpVCgxOZWdhdGl2ZUVudW0SFgoSTkVHQVRJ", + "VkVfRU5VTV9aRVJPEAASFgoJRml2ZUJlbG93EPv//////////wESFQoITWlu", + "dXNPbmUQ////////////ASouCg5EZXByZWNhdGVkRW51bRITCg9ERVBSRUNB", + "VEVEX1pFUk8QABIHCgNvbmUQAUIdqgIaVW5pdFRlc3QuSXNzdWVzLlRlc3RQ", + "cm90b3NiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, - new pbr::FileDescriptor[] { }, + new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null, null)})}), new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null, null), @@ -63,7 +70,10 @@ public static partial class UnittestIssuesReflection { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null, null)}), new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)}) + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging), global::UnitTest.Issues.TestProtos.OneofMerging.Parser, new[]{ "Text", "Nested" }, new[]{ "Value" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested), global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested.Parser, new[]{ "X", "Y" }, null, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueOutsideStruct), global::UnitTest.Issues.TestProtos.NullValueOutsideStruct.Parser, new[]{ "StringValue", "NullValue" }, new[]{ "Value" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NullValueNotInOneof), global::UnitTest.Issues.TestProtos.NullValueNotInOneof.Parser, new[]{ "NullValue" }, null, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.MixedRegularAndOptional), global::UnitTest.Issues.TestProtos.MixedRegularAndOptional.Parser, new[]{ "RegularField", "OptionalField" }, new[]{ "OptionalField" }, null, null, null) })); } #endregion @@ -88,7 +98,11 @@ public enum DeprecatedEnum { /// Issue 307: when generating doubly-nested types, any references /// should be of the form A.Types.B.Types.C. /// - public sealed partial class Issue307 : pb::IMessage { + public sealed partial class Issue307 : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Issue307()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -153,11 +167,24 @@ public sealed partial class Issue307 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -177,6 +204,9 @@ public sealed partial class Issue307 : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -185,13 +215,32 @@ public sealed partial class Issue307 : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif #region Nested types /// Container for nested types declared in the Issue307 message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class NestedOnce : pb::IMessage { + public sealed partial class NestedOnce : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedOnce()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -256,10 +305,23 @@ public sealed partial class NestedOnce : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -280,6 +342,9 @@ public sealed partial class NestedOnce : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -288,13 +353,32 @@ public sealed partial class NestedOnce : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif #region Nested types /// Container for nested types declared in the NestedOnce message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class NestedTwice : pb::IMessage { + public sealed partial class NestedTwice : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedTwice()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -359,10 +443,23 @@ public sealed partial class NestedTwice : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -383,6 +480,9 @@ public sealed partial class NestedTwice : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -391,7 +491,22 @@ public sealed partial class NestedTwice : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } @@ -405,7 +520,11 @@ public sealed partial class NestedTwice : pb::IMessage { } - public sealed partial class NegativeEnumMessage : pb::IMessage { + public sealed partial class NegativeEnumMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NegativeEnumMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -510,6 +629,9 @@ public sealed partial class NegativeEnumMessage : pb::IMessage { + public sealed partial class DeprecatedChild : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DeprecatedChild()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -641,10 +815,23 @@ public sealed partial class DeprecatedChild : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -665,6 +852,9 @@ public sealed partial class DeprecatedChild : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -673,11 +863,30 @@ public sealed partial class DeprecatedChild : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class DeprecatedFieldsMessage : pb::IMessage { + public sealed partial class DeprecatedFieldsMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DeprecatedFieldsMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -829,6 +1038,9 @@ public sealed partial class DeprecatedFieldsMessage : pb::IMessage /// Issue 45: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=45 /// - public sealed partial class ItemField : pb::IMessage { + public sealed partial class ItemField : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ItemField()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1018,6 +1306,9 @@ public sealed partial class ItemField : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Item != 0) { output.WriteRawTag(8); output.WriteInt32(Item); @@ -1025,8 +1316,22 @@ public sealed partial class ItemField : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Item != 0) { + output.WriteRawTag(8); + output.WriteInt32(Item); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -1052,6 +1357,9 @@ public sealed partial class ItemField : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1064,11 +1372,34 @@ public sealed partial class ItemField : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Item = input.ReadInt32(); + break; + } + } + } } + #endif } - public sealed partial class ReservedNames : pb::IMessage { + public sealed partial class ReservedNames : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ReservedNames()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1161,6 +1492,9 @@ public sealed partial class ReservedNames : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Types_ != 0) { output.WriteRawTag(8); output.WriteInt32(Types_); @@ -1172,7 +1506,25 @@ public sealed partial class ReservedNames : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Types_ != 0) { + output.WriteRawTag(8); + output.WriteInt32(Types_); + } + if (Descriptor_ != 0) { + output.WriteRawTag(16); + output.WriteInt32(Descriptor_); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1205,6 +1557,9 @@ public sealed partial class ReservedNames : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1221,7 +1576,30 @@ public sealed partial class ReservedNames : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Types_ = input.ReadInt32(); + break; + } + case 16: { + Descriptor_ = input.ReadInt32(); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the ReservedNames message type. @@ -1230,7 +1608,11 @@ public static partial class Types { /// /// Force a nested type called Types /// - public sealed partial class SomeNestedType : pb::IMessage { + public sealed partial class SomeNestedType : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SomeNestedType()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1295,10 +1677,23 @@ public sealed partial class SomeNestedType : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1319,6 +1714,9 @@ public sealed partial class SomeNestedType : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1327,7 +1725,22 @@ public sealed partial class SomeNestedType : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } @@ -1348,7 +1761,11 @@ public sealed partial class SomeNestedType : pb::IMessage { /// Alternatively, consider just adding this to /// unittest_proto3.proto if multiple platforms want it. /// - public sealed partial class TestJsonFieldOrdering : pb::IMessage { + public sealed partial class TestJsonFieldOrdering : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestJsonFieldOrdering()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1553,6 +1970,9 @@ public enum O2OneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (PlainString.Length != 0) { output.WriteRawTag(10); output.WriteString(PlainString); @@ -1580,7 +2000,41 @@ public enum O2OneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (PlainString.Length != 0) { + output.WriteRawTag(10); + output.WriteString(PlainString); + } + if (o1Case_ == O1OneofCase.O1String) { + output.WriteRawTag(18); + output.WriteString(O1String); + } + if (o2Case_ == O2OneofCase.O2String) { + output.WriteRawTag(26); + output.WriteString(O2String); + } + if (PlainInt32 != 0) { + output.WriteRawTag(32); + output.WriteInt32(PlainInt32); + } + if (o1Case_ == O1OneofCase.O1Int32) { + output.WriteRawTag(40); + output.WriteInt32(O1Int32); + } + if (o2Case_ == O2OneofCase.O2Int32) { + output.WriteRawTag(48); + output.WriteInt32(O2Int32); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1643,6 +2097,9 @@ public enum O2OneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1675,24 +2132,67 @@ public enum O2OneofCase { } } } + #endif } - } - - public sealed partial class TestJsonName : pb::IMessage { - private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestJsonName()); - private pb::UnknownFieldSet _unknownFields; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pb::MessageParser Parser { get { return _parser; } } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public static pbr::MessageDescriptor Descriptor { - get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[7]; } - } - + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - pbr::MessageDescriptor pb::IMessage.Descriptor { - get { return Descriptor; } + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + PlainString = input.ReadString(); + break; + } + case 18: { + O1String = input.ReadString(); + break; + } + case 26: { + O2String = input.ReadString(); + break; + } + case 32: { + PlainInt32 = input.ReadInt32(); + break; + } + case 40: { + O1Int32 = input.ReadInt32(); + break; + } + case 48: { + O2Int32 = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + public sealed partial class TestJsonName : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestJsonName()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[7]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1789,6 +2289,9 @@ public sealed partial class TestJsonName : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -1804,7 +2307,29 @@ public sealed partial class TestJsonName : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (Description.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Description); + } + if (Guid.Length != 0) { + output.WriteRawTag(26); + output.WriteString(Guid); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1843,6 +2368,9 @@ public sealed partial class TestJsonName : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1863,7 +2391,34 @@ public sealed partial class TestJsonName : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + Description = input.ReadString(); + break; + } + case 26: { + Guid = input.ReadString(); + break; + } + } + } } + #endif } @@ -1872,7 +2427,11 @@ public sealed partial class TestJsonName : pb::IMessage { /// oneof case, which is itself a message type, the submessages should /// be merged. /// - public sealed partial class OneofMerging : pb::IMessage { + public sealed partial class OneofMerging : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneofMerging()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1993,6 +2552,9 @@ public enum ValueOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (valueCase_ == ValueOneofCase.Text) { output.WriteRawTag(10); output.WriteString(Text); @@ -2004,7 +2566,25 @@ public enum ValueOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (valueCase_ == ValueOneofCase.Text) { + output.WriteRawTag(10); + output.WriteString(Text); + } + if (valueCase_ == ValueOneofCase.Nested) { + output.WriteRawTag(18); + output.WriteMessage(Nested); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2043,6 +2623,9 @@ public enum ValueOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2064,13 +2647,45 @@ public enum ValueOneofCase { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Text = input.ReadString(); + break; + } + case 18: { + global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested subBuilder = new global::UnitTest.Issues.TestProtos.OneofMerging.Types.Nested(); + if (valueCase_ == ValueOneofCase.Nested) { + subBuilder.MergeFrom(Nested); + } + input.ReadMessage(subBuilder); + Nested = subBuilder; + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the OneofMerging message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class Nested : pb::IMessage { + public sealed partial class Nested : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Nested()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2163,6 +2778,9 @@ public sealed partial class Nested : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (X != 0) { output.WriteRawTag(8); output.WriteInt32(X); @@ -2174,7 +2792,25 @@ public sealed partial class Nested : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (X != 0) { + output.WriteRawTag(8); + output.WriteInt32(X); + } + if (Y != 0) { + output.WriteRawTag(16); + output.WriteInt32(Y); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2207,6 +2843,9 @@ public sealed partial class Nested : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2223,7 +2862,30 @@ public sealed partial class Nested : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + X = input.ReadInt32(); + break; + } + case 16: { + Y = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -2232,6 +2894,637 @@ public sealed partial class Nested : pb::IMessage { } + public sealed partial class NullValueOutsideStruct : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NullValueOutsideStruct()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[9]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NullValueOutsideStruct() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NullValueOutsideStruct(NullValueOutsideStruct other) : this() { + switch (other.ValueCase) { + case ValueOneofCase.StringValue: + StringValue = other.StringValue; + break; + case ValueOneofCase.NullValue: + NullValue = other.NullValue; + break; + } + + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NullValueOutsideStruct Clone() { + return new NullValueOutsideStruct(this); + } + + /// Field number for the "string_value" field. + public const int StringValueFieldNumber = 1; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string StringValue { + get { return valueCase_ == ValueOneofCase.StringValue ? (string) value_ : ""; } + set { + value_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + valueCase_ = ValueOneofCase.StringValue; + } + } + + /// Field number for the "null_value" field. + public const int NullValueFieldNumber = 2; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Google.Protobuf.WellKnownTypes.NullValue NullValue { + get { return valueCase_ == ValueOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) value_ : global::Google.Protobuf.WellKnownTypes.NullValue.NullValue; } + set { + value_ = value; + valueCase_ = ValueOneofCase.NullValue; + } + } + + private object value_; + /// Enum of possible cases for the "value" oneof. + public enum ValueOneofCase { + None = 0, + StringValue = 1, + NullValue = 2, + } + private ValueOneofCase valueCase_ = ValueOneofCase.None; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ValueOneofCase ValueCase { + get { return valueCase_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearValue() { + valueCase_ = ValueOneofCase.None; + value_ = null; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as NullValueOutsideStruct); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(NullValueOutsideStruct other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (StringValue != other.StringValue) return false; + if (NullValue != other.NullValue) return false; + if (ValueCase != other.ValueCase) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (valueCase_ == ValueOneofCase.StringValue) hash ^= StringValue.GetHashCode(); + if (valueCase_ == ValueOneofCase.NullValue) hash ^= NullValue.GetHashCode(); + hash ^= (int) valueCase_; + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (valueCase_ == ValueOneofCase.StringValue) { + output.WriteRawTag(10); + output.WriteString(StringValue); + } + if (valueCase_ == ValueOneofCase.NullValue) { + output.WriteRawTag(16); + output.WriteEnum((int) NullValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (valueCase_ == ValueOneofCase.StringValue) { + output.WriteRawTag(10); + output.WriteString(StringValue); + } + if (valueCase_ == ValueOneofCase.NullValue) { + output.WriteRawTag(16); + output.WriteEnum((int) NullValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (valueCase_ == ValueOneofCase.StringValue) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(StringValue); + } + if (valueCase_ == ValueOneofCase.NullValue) { + size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) NullValue); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(NullValueOutsideStruct other) { + if (other == null) { + return; + } + switch (other.ValueCase) { + case ValueOneofCase.StringValue: + StringValue = other.StringValue; + break; + case ValueOneofCase.NullValue: + NullValue = other.NullValue; + break; + } + + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + StringValue = input.ReadString(); + break; + } + case 16: { + value_ = input.ReadEnum(); + valueCase_ = ValueOneofCase.NullValue; + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + StringValue = input.ReadString(); + break; + } + case 16: { + value_ = input.ReadEnum(); + valueCase_ = ValueOneofCase.NullValue; + break; + } + } + } + } + #endif + + } + + public sealed partial class NullValueNotInOneof : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NullValueNotInOneof()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[10]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NullValueNotInOneof() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NullValueNotInOneof(NullValueNotInOneof other) : this() { + nullValue_ = other.nullValue_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NullValueNotInOneof Clone() { + return new NullValueNotInOneof(this); + } + + /// Field number for the "null_value" field. + public const int NullValueFieldNumber = 2; + private global::Google.Protobuf.WellKnownTypes.NullValue nullValue_ = global::Google.Protobuf.WellKnownTypes.NullValue.NullValue; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::Google.Protobuf.WellKnownTypes.NullValue NullValue { + get { return nullValue_; } + set { + nullValue_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as NullValueNotInOneof); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(NullValueNotInOneof other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (NullValue != other.NullValue) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) hash ^= NullValue.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + output.WriteRawTag(16); + output.WriteEnum((int) NullValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + output.WriteRawTag(16); + output.WriteEnum((int) NullValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) NullValue); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(NullValueNotInOneof other) { + if (other == null) { + return; + } + if (other.NullValue != global::Google.Protobuf.WellKnownTypes.NullValue.NullValue) { + NullValue = other.NullValue; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 16: { + NullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 16: { + NullValue = (global::Google.Protobuf.WellKnownTypes.NullValue) input.ReadEnum(); + break; + } + } + } + } + #endif + + } + + public sealed partial class MixedRegularAndOptional : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MixedRegularAndOptional()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[11]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public MixedRegularAndOptional() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public MixedRegularAndOptional(MixedRegularAndOptional other) : this() { + regularField_ = other.regularField_; + optionalField_ = other.optionalField_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public MixedRegularAndOptional Clone() { + return new MixedRegularAndOptional(this); + } + + /// Field number for the "regular_field" field. + public const int RegularFieldFieldNumber = 1; + private string regularField_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string RegularField { + get { return regularField_; } + set { + regularField_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + /// Field number for the "optional_field" field. + public const int OptionalFieldFieldNumber = 2; + private string optionalField_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string OptionalField { + get { return optionalField_ ?? ""; } + set { + optionalField_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "optional_field" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalField { + get { return optionalField_ != null; } + } + /// Clears the value of the "optional_field" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalField() { + optionalField_ = null; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as MixedRegularAndOptional); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(MixedRegularAndOptional other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (RegularField != other.RegularField) return false; + if (OptionalField != other.OptionalField) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (RegularField.Length != 0) hash ^= RegularField.GetHashCode(); + if (HasOptionalField) hash ^= OptionalField.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (RegularField.Length != 0) { + output.WriteRawTag(10); + output.WriteString(RegularField); + } + if (HasOptionalField) { + output.WriteRawTag(18); + output.WriteString(OptionalField); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (RegularField.Length != 0) { + output.WriteRawTag(10); + output.WriteString(RegularField); + } + if (HasOptionalField) { + output.WriteRawTag(18); + output.WriteString(OptionalField); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (RegularField.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(RegularField); + } + if (HasOptionalField) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalField); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(MixedRegularAndOptional other) { + if (other == null) { + return; + } + if (other.RegularField.Length != 0) { + RegularField = other.RegularField; + } + if (other.HasOptionalField) { + OptionalField = other.OptionalField; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + RegularField = input.ReadString(); + break; + } + case 18: { + OptionalField = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + RegularField = input.ReadString(); + break; + } + case 18: { + OptionalField = input.ReadString(); + break; + } + } + } + } + #endif + + } + #endregion } diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3.cs index 3f01e38bb973..b81eb573836d 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3.cs @@ -254,7 +254,11 @@ public enum CommentEnum { /// This proto includes every type of field in both singular and repeated /// forms. /// - public sealed partial class TestAllTypes : pb::IMessage { + public sealed partial class TestAllTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestAllTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1015,6 +1019,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (SingleInt32 != 0) { output.WriteRawTag(8); output.WriteInt32(SingleInt32); @@ -1144,8 +1151,144 @@ public enum OneofFieldOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (SingleInt32 != 0) { + output.WriteRawTag(8); + output.WriteInt32(SingleInt32); + } + if (SingleInt64 != 0L) { + output.WriteRawTag(16); + output.WriteInt64(SingleInt64); + } + if (SingleUint32 != 0) { + output.WriteRawTag(24); + output.WriteUInt32(SingleUint32); + } + if (SingleUint64 != 0UL) { + output.WriteRawTag(32); + output.WriteUInt64(SingleUint64); + } + if (SingleSint32 != 0) { + output.WriteRawTag(40); + output.WriteSInt32(SingleSint32); + } + if (SingleSint64 != 0L) { + output.WriteRawTag(48); + output.WriteSInt64(SingleSint64); + } + if (SingleFixed32 != 0) { + output.WriteRawTag(61); + output.WriteFixed32(SingleFixed32); + } + if (SingleFixed64 != 0UL) { + output.WriteRawTag(65); + output.WriteFixed64(SingleFixed64); + } + if (SingleSfixed32 != 0) { + output.WriteRawTag(77); + output.WriteSFixed32(SingleSfixed32); + } + if (SingleSfixed64 != 0L) { + output.WriteRawTag(81); + output.WriteSFixed64(SingleSfixed64); + } + if (SingleFloat != 0F) { + output.WriteRawTag(93); + output.WriteFloat(SingleFloat); + } + if (SingleDouble != 0D) { + output.WriteRawTag(97); + output.WriteDouble(SingleDouble); + } + if (SingleBool != false) { + output.WriteRawTag(104); + output.WriteBool(SingleBool); + } + if (SingleString.Length != 0) { + output.WriteRawTag(114); + output.WriteString(SingleString); + } + if (SingleBytes.Length != 0) { + output.WriteRawTag(122); + output.WriteBytes(SingleBytes); + } + if (singleNestedMessage_ != null) { + output.WriteRawTag(146, 1); + output.WriteMessage(SingleNestedMessage); + } + if (singleForeignMessage_ != null) { + output.WriteRawTag(154, 1); + output.WriteMessage(SingleForeignMessage); + } + if (singleImportMessage_ != null) { + output.WriteRawTag(162, 1); + output.WriteMessage(SingleImportMessage); + } + if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.Unspecified) { + output.WriteRawTag(168, 1); + output.WriteEnum((int) SingleNestedEnum); + } + if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.ForeignUnspecified) { + output.WriteRawTag(176, 1); + output.WriteEnum((int) SingleForeignEnum); + } + if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.Unspecified) { + output.WriteRawTag(184, 1); + output.WriteEnum((int) SingleImportEnum); + } + if (singlePublicImportMessage_ != null) { + output.WriteRawTag(210, 1); + output.WriteMessage(SinglePublicImportMessage); + } + repeatedInt32_.WriteTo(ref output, _repeated_repeatedInt32_codec); + repeatedInt64_.WriteTo(ref output, _repeated_repeatedInt64_codec); + repeatedUint32_.WriteTo(ref output, _repeated_repeatedUint32_codec); + repeatedUint64_.WriteTo(ref output, _repeated_repeatedUint64_codec); + repeatedSint32_.WriteTo(ref output, _repeated_repeatedSint32_codec); + repeatedSint64_.WriteTo(ref output, _repeated_repeatedSint64_codec); + repeatedFixed32_.WriteTo(ref output, _repeated_repeatedFixed32_codec); + repeatedFixed64_.WriteTo(ref output, _repeated_repeatedFixed64_codec); + repeatedSfixed32_.WriteTo(ref output, _repeated_repeatedSfixed32_codec); + repeatedSfixed64_.WriteTo(ref output, _repeated_repeatedSfixed64_codec); + repeatedFloat_.WriteTo(ref output, _repeated_repeatedFloat_codec); + repeatedDouble_.WriteTo(ref output, _repeated_repeatedDouble_codec); + repeatedBool_.WriteTo(ref output, _repeated_repeatedBool_codec); + repeatedString_.WriteTo(ref output, _repeated_repeatedString_codec); + repeatedBytes_.WriteTo(ref output, _repeated_repeatedBytes_codec); + repeatedNestedMessage_.WriteTo(ref output, _repeated_repeatedNestedMessage_codec); + repeatedForeignMessage_.WriteTo(ref output, _repeated_repeatedForeignMessage_codec); + repeatedImportMessage_.WriteTo(ref output, _repeated_repeatedImportMessage_codec); + repeatedNestedEnum_.WriteTo(ref output, _repeated_repeatedNestedEnum_codec); + repeatedForeignEnum_.WriteTo(ref output, _repeated_repeatedForeignEnum_codec); + repeatedImportEnum_.WriteTo(ref output, _repeated_repeatedImportEnum_codec); + repeatedPublicImportMessage_.WriteTo(ref output, _repeated_repeatedPublicImportMessage_codec); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofUint32) { + output.WriteRawTag(248, 6); + output.WriteUInt32(OneofUint32); + } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + output.WriteRawTag(130, 7); + output.WriteMessage(OneofNestedMessage); + } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) { + output.WriteRawTag(138, 7); + output.WriteString(OneofString); + } + if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) { + output.WriteRawTag(146, 7); + output.WriteBytes(OneofBytes); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -1383,6 +1526,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1616,8 +1762,248 @@ public enum OneofFieldOneofCase { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + SingleInt32 = input.ReadInt32(); + break; + } + case 16: { + SingleInt64 = input.ReadInt64(); + break; + } + case 24: { + SingleUint32 = input.ReadUInt32(); + break; + } + case 32: { + SingleUint64 = input.ReadUInt64(); + break; + } + case 40: { + SingleSint32 = input.ReadSInt32(); + break; + } + case 48: { + SingleSint64 = input.ReadSInt64(); + break; + } + case 61: { + SingleFixed32 = input.ReadFixed32(); + break; + } + case 65: { + SingleFixed64 = input.ReadFixed64(); + break; + } + case 77: { + SingleSfixed32 = input.ReadSFixed32(); + break; + } + case 81: { + SingleSfixed64 = input.ReadSFixed64(); + break; + } + case 93: { + SingleFloat = input.ReadFloat(); + break; + } + case 97: { + SingleDouble = input.ReadDouble(); + break; + } + case 104: { + SingleBool = input.ReadBool(); + break; + } + case 114: { + SingleString = input.ReadString(); + break; + } + case 122: { + SingleBytes = input.ReadBytes(); + break; + } + case 146: { + if (singleNestedMessage_ == null) { + SingleNestedMessage = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage(); + } + input.ReadMessage(SingleNestedMessage); + break; + } + case 154: { + if (singleForeignMessage_ == null) { + SingleForeignMessage = new global::Google.Protobuf.TestProtos.ForeignMessage(); + } + input.ReadMessage(SingleForeignMessage); + break; + } + case 162: { + if (singleImportMessage_ == null) { + SingleImportMessage = new global::Google.Protobuf.TestProtos.ImportMessage(); + } + input.ReadMessage(SingleImportMessage); + break; + } + case 168: { + SingleNestedEnum = (global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) input.ReadEnum(); + break; + } + case 176: { + SingleForeignEnum = (global::Google.Protobuf.TestProtos.ForeignEnum) input.ReadEnum(); + break; + } + case 184: { + SingleImportEnum = (global::Google.Protobuf.TestProtos.ImportEnum) input.ReadEnum(); + break; + } + case 210: { + if (singlePublicImportMessage_ == null) { + SinglePublicImportMessage = new global::Google.Protobuf.TestProtos.PublicImportMessage(); + } + input.ReadMessage(SinglePublicImportMessage); + break; + } + case 250: + case 248: { + repeatedInt32_.AddEntriesFrom(ref input, _repeated_repeatedInt32_codec); + break; + } + case 258: + case 256: { + repeatedInt64_.AddEntriesFrom(ref input, _repeated_repeatedInt64_codec); + break; + } + case 266: + case 264: { + repeatedUint32_.AddEntriesFrom(ref input, _repeated_repeatedUint32_codec); + break; + } + case 274: + case 272: { + repeatedUint64_.AddEntriesFrom(ref input, _repeated_repeatedUint64_codec); + break; + } + case 282: + case 280: { + repeatedSint32_.AddEntriesFrom(ref input, _repeated_repeatedSint32_codec); + break; + } + case 290: + case 288: { + repeatedSint64_.AddEntriesFrom(ref input, _repeated_repeatedSint64_codec); + break; + } + case 298: + case 301: { + repeatedFixed32_.AddEntriesFrom(ref input, _repeated_repeatedFixed32_codec); + break; + } + case 306: + case 305: { + repeatedFixed64_.AddEntriesFrom(ref input, _repeated_repeatedFixed64_codec); + break; + } + case 314: + case 317: { + repeatedSfixed32_.AddEntriesFrom(ref input, _repeated_repeatedSfixed32_codec); + break; + } + case 322: + case 321: { + repeatedSfixed64_.AddEntriesFrom(ref input, _repeated_repeatedSfixed64_codec); + break; + } + case 330: + case 333: { + repeatedFloat_.AddEntriesFrom(ref input, _repeated_repeatedFloat_codec); + break; + } + case 338: + case 337: { + repeatedDouble_.AddEntriesFrom(ref input, _repeated_repeatedDouble_codec); + break; + } + case 346: + case 344: { + repeatedBool_.AddEntriesFrom(ref input, _repeated_repeatedBool_codec); + break; + } + case 354: { + repeatedString_.AddEntriesFrom(ref input, _repeated_repeatedString_codec); + break; + } + case 362: { + repeatedBytes_.AddEntriesFrom(ref input, _repeated_repeatedBytes_codec); + break; + } + case 386: { + repeatedNestedMessage_.AddEntriesFrom(ref input, _repeated_repeatedNestedMessage_codec); + break; + } + case 394: { + repeatedForeignMessage_.AddEntriesFrom(ref input, _repeated_repeatedForeignMessage_codec); + break; + } + case 402: { + repeatedImportMessage_.AddEntriesFrom(ref input, _repeated_repeatedImportMessage_codec); + break; + } + case 410: + case 408: { + repeatedNestedEnum_.AddEntriesFrom(ref input, _repeated_repeatedNestedEnum_codec); + break; + } + case 418: + case 416: { + repeatedForeignEnum_.AddEntriesFrom(ref input, _repeated_repeatedForeignEnum_codec); + break; + } + case 426: + case 424: { + repeatedImportEnum_.AddEntriesFrom(ref input, _repeated_repeatedImportEnum_codec); + break; + } + case 434: { + repeatedPublicImportMessage_.AddEntriesFrom(ref input, _repeated_repeatedPublicImportMessage_codec); + break; + } + case 888: { + OneofUint32 = input.ReadUInt32(); + break; + } + case 898: { + global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage subBuilder = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage(); + if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) { + subBuilder.MergeFrom(OneofNestedMessage); + } + input.ReadMessage(subBuilder); + OneofNestedMessage = subBuilder; + break; + } + case 906: { + OneofString = input.ReadString(); + break; + } + case 914: { + OneofBytes = input.ReadBytes(); + break; + } + } + } + } + #endif + #region Nested types /// Container for nested types declared in the TestAllTypes message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1633,7 +2019,11 @@ public enum NestedEnum { [pbr::OriginalName("NEG")] Neg = -1, } - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1717,6 +2107,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Bb != 0) { output.WriteRawTag(8); output.WriteInt32(Bb); @@ -1724,7 +2117,21 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Bb != 0) { + output.WriteRawTag(8); + output.WriteInt32(Bb); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1751,6 +2158,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1763,8 +2173,27 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Bb = input.ReadInt32(); + break; + } + } + } + } + #endif + } } @@ -1775,7 +2204,11 @@ public sealed partial class NestedMessage : pb::IMessage { /// /// This proto includes a recursively nested message. /// - public sealed partial class NestedTestAllTypes : pb::IMessage { + public sealed partial class NestedTestAllTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedTestAllTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1881,6 +2314,9 @@ public sealed partial class NestedTestAllTypes : pb::IMessage { + public sealed partial class TestDeprecatedFields : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestDeprecatedFields()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2044,6 +2539,9 @@ public sealed partial class TestDeprecatedFields : pb::IMessage - public sealed partial class ForeignMessage : pb::IMessage { + public sealed partial class ForeignMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ForeignMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2177,6 +2715,9 @@ public sealed partial class ForeignMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (C != 0) { output.WriteRawTag(8); output.WriteInt32(C); @@ -2184,7 +2725,21 @@ public sealed partial class ForeignMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (C != 0) { + output.WriteRawTag(8); + output.WriteInt32(C); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2210,12 +2765,33 @@ public sealed partial class ForeignMessage : pb::IMessage { } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + C = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 8: { C = input.ReadInt32(); @@ -2224,10 +2800,15 @@ public sealed partial class ForeignMessage : pb::IMessage { } } } + #endif } - public sealed partial class TestReservedFields : pb::IMessage { + public sealed partial class TestReservedFields : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestReservedFields()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2292,10 +2873,23 @@ public sealed partial class TestReservedFields : pb::IMessage /// Test that we can use NestedMessage from outside TestAllTypes. /// - public sealed partial class TestForeignNested : pb::IMessage { + public sealed partial class TestForeignNested : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestForeignNested()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2410,6 +3026,9 @@ public sealed partial class TestForeignNested : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (foreignNested_ != null) { output.WriteRawTag(10); output.WriteMessage(ForeignNested); @@ -2417,7 +3036,21 @@ public sealed partial class TestForeignNested : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (foreignNested_ != null) { + output.WriteRawTag(10); + output.WriteMessage(ForeignNested); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2447,6 +3080,9 @@ public sealed partial class TestForeignNested : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2462,14 +3098,40 @@ public sealed partial class TestForeignNested : pb::IMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (foreignNested_ == null) { + ForeignNested = new global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage(); + } + input.ReadMessage(ForeignNested); + break; + } + } + } } + #endif } /// /// Test that really large tag numbers don't break anything. /// - public sealed partial class TestReallyLargeTagNumber : pb::IMessage { + public sealed partial class TestReallyLargeTagNumber : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestReallyLargeTagNumber()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2566,6 +3228,9 @@ public sealed partial class TestReallyLargeTagNumber : pb::IMessage { + public sealed partial class TestRecursiveMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRecursiveMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2723,6 +3436,9 @@ public sealed partial class TestRecursiveMessage : pb::IMessage /// Test that mutual recursion works. /// - public sealed partial class TestMutualRecursionA : pb::IMessage { + public sealed partial class TestMutualRecursionA : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMutualRecursionA()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2875,6 +3642,9 @@ public sealed partial class TestMutualRecursionA : pb::IMessage { + public sealed partial class TestMutualRecursionB : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestMutualRecursionB()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3024,6 +3837,9 @@ public sealed partial class TestMutualRecursionB : pb::IMessage { + public sealed partial class TestEnumAllowAlias : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestEnumAllowAlias()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3173,6 +4040,9 @@ public sealed partial class TestEnumAllowAlias : pb::IMessage - public sealed partial class TestCamelCaseFieldNames : pb::IMessage { + public sealed partial class TestCamelCaseFieldNames : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestCamelCaseFieldNames()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3400,6 +4310,9 @@ public sealed partial class TestCamelCaseFieldNames : pb::IMessage - public sealed partial class TestFieldOrderings : pb::IMessage { + public sealed partial class TestFieldOrderings : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestFieldOrderings()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3653,6 +4655,9 @@ public sealed partial class TestFieldOrderings : pb::IMessageContainer for nested types declared in the TestFieldOrderings message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class NestedMessage : pb::IMessage { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3851,6 +4923,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Bb != 0) { output.WriteRawTag(8); output.WriteInt32(Bb); @@ -3862,7 +4937,25 @@ public sealed partial class NestedMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Bb != 0) { + output.WriteRawTag(8); + output.WriteInt32(Bb); + } + if (Oo != 0L) { + output.WriteRawTag(16); + output.WriteInt64(Oo); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -3895,6 +4988,9 @@ public sealed partial class NestedMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -3911,8 +5007,31 @@ public sealed partial class NestedMessage : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Bb = input.ReadInt32(); + break; + } + case 16: { + Oo = input.ReadInt64(); + break; + } + } + } + } + #endif + } } @@ -3920,7 +5039,11 @@ public sealed partial class NestedMessage : pb::IMessage { } - public sealed partial class SparseEnumMessage : pb::IMessage { + public sealed partial class SparseEnumMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SparseEnumMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3999,6 +5122,9 @@ public sealed partial class SparseEnumMessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.Unspecified) { output.WriteRawTag(8); output.WriteEnum((int) SparseEnum); @@ -4006,7 +5132,21 @@ public sealed partial class SparseEnumMessage : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.Unspecified) { + output.WriteRawTag(8); + output.WriteEnum((int) SparseEnum); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4033,6 +5173,9 @@ public sealed partial class SparseEnumMessage : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4045,14 +5188,37 @@ public sealed partial class SparseEnumMessage : pb::IMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + SparseEnum = (global::Google.Protobuf.TestProtos.TestSparseEnum) input.ReadEnum(); + break; + } + } + } } + #endif } /// /// Test String and Bytes: string is for valid UTF-8 strings /// - public sealed partial class OneString : pb::IMessage { + public sealed partial class OneString : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneString()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4131,6 +5297,9 @@ public sealed partial class OneString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data.Length != 0) { output.WriteRawTag(10); output.WriteString(Data); @@ -4138,7 +5307,21 @@ public sealed partial class OneString : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4165,6 +5348,9 @@ public sealed partial class OneString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4177,11 +5363,34 @@ public sealed partial class OneString : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Data = input.ReadString(); + break; + } + } + } } + #endif } - public sealed partial class MoreString : pb::IMessage { + public sealed partial class MoreString : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MoreString()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4259,12 +5468,26 @@ public sealed partial class MoreString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else data_.WriteTo(output, _repeated_data_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + data_.WriteTo(ref output, _repeated_data_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -4286,6 +5509,9 @@ public sealed partial class MoreString : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4298,11 +5524,34 @@ public sealed partial class MoreString : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + data_.AddEntriesFrom(ref input, _repeated_data_codec); + break; + } + } + } } + #endif } - public sealed partial class OneBytes : pb::IMessage { + public sealed partial class OneBytes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneBytes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4381,6 +5630,9 @@ public sealed partial class OneBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data.Length != 0) { output.WriteRawTag(10); output.WriteBytes(Data); @@ -4388,7 +5640,21 @@ public sealed partial class OneBytes : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data.Length != 0) { + output.WriteRawTag(10); + output.WriteBytes(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4415,6 +5681,9 @@ public sealed partial class OneBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4427,11 +5696,34 @@ public sealed partial class OneBytes : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Data = input.ReadBytes(); + break; + } + } + } } + #endif } - public sealed partial class MoreBytes : pb::IMessage { + public sealed partial class MoreBytes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MoreBytes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4510,6 +5802,9 @@ public sealed partial class MoreBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data.Length != 0) { output.WriteRawTag(10); output.WriteBytes(Data); @@ -4517,7 +5812,21 @@ public sealed partial class MoreBytes : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data.Length != 0) { + output.WriteRawTag(10); + output.WriteBytes(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4544,6 +5853,9 @@ public sealed partial class MoreBytes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4556,14 +5868,37 @@ public sealed partial class MoreBytes : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Data = input.ReadBytes(); + break; + } + } + } } + #endif } /// /// Test int32, uint32, int64, uint64, and bool are all compatible /// - public sealed partial class Int32Message : pb::IMessage { + public sealed partial class Int32Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int32Message()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4642,6 +5977,9 @@ public sealed partial class Int32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data != 0) { output.WriteRawTag(8); output.WriteInt32(Data); @@ -4649,8 +5987,22 @@ public sealed partial class Int32Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data != 0) { + output.WriteRawTag(8); + output.WriteInt32(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -4676,6 +6028,9 @@ public sealed partial class Int32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4688,11 +6043,34 @@ public sealed partial class Int32Message : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadInt32(); + break; + } + } + } } + #endif } - public sealed partial class Uint32Message : pb::IMessage { + public sealed partial class Uint32Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Uint32Message()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4771,6 +6149,9 @@ public sealed partial class Uint32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data != 0) { output.WriteRawTag(8); output.WriteUInt32(Data); @@ -4778,7 +6159,21 @@ public sealed partial class Uint32Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data != 0) { + output.WriteRawTag(8); + output.WriteUInt32(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4805,6 +6200,9 @@ public sealed partial class Uint32Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -4817,11 +6215,34 @@ public sealed partial class Uint32Message : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadUInt32(); + break; + } + } + } + } + #endif + } - public sealed partial class Int64Message : pb::IMessage { + public sealed partial class Int64Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int64Message()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -4900,6 +6321,9 @@ public sealed partial class Int64Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data != 0L) { output.WriteRawTag(8); output.WriteInt64(Data); @@ -4907,7 +6331,21 @@ public sealed partial class Int64Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4929,16 +6367,37 @@ public sealed partial class Int64Message : pb::IMessage { if (other.Data != 0L) { Data = other.Data; } - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Data = input.ReadInt64(); + break; + } + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 8: { Data = input.ReadInt64(); @@ -4947,10 +6406,15 @@ public sealed partial class Int64Message : pb::IMessage { } } } + #endif } - public sealed partial class Uint64Message : pb::IMessage { + public sealed partial class Uint64Message : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Uint64Message()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5029,6 +6493,9 @@ public sealed partial class Uint64Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data != 0UL) { output.WriteRawTag(8); output.WriteUInt64(Data); @@ -5036,7 +6503,21 @@ public sealed partial class Uint64Message : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data != 0UL) { + output.WriteRawTag(8); + output.WriteUInt64(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5063,6 +6544,9 @@ public sealed partial class Uint64Message : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5075,11 +6559,34 @@ public sealed partial class Uint64Message : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadUInt64(); + break; + } + } + } } + #endif } - public sealed partial class BoolMessage : pb::IMessage { + public sealed partial class BoolMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BoolMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5158,6 +6665,9 @@ public sealed partial class BoolMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Data != false) { output.WriteRawTag(8); output.WriteBool(Data); @@ -5165,7 +6675,21 @@ public sealed partial class BoolMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Data != false) { + output.WriteRawTag(8); + output.WriteBool(Data); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5192,6 +6716,9 @@ public sealed partial class BoolMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5204,14 +6731,37 @@ public sealed partial class BoolMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Data = input.ReadBool(); + break; + } + } + } } + #endif } /// /// Test oneofs. /// - public sealed partial class TestOneof : pb::IMessage { + public sealed partial class TestOneof : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestOneof()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5349,6 +6899,9 @@ public enum FooOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (fooCase_ == FooOneofCase.FooInt) { output.WriteRawTag(8); output.WriteInt32(FooInt); @@ -5364,7 +6917,29 @@ public enum FooOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (fooCase_ == FooOneofCase.FooInt) { + output.WriteRawTag(8); + output.WriteInt32(FooInt); + } + if (fooCase_ == FooOneofCase.FooString) { + output.WriteRawTag(18); + output.WriteString(FooString); + } + if (fooCase_ == FooOneofCase.FooMessage) { + output.WriteRawTag(26); + output.WriteMessage(FooMessage); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5409,6 +6984,9 @@ public enum FooOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5434,11 +7012,47 @@ public enum FooOneofCase { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + FooInt = input.ReadInt32(); + break; + } + case 18: { + FooString = input.ReadString(); + break; + } + case 26: { + global::Google.Protobuf.TestProtos.TestAllTypes subBuilder = new global::Google.Protobuf.TestProtos.TestAllTypes(); + if (fooCase_ == FooOneofCase.FooMessage) { + subBuilder.MergeFrom(FooMessage); + } + input.ReadMessage(subBuilder); + FooMessage = subBuilder; + break; + } + } + } } + #endif } - public sealed partial class TestPackedTypes : pb::IMessage { + public sealed partial class TestPackedTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestPackedTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -5685,6 +7299,9 @@ public sealed partial class TestPackedTypes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else packedInt32_.WriteTo(output, _repeated_packedInt32_codec); packedInt64_.WriteTo(output, _repeated_packedInt64_codec); packedUint32_.WriteTo(output, _repeated_packedUint32_codec); @@ -5702,7 +7319,31 @@ public sealed partial class TestPackedTypes : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + packedInt32_.WriteTo(ref output, _repeated_packedInt32_codec); + packedInt64_.WriteTo(ref output, _repeated_packedInt64_codec); + packedUint32_.WriteTo(ref output, _repeated_packedUint32_codec); + packedUint64_.WriteTo(ref output, _repeated_packedUint64_codec); + packedSint32_.WriteTo(ref output, _repeated_packedSint32_codec); + packedSint64_.WriteTo(ref output, _repeated_packedSint64_codec); + packedFixed32_.WriteTo(ref output, _repeated_packedFixed32_codec); + packedFixed64_.WriteTo(ref output, _repeated_packedFixed64_codec); + packedSfixed32_.WriteTo(ref output, _repeated_packedSfixed32_codec); + packedSfixed64_.WriteTo(ref output, _repeated_packedSfixed64_codec); + packedFloat_.WriteTo(ref output, _repeated_packedFloat_codec); + packedDouble_.WriteTo(ref output, _repeated_packedDouble_codec); + packedBool_.WriteTo(ref output, _repeated_packedBool_codec); + packedEnum_.WriteTo(ref output, _repeated_packedEnum_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5751,6 +7392,9 @@ public sealed partial class TestPackedTypes : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5829,7 +7473,92 @@ public sealed partial class TestPackedTypes : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 722: + case 720: { + packedInt32_.AddEntriesFrom(ref input, _repeated_packedInt32_codec); + break; + } + case 730: + case 728: { + packedInt64_.AddEntriesFrom(ref input, _repeated_packedInt64_codec); + break; + } + case 738: + case 736: { + packedUint32_.AddEntriesFrom(ref input, _repeated_packedUint32_codec); + break; + } + case 746: + case 744: { + packedUint64_.AddEntriesFrom(ref input, _repeated_packedUint64_codec); + break; + } + case 754: + case 752: { + packedSint32_.AddEntriesFrom(ref input, _repeated_packedSint32_codec); + break; + } + case 762: + case 760: { + packedSint64_.AddEntriesFrom(ref input, _repeated_packedSint64_codec); + break; + } + case 770: + case 773: { + packedFixed32_.AddEntriesFrom(ref input, _repeated_packedFixed32_codec); + break; + } + case 778: + case 777: { + packedFixed64_.AddEntriesFrom(ref input, _repeated_packedFixed64_codec); + break; + } + case 786: + case 789: { + packedSfixed32_.AddEntriesFrom(ref input, _repeated_packedSfixed32_codec); + break; + } + case 794: + case 793: { + packedSfixed64_.AddEntriesFrom(ref input, _repeated_packedSfixed64_codec); + break; + } + case 802: + case 805: { + packedFloat_.AddEntriesFrom(ref input, _repeated_packedFloat_codec); + break; + } + case 810: + case 809: { + packedDouble_.AddEntriesFrom(ref input, _repeated_packedDouble_codec); + break; + } + case 818: + case 816: { + packedBool_.AddEntriesFrom(ref input, _repeated_packedBool_codec); + break; + } + case 826: + case 824: { + packedEnum_.AddEntriesFrom(ref input, _repeated_packedEnum_codec); + break; + } + } + } } + #endif } @@ -5837,7 +7566,11 @@ public sealed partial class TestPackedTypes : pb::IMessage { /// A message with the same fields as TestPackedTypes, but without packing. Used /// to test packed <-> unpacked wire compatibility. /// - public sealed partial class TestUnpackedTypes : pb::IMessage { + public sealed partial class TestUnpackedTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestUnpackedTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6084,6 +7817,9 @@ public sealed partial class TestUnpackedTypes : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else unpackedInt32_.WriteTo(output, _repeated_unpackedInt32_codec); unpackedInt64_.WriteTo(output, _repeated_unpackedInt64_codec); unpackedUint32_.WriteTo(output, _repeated_unpackedUint32_codec); @@ -6101,7 +7837,31 @@ public sealed partial class TestUnpackedTypes : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + unpackedInt32_.WriteTo(ref output, _repeated_unpackedInt32_codec); + unpackedInt64_.WriteTo(ref output, _repeated_unpackedInt64_codec); + unpackedUint32_.WriteTo(ref output, _repeated_unpackedUint32_codec); + unpackedUint64_.WriteTo(ref output, _repeated_unpackedUint64_codec); + unpackedSint32_.WriteTo(ref output, _repeated_unpackedSint32_codec); + unpackedSint64_.WriteTo(ref output, _repeated_unpackedSint64_codec); + unpackedFixed32_.WriteTo(ref output, _repeated_unpackedFixed32_codec); + unpackedFixed64_.WriteTo(ref output, _repeated_unpackedFixed64_codec); + unpackedSfixed32_.WriteTo(ref output, _repeated_unpackedSfixed32_codec); + unpackedSfixed64_.WriteTo(ref output, _repeated_unpackedSfixed64_codec); + unpackedFloat_.WriteTo(ref output, _repeated_unpackedFloat_codec); + unpackedDouble_.WriteTo(ref output, _repeated_unpackedDouble_codec); + unpackedBool_.WriteTo(ref output, _repeated_unpackedBool_codec); + unpackedEnum_.WriteTo(ref output, _repeated_unpackedEnum_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -6131,108 +7891,200 @@ public sealed partial class TestUnpackedTypes : pb::IMessage if (other == null) { return; } - unpackedInt32_.Add(other.unpackedInt32_); - unpackedInt64_.Add(other.unpackedInt64_); - unpackedUint32_.Add(other.unpackedUint32_); - unpackedUint64_.Add(other.unpackedUint64_); - unpackedSint32_.Add(other.unpackedSint32_); - unpackedSint64_.Add(other.unpackedSint64_); - unpackedFixed32_.Add(other.unpackedFixed32_); - unpackedFixed64_.Add(other.unpackedFixed64_); - unpackedSfixed32_.Add(other.unpackedSfixed32_); - unpackedSfixed64_.Add(other.unpackedSfixed64_); - unpackedFloat_.Add(other.unpackedFloat_); - unpackedDouble_.Add(other.unpackedDouble_); - unpackedBool_.Add(other.unpackedBool_); - unpackedEnum_.Add(other.unpackedEnum_); - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + unpackedInt32_.Add(other.unpackedInt32_); + unpackedInt64_.Add(other.unpackedInt64_); + unpackedUint32_.Add(other.unpackedUint32_); + unpackedUint64_.Add(other.unpackedUint64_); + unpackedSint32_.Add(other.unpackedSint32_); + unpackedSint64_.Add(other.unpackedSint64_); + unpackedFixed32_.Add(other.unpackedFixed32_); + unpackedFixed64_.Add(other.unpackedFixed64_); + unpackedSfixed32_.Add(other.unpackedSfixed32_); + unpackedSfixed64_.Add(other.unpackedSfixed64_); + unpackedFloat_.Add(other.unpackedFloat_); + unpackedDouble_.Add(other.unpackedDouble_); + unpackedBool_.Add(other.unpackedBool_); + unpackedEnum_.Add(other.unpackedEnum_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 722: + case 720: { + unpackedInt32_.AddEntriesFrom(input, _repeated_unpackedInt32_codec); + break; + } + case 730: + case 728: { + unpackedInt64_.AddEntriesFrom(input, _repeated_unpackedInt64_codec); + break; + } + case 738: + case 736: { + unpackedUint32_.AddEntriesFrom(input, _repeated_unpackedUint32_codec); + break; + } + case 746: + case 744: { + unpackedUint64_.AddEntriesFrom(input, _repeated_unpackedUint64_codec); + break; + } + case 754: + case 752: { + unpackedSint32_.AddEntriesFrom(input, _repeated_unpackedSint32_codec); + break; + } + case 762: + case 760: { + unpackedSint64_.AddEntriesFrom(input, _repeated_unpackedSint64_codec); + break; + } + case 770: + case 773: { + unpackedFixed32_.AddEntriesFrom(input, _repeated_unpackedFixed32_codec); + break; + } + case 778: + case 777: { + unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec); + break; + } + case 786: + case 789: { + unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec); + break; + } + case 794: + case 793: { + unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec); + break; + } + case 802: + case 805: { + unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec); + break; + } + case 810: + case 809: { + unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec); + break; + } + case 818: + case 816: { + unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec); + break; + } + case 826: + case 824: { + unpackedEnum_.AddEntriesFrom(input, _repeated_unpackedEnum_codec); + break; + } + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); break; case 722: case 720: { - unpackedInt32_.AddEntriesFrom(input, _repeated_unpackedInt32_codec); + unpackedInt32_.AddEntriesFrom(ref input, _repeated_unpackedInt32_codec); break; } case 730: case 728: { - unpackedInt64_.AddEntriesFrom(input, _repeated_unpackedInt64_codec); + unpackedInt64_.AddEntriesFrom(ref input, _repeated_unpackedInt64_codec); break; } case 738: case 736: { - unpackedUint32_.AddEntriesFrom(input, _repeated_unpackedUint32_codec); + unpackedUint32_.AddEntriesFrom(ref input, _repeated_unpackedUint32_codec); break; } case 746: case 744: { - unpackedUint64_.AddEntriesFrom(input, _repeated_unpackedUint64_codec); + unpackedUint64_.AddEntriesFrom(ref input, _repeated_unpackedUint64_codec); break; } case 754: case 752: { - unpackedSint32_.AddEntriesFrom(input, _repeated_unpackedSint32_codec); + unpackedSint32_.AddEntriesFrom(ref input, _repeated_unpackedSint32_codec); break; } case 762: case 760: { - unpackedSint64_.AddEntriesFrom(input, _repeated_unpackedSint64_codec); + unpackedSint64_.AddEntriesFrom(ref input, _repeated_unpackedSint64_codec); break; } case 770: case 773: { - unpackedFixed32_.AddEntriesFrom(input, _repeated_unpackedFixed32_codec); + unpackedFixed32_.AddEntriesFrom(ref input, _repeated_unpackedFixed32_codec); break; } case 778: case 777: { - unpackedFixed64_.AddEntriesFrom(input, _repeated_unpackedFixed64_codec); + unpackedFixed64_.AddEntriesFrom(ref input, _repeated_unpackedFixed64_codec); break; } case 786: case 789: { - unpackedSfixed32_.AddEntriesFrom(input, _repeated_unpackedSfixed32_codec); + unpackedSfixed32_.AddEntriesFrom(ref input, _repeated_unpackedSfixed32_codec); break; } case 794: case 793: { - unpackedSfixed64_.AddEntriesFrom(input, _repeated_unpackedSfixed64_codec); + unpackedSfixed64_.AddEntriesFrom(ref input, _repeated_unpackedSfixed64_codec); break; } case 802: case 805: { - unpackedFloat_.AddEntriesFrom(input, _repeated_unpackedFloat_codec); + unpackedFloat_.AddEntriesFrom(ref input, _repeated_unpackedFloat_codec); break; } case 810: case 809: { - unpackedDouble_.AddEntriesFrom(input, _repeated_unpackedDouble_codec); + unpackedDouble_.AddEntriesFrom(ref input, _repeated_unpackedDouble_codec); break; } case 818: case 816: { - unpackedBool_.AddEntriesFrom(input, _repeated_unpackedBool_codec); + unpackedBool_.AddEntriesFrom(ref input, _repeated_unpackedBool_codec); break; } case 826: case 824: { - unpackedEnum_.AddEntriesFrom(input, _repeated_unpackedEnum_codec); + unpackedEnum_.AddEntriesFrom(ref input, _repeated_unpackedEnum_codec); break; } } } } + #endif } - public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage { + public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestRepeatedScalarDifferentTagSizes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6389,6 +8241,9 @@ public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage { + public sealed partial class TestCommentInjectionMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestCommentInjectionMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6555,6 +8478,9 @@ public sealed partial class TestCommentInjectionMessage : pb::IMessage /// Test that RPC services work. /// - public sealed partial class FooRequest : pb::IMessage { + public sealed partial class FooRequest : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooRequest()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6673,10 +8639,23 @@ public sealed partial class FooRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -6697,6 +8676,9 @@ public sealed partial class FooRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -6705,11 +8687,30 @@ public sealed partial class FooRequest : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class FooResponse : pb::IMessage { + public sealed partial class FooResponse : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooResponse()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6774,11 +8775,24 @@ public sealed partial class FooResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -6798,6 +8812,9 @@ public sealed partial class FooResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -6806,11 +8823,30 @@ public sealed partial class FooResponse : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class FooClientMessage : pb::IMessage { + public sealed partial class FooClientMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooClientMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6875,10 +8911,23 @@ public sealed partial class FooClientMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -6899,6 +8948,9 @@ public sealed partial class FooClientMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -6907,11 +8959,30 @@ public sealed partial class FooClientMessage : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class FooServerMessage : pb::IMessage { + public sealed partial class FooServerMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooServerMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -6976,10 +9047,23 @@ public sealed partial class FooServerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7000,6 +9084,9 @@ public sealed partial class FooServerMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7008,11 +9095,30 @@ public sealed partial class FooServerMessage : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class BarRequest : pb::IMessage { + public sealed partial class BarRequest : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BarRequest()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -7077,10 +9183,23 @@ public sealed partial class BarRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7101,6 +9220,9 @@ public sealed partial class BarRequest : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7109,11 +9231,30 @@ public sealed partial class BarRequest : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class BarResponse : pb::IMessage { + public sealed partial class BarResponse : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BarResponse()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -7178,10 +9319,23 @@ public sealed partial class BarResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7202,6 +9356,9 @@ public sealed partial class BarResponse : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7210,11 +9367,30 @@ public sealed partial class BarResponse : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } - public sealed partial class TestEmptyMessage : pb::IMessage { + public sealed partial class TestEmptyMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestEmptyMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -7279,10 +9455,23 @@ public sealed partial class TestEmptyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7303,6 +9492,9 @@ public sealed partial class TestEmptyMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7311,14 +9503,33 @@ public sealed partial class TestEmptyMessage : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } /// /// This is a leading comment /// - public sealed partial class CommentMessage : pb::IMessage { + public sealed partial class CommentMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new CommentMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -7400,6 +9611,9 @@ public sealed partial class CommentMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Text.Length != 0) { output.WriteRawTag(10); output.WriteString(Text); @@ -7407,7 +9621,21 @@ public sealed partial class CommentMessage : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Text.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Text); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7434,6 +9662,9 @@ public sealed partial class CommentMessage : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7446,7 +9677,26 @@ public sealed partial class CommentMessage : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Text = input.ReadString(); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the CommentMessage message type. @@ -7465,7 +9715,11 @@ public enum NestedCommentEnum { /// /// Leading nested message comment /// - public sealed partial class NestedCommentMessage : pb::IMessage { + public sealed partial class NestedCommentMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedCommentMessage()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -7547,6 +9801,9 @@ public sealed partial class NestedCommentMessage : pb::IMessage +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/unittest_proto3_optional.proto +// +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace ProtobufUnittest { + + /// Holder for reflection information generated from google/protobuf/unittest_proto3_optional.proto + public static partial class UnittestProto3OptionalReflection { + + #region Descriptor + /// File descriptor for google/protobuf/unittest_proto3_optional.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static UnittestProto3OptionalReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "Ci5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnBy", + "b3RvEhFwcm90b2J1Zl91bml0dGVzdCKxCgoSVGVzdFByb3RvM09wdGlvbmFs", + "EhsKDm9wdGlvbmFsX2ludDMyGAEgASgFSACIAQESGwoOb3B0aW9uYWxfaW50", + "NjQYAiABKANIAYgBARIcCg9vcHRpb25hbF91aW50MzIYAyABKA1IAogBARIc", + "Cg9vcHRpb25hbF91aW50NjQYBCABKARIA4gBARIcCg9vcHRpb25hbF9zaW50", + "MzIYBSABKBFIBIgBARIcCg9vcHRpb25hbF9zaW50NjQYBiABKBJIBYgBARId", + "ChBvcHRpb25hbF9maXhlZDMyGAcgASgHSAaIAQESHQoQb3B0aW9uYWxfZml4", + "ZWQ2NBgIIAEoBkgHiAEBEh4KEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPSAiI", + "AQESHgoRb3B0aW9uYWxfc2ZpeGVkNjQYCiABKBBICYgBARIbCg5vcHRpb25h", + "bF9mbG9hdBgLIAEoAkgKiAEBEhwKD29wdGlvbmFsX2RvdWJsZRgMIAEoAUgL", + "iAEBEhoKDW9wdGlvbmFsX2Jvb2wYDSABKAhIDIgBARIcCg9vcHRpb25hbF9z", + "dHJpbmcYDiABKAlIDYgBARIbCg5vcHRpb25hbF9ieXRlcxgPIAEoDEgOiAEB", + "Eh4KDW9wdGlvbmFsX2NvcmQYECABKAlCAggBSA+IAQESWQoXb3B0aW9uYWxf", + "bmVzdGVkX21lc3NhZ2UYEiABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0", + "UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUgQiAEBElkKE2xhenlfbmVz", + "dGVkX21lc3NhZ2UYEyABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJv", + "dG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUICKAFIEYgBARJTChRvcHRpb25h", + "bF9uZXN0ZWRfZW51bRgVIAEoDjIwLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQ", + "cm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtSBKIAQESFgoOc2luZ3VsYXJfaW50", + "MzIYFiABKAUSFgoOc2luZ3VsYXJfaW50NjQYFyABKAMaJwoNTmVzdGVkTWVz", + "c2FnZRIPCgJiYhgBIAEoBUgAiAEBQgUKA19iYiJKCgpOZXN0ZWRFbnVtEg8K", + "C1VOU1BFQ0lGSUVEEAASBwoDRk9PEAESBwoDQkFSEAISBwoDQkFaEAMSEAoD", + "TkVHEP///////////wFCEQoPX29wdGlvbmFsX2ludDMyQhEKD19vcHRpb25h", + "bF9pbnQ2NEISChBfb3B0aW9uYWxfdWludDMyQhIKEF9vcHRpb25hbF91aW50", + "NjRCEgoQX29wdGlvbmFsX3NpbnQzMkISChBfb3B0aW9uYWxfc2ludDY0QhMK", + "EV9vcHRpb25hbF9maXhlZDMyQhMKEV9vcHRpb25hbF9maXhlZDY0QhQKEl9v", + "cHRpb25hbF9zZml4ZWQzMkIUChJfb3B0aW9uYWxfc2ZpeGVkNjRCEQoPX29w", + "dGlvbmFsX2Zsb2F0QhIKEF9vcHRpb25hbF9kb3VibGVCEAoOX29wdGlvbmFs", + "X2Jvb2xCEgoQX29wdGlvbmFsX3N0cmluZ0IRCg9fb3B0aW9uYWxfYnl0ZXNC", + "EAoOX29wdGlvbmFsX2NvcmRCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdl", + "QhYKFF9sYXp5X25lc3RlZF9tZXNzYWdlQhcKFV9vcHRpb25hbF9uZXN0ZWRf", + "ZW51bSKJAgoZVGVzdFByb3RvM09wdGlvbmFsTWVzc2FnZRJSCg5uZXN0ZWRf", + "bWVzc2FnZRgBIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90bzNP", + "cHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZRJgChdvcHRpb25hbF9uZXN0", + "ZWRfbWVzc2FnZRgCIAEoCzI6LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQcm90", + "bzNPcHRpb25hbE1lc3NhZ2UuTmVzdGVkTWVzc2FnZUgAiAEBGhoKDU5lc3Rl", + "ZE1lc3NhZ2USCQoBcxgBIAEoCUIaChhfb3B0aW9uYWxfbmVzdGVkX21lc3Nh", + "Z2VCJQohY29tLmdvb2dsZS5wcm90b2J1Zi50ZXN0aW5nLnByb3RvUAFiBnBy", + "b3RvMw==")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { }, + new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional), global::ProtobufUnittest.TestProto3Optional.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum", "SingularInt32", "SingularInt64" }, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage), global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage.Parser, new[]{ "Bb" }, new[]{ "Bb" }, null, null, null)}), + new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Parser, new[]{ "NestedMessage", "OptionalNestedMessage" }, new[]{ "OptionalNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage), global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage.Parser, new[]{ "S" }, null, null, null, null)}) + })); + } + #endregion + + } + #region Messages + public sealed partial class TestProto3Optional : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestProto3Optional()); + private pb::UnknownFieldSet _unknownFields; + private int _hasBits0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufUnittest.UnittestProto3OptionalReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public TestProto3Optional() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public TestProto3Optional(TestProto3Optional other) : this() { + _hasBits0 = other._hasBits0; + optionalInt32_ = other.optionalInt32_; + optionalInt64_ = other.optionalInt64_; + optionalUint32_ = other.optionalUint32_; + optionalUint64_ = other.optionalUint64_; + optionalSint32_ = other.optionalSint32_; + optionalSint64_ = other.optionalSint64_; + optionalFixed32_ = other.optionalFixed32_; + optionalFixed64_ = other.optionalFixed64_; + optionalSfixed32_ = other.optionalSfixed32_; + optionalSfixed64_ = other.optionalSfixed64_; + optionalFloat_ = other.optionalFloat_; + optionalDouble_ = other.optionalDouble_; + optionalBool_ = other.optionalBool_; + optionalString_ = other.optionalString_; + optionalBytes_ = other.optionalBytes_; + optionalCord_ = other.optionalCord_; + optionalNestedMessage_ = other.optionalNestedMessage_ != null ? other.optionalNestedMessage_.Clone() : null; + lazyNestedMessage_ = other.lazyNestedMessage_ != null ? other.lazyNestedMessage_.Clone() : null; + optionalNestedEnum_ = other.optionalNestedEnum_; + singularInt32_ = other.singularInt32_; + singularInt64_ = other.singularInt64_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public TestProto3Optional Clone() { + return new TestProto3Optional(this); + } + + /// Field number for the "optional_int32" field. + public const int OptionalInt32FieldNumber = 1; + private int optionalInt32_; + /// + /// Singular + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int OptionalInt32 { + get { if ((_hasBits0 & 1) != 0) { return optionalInt32_; } else { return 0; } } + set { + _hasBits0 |= 1; + optionalInt32_ = value; + } + } + /// Gets whether the "optional_int32" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalInt32 { + get { return (_hasBits0 & 1) != 0; } + } + /// Clears the value of the "optional_int32" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalInt32() { + _hasBits0 &= ~1; + } + + /// Field number for the "optional_int64" field. + public const int OptionalInt64FieldNumber = 2; + private long optionalInt64_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long OptionalInt64 { + get { if ((_hasBits0 & 2) != 0) { return optionalInt64_; } else { return 0L; } } + set { + _hasBits0 |= 2; + optionalInt64_ = value; + } + } + /// Gets whether the "optional_int64" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalInt64 { + get { return (_hasBits0 & 2) != 0; } + } + /// Clears the value of the "optional_int64" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalInt64() { + _hasBits0 &= ~2; + } + + /// Field number for the "optional_uint32" field. + public const int OptionalUint32FieldNumber = 3; + private uint optionalUint32_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public uint OptionalUint32 { + get { if ((_hasBits0 & 4) != 0) { return optionalUint32_; } else { return 0; } } + set { + _hasBits0 |= 4; + optionalUint32_ = value; + } + } + /// Gets whether the "optional_uint32" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalUint32 { + get { return (_hasBits0 & 4) != 0; } + } + /// Clears the value of the "optional_uint32" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalUint32() { + _hasBits0 &= ~4; + } + + /// Field number for the "optional_uint64" field. + public const int OptionalUint64FieldNumber = 4; + private ulong optionalUint64_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ulong OptionalUint64 { + get { if ((_hasBits0 & 8) != 0) { return optionalUint64_; } else { return 0UL; } } + set { + _hasBits0 |= 8; + optionalUint64_ = value; + } + } + /// Gets whether the "optional_uint64" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalUint64 { + get { return (_hasBits0 & 8) != 0; } + } + /// Clears the value of the "optional_uint64" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalUint64() { + _hasBits0 &= ~8; + } + + /// Field number for the "optional_sint32" field. + public const int OptionalSint32FieldNumber = 5; + private int optionalSint32_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int OptionalSint32 { + get { if ((_hasBits0 & 16) != 0) { return optionalSint32_; } else { return 0; } } + set { + _hasBits0 |= 16; + optionalSint32_ = value; + } + } + /// Gets whether the "optional_sint32" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalSint32 { + get { return (_hasBits0 & 16) != 0; } + } + /// Clears the value of the "optional_sint32" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalSint32() { + _hasBits0 &= ~16; + } + + /// Field number for the "optional_sint64" field. + public const int OptionalSint64FieldNumber = 6; + private long optionalSint64_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long OptionalSint64 { + get { if ((_hasBits0 & 32) != 0) { return optionalSint64_; } else { return 0L; } } + set { + _hasBits0 |= 32; + optionalSint64_ = value; + } + } + /// Gets whether the "optional_sint64" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalSint64 { + get { return (_hasBits0 & 32) != 0; } + } + /// Clears the value of the "optional_sint64" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalSint64() { + _hasBits0 &= ~32; + } + + /// Field number for the "optional_fixed32" field. + public const int OptionalFixed32FieldNumber = 7; + private uint optionalFixed32_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public uint OptionalFixed32 { + get { if ((_hasBits0 & 64) != 0) { return optionalFixed32_; } else { return 0; } } + set { + _hasBits0 |= 64; + optionalFixed32_ = value; + } + } + /// Gets whether the "optional_fixed32" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalFixed32 { + get { return (_hasBits0 & 64) != 0; } + } + /// Clears the value of the "optional_fixed32" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalFixed32() { + _hasBits0 &= ~64; + } + + /// Field number for the "optional_fixed64" field. + public const int OptionalFixed64FieldNumber = 8; + private ulong optionalFixed64_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public ulong OptionalFixed64 { + get { if ((_hasBits0 & 128) != 0) { return optionalFixed64_; } else { return 0UL; } } + set { + _hasBits0 |= 128; + optionalFixed64_ = value; + } + } + /// Gets whether the "optional_fixed64" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalFixed64 { + get { return (_hasBits0 & 128) != 0; } + } + /// Clears the value of the "optional_fixed64" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalFixed64() { + _hasBits0 &= ~128; + } + + /// Field number for the "optional_sfixed32" field. + public const int OptionalSfixed32FieldNumber = 9; + private int optionalSfixed32_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int OptionalSfixed32 { + get { if ((_hasBits0 & 256) != 0) { return optionalSfixed32_; } else { return 0; } } + set { + _hasBits0 |= 256; + optionalSfixed32_ = value; + } + } + /// Gets whether the "optional_sfixed32" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalSfixed32 { + get { return (_hasBits0 & 256) != 0; } + } + /// Clears the value of the "optional_sfixed32" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalSfixed32() { + _hasBits0 &= ~256; + } + + /// Field number for the "optional_sfixed64" field. + public const int OptionalSfixed64FieldNumber = 10; + private long optionalSfixed64_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long OptionalSfixed64 { + get { if ((_hasBits0 & 512) != 0) { return optionalSfixed64_; } else { return 0L; } } + set { + _hasBits0 |= 512; + optionalSfixed64_ = value; + } + } + /// Gets whether the "optional_sfixed64" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalSfixed64 { + get { return (_hasBits0 & 512) != 0; } + } + /// Clears the value of the "optional_sfixed64" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalSfixed64() { + _hasBits0 &= ~512; + } + + /// Field number for the "optional_float" field. + public const int OptionalFloatFieldNumber = 11; + private float optionalFloat_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public float OptionalFloat { + get { if ((_hasBits0 & 1024) != 0) { return optionalFloat_; } else { return 0F; } } + set { + _hasBits0 |= 1024; + optionalFloat_ = value; + } + } + /// Gets whether the "optional_float" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalFloat { + get { return (_hasBits0 & 1024) != 0; } + } + /// Clears the value of the "optional_float" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalFloat() { + _hasBits0 &= ~1024; + } + + /// Field number for the "optional_double" field. + public const int OptionalDoubleFieldNumber = 12; + private double optionalDouble_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public double OptionalDouble { + get { if ((_hasBits0 & 2048) != 0) { return optionalDouble_; } else { return 0D; } } + set { + _hasBits0 |= 2048; + optionalDouble_ = value; + } + } + /// Gets whether the "optional_double" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalDouble { + get { return (_hasBits0 & 2048) != 0; } + } + /// Clears the value of the "optional_double" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalDouble() { + _hasBits0 &= ~2048; + } + + /// Field number for the "optional_bool" field. + public const int OptionalBoolFieldNumber = 13; + private bool optionalBool_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool OptionalBool { + get { if ((_hasBits0 & 4096) != 0) { return optionalBool_; } else { return false; } } + set { + _hasBits0 |= 4096; + optionalBool_ = value; + } + } + /// Gets whether the "optional_bool" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalBool { + get { return (_hasBits0 & 4096) != 0; } + } + /// Clears the value of the "optional_bool" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalBool() { + _hasBits0 &= ~4096; + } + + /// Field number for the "optional_string" field. + public const int OptionalStringFieldNumber = 14; + private string optionalString_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string OptionalString { + get { return optionalString_ ?? ""; } + set { + optionalString_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "optional_string" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalString { + get { return optionalString_ != null; } + } + /// Clears the value of the "optional_string" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalString() { + optionalString_ = null; + } + + /// Field number for the "optional_bytes" field. + public const int OptionalBytesFieldNumber = 15; + private pb::ByteString optionalBytes_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public pb::ByteString OptionalBytes { + get { return optionalBytes_ ?? pb::ByteString.Empty; } + set { + optionalBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "optional_bytes" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalBytes { + get { return optionalBytes_ != null; } + } + /// Clears the value of the "optional_bytes" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalBytes() { + optionalBytes_ = null; + } + + /// Field number for the "optional_cord" field. + public const int OptionalCordFieldNumber = 16; + private string optionalCord_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string OptionalCord { + get { return optionalCord_ ?? ""; } + set { + optionalCord_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "optional_cord" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalCord { + get { return optionalCord_ != null; } + } + /// Clears the value of the "optional_cord" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalCord() { + optionalCord_ = null; + } + + /// Field number for the "optional_nested_message" field. + public const int OptionalNestedMessageFieldNumber = 18; + private global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage optionalNestedMessage_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage OptionalNestedMessage { + get { return optionalNestedMessage_; } + set { + optionalNestedMessage_ = value; + } + } + + /// Field number for the "lazy_nested_message" field. + public const int LazyNestedMessageFieldNumber = 19; + private global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage lazyNestedMessage_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage LazyNestedMessage { + get { return lazyNestedMessage_; } + set { + lazyNestedMessage_ = value; + } + } + + /// Field number for the "optional_nested_enum" field. + public const int OptionalNestedEnumFieldNumber = 21; + private global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum optionalNestedEnum_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum OptionalNestedEnum { + get { if ((_hasBits0 & 8192) != 0) { return optionalNestedEnum_; } else { return global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum.Unspecified; } } + set { + _hasBits0 |= 8192; + optionalNestedEnum_ = value; + } + } + /// Gets whether the "optional_nested_enum" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasOptionalNestedEnum { + get { return (_hasBits0 & 8192) != 0; } + } + /// Clears the value of the "optional_nested_enum" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearOptionalNestedEnum() { + _hasBits0 &= ~8192; + } + + /// Field number for the "singular_int32" field. + public const int SingularInt32FieldNumber = 22; + private int singularInt32_; + /// + /// Add some non-optional fields to verify we can mix them. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int SingularInt32 { + get { return singularInt32_; } + set { + singularInt32_ = value; + } + } + + /// Field number for the "singular_int64" field. + public const int SingularInt64FieldNumber = 23; + private long singularInt64_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public long SingularInt64 { + get { return singularInt64_; } + set { + singularInt64_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as TestProto3Optional); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(TestProto3Optional other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (OptionalInt32 != other.OptionalInt32) return false; + if (OptionalInt64 != other.OptionalInt64) return false; + if (OptionalUint32 != other.OptionalUint32) return false; + if (OptionalUint64 != other.OptionalUint64) return false; + if (OptionalSint32 != other.OptionalSint32) return false; + if (OptionalSint64 != other.OptionalSint64) return false; + if (OptionalFixed32 != other.OptionalFixed32) return false; + if (OptionalFixed64 != other.OptionalFixed64) return false; + if (OptionalSfixed32 != other.OptionalSfixed32) return false; + if (OptionalSfixed64 != other.OptionalSfixed64) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(OptionalFloat, other.OptionalFloat)) return false; + if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(OptionalDouble, other.OptionalDouble)) return false; + if (OptionalBool != other.OptionalBool) return false; + if (OptionalString != other.OptionalString) return false; + if (OptionalBytes != other.OptionalBytes) return false; + if (OptionalCord != other.OptionalCord) return false; + if (!object.Equals(OptionalNestedMessage, other.OptionalNestedMessage)) return false; + if (!object.Equals(LazyNestedMessage, other.LazyNestedMessage)) return false; + if (OptionalNestedEnum != other.OptionalNestedEnum) return false; + if (SingularInt32 != other.SingularInt32) return false; + if (SingularInt64 != other.SingularInt64) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (HasOptionalInt32) hash ^= OptionalInt32.GetHashCode(); + if (HasOptionalInt64) hash ^= OptionalInt64.GetHashCode(); + if (HasOptionalUint32) hash ^= OptionalUint32.GetHashCode(); + if (HasOptionalUint64) hash ^= OptionalUint64.GetHashCode(); + if (HasOptionalSint32) hash ^= OptionalSint32.GetHashCode(); + if (HasOptionalSint64) hash ^= OptionalSint64.GetHashCode(); + if (HasOptionalFixed32) hash ^= OptionalFixed32.GetHashCode(); + if (HasOptionalFixed64) hash ^= OptionalFixed64.GetHashCode(); + if (HasOptionalSfixed32) hash ^= OptionalSfixed32.GetHashCode(); + if (HasOptionalSfixed64) hash ^= OptionalSfixed64.GetHashCode(); + if (HasOptionalFloat) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(OptionalFloat); + if (HasOptionalDouble) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OptionalDouble); + if (HasOptionalBool) hash ^= OptionalBool.GetHashCode(); + if (HasOptionalString) hash ^= OptionalString.GetHashCode(); + if (HasOptionalBytes) hash ^= OptionalBytes.GetHashCode(); + if (HasOptionalCord) hash ^= OptionalCord.GetHashCode(); + if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode(); + if (lazyNestedMessage_ != null) hash ^= LazyNestedMessage.GetHashCode(); + if (HasOptionalNestedEnum) hash ^= OptionalNestedEnum.GetHashCode(); + if (SingularInt32 != 0) hash ^= SingularInt32.GetHashCode(); + if (SingularInt64 != 0L) hash ^= SingularInt64.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasOptionalInt32) { + output.WriteRawTag(8); + output.WriteInt32(OptionalInt32); + } + if (HasOptionalInt64) { + output.WriteRawTag(16); + output.WriteInt64(OptionalInt64); + } + if (HasOptionalUint32) { + output.WriteRawTag(24); + output.WriteUInt32(OptionalUint32); + } + if (HasOptionalUint64) { + output.WriteRawTag(32); + output.WriteUInt64(OptionalUint64); + } + if (HasOptionalSint32) { + output.WriteRawTag(40); + output.WriteSInt32(OptionalSint32); + } + if (HasOptionalSint64) { + output.WriteRawTag(48); + output.WriteSInt64(OptionalSint64); + } + if (HasOptionalFixed32) { + output.WriteRawTag(61); + output.WriteFixed32(OptionalFixed32); + } + if (HasOptionalFixed64) { + output.WriteRawTag(65); + output.WriteFixed64(OptionalFixed64); + } + if (HasOptionalSfixed32) { + output.WriteRawTag(77); + output.WriteSFixed32(OptionalSfixed32); + } + if (HasOptionalSfixed64) { + output.WriteRawTag(81); + output.WriteSFixed64(OptionalSfixed64); + } + if (HasOptionalFloat) { + output.WriteRawTag(93); + output.WriteFloat(OptionalFloat); + } + if (HasOptionalDouble) { + output.WriteRawTag(97); + output.WriteDouble(OptionalDouble); + } + if (HasOptionalBool) { + output.WriteRawTag(104); + output.WriteBool(OptionalBool); + } + if (HasOptionalString) { + output.WriteRawTag(114); + output.WriteString(OptionalString); + } + if (HasOptionalBytes) { + output.WriteRawTag(122); + output.WriteBytes(OptionalBytes); + } + if (HasOptionalCord) { + output.WriteRawTag(130, 1); + output.WriteString(OptionalCord); + } + if (optionalNestedMessage_ != null) { + output.WriteRawTag(146, 1); + output.WriteMessage(OptionalNestedMessage); + } + if (lazyNestedMessage_ != null) { + output.WriteRawTag(154, 1); + output.WriteMessage(LazyNestedMessage); + } + if (HasOptionalNestedEnum) { + output.WriteRawTag(168, 1); + output.WriteEnum((int) OptionalNestedEnum); + } + if (SingularInt32 != 0) { + output.WriteRawTag(176, 1); + output.WriteInt32(SingularInt32); + } + if (SingularInt64 != 0L) { + output.WriteRawTag(184, 1); + output.WriteInt64(SingularInt64); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasOptionalInt32) { + output.WriteRawTag(8); + output.WriteInt32(OptionalInt32); + } + if (HasOptionalInt64) { + output.WriteRawTag(16); + output.WriteInt64(OptionalInt64); + } + if (HasOptionalUint32) { + output.WriteRawTag(24); + output.WriteUInt32(OptionalUint32); + } + if (HasOptionalUint64) { + output.WriteRawTag(32); + output.WriteUInt64(OptionalUint64); + } + if (HasOptionalSint32) { + output.WriteRawTag(40); + output.WriteSInt32(OptionalSint32); + } + if (HasOptionalSint64) { + output.WriteRawTag(48); + output.WriteSInt64(OptionalSint64); + } + if (HasOptionalFixed32) { + output.WriteRawTag(61); + output.WriteFixed32(OptionalFixed32); + } + if (HasOptionalFixed64) { + output.WriteRawTag(65); + output.WriteFixed64(OptionalFixed64); + } + if (HasOptionalSfixed32) { + output.WriteRawTag(77); + output.WriteSFixed32(OptionalSfixed32); + } + if (HasOptionalSfixed64) { + output.WriteRawTag(81); + output.WriteSFixed64(OptionalSfixed64); + } + if (HasOptionalFloat) { + output.WriteRawTag(93); + output.WriteFloat(OptionalFloat); + } + if (HasOptionalDouble) { + output.WriteRawTag(97); + output.WriteDouble(OptionalDouble); + } + if (HasOptionalBool) { + output.WriteRawTag(104); + output.WriteBool(OptionalBool); + } + if (HasOptionalString) { + output.WriteRawTag(114); + output.WriteString(OptionalString); + } + if (HasOptionalBytes) { + output.WriteRawTag(122); + output.WriteBytes(OptionalBytes); + } + if (HasOptionalCord) { + output.WriteRawTag(130, 1); + output.WriteString(OptionalCord); + } + if (optionalNestedMessage_ != null) { + output.WriteRawTag(146, 1); + output.WriteMessage(OptionalNestedMessage); + } + if (lazyNestedMessage_ != null) { + output.WriteRawTag(154, 1); + output.WriteMessage(LazyNestedMessage); + } + if (HasOptionalNestedEnum) { + output.WriteRawTag(168, 1); + output.WriteEnum((int) OptionalNestedEnum); + } + if (SingularInt32 != 0) { + output.WriteRawTag(176, 1); + output.WriteInt32(SingularInt32); + } + if (SingularInt64 != 0L) { + output.WriteRawTag(184, 1); + output.WriteInt64(SingularInt64); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (HasOptionalInt32) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32); + } + if (HasOptionalInt64) { + size += 1 + pb::CodedOutputStream.ComputeInt64Size(OptionalInt64); + } + if (HasOptionalUint32) { + size += 1 + pb::CodedOutputStream.ComputeUInt32Size(OptionalUint32); + } + if (HasOptionalUint64) { + size += 1 + pb::CodedOutputStream.ComputeUInt64Size(OptionalUint64); + } + if (HasOptionalSint32) { + size += 1 + pb::CodedOutputStream.ComputeSInt32Size(OptionalSint32); + } + if (HasOptionalSint64) { + size += 1 + pb::CodedOutputStream.ComputeSInt64Size(OptionalSint64); + } + if (HasOptionalFixed32) { + size += 1 + 4; + } + if (HasOptionalFixed64) { + size += 1 + 8; + } + if (HasOptionalSfixed32) { + size += 1 + 4; + } + if (HasOptionalSfixed64) { + size += 1 + 8; + } + if (HasOptionalFloat) { + size += 1 + 4; + } + if (HasOptionalDouble) { + size += 1 + 8; + } + if (HasOptionalBool) { + size += 1 + 1; + } + if (HasOptionalString) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalString); + } + if (HasOptionalBytes) { + size += 1 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes); + } + if (HasOptionalCord) { + size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord); + } + if (optionalNestedMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage); + } + if (lazyNestedMessage_ != null) { + size += 2 + pb::CodedOutputStream.ComputeMessageSize(LazyNestedMessage); + } + if (HasOptionalNestedEnum) { + size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum); + } + if (SingularInt32 != 0) { + size += 2 + pb::CodedOutputStream.ComputeInt32Size(SingularInt32); + } + if (SingularInt64 != 0L) { + size += 2 + pb::CodedOutputStream.ComputeInt64Size(SingularInt64); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(TestProto3Optional other) { + if (other == null) { + return; + } + if (other.HasOptionalInt32) { + OptionalInt32 = other.OptionalInt32; + } + if (other.HasOptionalInt64) { + OptionalInt64 = other.OptionalInt64; + } + if (other.HasOptionalUint32) { + OptionalUint32 = other.OptionalUint32; + } + if (other.HasOptionalUint64) { + OptionalUint64 = other.OptionalUint64; + } + if (other.HasOptionalSint32) { + OptionalSint32 = other.OptionalSint32; + } + if (other.HasOptionalSint64) { + OptionalSint64 = other.OptionalSint64; + } + if (other.HasOptionalFixed32) { + OptionalFixed32 = other.OptionalFixed32; + } + if (other.HasOptionalFixed64) { + OptionalFixed64 = other.OptionalFixed64; + } + if (other.HasOptionalSfixed32) { + OptionalSfixed32 = other.OptionalSfixed32; + } + if (other.HasOptionalSfixed64) { + OptionalSfixed64 = other.OptionalSfixed64; + } + if (other.HasOptionalFloat) { + OptionalFloat = other.OptionalFloat; + } + if (other.HasOptionalDouble) { + OptionalDouble = other.OptionalDouble; + } + if (other.HasOptionalBool) { + OptionalBool = other.OptionalBool; + } + if (other.HasOptionalString) { + OptionalString = other.OptionalString; + } + if (other.HasOptionalBytes) { + OptionalBytes = other.OptionalBytes; + } + if (other.HasOptionalCord) { + OptionalCord = other.OptionalCord; + } + if (other.optionalNestedMessage_ != null) { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage(); + } + OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage); + } + if (other.lazyNestedMessage_ != null) { + if (lazyNestedMessage_ == null) { + LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage(); + } + LazyNestedMessage.MergeFrom(other.LazyNestedMessage); + } + if (other.HasOptionalNestedEnum) { + OptionalNestedEnum = other.OptionalNestedEnum; + } + if (other.SingularInt32 != 0) { + SingularInt32 = other.SingularInt32; + } + if (other.SingularInt64 != 0L) { + SingularInt64 = other.SingularInt64; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + OptionalInt32 = input.ReadInt32(); + break; + } + case 16: { + OptionalInt64 = input.ReadInt64(); + break; + } + case 24: { + OptionalUint32 = input.ReadUInt32(); + break; + } + case 32: { + OptionalUint64 = input.ReadUInt64(); + break; + } + case 40: { + OptionalSint32 = input.ReadSInt32(); + break; + } + case 48: { + OptionalSint64 = input.ReadSInt64(); + break; + } + case 61: { + OptionalFixed32 = input.ReadFixed32(); + break; + } + case 65: { + OptionalFixed64 = input.ReadFixed64(); + break; + } + case 77: { + OptionalSfixed32 = input.ReadSFixed32(); + break; + } + case 81: { + OptionalSfixed64 = input.ReadSFixed64(); + break; + } + case 93: { + OptionalFloat = input.ReadFloat(); + break; + } + case 97: { + OptionalDouble = input.ReadDouble(); + break; + } + case 104: { + OptionalBool = input.ReadBool(); + break; + } + case 114: { + OptionalString = input.ReadString(); + break; + } + case 122: { + OptionalBytes = input.ReadBytes(); + break; + } + case 130: { + OptionalCord = input.ReadString(); + break; + } + case 146: { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage(); + } + input.ReadMessage(OptionalNestedMessage); + break; + } + case 154: { + if (lazyNestedMessage_ == null) { + LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage(); + } + input.ReadMessage(LazyNestedMessage); + break; + } + case 168: { + OptionalNestedEnum = (global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) input.ReadEnum(); + break; + } + case 176: { + SingularInt32 = input.ReadInt32(); + break; + } + case 184: { + SingularInt64 = input.ReadInt64(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + OptionalInt32 = input.ReadInt32(); + break; + } + case 16: { + OptionalInt64 = input.ReadInt64(); + break; + } + case 24: { + OptionalUint32 = input.ReadUInt32(); + break; + } + case 32: { + OptionalUint64 = input.ReadUInt64(); + break; + } + case 40: { + OptionalSint32 = input.ReadSInt32(); + break; + } + case 48: { + OptionalSint64 = input.ReadSInt64(); + break; + } + case 61: { + OptionalFixed32 = input.ReadFixed32(); + break; + } + case 65: { + OptionalFixed64 = input.ReadFixed64(); + break; + } + case 77: { + OptionalSfixed32 = input.ReadSFixed32(); + break; + } + case 81: { + OptionalSfixed64 = input.ReadSFixed64(); + break; + } + case 93: { + OptionalFloat = input.ReadFloat(); + break; + } + case 97: { + OptionalDouble = input.ReadDouble(); + break; + } + case 104: { + OptionalBool = input.ReadBool(); + break; + } + case 114: { + OptionalString = input.ReadString(); + break; + } + case 122: { + OptionalBytes = input.ReadBytes(); + break; + } + case 130: { + OptionalCord = input.ReadString(); + break; + } + case 146: { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage(); + } + input.ReadMessage(OptionalNestedMessage); + break; + } + case 154: { + if (lazyNestedMessage_ == null) { + LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage(); + } + input.ReadMessage(LazyNestedMessage); + break; + } + case 168: { + OptionalNestedEnum = (global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) input.ReadEnum(); + break; + } + case 176: { + SingularInt32 = input.ReadInt32(); + break; + } + case 184: { + SingularInt64 = input.ReadInt64(); + break; + } + } + } + } + #endif + + #region Nested types + /// Container for nested types declared in the TestProto3Optional message type. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static partial class Types { + public enum NestedEnum { + [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0, + [pbr::OriginalName("FOO")] Foo = 1, + [pbr::OriginalName("BAR")] Bar = 2, + [pbr::OriginalName("BAZ")] Baz = 3, + /// + /// Intentionally negative. + /// + [pbr::OriginalName("NEG")] Neg = -1, + } + + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); + private pb::UnknownFieldSet _unknownFields; + private int _hasBits0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufUnittest.TestProto3Optional.Descriptor.NestedTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NestedMessage() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NestedMessage(NestedMessage other) : this() { + _hasBits0 = other._hasBits0; + bb_ = other.bb_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NestedMessage Clone() { + return new NestedMessage(this); + } + + /// Field number for the "bb" field. + public const int BbFieldNumber = 1; + private int bb_; + /// + /// The field name "b" fails to compile in proto1 because it conflicts with + /// a local variable named "b" in one of the generated methods. Doh. + /// This file needs to compile in proto1 to test backwards-compatibility. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int Bb { + get { if ((_hasBits0 & 1) != 0) { return bb_; } else { return 0; } } + set { + _hasBits0 |= 1; + bb_ = value; + } + } + /// Gets whether the "bb" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasBb { + get { return (_hasBits0 & 1) != 0; } + } + /// Clears the value of the "bb" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearBb() { + _hasBits0 &= ~1; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as NestedMessage); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(NestedMessage other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Bb != other.Bb) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (HasBb) hash ^= Bb.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasBb) { + output.WriteRawTag(8); + output.WriteInt32(Bb); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasBb) { + output.WriteRawTag(8); + output.WriteInt32(Bb); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (HasBb) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Bb); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(NestedMessage other) { + if (other == null) { + return; + } + if (other.HasBb) { + Bb = other.Bb; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Bb = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Bb = input.ReadInt32(); + break; + } + } + } + } + #endif + + } + + } + #endregion + + } + + public sealed partial class TestProto3OptionalMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestProto3OptionalMessage()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufUnittest.UnittestProto3OptionalReflection.Descriptor.MessageTypes[1]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public TestProto3OptionalMessage() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public TestProto3OptionalMessage(TestProto3OptionalMessage other) : this() { + nestedMessage_ = other.nestedMessage_ != null ? other.nestedMessage_.Clone() : null; + optionalNestedMessage_ = other.optionalNestedMessage_ != null ? other.optionalNestedMessage_.Clone() : null; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public TestProto3OptionalMessage Clone() { + return new TestProto3OptionalMessage(this); + } + + /// Field number for the "nested_message" field. + public const int NestedMessageFieldNumber = 1; + private global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage nestedMessage_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage NestedMessage { + get { return nestedMessage_; } + set { + nestedMessage_ = value; + } + } + + /// Field number for the "optional_nested_message" field. + public const int OptionalNestedMessageFieldNumber = 2; + private global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage optionalNestedMessage_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage OptionalNestedMessage { + get { return optionalNestedMessage_; } + set { + optionalNestedMessage_ = value; + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as TestProto3OptionalMessage); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(TestProto3OptionalMessage other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (!object.Equals(NestedMessage, other.NestedMessage)) return false; + if (!object.Equals(OptionalNestedMessage, other.OptionalNestedMessage)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (nestedMessage_ != null) hash ^= NestedMessage.GetHashCode(); + if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (nestedMessage_ != null) { + output.WriteRawTag(10); + output.WriteMessage(NestedMessage); + } + if (optionalNestedMessage_ != null) { + output.WriteRawTag(18); + output.WriteMessage(OptionalNestedMessage); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (nestedMessage_ != null) { + output.WriteRawTag(10); + output.WriteMessage(NestedMessage); + } + if (optionalNestedMessage_ != null) { + output.WriteRawTag(18); + output.WriteMessage(OptionalNestedMessage); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (nestedMessage_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(NestedMessage); + } + if (optionalNestedMessage_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(TestProto3OptionalMessage other) { + if (other == null) { + return; + } + if (other.nestedMessage_ != null) { + if (nestedMessage_ == null) { + NestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage(); + } + NestedMessage.MergeFrom(other.NestedMessage); + } + if (other.optionalNestedMessage_ != null) { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage(); + } + OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage); + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + if (nestedMessage_ == null) { + NestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage(); + } + input.ReadMessage(NestedMessage); + break; + } + case 18: { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage(); + } + input.ReadMessage(OptionalNestedMessage); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (nestedMessage_ == null) { + NestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage(); + } + input.ReadMessage(NestedMessage); + break; + } + case 18: { + if (optionalNestedMessage_ == null) { + OptionalNestedMessage = new global::ProtobufUnittest.TestProto3OptionalMessage.Types.NestedMessage(); + } + input.ReadMessage(OptionalNestedMessage); + break; + } + } + } + } + #endif + + #region Nested types + /// Container for nested types declared in the TestProto3OptionalMessage message type. + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static partial class Types { + public sealed partial class NestedMessage : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NestedMessage()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::ProtobufUnittest.TestProto3OptionalMessage.Descriptor.NestedTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NestedMessage() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NestedMessage(NestedMessage other) : this() { + s_ = other.s_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public NestedMessage Clone() { + return new NestedMessage(this); + } + + /// Field number for the "s" field. + public const int SFieldNumber = 1; + private string s_ = ""; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public string S { + get { return s_; } + set { + s_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as NestedMessage); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(NestedMessage other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (S != other.S) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (S.Length != 0) hash ^= S.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (S.Length != 0) { + output.WriteRawTag(10); + output.WriteString(S); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (S.Length != 0) { + output.WriteRawTag(10); + output.WriteString(S); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (S.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(S); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(NestedMessage other) { + if (other == null) { + return; + } + if (other.S.Length != 0) { + S = other.S; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + S = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + S = input.ReadString(); + break; + } + } + } + } + #endif + + } + + } + #endregion + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestSelfreferentialOptions.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestSelfreferentialOptions.cs new file mode 100644 index 000000000000..7ed1580ab2c5 --- /dev/null +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestSelfreferentialOptions.cs @@ -0,0 +1,357 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: unittest_selfreferential_options.proto +// +#pragma warning disable 1591, 0612, 3021 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace UnitTest.Issues.TestProtos.SelfreferentialOptions { + + /// Holder for reflection information generated from unittest_selfreferential_options.proto + public static partial class UnittestSelfreferentialOptionsReflection { + + #region Descriptor + /// File descriptor for unittest_selfreferential_options.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static UnittestSelfreferentialOptionsReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CiZ1bml0dGVzdF9zZWxmcmVmZXJlbnRpYWxfb3B0aW9ucy5wcm90bxIpcHJv", + "dG9idWZfdW5pdHRlc3Rfc2VsZnJlZmVyZW50aWFsX29wdGlvbnMaIGdvb2ds", + "ZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvIkwKCkZvb09wdGlvbnMSHgoH", + "aW50X29wdBgBIAEoBUINyj4KCAHAPgLKPgIIAxITCgNmb28YAiABKAVCBso+", + "AxDSCSoJCOgHEICAgIACOjkKC2Jhcl9vcHRpb25zEh0uZ29vZ2xlLnByb3Rv", + "YnVmLkZpZWxkT3B0aW9ucxjoByABKAVCBMA+0gk6agoLZm9vX29wdGlvbnMS", + "HS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOkHIAEoCzI1LnByb3Rv", + "YnVmX3VuaXR0ZXN0X3NlbGZyZWZlcmVudGlhbF9vcHRpb25zLkZvb09wdGlv", + "bnM6SwoLZm9vX2ludF9vcHQSNS5wcm90b2J1Zl91bml0dGVzdF9zZWxmcmVm", + "ZXJlbnRpYWxfb3B0aW9ucy5Gb29PcHRpb25zGOgHIAEoBTqCAQoLZm9vX2Zv", + "b19vcHQSNS5wcm90b2J1Zl91bml0dGVzdF9zZWxmcmVmZXJlbnRpYWxfb3B0", + "aW9ucy5Gb29PcHRpb25zGOkHIAEoCzI1LnByb3RvYnVmX3VuaXR0ZXN0X3Nl", + "bGZyZWZlcmVudGlhbF9vcHRpb25zLkZvb09wdGlvbnNCNKoCMVVuaXRUZXN0", + "Lklzc3Vlcy5UZXN0UHJvdG9zLlNlbGZyZWZlcmVudGlhbE9wdGlvbnM=")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor, }, + new pbr::GeneratedClrTypeInfo(null, new pb::Extension[] { UnittestSelfreferentialOptionsExtensions.BarOptions, UnittestSelfreferentialOptionsExtensions.FooOptions, UnittestSelfreferentialOptionsExtensions.FooIntOpt, UnittestSelfreferentialOptionsExtensions.FooFooOpt }, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.SelfreferentialOptions.FooOptions), global::UnitTest.Issues.TestProtos.SelfreferentialOptions.FooOptions.Parser, new[]{ "IntOpt", "Foo" }, null, null, null, null) + })); + } + #endregion + + } + /// Holder for extension identifiers generated from the top level of unittest_selfreferential_options.proto + public static partial class UnittestSelfreferentialOptionsExtensions { + /// + /// Custom field option used on the definition of that field option. + /// + public static readonly pb::Extension BarOptions = + new pb::Extension(1000, pb::FieldCodec.ForInt32(8000, 0)); + public static readonly pb::Extension FooOptions = + new pb::Extension(1001, pb::FieldCodec.ForMessage(8010, global::UnitTest.Issues.TestProtos.SelfreferentialOptions.FooOptions.Parser)); + public static readonly pb::Extension FooIntOpt = + new pb::Extension(1000, pb::FieldCodec.ForInt32(8000, 0)); + public static readonly pb::Extension FooFooOpt = + new pb::Extension(1001, pb::FieldCodec.ForMessage(8010, global::UnitTest.Issues.TestProtos.SelfreferentialOptions.FooOptions.Parser)); + } + + #region Messages + public sealed partial class FooOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FooOptions()); + private pb::UnknownFieldSet _unknownFields; + private pb::ExtensionSet _extensions; + private pb::ExtensionSet _Extensions { get { return _extensions; } } + private int _hasBits0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public static pbr::MessageDescriptor Descriptor { + get { return global::UnitTest.Issues.TestProtos.SelfreferentialOptions.UnittestSelfreferentialOptionsReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public FooOptions() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public FooOptions(FooOptions other) : this() { + _hasBits0 = other._hasBits0; + intOpt_ = other.intOpt_; + foo_ = other.foo_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + _extensions = pb::ExtensionSet.Clone(other._extensions); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public FooOptions Clone() { + return new FooOptions(this); + } + + /// Field number for the "int_opt" field. + public const int IntOptFieldNumber = 1; + private readonly static int IntOptDefaultValue = 0; + + private int intOpt_; + /// + /// Custom field option used in definition of the extension message. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int IntOpt { + get { if ((_hasBits0 & 1) != 0) { return intOpt_; } else { return IntOptDefaultValue; } } + set { + _hasBits0 |= 1; + intOpt_ = value; + } + } + /// Gets whether the "int_opt" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasIntOpt { + get { return (_hasBits0 & 1) != 0; } + } + /// Clears the value of the "int_opt" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearIntOpt() { + _hasBits0 &= ~1; + } + + /// Field number for the "foo" field. + public const int FooFieldNumber = 2; + private readonly static int FooDefaultValue = 0; + + private int foo_; + /// + /// Custom field option used in definition of the custom option's message. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int Foo { + get { if ((_hasBits0 & 2) != 0) { return foo_; } else { return FooDefaultValue; } } + set { + _hasBits0 |= 2; + foo_ = value; + } + } + /// Gets whether the "foo" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool HasFoo { + get { return (_hasBits0 & 2) != 0; } + } + /// Clears the value of the "foo" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void ClearFoo() { + _hasBits0 &= ~2; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override bool Equals(object other) { + return Equals(other as FooOptions); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Equals(FooOptions other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (IntOpt != other.IntOpt) return false; + if (Foo != other.Foo) return false; + if (!Equals(_extensions, other._extensions)) { + return false; + } + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override int GetHashCode() { + int hash = 1; + if (HasIntOpt) hash ^= IntOpt.GetHashCode(); + if (HasFoo) hash ^= Foo.GetHashCode(); + if (_extensions != null) { + hash ^= _extensions.GetHashCode(); + } + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasIntOpt) { + output.WriteRawTag(8); + output.WriteInt32(IntOpt); + } + if (HasFoo) { + output.WriteRawTag(16); + output.WriteInt32(Foo); + } + if (_extensions != null) { + _extensions.WriteTo(output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasIntOpt) { + output.WriteRawTag(8); + output.WriteInt32(IntOpt); + } + if (HasFoo) { + output.WriteRawTag(16); + output.WriteInt32(Foo); + } + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public int CalculateSize() { + int size = 0; + if (HasIntOpt) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(IntOpt); + } + if (HasFoo) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(Foo); + } + if (_extensions != null) { + size += _extensions.CalculateSize(); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(FooOptions other) { + if (other == null) { + return; + } + if (other.HasIntOpt) { + IntOpt = other.IntOpt; + } + if (other.HasFoo) { + Foo = other.Foo; + } + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } + break; + case 8: { + IntOpt = input.ReadInt32(); + break; + } + case 16: { + Foo = input.ReadInt32(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + case 8: { + IntOpt = input.ReadInt32(); + break; + } + case 16: { + Foo = input.ReadInt32(); + break; + } + } + } + } + #endif + + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetOrInitializeExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension); + } + public void SetExtension(pb::Extension extension, TValue value) { + pb::ExtensionSet.Set(ref _extensions, extension, value); + } + public bool HasExtension(pb::Extension extension) { + return pb::ExtensionSet.Has(ref _extensions, extension); + } + public void ClearExtension(pb::Extension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + public void ClearExtension(pb::RepeatedExtension extension) { + pb::ExtensionSet.Clear(ref _extensions, extension); + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs index 90b338436bc9..996e928cfd52 100644 --- a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs +++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestWellKnownTypes.cs @@ -179,7 +179,11 @@ public static partial class UnittestWellKnownTypesReflection { /// Each wrapper type is included separately, as languages /// map handle different wrappers in different ways. /// - public sealed partial class TestWellKnownTypes : pb::IMessage { + public sealed partial class TestWellKnownTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new TestWellKnownTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -531,6 +535,9 @@ public sealed partial class TestWellKnownTypes : pb::IMessage /// A repeated field for each well-known type. /// - public sealed partial class RepeatedWellKnownTypes : pb::IMessage { + public sealed partial class RepeatedWellKnownTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new RepeatedWellKnownTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1234,6 +1473,9 @@ public sealed partial class RepeatedWellKnownTypes : pb::IMessage { + public sealed partial class OneofWellKnownTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneofWellKnownTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1798,6 +2162,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) { output.WriteRawTag(10); output.WriteMessage(AnyField); @@ -1864,8 +2231,81 @@ public enum OneofFieldOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) { + output.WriteRawTag(10); + output.WriteMessage(AnyField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.ApiField) { + output.WriteRawTag(18); + output.WriteMessage(ApiField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.DurationField) { + output.WriteRawTag(26); + output.WriteMessage(DurationField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.EmptyField) { + output.WriteRawTag(34); + output.WriteMessage(EmptyField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.FieldMaskField) { + output.WriteRawTag(42); + output.WriteMessage(FieldMaskField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.SourceContextField) { + output.WriteRawTag(50); + output.WriteMessage(SourceContextField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.StructField) { + output.WriteRawTag(58); + output.WriteMessage(StructField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.TimestampField) { + output.WriteRawTag(66); + output.WriteMessage(TimestampField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.TypeField) { + output.WriteRawTag(74); + output.WriteMessage(TypeField); + } + if (oneofFieldCase_ == OneofFieldOneofCase.DoubleField) { + _oneof_doubleField_codec.WriteTagAndValue(ref output, (double?) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.FloatField) { + _oneof_floatField_codec.WriteTagAndValue(ref output, (float?) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.Int64Field) { + _oneof_int64Field_codec.WriteTagAndValue(ref output, (long?) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.Uint64Field) { + _oneof_uint64Field_codec.WriteTagAndValue(ref output, (ulong?) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.Int32Field) { + _oneof_int32Field_codec.WriteTagAndValue(ref output, (int?) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.Uint32Field) { + _oneof_uint32Field_codec.WriteTagAndValue(ref output, (uint?) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.BoolField) { + _oneof_boolField_codec.WriteTagAndValue(ref output, (bool?) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.StringField) { + _oneof_stringField_codec.WriteTagAndValue(ref output, (string) oneofField_); + } + if (oneofFieldCase_ == OneofFieldOneofCase.BytesField) { + _oneof_bytesField_codec.WriteTagAndValue(ref output, (pb::ByteString) oneofField_); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -2023,6 +2463,9 @@ public enum OneofFieldOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2148,8 +2591,140 @@ public enum OneofFieldOneofCase { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + global::Google.Protobuf.WellKnownTypes.Any subBuilder = new global::Google.Protobuf.WellKnownTypes.Any(); + if (oneofFieldCase_ == OneofFieldOneofCase.AnyField) { + subBuilder.MergeFrom(AnyField); + } + input.ReadMessage(subBuilder); + AnyField = subBuilder; + break; + } + case 18: { + global::Google.Protobuf.WellKnownTypes.Api subBuilder = new global::Google.Protobuf.WellKnownTypes.Api(); + if (oneofFieldCase_ == OneofFieldOneofCase.ApiField) { + subBuilder.MergeFrom(ApiField); + } + input.ReadMessage(subBuilder); + ApiField = subBuilder; + break; + } + case 26: { + global::Google.Protobuf.WellKnownTypes.Duration subBuilder = new global::Google.Protobuf.WellKnownTypes.Duration(); + if (oneofFieldCase_ == OneofFieldOneofCase.DurationField) { + subBuilder.MergeFrom(DurationField); + } + input.ReadMessage(subBuilder); + DurationField = subBuilder; + break; + } + case 34: { + global::Google.Protobuf.WellKnownTypes.Empty subBuilder = new global::Google.Protobuf.WellKnownTypes.Empty(); + if (oneofFieldCase_ == OneofFieldOneofCase.EmptyField) { + subBuilder.MergeFrom(EmptyField); + } + input.ReadMessage(subBuilder); + EmptyField = subBuilder; + break; + } + case 42: { + global::Google.Protobuf.WellKnownTypes.FieldMask subBuilder = new global::Google.Protobuf.WellKnownTypes.FieldMask(); + if (oneofFieldCase_ == OneofFieldOneofCase.FieldMaskField) { + subBuilder.MergeFrom(FieldMaskField); + } + input.ReadMessage(subBuilder); + FieldMaskField = subBuilder; + break; + } + case 50: { + global::Google.Protobuf.WellKnownTypes.SourceContext subBuilder = new global::Google.Protobuf.WellKnownTypes.SourceContext(); + if (oneofFieldCase_ == OneofFieldOneofCase.SourceContextField) { + subBuilder.MergeFrom(SourceContextField); + } + input.ReadMessage(subBuilder); + SourceContextField = subBuilder; + break; + } + case 58: { + global::Google.Protobuf.WellKnownTypes.Struct subBuilder = new global::Google.Protobuf.WellKnownTypes.Struct(); + if (oneofFieldCase_ == OneofFieldOneofCase.StructField) { + subBuilder.MergeFrom(StructField); + } + input.ReadMessage(subBuilder); + StructField = subBuilder; + break; + } + case 66: { + global::Google.Protobuf.WellKnownTypes.Timestamp subBuilder = new global::Google.Protobuf.WellKnownTypes.Timestamp(); + if (oneofFieldCase_ == OneofFieldOneofCase.TimestampField) { + subBuilder.MergeFrom(TimestampField); + } + input.ReadMessage(subBuilder); + TimestampField = subBuilder; + break; + } + case 74: { + global::Google.Protobuf.WellKnownTypes.Type subBuilder = new global::Google.Protobuf.WellKnownTypes.Type(); + if (oneofFieldCase_ == OneofFieldOneofCase.TypeField) { + subBuilder.MergeFrom(TypeField); + } + input.ReadMessage(subBuilder); + TypeField = subBuilder; + break; + } + case 82: { + DoubleField = _oneof_doubleField_codec.Read(ref input); + break; + } + case 90: { + FloatField = _oneof_floatField_codec.Read(ref input); + break; + } + case 98: { + Int64Field = _oneof_int64Field_codec.Read(ref input); + break; + } + case 106: { + Uint64Field = _oneof_uint64Field_codec.Read(ref input); + break; + } + case 114: { + Int32Field = _oneof_int32Field_codec.Read(ref input); + break; + } + case 122: { + Uint32Field = _oneof_uint32Field_codec.Read(ref input); + break; + } + case 130: { + BoolField = _oneof_boolField_codec.Read(ref input); + break; + } + case 138: { + StringField = _oneof_stringField_codec.Read(ref input); + break; + } + case 146: { + BytesField = _oneof_bytesField_codec.Read(ref input); + break; + } + } + } + } + #endif + } /// @@ -2157,7 +2732,11 @@ public enum OneofFieldOneofCase { /// need to worry about the value part of the map being the /// well-known types, as messages can't be map keys. /// - public sealed partial class MapWellKnownTypes : pb::IMessage { + public sealed partial class MapWellKnownTypes : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MapWellKnownTypes()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2456,6 +3035,9 @@ public sealed partial class MapWellKnownTypes : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else anyField_.WriteTo(output, _map_anyField_codec); apiField_.WriteTo(output, _map_apiField_codec); durationField_.WriteTo(output, _map_durationField_codec); @@ -2477,7 +3059,35 @@ public sealed partial class MapWellKnownTypes : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + anyField_.WriteTo(ref output, _map_anyField_codec); + apiField_.WriteTo(ref output, _map_apiField_codec); + durationField_.WriteTo(ref output, _map_durationField_codec); + emptyField_.WriteTo(ref output, _map_emptyField_codec); + fieldMaskField_.WriteTo(ref output, _map_fieldMaskField_codec); + sourceContextField_.WriteTo(ref output, _map_sourceContextField_codec); + structField_.WriteTo(ref output, _map_structField_codec); + timestampField_.WriteTo(ref output, _map_timestampField_codec); + typeField_.WriteTo(ref output, _map_typeField_codec); + doubleField_.WriteTo(ref output, _map_doubleField_codec); + floatField_.WriteTo(ref output, _map_floatField_codec); + int64Field_.WriteTo(ref output, _map_int64Field_codec); + uint64Field_.WriteTo(ref output, _map_uint64Field_codec); + int32Field_.WriteTo(ref output, _map_int32Field_codec); + uint32Field_.WriteTo(ref output, _map_uint32Field_codec); + boolField_.WriteTo(ref output, _map_boolField_codec); + stringField_.WriteTo(ref output, _map_stringField_codec); + bytesField_.WriteTo(ref output, _map_bytesField_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -2534,6 +3144,9 @@ public sealed partial class MapWellKnownTypes : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -2614,7 +3227,94 @@ public sealed partial class MapWellKnownTypes : pb::IMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + anyField_.AddEntriesFrom(ref input, _map_anyField_codec); + break; + } + case 18: { + apiField_.AddEntriesFrom(ref input, _map_apiField_codec); + break; + } + case 26: { + durationField_.AddEntriesFrom(ref input, _map_durationField_codec); + break; + } + case 34: { + emptyField_.AddEntriesFrom(ref input, _map_emptyField_codec); + break; + } + case 42: { + fieldMaskField_.AddEntriesFrom(ref input, _map_fieldMaskField_codec); + break; + } + case 50: { + sourceContextField_.AddEntriesFrom(ref input, _map_sourceContextField_codec); + break; + } + case 58: { + structField_.AddEntriesFrom(ref input, _map_structField_codec); + break; + } + case 66: { + timestampField_.AddEntriesFrom(ref input, _map_timestampField_codec); + break; + } + case 74: { + typeField_.AddEntriesFrom(ref input, _map_typeField_codec); + break; + } + case 82: { + doubleField_.AddEntriesFrom(ref input, _map_doubleField_codec); + break; + } + case 90: { + floatField_.AddEntriesFrom(ref input, _map_floatField_codec); + break; + } + case 98: { + int64Field_.AddEntriesFrom(ref input, _map_int64Field_codec); + break; + } + case 106: { + uint64Field_.AddEntriesFrom(ref input, _map_uint64Field_codec); + break; + } + case 114: { + int32Field_.AddEntriesFrom(ref input, _map_int32Field_codec); + break; + } + case 122: { + uint32Field_.AddEntriesFrom(ref input, _map_uint32Field_codec); + break; + } + case 130: { + boolField_.AddEntriesFrom(ref input, _map_boolField_codec); + break; + } + case 138: { + stringField_.AddEntriesFrom(ref input, _map_stringField_codec); + break; + } + case 146: { + bytesField_.AddEntriesFrom(ref input, _map_bytesField_codec); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs b/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs new file mode 100644 index 000000000000..5b9913b29035 --- /dev/null +++ b/csharp/src/Google.Protobuf.Test/Buffers/ArrayBufferWriter.cs @@ -0,0 +1,225 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Diagnostics; + +namespace Google.Protobuf.Buffers +{ + /// + /// Represents a heap-based, array-backed output sink into which data can be written. + /// + /// ArrayBufferWriter is originally from corefx, and has been contributed to Protobuf + /// https://github.com/dotnet/runtime/blob/071da4c41aa808c949a773b92dca6f88de9d11f3/src/libraries/Common/src/System/Buffers/ArrayBufferWriter.cs + /// + internal sealed class ArrayBufferWriter : IBufferWriter + { + private T[] _buffer; + private int _index; + + private const int DefaultInitialBufferSize = 256; + + /// + /// Creates an instance of an , in which data can be written to, + /// with the default initial capacity. + /// + public ArrayBufferWriter() + { + _buffer = new T[0]; + _index = 0; + } + + /// + /// Useful for testing writing to buffer writer with a lot of small segments. + /// If set, it limits the max number of bytes by which the buffer grows by at once. + /// + public int? MaxGrowBy { get; set; } + + /// + /// Creates an instance of an , in which data can be written to, + /// with an initial capacity specified. + /// + /// The minimum capacity with which to initialize the underlying buffer. + /// + /// Thrown when is not positive (i.e. less than or equal to 0). + /// + public ArrayBufferWriter(int initialCapacity) + { + if (initialCapacity <= 0) + throw new ArgumentException(nameof(initialCapacity)); + + _buffer = new T[initialCapacity]; + _index = 0; + } + + /// + /// Returns the data written to the underlying buffer so far, as a . + /// + public ReadOnlyMemory WrittenMemory => _buffer.AsMemory(0, _index); + + /// + /// Returns the data written to the underlying buffer so far, as a . + /// + public ReadOnlySpan WrittenSpan => _buffer.AsSpan(0, _index); + + /// + /// Returns the amount of data written to the underlying buffer so far. + /// + public int WrittenCount => _index; + + /// + /// Returns the total amount of space within the underlying buffer. + /// + public int Capacity => _buffer.Length; + + /// + /// Returns the amount of space available that can still be written into without forcing the underlying buffer to grow. + /// + public int FreeCapacity => _buffer.Length - _index; + + /// + /// Clears the data written to the underlying buffer. + /// + /// + /// You must clear the before trying to re-use it. + /// + public void Clear() + { + Debug.Assert(_buffer.Length >= _index); + _buffer.AsSpan(0, _index).Clear(); + _index = 0; + } + + /// + /// Notifies that amount of data was written to the output / + /// + /// + /// Thrown when is negative. + /// + /// + /// Thrown when attempting to advance past the end of the underlying buffer. + /// + /// + /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer. + /// + public void Advance(int count) + { + if (count < 0) + throw new ArgumentException(nameof(count)); + + if (_index > _buffer.Length - count) + throw new InvalidOperationException("Advanced past capacity."); + + _index += count; + } + + /// + /// Returns a to write to that is at least the requested length (specified by ). + /// If no is provided (or it's equal to 0), some non-empty buffer is returned. + /// + /// + /// Thrown when is negative. + /// + /// + /// This will never return an empty . + /// + /// + /// There is no guarantee that successive calls will return the same buffer or the same-sized buffer. + /// + /// + /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer. + /// + public Memory GetMemory(int sizeHint = 0) + { + CheckAndResizeBuffer(sizeHint); + Debug.Assert(_buffer.Length > _index); + return _buffer.AsMemory(_index); + } + + /// + /// Returns a to write to that is at least the requested length (specified by ). + /// If no is provided (or it's equal to 0), some non-empty buffer is returned. + /// + /// + /// Thrown when is negative. + /// + /// + /// This will never return an empty . + /// + /// + /// There is no guarantee that successive calls will return the same buffer or the same-sized buffer. + /// + /// + /// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer. + /// + public Span GetSpan(int sizeHint = 0) + { + CheckAndResizeBuffer(sizeHint); + Debug.Assert(_buffer.Length > _index); + return _buffer.AsSpan(_index); + } + + private void CheckAndResizeBuffer(int sizeHint) + { + if (sizeHint < 0) + throw new ArgumentException(nameof(sizeHint)); + + if (sizeHint == 0) + { + sizeHint = 1; + } + + if (sizeHint > FreeCapacity) + { + int growBy = Math.Max(sizeHint, _buffer.Length); + + if (_buffer.Length == 0) + { + growBy = Math.Max(growBy, DefaultInitialBufferSize); + } + + // enable tests that write to small buffer segments + if (MaxGrowBy.HasValue && growBy > MaxGrowBy.Value) + { + growBy = MaxGrowBy.Value; + } + + int newSize = checked(_buffer.Length + growBy); + + Array.Resize(ref _buffer, newSize); + } + + Debug.Assert(FreeCapacity > 0 && FreeCapacity >= sizeHint); + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs index 84e6341e9510..d9f607448d9c 100644 --- a/csharp/src/Google.Protobuf.Test/ByteStringTest.cs +++ b/csharp/src/Google.Protobuf.Test/ByteStringTest.cs @@ -34,6 +34,13 @@ using System.Text; using NUnit.Framework; using System.IO; +using System.Collections.Generic; +using System.Collections; +using System.Linq; +using System.Buffers; +using System.Runtime.InteropServices; +using System.Threading; +using System.Runtime.CompilerServices; #if !NET35 using System.Threading.Tasks; #endif @@ -54,6 +61,7 @@ public void Equality() EqualityTester.AssertInequality(b1, b3); EqualityTester.AssertInequality(b1, b4); EqualityTester.AssertInequality(b1, null); + EqualityTester.AssertEquality(ByteString.Empty, ByteString.Empty); #pragma warning disable 1718 // Deliberately calling ==(b1, b1) and !=(b1, b1) Assert.IsTrue(b1 == b1); Assert.IsTrue(b1 == b2); @@ -63,6 +71,7 @@ public void Equality() Assert.IsTrue((ByteString) null == null); Assert.IsFalse(b1 != b1); Assert.IsFalse(b1 != b2); + Assert.IsTrue(ByteString.Empty == ByteString.Empty); #pragma warning disable 1718 Assert.IsTrue(b1 != b3); Assert.IsTrue(b1 != b4); @@ -110,6 +119,18 @@ public void CopyFromByteArrayCopiesContents() Assert.AreEqual(10, bs[0]); } + [Test] + public void CopyFromReadOnlySpanCopiesContents() + { + byte[] data = new byte[1]; + data[0] = 10; + ReadOnlySpan byteSpan = data; + var bs = ByteString.CopyFrom(byteSpan); + Assert.AreEqual(10, bs[0]); + data[0] = 5; + Assert.AreEqual(10, bs[0]); + } + [Test] public void ToByteArrayCopiesContents() { @@ -142,6 +163,84 @@ public void CopyFromPortion() Assert.AreEqual(3, bs[1]); } + [Test] + public void CopyTo() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = ByteString.CopyFrom(data); + + byte[] dest = new byte[data.Length]; + bs.CopyTo(dest, 0); + + CollectionAssert.AreEqual(data, dest); + } + + [Test] + public void GetEnumerator() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = ByteString.CopyFrom(data); + + IEnumerator genericEnumerator = bs.GetEnumerator(); + Assert.IsTrue(genericEnumerator.MoveNext()); + Assert.AreEqual(0, genericEnumerator.Current); + + IEnumerator enumerator = ((IEnumerable)bs).GetEnumerator(); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(0, enumerator.Current); + + // Call via LINQ + CollectionAssert.AreEqual(bs.Span.ToArray(), bs.ToArray()); + } + + [Test] + public void UnsafeWrap() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = UnsafeByteOperations.UnsafeWrap(data.AsMemory(2, 3)); + ReadOnlySpan s = bs.Span; + + Assert.AreEqual(3, s.Length); + Assert.AreEqual(2, s[0]); + Assert.AreEqual(3, s[1]); + Assert.AreEqual(4, s[2]); + + // Check that the value is not a copy + data[2] = byte.MaxValue; + Assert.AreEqual(byte.MaxValue, s[0]); + } + + [Test] + public void WriteToStream() + { + byte[] data = new byte[] { 0, 1, 2, 3, 4, 5, 6 }; + ByteString bs = ByteString.CopyFrom(data); + + MemoryStream ms = new MemoryStream(); + bs.WriteTo(ms); + + CollectionAssert.AreEqual(data, ms.ToArray()); + } + + [Test] + public void WriteToStream_Stackalloc() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world"); + Span s = stackalloc byte[data.Length]; + data.CopyTo(s); + + MemoryStream ms = new MemoryStream(); + + using (UnmanagedMemoryManager manager = new UnmanagedMemoryManager(s)) + { + ByteString bs = ByteString.AttachBytes(manager.Memory); + + bs.WriteTo(ms); + } + + CollectionAssert.AreEqual(data, ms.ToArray()); + } + [Test] public void ToStringUtf8() { @@ -156,6 +255,21 @@ public void ToStringWithExplicitEncoding() Assert.AreEqual("\u20ac", bs.ToString(Encoding.Unicode)); } + [Test] + public void ToString_Stackalloc() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world"); + Span s = stackalloc byte[data.Length]; + data.CopyTo(s); + + using (UnmanagedMemoryManager manager = new UnmanagedMemoryManager(s)) + { + ByteString bs = ByteString.AttachBytes(manager.Memory); + + Assert.AreEqual("Hello world", bs.ToString(Encoding.UTF8)); + } + } + [Test] public void FromBase64_WithText() { @@ -172,6 +286,29 @@ public void FromBase64_Empty() Assert.AreSame(ByteString.Empty, ByteString.FromBase64("")); } + [Test] + public void ToBase64_Array() + { + ByteString bs = ByteString.CopyFrom(Encoding.UTF8.GetBytes("Hello world")); + + Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); + } + + [Test] + public void ToBase64_Stackalloc() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world"); + Span s = stackalloc byte[data.Length]; + data.CopyTo(s); + + using (UnmanagedMemoryManager manager = new UnmanagedMemoryManager(s)) + { + ByteString bs = ByteString.AttachBytes(manager.Memory); + + Assert.AreEqual("SGVsbG8gd29ybGQ=", bs.ToBase64()); + } + } + [Test] public void FromStream_Seekable() { @@ -233,5 +370,54 @@ public void GetHashCode_Regression() ByteString b2 = ByteString.CopyFrom(200, 1, 2, 3, 4); Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode()); } + + [Test] + public void GetContentsAsReadOnlySpan() + { + var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5); + var copied = byteString.Span.ToArray(); + CollectionAssert.AreEqual(byteString, copied); + } + + [Test] + public void GetContentsAsReadOnlyMemory() + { + var byteString = ByteString.CopyFrom(1, 2, 3, 4, 5); + var copied = byteString.Memory.ToArray(); + CollectionAssert.AreEqual(byteString, copied); + } + + // Create Memory from non-array source. + // Use by ByteString tests that have optimized path for array backed Memory. + private sealed unsafe class UnmanagedMemoryManager : MemoryManager where T : unmanaged + { + private readonly T* _pointer; + private readonly int _length; + + public UnmanagedMemoryManager(Span span) + { + fixed (T* ptr = &MemoryMarshal.GetReference(span)) + { + _pointer = ptr; + _length = span.Length; + } + } + + public override Span GetSpan() => new Span(_pointer, _length); + + public override MemoryHandle Pin(int elementIndex = 0) + { + if (elementIndex < 0 || elementIndex >= _length) + { + throw new ArgumentOutOfRangeException(nameof(elementIndex)); + } + + return new MemoryHandle(_pointer + elementIndex); + } + + public override void Unpin() { } + + protected override void Dispose(bool disposing) { } + } } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs index ba65b328e806..0ad286f3787f 100644 --- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs +++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs @@ -31,8 +31,10 @@ #endregion using System; +using System.Buffers; using System.IO; using Google.Protobuf.TestProtos; +using Proto2 = Google.Protobuf.TestProtos.Proto2; using NUnit.Framework; namespace Google.Protobuf @@ -61,11 +63,22 @@ private static void AssertReadVarint(byte[] data, ulong value) { CodedInputStream input = new CodedInputStream(data); Assert.AreEqual((uint) value, input.ReadRawVarint32()); + Assert.IsTrue(input.IsAtEnd); input = new CodedInputStream(data); Assert.AreEqual(value, input.ReadRawVarint64()); Assert.IsTrue(input.IsAtEnd); + AssertReadFromParseContext(new ReadOnlySequence(data), (ref ParseContext ctx) => + { + Assert.AreEqual((uint) value, ctx.ReadUInt32()); + }, true); + + AssertReadFromParseContext(new ReadOnlySequence(data), (ref ParseContext ctx) => + { + Assert.AreEqual(value, ctx.ReadUInt64()); + }, true); + // Try different block sizes. for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) { @@ -75,6 +88,16 @@ private static void AssertReadVarint(byte[] data, ulong value) input = new CodedInputStream(new SmallBlockInputStream(data, bufferSize)); Assert.AreEqual(value, input.ReadRawVarint64()); Assert.IsTrue(input.IsAtEnd); + + AssertReadFromParseContext(ReadOnlySequenceFactory.CreateWithContent(data, bufferSize), (ref ParseContext ctx) => + { + Assert.AreEqual((uint) value, ctx.ReadUInt32()); + }, true); + + AssertReadFromParseContext(ReadOnlySequenceFactory.CreateWithContent(data, bufferSize), (ref ParseContext ctx) => + { + Assert.AreEqual(value, ctx.ReadUInt64()); + }, true); } // Try reading directly from a MemoryStream. We want to verify that it @@ -103,11 +126,49 @@ private static void AssertReadVarintFailure(InvalidProtocolBufferException expec exception = Assert.Throws(() => input.ReadRawVarint64()); Assert.AreEqual(expected.Message, exception.Message); + AssertReadFromParseContext(new ReadOnlySequence(data), (ref ParseContext ctx) => + { + try + { + ctx.ReadUInt32(); + Assert.Fail(); + } + catch (InvalidProtocolBufferException ex) + { + Assert.AreEqual(expected.Message, ex.Message); + } + }, false); + + AssertReadFromParseContext(new ReadOnlySequence(data), (ref ParseContext ctx) => + { + try + { + ctx.ReadUInt64(); + Assert.Fail(); + } + catch (InvalidProtocolBufferException ex) + { + Assert.AreEqual(expected.Message, ex.Message); + } + }, false); + // Make sure we get the same error when reading directly from a Stream. exception = Assert.Throws(() => CodedInputStream.ReadRawVarint32(new MemoryStream(data))); Assert.AreEqual(expected.Message, exception.Message); } + private delegate void ParseContextAssertAction(ref ParseContext ctx); + + private static void AssertReadFromParseContext(ReadOnlySequence input, ParseContextAssertAction assertAction, bool assertIsAtEnd) + { + ParseContext.Initialize(input, out ParseContext parseCtx); + assertAction(ref parseCtx); + if (assertIsAtEnd) + { + Assert.IsTrue(SegmentedBufferHelper.IsAtEnd(ref parseCtx.buffer, ref parseCtx.state)); + } + } + [Test] public void ReadVarint() { @@ -156,6 +217,11 @@ private static void AssertReadLittleEndian32(byte[] data, uint value) Assert.AreEqual(value, input.ReadRawLittleEndian32()); Assert.IsTrue(input.IsAtEnd); + AssertReadFromParseContext(new ReadOnlySequence(data), (ref ParseContext ctx) => + { + Assert.AreEqual(value, ctx.ReadFixed32()); + }, true); + // Try different block sizes. for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { @@ -163,6 +229,11 @@ private static void AssertReadLittleEndian32(byte[] data, uint value) new SmallBlockInputStream(data, blockSize)); Assert.AreEqual(value, input.ReadRawLittleEndian32()); Assert.IsTrue(input.IsAtEnd); + + AssertReadFromParseContext(ReadOnlySequenceFactory.CreateWithContent(data, blockSize), (ref ParseContext ctx) => + { + Assert.AreEqual(value, ctx.ReadFixed32()); + }, true); } } @@ -176,6 +247,11 @@ private static void AssertReadLittleEndian64(byte[] data, ulong value) Assert.AreEqual(value, input.ReadRawLittleEndian64()); Assert.IsTrue(input.IsAtEnd); + AssertReadFromParseContext(new ReadOnlySequence(data), (ref ParseContext ctx) => + { + Assert.AreEqual(value, ctx.ReadFixed64()); + }, true); + // Try different block sizes. for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { @@ -183,6 +259,11 @@ private static void AssertReadLittleEndian64(byte[] data, ulong value) new SmallBlockInputStream(data, blockSize)); Assert.AreEqual(value, input.ReadRawLittleEndian64()); Assert.IsTrue(input.IsAtEnd); + + AssertReadFromParseContext(ReadOnlySequenceFactory.CreateWithContent(data, blockSize), (ref ParseContext ctx) => + { + Assert.AreEqual(value, ctx.ReadFixed64()); + }, true); } } @@ -201,29 +282,29 @@ public void ReadLittleEndian() [Test] public void DecodeZigZag32() { - Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(0)); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(1)); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(2)); - Assert.AreEqual(-2, CodedInputStream.DecodeZigZag32(3)); - Assert.AreEqual(0x3FFFFFFF, CodedInputStream.DecodeZigZag32(0x7FFFFFFE)); - Assert.AreEqual(unchecked((int) 0xC0000000), CodedInputStream.DecodeZigZag32(0x7FFFFFFF)); - Assert.AreEqual(0x7FFFFFFF, CodedInputStream.DecodeZigZag32(0xFFFFFFFE)); - Assert.AreEqual(unchecked((int) 0x80000000), CodedInputStream.DecodeZigZag32(0xFFFFFFFF)); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(0)); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(1)); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(2)); + Assert.AreEqual(-2, ParsingPrimitives.DecodeZigZag32(3)); + Assert.AreEqual(0x3FFFFFFF, ParsingPrimitives.DecodeZigZag32(0x7FFFFFFE)); + Assert.AreEqual(unchecked((int) 0xC0000000), ParsingPrimitives.DecodeZigZag32(0x7FFFFFFF)); + Assert.AreEqual(0x7FFFFFFF, ParsingPrimitives.DecodeZigZag32(0xFFFFFFFE)); + Assert.AreEqual(unchecked((int) 0x80000000), ParsingPrimitives.DecodeZigZag32(0xFFFFFFFF)); } [Test] public void DecodeZigZag64() { - Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(0)); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(1)); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(2)); - Assert.AreEqual(-2, CodedInputStream.DecodeZigZag64(3)); - Assert.AreEqual(0x000000003FFFFFFFL, CodedInputStream.DecodeZigZag64(0x000000007FFFFFFEL)); - Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), CodedInputStream.DecodeZigZag64(0x000000007FFFFFFFL)); - Assert.AreEqual(0x000000007FFFFFFFL, CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFEL)); - Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), CodedInputStream.DecodeZigZag64(0x00000000FFFFFFFFL)); - Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL)); - Assert.AreEqual(unchecked((long) 0x8000000000000000L), CodedInputStream.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL)); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(0)); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(1)); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(2)); + Assert.AreEqual(-2, ParsingPrimitives.DecodeZigZag64(3)); + Assert.AreEqual(0x000000003FFFFFFFL, ParsingPrimitives.DecodeZigZag64(0x000000007FFFFFFEL)); + Assert.AreEqual(unchecked((long) 0xFFFFFFFFC0000000L), ParsingPrimitives.DecodeZigZag64(0x000000007FFFFFFFL)); + Assert.AreEqual(0x000000007FFFFFFFL, ParsingPrimitives.DecodeZigZag64(0x00000000FFFFFFFEL)); + Assert.AreEqual(unchecked((long) 0xFFFFFFFF80000000L), ParsingPrimitives.DecodeZigZag64(0x00000000FFFFFFFFL)); + Assert.AreEqual(0x7FFFFFFFFFFFFFFFL, ParsingPrimitives.DecodeZigZag64(0xFFFFFFFFFFFFFFFEL)); + Assert.AreEqual(unchecked((long) 0x8000000000000000L), ParsingPrimitives.DecodeZigZag64(0xFFFFFFFFFFFFFFFFL)); } [Test] @@ -243,7 +324,44 @@ public void ReadWholeMessage_VaryingBlockSizes() Assert.AreEqual(message, message2); } } - + + [Test] + public void ReadWholeMessage_VaryingBlockSizes_FromSequence() + { + TestAllTypes message = SampleMessages.CreateFullTestAllTypes(); + + byte[] rawBytes = message.ToByteArray(); + Assert.AreEqual(rawBytes.Length, message.CalculateSize()); + TestAllTypes message2 = TestAllTypes.Parser.ParseFrom(rawBytes); + Assert.AreEqual(message, message2); + + // Try different block sizes. + for (int blockSize = 1; blockSize < 256; blockSize *= 2) + { + message2 = TestAllTypes.Parser.ParseFrom(ReadOnlySequenceFactory.CreateWithContent(rawBytes, blockSize)); + Assert.AreEqual(message, message2); + } + } + + [Test] + public void ReadInt32Wrapper_VariableBlockSizes() + { + byte[] rawBytes = new byte[] { 202, 1, 11, 8, 254, 255, 255, 255, 255, 255, 255, 255, 255, 1 }; + + for (int blockSize = 1; blockSize <= rawBytes.Length; blockSize++) + { + ReadOnlySequence data = ReadOnlySequenceFactory.CreateWithContent(rawBytes, blockSize); + AssertReadFromParseContext(data, (ref ParseContext ctx) => + { + ctx.ReadTag(); + + var value = ParsingPrimitivesWrappers.ReadInt32Wrapper(ref ctx); + + Assert.AreEqual(-2, value); + }, true); + } + } + [Test] public void ReadHugeBlob() { @@ -284,6 +402,70 @@ public void ReadMaliciouslyLargeBlob() Assert.Throws(() => input.ReadBytes()); } + [Test] + public void ReadBlobGreaterThanCurrentLimit() + { + MemoryStream ms = new MemoryStream(); + CodedOutputStream output = new CodedOutputStream(ms); + uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); + output.WriteRawVarint32(tag); + output.WriteRawVarint32(4); + output.WriteRawBytes(new byte[4]); // Pad with a few random bytes. + output.Flush(); + ms.Position = 0; + + CodedInputStream input = new CodedInputStream(ms); + Assert.AreEqual(tag, input.ReadTag()); + + // Specify limit smaller than data length + input.PushLimit(3); + Assert.Throws(() => input.ReadBytes()); + + AssertReadFromParseContext(new ReadOnlySequence(ms.ToArray()), (ref ParseContext ctx) => + { + Assert.AreEqual(tag, ctx.ReadTag()); + SegmentedBufferHelper.PushLimit(ref ctx.state, 3); + try + { + ctx.ReadBytes(); + Assert.Fail(); + } + catch (InvalidProtocolBufferException) {} + }, true); + } + + [Test] + public void ReadStringGreaterThanCurrentLimit() + { + MemoryStream ms = new MemoryStream(); + CodedOutputStream output = new CodedOutputStream(ms); + uint tag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); + output.WriteRawVarint32(tag); + output.WriteRawVarint32(4); + output.WriteRawBytes(new byte[4]); // Pad with a few random bytes. + output.Flush(); + ms.Position = 0; + + CodedInputStream input = new CodedInputStream(ms.ToArray()); + Assert.AreEqual(tag, input.ReadTag()); + + // Specify limit smaller than data length + input.PushLimit(3); + Assert.Throws(() => input.ReadString()); + + AssertReadFromParseContext(new ReadOnlySequence(ms.ToArray()), (ref ParseContext ctx) => + { + Assert.AreEqual(tag, ctx.ReadTag()); + SegmentedBufferHelper.PushLimit(ref ctx.state, 3); + try + { + ctx.ReadString(); + Assert.Fail(); + } + catch (InvalidProtocolBufferException) { } + }, true); + } + // Representations of a tag for field 0 with various wire types [Test] [TestCase(0)] @@ -337,6 +519,66 @@ public void MaliciousRecursion() CodedInputStream input = CodedInputStream.CreateWithLimits(new MemoryStream(atRecursiveLimit.ToByteArray()), 1000000, CodedInputStream.DefaultRecursionLimit - 1); Assert.Throws(() => TestRecursiveMessage.Parser.ParseFrom(input)); } + + private static byte[] MakeMaliciousRecursionUnknownFieldsPayload(int recursionDepth) + { + // generate recursively nested groups that will be parsed as unknown fields + int unknownFieldNumber = 14; // an unused field number + MemoryStream ms = new MemoryStream(); + CodedOutputStream output = new CodedOutputStream(ms); + for (int i = 0; i < recursionDepth; i++) + { + output.WriteTag(WireFormat.MakeTag(unknownFieldNumber, WireFormat.WireType.StartGroup)); + } + for (int i = 0; i < recursionDepth; i++) + { + output.WriteTag(WireFormat.MakeTag(unknownFieldNumber, WireFormat.WireType.EndGroup)); + } + output.Flush(); + return ms.ToArray(); + } + + [Test] + public void MaliciousRecursion_UnknownFields() + { + byte[] payloadAtRecursiveLimit = MakeMaliciousRecursionUnknownFieldsPayload(CodedInputStream.DefaultRecursionLimit); + byte[] payloadBeyondRecursiveLimit = MakeMaliciousRecursionUnknownFieldsPayload(CodedInputStream.DefaultRecursionLimit + 1); + + Assert.DoesNotThrow(() => TestRecursiveMessage.Parser.ParseFrom(payloadAtRecursiveLimit)); + Assert.Throws(() => TestRecursiveMessage.Parser.ParseFrom(payloadBeyondRecursiveLimit)); + } + + [Test] + public void ReadGroup_WrongEndGroupTag() + { + int groupFieldNumber = Proto2.TestAllTypes.OptionalGroupFieldNumber; + + // write Proto2.TestAllTypes with "optional_group" set, but use wrong EndGroup closing tag + MemoryStream ms = new MemoryStream(); + CodedOutputStream output = new CodedOutputStream(ms); + output.WriteTag(WireFormat.MakeTag(groupFieldNumber, WireFormat.WireType.StartGroup)); + output.WriteGroup(new Proto2.TestAllTypes.Types.OptionalGroup { A = 12345 }); + // end group with different field number + output.WriteTag(WireFormat.MakeTag(groupFieldNumber + 1, WireFormat.WireType.EndGroup)); + output.Flush(); + var payload = ms.ToArray(); + + Assert.Throws(() => Proto2.TestAllTypes.Parser.ParseFrom(payload)); + } + + [Test] + public void ReadGroup_UnknownFields_WrongEndGroupTag() + { + MemoryStream ms = new MemoryStream(); + CodedOutputStream output = new CodedOutputStream(ms); + output.WriteTag(WireFormat.MakeTag(14, WireFormat.WireType.StartGroup)); + // end group with different field number + output.WriteTag(WireFormat.MakeTag(15, WireFormat.WireType.EndGroup)); + output.Flush(); + var payload = ms.ToArray(); + + Assert.Throws(() => TestRecursiveMessage.Parser.ParseFrom(payload)); + } [Test] public void SizeLimit() @@ -735,4 +977,4 @@ public override int Read(byte[] buffer, int offset, int count) } } } -} \ No newline at end of file +} diff --git a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs index 98cabd55adc4..1c77e121d3eb 100644 --- a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs +++ b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs @@ -33,6 +33,7 @@ using System; using System.IO; using Google.Protobuf.TestProtos; +using Google.Protobuf.Buffers; using NUnit.Framework; namespace Google.Protobuf @@ -48,22 +49,39 @@ private static void AssertWriteVarint(byte[] data, ulong value) // Only do 32-bit write if the value fits in 32 bits. if ((value >> 32) == 0) { + // CodedOutputStream MemoryStream rawOutput = new MemoryStream(); CodedOutputStream output = new CodedOutputStream(rawOutput); output.WriteRawVarint32((uint) value); output.Flush(); Assert.AreEqual(data, rawOutput.ToArray()); + + // IBufferWriter + var bufferWriter = new ArrayBufferWriter(); + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteUInt32((uint) value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); + // Also try computing size. Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint32Size((uint) value)); } { + // CodedOutputStream MemoryStream rawOutput = new MemoryStream(); CodedOutputStream output = new CodedOutputStream(rawOutput); output.WriteRawVarint64(value); output.Flush(); Assert.AreEqual(data, rawOutput.ToArray()); + // IBufferWriter + var bufferWriter = new ArrayBufferWriter(); + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteUInt64(value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); + // Also try computing size. Assert.AreEqual(data.Length, CodedOutputStream.ComputeRawVarint64Size(value)); } @@ -80,6 +98,13 @@ private static void AssertWriteVarint(byte[] data, ulong value) output.WriteRawVarint32((uint) value); output.Flush(); Assert.AreEqual(data, rawOutput.ToArray()); + + var bufferWriter = new ArrayBufferWriter(); + bufferWriter.MaxGrowBy = bufferSize; + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteUInt32((uint) value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); } { @@ -88,7 +113,15 @@ private static void AssertWriteVarint(byte[] data, ulong value) output.WriteRawVarint64(value); output.Flush(); Assert.AreEqual(data, rawOutput.ToArray()); + + var bufferWriter = new ArrayBufferWriter(); + bufferWriter.MaxGrowBy = bufferSize; + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteUInt64(value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); } + } } @@ -133,20 +166,35 @@ public void WriteVarint() /// private static void AssertWriteLittleEndian32(byte[] data, uint value) { - MemoryStream rawOutput = new MemoryStream(); - CodedOutputStream output = new CodedOutputStream(rawOutput); - output.WriteRawLittleEndian32(value); - output.Flush(); - Assert.AreEqual(data, rawOutput.ToArray()); + { + var rawOutput = new MemoryStream(); + var output = new CodedOutputStream(rawOutput); + output.WriteRawLittleEndian32(value); + output.Flush(); + Assert.AreEqual(data, rawOutput.ToArray()); + + var bufferWriter = new ArrayBufferWriter(); + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteFixed32(value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); + } // Try different buffer sizes. for (int bufferSize = 1; bufferSize <= 16; bufferSize *= 2) { - rawOutput = new MemoryStream(); - output = new CodedOutputStream(rawOutput, bufferSize); + var rawOutput = new MemoryStream(); + var output = new CodedOutputStream(rawOutput, bufferSize); output.WriteRawLittleEndian32(value); output.Flush(); Assert.AreEqual(data, rawOutput.ToArray()); + + var bufferWriter = new ArrayBufferWriter(); + bufferWriter.MaxGrowBy = bufferSize; + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteFixed32(value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); } } @@ -156,20 +204,35 @@ private static void AssertWriteLittleEndian32(byte[] data, uint value) /// private static void AssertWriteLittleEndian64(byte[] data, ulong value) { - MemoryStream rawOutput = new MemoryStream(); - CodedOutputStream output = new CodedOutputStream(rawOutput); - output.WriteRawLittleEndian64(value); - output.Flush(); - Assert.AreEqual(data, rawOutput.ToArray()); + { + var rawOutput = new MemoryStream(); + var output = new CodedOutputStream(rawOutput); + output.WriteRawLittleEndian64(value); + output.Flush(); + Assert.AreEqual(data, rawOutput.ToArray()); + + var bufferWriter = new ArrayBufferWriter(); + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteFixed64(value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); + } // Try different block sizes. for (int blockSize = 1; blockSize <= 16; blockSize *= 2) { - rawOutput = new MemoryStream(); - output = new CodedOutputStream(rawOutput, blockSize); + var rawOutput = new MemoryStream(); + var output = new CodedOutputStream(rawOutput, blockSize); output.WriteRawLittleEndian64(value); output.Flush(); Assert.AreEqual(data, rawOutput.ToArray()); + + var bufferWriter = new ArrayBufferWriter(); + bufferWriter.MaxGrowBy = blockSize; + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteFixed64(value); + ctx.Flush(); + Assert.AreEqual(data, bufferWriter.WrittenSpan.ToArray()); } } @@ -205,41 +268,72 @@ public void WriteWholeMessage_VaryingBlockSizes() message.WriteTo(output); output.Flush(); Assert.AreEqual(rawBytes, rawOutput.ToArray()); + + var bufferWriter = new ArrayBufferWriter(); + bufferWriter.MaxGrowBy = blockSize; + message.WriteTo(bufferWriter); + Assert.AreEqual(rawBytes, bufferWriter.WrittenSpan.ToArray()); } } + + [Test] + public void WriteContext_WritesWithFlushes() + { + TestAllTypes message = SampleMessages.CreateFullTestAllTypes(); + + MemoryStream expectedOutput = new MemoryStream(); + CodedOutputStream output = new CodedOutputStream(expectedOutput); + output.WriteMessage(message); + output.Flush(); + byte[] expectedBytes1 = expectedOutput.ToArray(); + + output.WriteMessage(message); + output.Flush(); + byte[] expectedBytes2 = expectedOutput.ToArray(); + + var bufferWriter = new ArrayBufferWriter(); + WriteContext.Initialize(bufferWriter, out WriteContext ctx); + ctx.WriteMessage(message); + ctx.Flush(); + Assert.AreEqual(expectedBytes1, bufferWriter.WrittenSpan.ToArray()); + + ctx.WriteMessage(message); + ctx.Flush(); + Assert.AreEqual(expectedBytes2, bufferWriter.WrittenSpan.ToArray()); + } [Test] public void EncodeZigZag32() { - Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag32(0)); - Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag32(-1)); - Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag32(1)); - Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag32(-2)); - Assert.AreEqual(0x7FFFFFFEu, CodedOutputStream.EncodeZigZag32(0x3FFFFFFF)); - Assert.AreEqual(0x7FFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0xC0000000))); - Assert.AreEqual(0xFFFFFFFEu, CodedOutputStream.EncodeZigZag32(0x7FFFFFFF)); - Assert.AreEqual(0xFFFFFFFFu, CodedOutputStream.EncodeZigZag32(unchecked((int) 0x80000000))); + Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag32(0)); + Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag32(-1)); + Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag32(1)); + Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag32(-2)); + Assert.AreEqual(0x7FFFFFFEu, WritingPrimitives.EncodeZigZag32(0x3FFFFFFF)); + Assert.AreEqual(0x7FFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0xC0000000))); + Assert.AreEqual(0xFFFFFFFEu, WritingPrimitives.EncodeZigZag32(0x7FFFFFFF)); + Assert.AreEqual(0xFFFFFFFFu, WritingPrimitives.EncodeZigZag32(unchecked((int) 0x80000000))); } [Test] public void EncodeZigZag64() { - Assert.AreEqual(0u, CodedOutputStream.EncodeZigZag64(0)); - Assert.AreEqual(1u, CodedOutputStream.EncodeZigZag64(-1)); - Assert.AreEqual(2u, CodedOutputStream.EncodeZigZag64(1)); - Assert.AreEqual(3u, CodedOutputStream.EncodeZigZag64(-2)); + Assert.AreEqual(0u, WritingPrimitives.EncodeZigZag64(0)); + Assert.AreEqual(1u, WritingPrimitives.EncodeZigZag64(-1)); + Assert.AreEqual(2u, WritingPrimitives.EncodeZigZag64(1)); + Assert.AreEqual(3u, WritingPrimitives.EncodeZigZag64(-2)); Assert.AreEqual(0x000000007FFFFFFEuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000003FFFFFFFUL))); Assert.AreEqual(0x000000007FFFFFFFuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFFC0000000UL))); Assert.AreEqual(0x00000000FFFFFFFEuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x000000007FFFFFFFUL))); Assert.AreEqual(0x00000000FFFFFFFFuL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0xFFFFFFFF80000000UL))); Assert.AreEqual(0xFFFFFFFFFFFFFFFEL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x7FFFFFFFFFFFFFFFUL))); Assert.AreEqual(0xFFFFFFFFFFFFFFFFL, - CodedOutputStream.EncodeZigZag64(unchecked((long) 0x8000000000000000UL))); + WritingPrimitives.EncodeZigZag64(unchecked((long) 0x8000000000000000UL))); } [Test] @@ -247,26 +341,26 @@ public void RoundTripZigZag32() { // Some easier-to-verify round-trip tests. The inputs (other than 0, 1, -1) // were chosen semi-randomly via keyboard bashing. - Assert.AreEqual(0, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(0))); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(1))); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-1))); - Assert.AreEqual(14927, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(14927))); - Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag32(CodedOutputStream.EncodeZigZag32(-3612))); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(0))); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(1))); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-1))); + Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(14927))); + Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag32(WritingPrimitives.EncodeZigZag32(-3612))); } [Test] public void RoundTripZigZag64() { - Assert.AreEqual(0, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(0))); - Assert.AreEqual(1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(1))); - Assert.AreEqual(-1, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-1))); - Assert.AreEqual(14927, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(14927))); - Assert.AreEqual(-3612, CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-3612))); + Assert.AreEqual(0, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(0))); + Assert.AreEqual(1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(1))); + Assert.AreEqual(-1, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-1))); + Assert.AreEqual(14927, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(14927))); + Assert.AreEqual(-3612, ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-3612))); Assert.AreEqual(856912304801416L, - CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(856912304801416L))); + ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(856912304801416L))); Assert.AreEqual(-75123905439571256L, - CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L))); + ParsingPrimitives.DecodeZigZag64(WritingPrimitives.EncodeZigZag64(-75123905439571256L))); } [Test] @@ -395,7 +489,7 @@ public void Dispose_DisposesUnderlyingStream() Assert.IsTrue(memoryStream.CanWrite); using (var cos = new CodedOutputStream(memoryStream)) { - cos.WriteRawByte(0); + cos.WriteRawBytes(new byte[] {0}); Assert.AreEqual(0, memoryStream.Position); // Not flushed yet } Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream @@ -409,7 +503,7 @@ public void Dispose_WithLeaveOpen() Assert.IsTrue(memoryStream.CanWrite); using (var cos = new CodedOutputStream(memoryStream, true)) { - cos.WriteRawByte(0); + cos.WriteRawBytes(new byte[] {0}); Assert.AreEqual(0, memoryStream.Position); // Not flushed yet } Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs index f64ebac4ef9f..d8cdee0f0f75 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs @@ -31,6 +31,7 @@ #endregion using System; +using System.IO; using System.Collections.Generic; using Google.Protobuf.TestProtos; using NUnit.Framework; @@ -583,6 +584,33 @@ public void NaNKeysComparedBitwise() Assert.False(map.TryGetValue(SampleNaNs.PayloadFlipped, out ignored)); } + [Test] + public void AddEntriesFrom_CodedInputStream() + { + // map will have string key and string value + var keyTag = WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited); + var valueTag = WireFormat.MakeTag(2, WireFormat.WireType.LengthDelimited); + + var memoryStream = new MemoryStream(); + var output = new CodedOutputStream(memoryStream); + output.WriteLength(20); // total of keyTag + key + valueTag + value + output.WriteTag(keyTag); + output.WriteString("the_key"); + output.WriteTag(valueTag); + output.WriteString("the_value"); + output.Flush(); + + var field = new MapField(); + var mapCodec = new MapField.Codec(FieldCodec.ForString(keyTag, ""), FieldCodec.ForString(valueTag, ""), 10); + var input = new CodedInputStream(memoryStream.ToArray()); + + // test the legacy overload of AddEntriesFrom that takes a CodedInputStream + field.AddEntriesFrom(input, mapCodec); + CollectionAssert.AreEquivalent(new[] { "the_key" }, field.Keys); + CollectionAssert.AreEquivalent(new[] { "the_value" }, field.Values); + Assert.IsTrue(input.IsAtEnd); + } + #if !NET35 [Test] public void IDictionaryKeys_Equals_IReadOnlyDictionaryKeys() diff --git a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs index 527c7d404c46..61453e5ab2e6 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs @@ -595,6 +595,95 @@ public void TestNegativeEnumPackedArray() Assert.AreEqual(((SampleEnum)(-5)), values[5]); } + [Test] + public void TestPackedRepeatedFieldCollectionNonDivisibleLength() + { + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var codec = FieldCodec.ForFixed32(tag); + var stream = new MemoryStream(); + var output = new CodedOutputStream(stream); + output.WriteTag(tag); + output.WriteString("A long string"); + output.WriteTag(codec.Tag); + output.WriteRawVarint32((uint)codec.FixedSize - 1); // Length not divisible by FixedSize + output.WriteFixed32(uint.MaxValue); + output.Flush(); + stream.Position = 0; + + var input = new CodedInputStream(stream); + input.ReadTag(); + input.ReadString(); + input.ReadTag(); + var field = new RepeatedField(); + Assert.Throws(() => field.AddEntriesFrom(input, codec)); + + // Collection was not pre-initialized + Assert.AreEqual(0, field.Count); + } + + [Test] + public void TestPackedRepeatedFieldCollectionNotAllocatedWhenLengthExceedsBuffer() + { + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var codec = FieldCodec.ForFixed32(tag); + var stream = new MemoryStream(); + var output = new CodedOutputStream(stream); + output.WriteTag(tag); + output.WriteString("A long string"); + output.WriteTag(codec.Tag); + output.WriteRawVarint32((uint)codec.FixedSize); + // Note that there is no content for the packed field. + // The field length exceeds the remaining length of content. + output.Flush(); + stream.Position = 0; + + var input = new CodedInputStream(stream); + input.ReadTag(); + input.ReadString(); + input.ReadTag(); + var field = new RepeatedField(); + Assert.Throws(() => field.AddEntriesFrom(input, codec)); + + // Collection was not pre-initialized + Assert.AreEqual(0, field.Count); + } + + [Test] + public void TestPackedRepeatedFieldCollectionNotAllocatedWhenLengthExceedsRemainingData() + { + uint tag = WireFormat.MakeTag(10, WireFormat.WireType.LengthDelimited); + var codec = FieldCodec.ForFixed32(tag); + var stream = new MemoryStream(); + var output = new CodedOutputStream(stream); + output.WriteTag(tag); + output.WriteString("A long string"); + output.WriteTag(codec.Tag); + output.WriteRawVarint32((uint)codec.FixedSize); + // Note that there is no content for the packed field. + // The field length exceeds the remaining length of the buffer. + output.Flush(); + stream.Position = 0; + + var sequence = ReadOnlySequenceFactory.CreateWithContent(stream.ToArray()); + ParseContext.Initialize(sequence, out ParseContext ctx); + + ctx.ReadTag(); + ctx.ReadString(); + ctx.ReadTag(); + var field = new RepeatedField(); + try + { + field.AddEntriesFrom(ref ctx, codec); + Assert.Fail(); + } + catch (InvalidProtocolBufferException) + { + } + + // Collection was not pre-initialized + Assert.AreEqual(0, field.Count); + } + // Fairly perfunctory tests for the non-generic IList implementation [Test] public void IList_Indexer() diff --git a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs index 33dc50430d07..aceb4a68f7b2 100644 --- a/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs +++ b/csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs @@ -1,4 +1,4 @@ -using Google.Protobuf.TestProtos.Proto2; +using Google.Protobuf.TestProtos.Proto2; using NUnit.Framework; using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions; @@ -34,12 +34,16 @@ public void TestMergeCodedInput() message.SetExtension(OptionalBoolExtension, true); var serialized = message.ToByteArray(); - var other = TestAllExtensions.Parser - .WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension }) - .ParseFrom(serialized); + MessageParsingHelpers.AssertWritingMessage(message); - Assert.AreEqual(message, other); - Assert.AreEqual(message.CalculateSize(), other.CalculateSize()); + MessageParsingHelpers.AssertReadingMessage( + TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension }), + serialized, + other => + { + Assert.AreEqual(message, other); + Assert.AreEqual(message.CalculateSize(), other.CalculateSize()); + }); } [Test] @@ -59,6 +63,22 @@ public void TestMergeMessage() Assert.AreEqual(message.CalculateSize(), other.CalculateSize()); } + [Test] + public void TryMergeFieldFrom_CodedInputStream() + { + var message = new TestAllExtensions(); + message.SetExtension(OptionalStringExtension, "abcd"); + + var input = new CodedInputStream(message.ToByteArray()); + input.ExtensionRegistry = new ExtensionRegistry() { OptionalStringExtension }; + input.ReadTag(); // TryMergeFieldFrom expects that a tag was just read and will inspect the LastTag value + + ExtensionSet extensionSet = null; + // test the legacy overload of TryMergeFieldFrom that takes a CodedInputStream + Assert.IsTrue(ExtensionSet.TryMergeFieldFrom(ref extensionSet, input)); + Assert.AreEqual("abcd", ExtensionSet.Get(ref extensionSet, OptionalStringExtension)); + } + [Test] public void TestEquals() { diff --git a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs index b20ecccde2d0..7f366926fa02 100644 --- a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs +++ b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs @@ -124,11 +124,21 @@ public void TestRoundTripRaw() { var stream = new MemoryStream(); var codedOutput = new CodedOutputStream(stream); - codec.ValueWriter(codedOutput, sampleValue); + WriteContext.Initialize(codedOutput, out WriteContext ctx); + try + { + // only write the value using the codec + codec.ValueWriter(ref ctx, sampleValue); + } + finally + { + ctx.CopyStateTo(codedOutput); + } + codedOutput.Flush(); stream.Position = 0; var codedInput = new CodedInputStream(stream); - Assert.AreEqual(sampleValue, codec.ValueReader(codedInput)); + Assert.AreEqual(sampleValue, codec.Read(codedInput)); Assert.IsTrue(codedInput.IsAtEnd); } @@ -158,7 +168,7 @@ public void TestDefaultValue() { // WriteTagAndValue ignores default values var stream = new MemoryStream(); - CodedOutputStream codedOutput; + CodedOutputStream codedOutput; #if !NET35 codedOutput = new CodedOutputStream(stream); codec.WriteTagAndValue(codedOutput, codec.DefaultValue); @@ -175,13 +185,23 @@ public void TestDefaultValue() if (codec.DefaultValue != null) // This part isn't appropriate for message types. { codedOutput = new CodedOutputStream(stream); - codec.ValueWriter(codedOutput, codec.DefaultValue); + WriteContext.Initialize(codedOutput, out WriteContext ctx); + try + { + // only write the value using the codec + codec.ValueWriter(ref ctx, codec.DefaultValue); + } + finally + { + ctx.CopyStateTo(codedOutput); + } + codedOutput.Flush(); Assert.AreNotEqual(0, stream.Position); Assert.AreEqual(stream.Position, codec.ValueSizeCalculator(codec.DefaultValue)); stream.Position = 0; var codedInput = new CodedInputStream(stream); - Assert.AreEqual(codec.DefaultValue, codec.ValueReader(codedInput)); + Assert.AreEqual(codec.DefaultValue, codec.Read(codedInput)); } } diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs index 718c3edcb80e..1abed60563c8 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs @@ -269,8 +269,8 @@ public void RequiredFields() [Test] public void RequiredFieldsNoThrow() { - Assert.DoesNotThrow(() => TestRequired.Parser.ParseFrom(new byte[0])); - Assert.DoesNotThrow(() => (TestRequired.Parser as MessageParser).ParseFrom(new byte[0])); + Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser, new byte[0], m => { })); + Assert.DoesNotThrow(() => MessageParsingHelpers.AssertReadingMessage(TestRequired.Parser as MessageParser, new byte[0], m => { })); } [Test] @@ -344,9 +344,9 @@ public void RoundTrip_Groups() } }; - byte[] bytes = message.ToByteArray(); - TestAllTypes parsed = Proto2.TestAllTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, parsed); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(Proto2.TestAllTypes.Parser, message); } [Test] @@ -361,9 +361,11 @@ public void RoundTrip_ExtensionGroups() new RepeatedGroup_extension { A = 30 } }); - byte[] bytes = message.ToByteArray(); - TestAllExtensions extendable_parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }).ParseFrom(bytes); - Assert.AreEqual(message, extendable_parsed); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip( + TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }), + message); } [Test] @@ -372,9 +374,11 @@ public void RoundTrip_NestedExtensionGroup() var message = new TestGroupExtension(); message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 }); - byte[] bytes = message.ToByteArray(); - TestGroupExtension extendable_parsed = TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }).ParseFrom(bytes); - Assert.AreEqual(message, extendable_parsed); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip( + TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }), + message); } } } diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs index 103df7dd2fef..06af5e9e9a04 100644 --- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs +++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs @@ -131,8 +131,10 @@ public void RoundTrip_Empty() // Without setting any values, there's nothing to write. byte[] bytes = message.ToByteArray(); Assert.AreEqual(0, bytes.Length); - TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, parsed); + + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message); } [Test] @@ -164,9 +166,9 @@ public void RoundTrip_SingleValues() SingleUint64 = ulong.MaxValue }; - byte[] bytes = message.ToByteArray(); - TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, parsed); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message); } [Test] @@ -198,9 +200,9 @@ public void RoundTrip_RepeatedValues() RepeatedUint64 = { ulong.MaxValue, uint.MinValue } }; - byte[] bytes = message.ToByteArray(); - TestAllTypes parsed = TestAllTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, parsed); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message); } // Note that not every map within map_unittest_proto3 is used. They all go through very @@ -230,9 +232,9 @@ public void RoundTrip_Maps() } }; - byte[] bytes = message.ToByteArray(); - TestMap parsed = TestMap.Parser.ParseFrom(bytes); - Assert.AreEqual(message, parsed); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestMap.Parser, message); } [Test] @@ -246,9 +248,16 @@ public void MapWithEmptyEntry() byte[] bytes = message.ToByteArray(); Assert.AreEqual(2, bytes.Length); // Tag for field entry (1 byte), length of entry (0; 1 byte) - var parsed = TestMap.Parser.ParseFrom(bytes); - Assert.AreEqual(1, parsed.MapInt32Bytes.Count); - Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + bytes, + parsed=> + { + Assert.AreEqual(1, parsed.MapInt32Bytes.Count); + Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]); + }); } [Test] @@ -265,8 +274,13 @@ public void MapWithOnlyValue() output.WriteMessage(nestedMessage); output.Flush(); - var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray()); - Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]); + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + memoryStream.ToArray(), + parsed => + { + Assert.AreEqual(nestedMessage, parsed.MapInt32ForeignMessage[0]); + }); } [Test] @@ -282,8 +296,13 @@ public void MapWithOnlyKey_PrimitiveValue() output.WriteInt32(key); output.Flush(); - var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray()); - Assert.AreEqual(0.0, parsed.MapInt32Double[key]); + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + memoryStream.ToArray(), + parsed => + { + Assert.AreEqual(0.0, parsed.MapInt32Double[key]); + }); } [Test] @@ -299,8 +318,13 @@ public void MapWithOnlyKey_MessageValue() output.WriteInt32(key); output.Flush(); - var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray()); - Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]); + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + memoryStream.ToArray(), + parsed => + { + Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]); + }); } [Test] @@ -327,8 +351,13 @@ public void MapIgnoresExtraFieldsWithinEntryMessages() output.WriteInt32(extra); output.Flush(); - var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray()); - Assert.AreEqual(value, parsed.MapInt32Int32[key]); + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + memoryStream.ToArray(), + parsed => + { + Assert.AreEqual(value, parsed.MapInt32Int32[key]); + }); } [Test] @@ -351,8 +380,13 @@ public void MapFieldOrderIsIrrelevant() output.WriteInt32(key); output.Flush(); - var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray()); - Assert.AreEqual(value, parsed.MapInt32Int32[key]); + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + memoryStream.ToArray(), + parsed => + { + Assert.AreEqual(value, parsed.MapInt32Int32[key]); + }); } [Test] @@ -397,13 +431,19 @@ public void MapNonContiguousEntries() output.WriteInt32(value3); output.Flush(); - var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray()); - var expected = new TestMap - { - MapInt32Int32 = { { key1, value1 }, { key3, value3 } }, - MapStringString = { { key2, value2 } } - }; - Assert.AreEqual(expected, parsed); + + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + memoryStream.ToArray(), + parsed => + { + var expected = new TestMap + { + MapInt32Int32 = { { key1, value1 }, { key3, value3 } }, + MapStringString = { { key2, value2 } } + }; + Assert.AreEqual(expected, parsed); + }); } [Test] @@ -433,8 +473,13 @@ public void DuplicateKeys_LastEntryWins() output.WriteInt32(value2); output.Flush(); - var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray()); - Assert.AreEqual(value2, parsed.MapInt32Int32[key]); + MessageParsingHelpers.AssertReadingMessage( + TestMap.Parser, + memoryStream.ToArray(), + parsed => + { + Assert.AreEqual(value2, parsed.MapInt32Int32[key]); + }); } [Test] @@ -619,9 +664,12 @@ public void OneofSerialization_NonDefaultValue() var bytes = message.ToByteArray(); Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - no string! - var message2 = TestAllTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, message2); - Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage => + { + Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase); + }); } [Test] @@ -633,9 +681,12 @@ public void OneofSerialization_DefaultValue() var bytes = message.ToByteArray(); Assert.AreEqual(3, bytes.Length); // 2 bytes for the tag + 1 for the value - it's still serialized - var message2 = TestAllTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, message2); - Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestAllTypes.Parser, message, parsedMessage => + { + Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, parsedMessage.OneofFieldCase); + }); } [Test] @@ -651,10 +702,14 @@ public void DiscardUnknownFields_RealDataStillRead() message.WriteTo(output); output.Flush(); - stream.Position = 0; - var parsed = TestAllTypes.Parser.ParseFrom(stream); - // TODO(jieluo): Add test back when DiscardUnknownFields API is supported. - // Assert.AreEqual(message, parsed); + MessageParsingHelpers.AssertReadingMessage( + TestAllTypes.Parser, + stream.ToArray(), + parsed => + { + // TODO(jieluo): Add test back when DiscardUnknownFields API is supported. + // Assert.AreEqual(message, parsed); + }); } [Test] @@ -663,8 +718,15 @@ public void DiscardUnknownFields_AllTypes() // Simple way of ensuring we can skip all kinds of fields. var data = SampleMessages.CreateFullTestAllTypes().ToByteArray(); var empty = Empty.Parser.ParseFrom(data); - // TODO(jieluo): Add test back when DiscardUnknownFields API is supported. - // Assert.AreNotEqual(new Empty(), empty); + + MessageParsingHelpers.AssertReadingMessage( + Empty.Parser, + data, + parsed => + { + // TODO(jieluo): Add test back when DiscardUnknownFields API is supported. + // Assert.AreNotEqual(new Empty(), empty); + }); } // This was originally seen as a conformance test failure. @@ -674,7 +736,7 @@ public void TruncatedMessageFieldThrows() // 130, 3 is the message tag // 1 is the data length - but there's no data. var data = new byte[] { 130, 3, 1 }; - Assert.Throws(() => TestAllTypes.Parser.ParseFrom(data)); + MessageParsingHelpers.AssertReadingMessageThrows(TestAllTypes.Parser, data); } /// @@ -695,7 +757,7 @@ public void ExtraEndGroupThrows() output.Flush(); stream.Position = 0; - Assert.Throws(() => TestAllTypes.Parser.ParseFrom(stream)); + MessageParsingHelpers.AssertReadingMessageThrows(TestAllTypes.Parser, stream.ToArray()); } [Test] diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj index 1a7953d6b786..89fe5d4febbc 100644 --- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj +++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj @@ -6,6 +6,7 @@ true true False + True diff --git a/csharp/src/Google.Protobuf.Test/IssuesTest.cs b/csharp/src/Google.Protobuf.Test/IssuesTest.cs index 2caf80a93fa4..2904c461df30 100644 --- a/csharp/src/Google.Protobuf.Test/IssuesTest.cs +++ b/csharp/src/Google.Protobuf.Test/IssuesTest.cs @@ -33,6 +33,7 @@ using Google.Protobuf.Reflection; using UnitTest.Issues.TestProtos; using NUnit.Framework; +using System.IO; using static UnitTest.Issues.TestProtos.OneofMerging.Types; namespace Google.Protobuf @@ -90,5 +91,26 @@ public void OneofMerging() merged.MergeFrom(message2); Assert.AreEqual(expected, merged); } + + // Check that a tag immediately followed by end of limit can still be read. + [Test] + public void CodedInputStream_LimitReachedRightAfterTag() + { + MemoryStream ms = new MemoryStream(); + var cos = new CodedOutputStream(ms); + cos.WriteTag(11, WireFormat.WireType.Varint); + Assert.AreEqual(1, cos.Position); + cos.WriteString("some extra padding"); // ensure is currentLimit distinct from the end of the buffer. + cos.Flush(); + + var cis = new CodedInputStream(ms.ToArray()); + cis.PushLimit(1); // make sure we reach the limit right after reading the tag. + + // we still must read the tag correctly, even though the tag is at the very end of our limited input + // (which is a corner case and will most likely result in an error when trying to read value of the field + // described by this tag, but it would be a logical error not to read the tag that's actually present). + // See https://github.com/protocolbuffers/protobuf/pull/7289 + cis.AssertNextTag(WireFormat.MakeTag(11, WireFormat.WireType.Varint)); + } } } diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs index b07a84161ae8..1a650933efd4 100644 --- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs @@ -40,6 +40,7 @@ using static Google.Protobuf.JsonParserTest; // For WrapInQuotes using System.IO; using Google.Protobuf.Collections; +using ProtobufUnittest; namespace Google.Protobuf { @@ -153,6 +154,48 @@ public void AllSingleFields() AssertJson(expectedText, actualText); } + [Test] + public void WithFormatDefaultValues_DoesNotAffectMessageFields() + { + var message = new TestAllTypes(); + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + Assert.IsFalse(json.Contains("\"singleNestedMessage\"")); + Assert.IsFalse(json.Contains("\"singleForeignMessage\"")); + Assert.IsFalse(json.Contains("\"singleImportMessage\"")); + } + + [Test] + public void WithFormatDefaultValues_DoesNotAffectProto3OptionalFields() + { + var message = new TestProto3Optional(); + message.OptionalInt32 = 0; + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + // The non-optional proto3 fields are formatted, as is the optional-but-specified field. + AssertJson("{ 'optionalInt32': 0, 'singularInt32': 0, 'singularInt64': '0' }", json); + } + + [Test] + public void WithFormatDefaultValues_DoesNotAffectProto2Fields() + { + var message = new TestProtos.Proto2.ForeignMessage(); + message.C = 0; + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + // The specified field is formatted, but the non-specified field (d) is not. + AssertJson("{ 'c': 0 }", json); + } + + [Test] + public void WithFormatDefaultValues_DoesNotAffectOneofFields() + { + var message = new TestOneof(); + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var json = formatter.Format(message); + AssertJson("{ }", json); + } + [Test] public void RepeatedField() { @@ -183,6 +226,28 @@ public void MapField_BoolBool() JsonFormatter.Default.Format(new TestMap { MapBoolBool = { { false, true }, { true, false } } })); } + [Test] + public void NullValueOutsideStruct() + { + var message = new NullValueOutsideStruct { NullValue = NullValue.NullValue }; + AssertJson("{ 'nullValue': null }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void NullValueNotInOneof() + { + var message = new NullValueNotInOneof(); + AssertJson("{ }", JsonFormatter.Default.Format(message)); + } + + [Test] + public void NullValueNotInOneof_FormatDefaults() + { + var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); + var message = new NullValueNotInOneof(); + AssertJson("{ 'nullValue': null }", formatter.Format(message)); + } + [TestCase(1.0, "1")] [TestCase(double.NaN, "'NaN'")] [TestCase(double.PositiveInfinity, "'Infinity'")] @@ -313,14 +378,16 @@ public void WrapperFormatting_Message() } [Test] - public void WrapperFormatting_IncludeNull() + public void WrapperFormatting_FormatDefaultValuesDoesNotFormatNull() { // The actual JSON here is very large because there are lots of fields. Just test a couple of them. var message = new TestWellKnownTypes { Int32Field = 10 }; var formatter = new JsonFormatter(JsonFormatter.Settings.Default.WithFormatDefaultValues(true)); var actualJson = formatter.Format(message); - Assert.IsTrue(actualJson.Contains("\"int64Field\": null")); - Assert.IsFalse(actualJson.Contains("\"int32Field\": null")); + // This *used* to include "int64Field": null, but that was a bug. + // WithDefaultValues should not affect message fields, including wrapper types. + Assert.IsFalse(actualJson.Contains("\"int64Field\": null")); + Assert.IsTrue(actualJson.Contains("\"int32Field\": 10")); } [Test] @@ -602,6 +669,13 @@ public void WriteValue_List() AssertWriteValue(value, "[ 1, 2, 3 ]"); } + [Test] + public void Proto2_DefaultValuesWritten() + { + var value = new ProtobufTestMessages.Proto2.TestAllTypesProto2() { FieldName13 = 0 }; + AssertWriteValue(value, "{ 'FieldName13': 0 }"); + } + private static void AssertWriteValue(object value, string expectedJson) { var writer = new StringWriter(); diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs index a6cf04ab7af2..e170fcc5a09c 100644 --- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs @@ -34,7 +34,9 @@ using Google.Protobuf.TestProtos; using Google.Protobuf.WellKnownTypes; using NUnit.Framework; +using ProtobufTestMessages.Proto2; using System; +using UnitTest.Issues.TestProtos; namespace Google.Protobuf { @@ -949,6 +951,16 @@ public void UnknownField_NotIgnored() Assert.Throws(() => TestAllTypes.Parser.ParseJson(json)); } + [Test] + public void Proto2_DefaultValuesPreserved() + { + string json = "{ \"FieldName13\": 0 }"; + var parsed = TestAllTypesProto2.Parser.ParseJson(json); + Assert.False(parsed.HasFieldName10); + Assert.True(parsed.HasFieldName13); + Assert.AreEqual(0, parsed.FieldName13); + } + [Test] [TestCase("5")] [TestCase("\"text\"")] @@ -963,6 +975,43 @@ public void UnknownField_Ignored(string value) Assert.AreEqual(expected, actual); } + [Test] + public void NullValueOutsideStruct_NullLiteral() + { + string json = "{ \"nullValue\": null }"; + var message = NullValueOutsideStruct.Parser.ParseJson(json); + Assert.AreEqual(NullValueOutsideStruct.ValueOneofCase.NullValue, message.ValueCase); + } + + [Test] + public void NullValueNotInOneof_NullLiteral() + { + // We'd only normally see this with FormatDefaultValues set to true. + string json = "{ \"nullValue\": null }"; + var message = NullValueNotInOneof.Parser.ParseJson(json); + Assert.AreEqual(NullValue.NullValue, message.NullValue); + } + + // NullValue used to only be converted to the null literal when part of a struct. + // Otherwise, it would end up as a string "NULL_VALUE" (the name of the enum value). + // We still parse that form, for compatibility. + [Test] + public void NullValueOutsideStruct_Compatibility() + { + string json = "{ \"nullValue\": \"NULL_VALUE\" }"; + var message = NullValueOutsideStruct.Parser.ParseJson(json); + Assert.AreEqual(NullValueOutsideStruct.ValueOneofCase.NullValue, message.ValueCase); + } + + [Test] + public void NullValueNotInOneof_Compatibility() + { + // We'd only normally see this with FormatDefaultValues set to true. + string json = "{ \"nullValue\": \"NULL_VALUE\" }"; + var message = NullValueNotInOneof.Parser.ParseJson(json); + Assert.AreEqual(NullValue.NullValue, message.NullValue); + } + /// /// Various tests use strings which have quotes round them for parsing or as the result /// of formatting, but without those quotes being specified in the tests (for the sake of readability). diff --git a/csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs b/csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs new file mode 100644 index 000000000000..da7b4a8c077a --- /dev/null +++ b/csharp/src/Google.Protobuf.Test/LegacyGeneratedCodeTest.cs @@ -0,0 +1,296 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion +using Google.Protobuf; +using Google.Protobuf.Reflection; +using System.Buffers; +using pb = global::Google.Protobuf; +using pbr = global::Google.Protobuf.Reflection; +using NUnit.Framework; +using System.IO; +using System; +using Google.Protobuf.Buffers; + +namespace Google.Protobuf +{ + public class LegacyGeneratedCodeTest + { + [Test] + public void IntermixingOfNewAndLegacyGeneratedCodeWorksWithCodedInputStream() + { + var message = new ParseContextEnabledMessageB + { + A = new LegacyGeneratedCodeMessageA + { + Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 } + }, + OptionalInt32 = 6789 + }; + var data = message.ToByteArray(); + + // when parsing started using CodedInputStream and a message with legacy generated code + // is encountered somewhere in the parse tree, we still need to be able to use its + // MergeFrom(CodedInputStream) method to parse correctly. + var codedInput = new CodedInputStream(data); + var parsed = new ParseContextEnabledMessageB(); + codedInput.ReadRawMessage(parsed); + Assert.IsTrue(codedInput.IsAtEnd); + + Assert.AreEqual(12345, parsed.A.Bb.OptionalInt32); + Assert.AreEqual(6789, parsed.OptionalInt32); + } + + [Test] + public void LegacyGeneratedCodeThrowsWithReadOnlySequence() + { + var message = new ParseContextEnabledMessageB + { + A = new LegacyGeneratedCodeMessageA + { + Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 } + }, + OptionalInt32 = 6789 + }; + var data = message.ToByteArray(); + + // if parsing started using ReadOnlySequence and we don't have a CodedInputStream + // instance at hand, we cannot fall back to the legacy MergeFrom(CodedInputStream) + // method and parsing will fail. As a consequence, one can only use parsing + // from ReadOnlySequence if all the messages in the parsing tree have their generated + // code up to date. + var exception = Assert.Throws(() => + { + ParseContext.Initialize(new ReadOnlySequence(data), out ParseContext parseCtx); + var parsed = new ParseContextEnabledMessageB(); + ParsingPrimitivesMessages.ReadRawMessage(ref parseCtx, parsed); + }); + Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables ParseContext-based parsing. You might need to regenerate the generated protobuf code.", exception.Message); + } + + [Test] + public void IntermixingOfNewAndLegacyGeneratedCodeWorksWithCodedOutputStream() + { + // when serialization started using CodedOutputStream and a message with legacy generated code + // is encountered somewhere in the parse tree, we still need to be able to use its + // WriteTo(CodedOutputStream) method to serialize correctly. + var ms = new MemoryStream(); + var codedOutput = new CodedOutputStream(ms); + var message = new ParseContextEnabledMessageB + { + A = new LegacyGeneratedCodeMessageA + { + Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 } + }, + OptionalInt32 = 6789 + }; + message.WriteTo(codedOutput); + codedOutput.Flush(); + + var codedInput = new CodedInputStream(ms.ToArray()); + var parsed = new ParseContextEnabledMessageB(); + codedInput.ReadRawMessage(parsed); + Assert.IsTrue(codedInput.IsAtEnd); + + Assert.AreEqual(12345, parsed.A.Bb.OptionalInt32); + Assert.AreEqual(6789, parsed.OptionalInt32); + } + + [Test] + public void LegacyGeneratedCodeThrowsWithIBufferWriter() + { + // if serialization started using IBufferWriter and we don't have a CodedOutputStream + // instance at hand, we cannot fall back to the legacy WriteTo(CodedOutputStream) + // method and serializatin will fail. As a consequence, one can only use serialization + // to IBufferWriter if all the messages in the parsing tree have their generated + // code up to date. + var message = new ParseContextEnabledMessageB + { + A = new LegacyGeneratedCodeMessageA + { + Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 } + }, + OptionalInt32 = 6789 + }; + var exception = Assert.Throws(() => + { + WriteContext.Initialize(new ArrayBufferWriter(), out WriteContext writeCtx); + ((IBufferMessage)message).InternalWriteTo(ref writeCtx); + }); + Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code.", exception.Message); + } + + // hand-modified version of a generated message that only provides the legacy + // MergeFrom(CodedInputStream) method and doesn't implement IBufferMessage. + private sealed partial class LegacyGeneratedCodeMessageA : pb::IMessage { + private pb::UnknownFieldSet _unknownFields; + + pbr::MessageDescriptor pb::IMessage.Descriptor => throw new System.NotImplementedException(); + + /// Field number for the "bb" field. + public const int BbFieldNumber = 1; + private ParseContextEnabledMessageB bb_; + public ParseContextEnabledMessageB Bb { + get { return bb_; } + set { + bb_ = value; + } + } + + public void WriteTo(pb::CodedOutputStream output) { + if (bb_ != null) { + output.WriteRawTag(10); + output.WriteMessage(Bb); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + } + + public int CalculateSize() { + int size = 0; + if (bb_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Bb); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + if (bb_ == null) { + Bb = new ParseContextEnabledMessageB(); + } + input.ReadMessage(Bb); + break; + } + } + } + } + } + + // hand-modified version of a generated message that does provide + // the new InternalMergeFrom(ref ParseContext) method. + private sealed partial class ParseContextEnabledMessageB : pb::IBufferMessage { + private pb::UnknownFieldSet _unknownFields; + + pbr::MessageDescriptor pb::IMessage.Descriptor => throw new System.NotImplementedException(); + + /// Field number for the "a" field. + public const int AFieldNumber = 1; + private LegacyGeneratedCodeMessageA a_; + public LegacyGeneratedCodeMessageA A { + get { return a_; } + set { + a_ = value; + } + } + + /// Field number for the "optional_int32" field. + public const int OptionalInt32FieldNumber = 2; + private int optionalInt32_; + public int OptionalInt32 { + get { return optionalInt32_; } + set { + optionalInt32_ = value; + } + } + + public void WriteTo(pb::CodedOutputStream output) { + output.WriteRawMessage(this); + } + + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) + { + if (a_ != null) + { + output.WriteRawTag(10); + output.WriteMessage(A); + } + if (OptionalInt32 != 0) + { + output.WriteRawTag(16); + output.WriteInt32(OptionalInt32); + } + if (_unknownFields != null) + { + _unknownFields.WriteTo(ref output); + } + } + + public int CalculateSize() { + int size = 0; + if (a_ != null) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(A); + } + if (OptionalInt32 != 0) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + public void MergeFrom(pb::CodedInputStream input) { + input.ReadRawMessage(this); + } + + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + if (a_ == null) { + A = new LegacyGeneratedCodeMessageA(); + } + input.ReadMessage(A); + break; + } + case 16: { + OptionalInt32 = input.ReadInt32(); + break; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs b/csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs new file mode 100644 index 000000000000..36a2f0222946 --- /dev/null +++ b/csharp/src/Google.Protobuf.Test/MessageParsingHelpers.cs @@ -0,0 +1,142 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2015 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using NUnit.Framework; +using System; +using System.Buffers; +using Google.Protobuf.Buffers; + +namespace Google.Protobuf +{ + public static class MessageParsingHelpers + { + public static void AssertReadingMessage(MessageParser parser, byte[] bytes, Action assert) where T : IMessage + { + var parsedStream = parser.ParseFrom(bytes); + + // Load content as single segment + var parsedBuffer = parser.ParseFrom(new ReadOnlySequence(bytes)); + assert(parsedBuffer); + + // Load content as multiple segments + parsedBuffer = parser.ParseFrom(ReadOnlySequenceFactory.CreateWithContent(bytes)); + assert(parsedBuffer); + + assert(parsedStream); + } + + public static void AssertReadingMessage(MessageParser parser, byte[] bytes, Action assert) + { + var parsedStream = parser.ParseFrom(bytes); + + // Load content as single segment + var parsedBuffer = parser.ParseFrom(new ReadOnlySequence(bytes)); + assert(parsedBuffer); + + // Load content as multiple segments + parsedBuffer = parser.ParseFrom(ReadOnlySequenceFactory.CreateWithContent(bytes)); + assert(parsedBuffer); + + assert(parsedStream); + } + + public static void AssertReadingMessageThrows(MessageParser parser, byte[] bytes) + where TMessage : IMessage + where TException : Exception + { + Assert.Throws(() => parser.ParseFrom(bytes)); + + Assert.Throws(() => parser.ParseFrom(new ReadOnlySequence(bytes))); + } + + public static void AssertRoundtrip(MessageParser parser, T message, Action additionalAssert = null) where T : IMessage + { + var bytes = message.ToByteArray(); + + // also serialize using IBufferWriter and check it leads to the same data + var bufferWriter = new ArrayBufferWriter(); + message.WriteTo(bufferWriter); + Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray(), "Both serialization approaches need to result in the same data."); + + // Load content as single segment + var parsedBuffer = parser.ParseFrom(new ReadOnlySequence(bytes)); + Assert.AreEqual(message, parsedBuffer); + additionalAssert?.Invoke(parsedBuffer); + + // Load content as multiple segments + parsedBuffer = parser.ParseFrom(ReadOnlySequenceFactory.CreateWithContent(bytes)); + Assert.AreEqual(message, parsedBuffer); + additionalAssert?.Invoke(parsedBuffer); + + var parsedStream = parser.ParseFrom(bytes); + + Assert.AreEqual(message, parsedStream); + additionalAssert?.Invoke(parsedStream); + } + + public static void AssertWritingMessage(IMessage message) + { + // serialize using CodedOutputStream + var bytes = message.ToByteArray(); + + int messageSize = message.CalculateSize(); + Assert.AreEqual(message.CalculateSize(), bytes.Length); + + // serialize using IBufferWriter and check it leads to the same output + var bufferWriter = new ArrayBufferWriter(); + message.WriteTo(bufferWriter); + Assert.AreEqual(bytes, bufferWriter.WrittenSpan.ToArray()); + + // serialize into a single span and check it leads to the same output + var singleSpan = new Span(new byte[messageSize]); + message.WriteTo(singleSpan); + Assert.AreEqual(bytes, singleSpan.ToArray()); + + // test for different IBufferWriter.GetSpan() segment sizes + for (int blockSize = 1; blockSize < 256; blockSize *= 2) + { + var segmentedBufferWriter = new ArrayBufferWriter(); + segmentedBufferWriter.MaxGrowBy = blockSize; + message.WriteTo(segmentedBufferWriter); + Assert.AreEqual(bytes, segmentedBufferWriter.WrittenSpan.ToArray()); + } + + // if the full message is small enough, try serializing directly into stack-allocated buffer + if (bytes.Length <= 256) + { + Span stackAllocBuffer = stackalloc byte[bytes.Length]; + message.WriteTo(stackAllocBuffer); + Assert.AreEqual(bytes, stackAllocBuffer.ToArray()); + } + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs b/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs new file mode 100644 index 000000000000..46a8c57a78ab --- /dev/null +++ b/csharp/src/Google.Protobuf.Test/Proto3OptionalTest.cs @@ -0,0 +1,153 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using NUnit.Framework; +using ProtobufUnittest; +using System; +using System.IO; +using UnitTest.Issues.TestProtos; + +namespace Google.Protobuf.Test +{ + class Proto3OptionalTest + { + [Test] + public void OptionalInt32FieldLifecycle() + { + var message = new TestProto3Optional(); + Assert.IsFalse(message.HasOptionalInt32); + Assert.AreEqual(0, message.OptionalInt32); + + message.OptionalInt32 = 5; + Assert.IsTrue(message.HasOptionalInt32); + Assert.AreEqual(5, message.OptionalInt32); + + message.OptionalInt32 = 0; + Assert.IsTrue(message.HasOptionalInt32); + Assert.AreEqual(0, message.OptionalInt32); + + message.ClearOptionalInt32(); + Assert.IsFalse(message.HasOptionalInt32); + Assert.AreEqual(0, message.OptionalInt32); + } + + [Test] + public void OptionalStringFieldLifecycle() + { + var message = new TestProto3Optional(); + Assert.IsFalse(message.HasOptionalString); + Assert.AreEqual("", message.OptionalString); + + message.OptionalString = "x"; + Assert.IsTrue(message.HasOptionalString); + Assert.AreEqual("x", message.OptionalString); + + message.OptionalString = ""; + Assert.IsTrue(message.HasOptionalString); + Assert.AreEqual("", message.OptionalString); + + message.ClearOptionalString(); + Assert.IsFalse(message.HasOptionalString); + Assert.AreEqual("", message.OptionalString); + + Assert.Throws(() => message.OptionalString = null); + } + + [Test] + public void Clone() + { + var original = new TestProto3Optional { OptionalInt64 = 0L }; + + var clone = original.Clone(); + Assert.False(clone.HasOptionalInt32); + Assert.AreEqual(0, clone.OptionalInt32); + Assert.True(clone.HasOptionalInt64); + Assert.AreEqual(0L, clone.OptionalInt64); + } + + [Test] + public void Serialization_NotSet() + { + var stream = new MemoryStream(); + var message = new TestProto3Optional(); + message.WriteTo(stream); + Assert.AreEqual(0, stream.Length); + } + + [Test] + public void Serialization_SetToDefault() + { + var stream = new MemoryStream(); + var message = new TestProto3Optional { OptionalInt32 = 0 }; + message.WriteTo(stream); + Assert.AreEqual(2, stream.Length); // Tag and value + } + + [Test] + public void Serialization_Roundtrip() + { + var original = new TestProto3Optional { OptionalInt64 = 0L, OptionalFixed32 = 5U }; + var stream = new MemoryStream(); + original.WriteTo(stream); + stream.Position = 0; + var deserialized = TestProto3Optional.Parser.ParseFrom(stream); + + Assert.AreEqual(0, deserialized.OptionalInt32); + Assert.IsFalse(deserialized.HasOptionalInt32); + + Assert.AreEqual(0L, deserialized.OptionalInt64); + Assert.IsTrue(deserialized.HasOptionalInt64); + + Assert.AreEqual(5U, deserialized.OptionalFixed32); + Assert.IsTrue(deserialized.HasOptionalFixed32); + } + + [Test] + public void Equality_IgnoresPresence() + { + var message1 = new TestProto3Optional { OptionalInt32 = 0 }; + var message2 = new TestProto3Optional(); + + Assert.IsTrue(message1.Equals(message2)); + message1.ClearOptionalInt32(); + } + + [Test] + public void MixedFields() + { + var descriptor = MixedRegularAndOptional.Descriptor; + Assert.AreEqual(1, descriptor.Oneofs.Count); + Assert.AreEqual(0, descriptor.RealOneofCount); + Assert.True(descriptor.Oneofs[0].IsSynthetic); + } + } +} diff --git a/csharp/src/Google.Protobuf.Test/ReadOnlySequenceFactory.cs b/csharp/src/Google.Protobuf.Test/ReadOnlySequenceFactory.cs new file mode 100644 index 000000000000..f0248ac3c34f --- /dev/null +++ b/csharp/src/Google.Protobuf.Test/ReadOnlySequenceFactory.cs @@ -0,0 +1,139 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Google.Protobuf +{ + internal static class ReadOnlySequenceFactory + { + /// + /// Create a sequence from the specified data. The data will be divided up into segments in the sequence. + /// + public static ReadOnlySequence CreateWithContent(byte[] data, int segmentSize = 1, bool addEmptySegmentDelimiters = true) + { + var segments = new List(); + + if (addEmptySegmentDelimiters) + { + segments.Add(new byte[0]); + } + + var currentIndex = 0; + while (currentIndex < data.Length) + { + var segment = new List(); + while (segment.Count < segmentSize && currentIndex < data.Length) + { + segment.Add(data[currentIndex++]); + } + segments.Add(segment.ToArray()); + + if (addEmptySegmentDelimiters) + { + segments.Add(new byte[0]); + } + } + + return CreateSegments(segments.ToArray()); + } + + /// + /// Originally from corefx, and has been contributed to Protobuf + /// https://github.com/dotnet/corefx/blob/e99ec129cfd594d53f4390bf97d1d736cff6f860/src/System.Memory/tests/ReadOnlyBuffer/ReadOnlySequenceFactory.byte.cs + /// + private static ReadOnlySequence CreateSegments(params byte[][] inputs) + { + if (inputs == null || inputs.Length == 0) + { + throw new InvalidOperationException(); + } + + int i = 0; + + BufferSegment last = null; + BufferSegment first = null; + + do + { + byte[] s = inputs[i]; + int length = s.Length; + int dataOffset = length; + var chars = new byte[length * 2]; + + for (int j = 0; j < length; j++) + { + chars[dataOffset + j] = s[j]; + } + + // Create a segment that has offset relative to the OwnedMemory and OwnedMemory itself has offset relative to array + var memory = new Memory(chars).Slice(length, length); + + if (first == null) + { + first = new BufferSegment(memory); + last = first; + } + else + { + last = last.Append(memory); + } + i++; + } while (i < inputs.Length); + + return new ReadOnlySequence(first, 0, last, last.Memory.Length); + } + + private class BufferSegment : ReadOnlySequenceSegment + { + public BufferSegment(Memory memory) + { + Memory = memory; + } + + public BufferSegment Append(Memory memory) + { + var segment = new BufferSegment(memory) + { + RunningIndex = RunningIndex + Memory.Length + }; + Next = segment; + return segment; + } + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs b/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs new file mode 100644 index 000000000000..f2d9a2d4e2e4 --- /dev/null +++ b/csharp/src/Google.Protobuf.Test/RefStructCompatibilityTest.cs @@ -0,0 +1,119 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using NUnit.Framework; +using System.Diagnostics; +using System; +using System.Reflection; +using System.IO; + +namespace Google.Protobuf +{ + public class RefStructCompatibilityTest + { + /// + /// Checks that the generated code can be compiler with an old C# compiler. + /// The reason why this test is needed is that even though dotnet SDK projects allow to set LangVersion, + /// this setting doesn't accurately simulate compilation with an actual old pre-roslyn C# compiler. + /// For instance, the "ref struct" types are only supported by C# 7.2 and higher, but even if + /// LangVersion is set low, the roslyn compiler still understands the concept of ref struct + /// and silently accepts them. Therefore we try to build the generated code with an actual old C# compiler + /// to be able to catch these sort of compatibility problems. + /// + [Test] + public void GeneratedCodeCompilesWithOldCsharpCompiler() + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + // This tests needs old C# compiler which is only available on Windows. Skipping it on all other platforms. + return; + } + + var currentAssemblyDir = Path.GetDirectoryName(typeof(RefStructCompatibilityTest).GetTypeInfo().Assembly.Location); + var testProtosProjectDir = Path.GetFullPath(Path.Combine(currentAssemblyDir, "..", "..", "..", "..", "Google.Protobuf.Test.TestProtos")); + var testProtosOutputDir = (currentAssemblyDir.Contains("bin/Debug/") || currentAssemblyDir.Contains("bin\\Debug\\")) ? "bin\\Debug\\net45" : "bin\\Release\\net45"; + + // If "ref struct" types are used in the generated code, compilation with an old compiler will fail with the following error: + // "XYZ is obsolete: 'Types with embedded references are not supported in this version of your compiler.'" + // We build the code with GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE to avoid the use of ref struct in the generated code. + var compatibilityFlag = "-define:GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE"; + var sources = "*.cs"; // the generated sources from the TestProtos project + var args = $"-langversion:3 -target:library {compatibilityFlag} -reference:{testProtosOutputDir}\\Google.Protobuf.dll -out:{testProtosOutputDir}\\TestProtos.RefStructCompatibilityTest.OldCompiler.dll {sources}"; + RunOldCsharpCompilerAndCheckSuccess(args, testProtosProjectDir); + } + + /// + /// Invoke an old C# compiler in a subprocess and check it finished successful. + /// + /// + /// + private void RunOldCsharpCompilerAndCheckSuccess(string args, string workingDirectory) + { + using (var process = new Process()) + { + // Get the path to the old C# 5 compiler from .NET framework. This approach is not 100% reliable, but works on most machines. + // Alternative way of getting the framework path is System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() + // but it only works with the net45 target. + var oldCsharpCompilerPath = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), "Microsoft.NET", "Framework", "v4.0.30319", "csc.exe"); + process.StartInfo.FileName = oldCsharpCompilerPath; + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.RedirectStandardError = true; + process.StartInfo.UseShellExecute = false; + process.StartInfo.Arguments = args; + process.StartInfo.WorkingDirectory = workingDirectory; + + process.OutputDataReceived += (sender, e) => + { + if (e.Data != null) + { + Console.WriteLine(e.Data); + } + }; + process.ErrorDataReceived += (sender, e) => + { + if (e.Data != null) + { + Console.WriteLine(e.Data); + } + }; + + process.Start(); + + process.BeginErrorReadLine(); + process.BeginOutputReadLine(); + + process.WaitForExit(); + Assert.AreEqual(0, process.ExitCode); + } + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs index bfee5f5d439b..68b9bd35074f 100644 --- a/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Reflection/CustomOptionsTest.cs @@ -1,4 +1,4 @@ -#region Copyright notice and license +#region Copyright notice and license // Protocol Buffers - Google's data interchange format // Copyright 2017 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ @@ -71,25 +71,49 @@ OptionFetcher EnumFetcher(CustomOptions options) }; } + [Test] + public void BuiltinOptionsCanBeRetrieved() + { + // non-custom options (that are not extensions but regular fields) can only be accessed via descriptor.Options + var fileOptions = UnittestProto3Reflection.Descriptor.GetOptions(); + Assert.AreEqual("Google.Protobuf.TestProtos", fileOptions.CsharpNamespace); + } + + [Test] + public void OptionPresenceCanBeDetected() + { + // case 1: the descriptor has no options at all so the options message is not present + Assert.IsNull(TestAllTypes.Descriptor.GetOptions()); + + // case 2: the descriptor has some options, but not the one we're looking for + // HasExtension will be false and GetExtension returns extension's default value + Assert.IsFalse(UnittestProto3Reflection.Descriptor.GetOptions().HasExtension(FileOpt1)); + Assert.AreEqual(0, UnittestProto3Reflection.Descriptor.GetOptions().GetExtension(FileOpt1)); + + // case 3: option is present + Assert.IsTrue(UnittestCustomOptionsProto3Reflection.Descriptor.GetOptions().HasExtension(FileOpt1)); + Assert.AreEqual(9876543210UL, UnittestCustomOptionsProto3Reflection.Descriptor.GetOptions().GetExtension(FileOpt1)); + } + [Test] public void ScalarOptions() { var d = CustomOptionOtherValues.Descriptor; - var options = d.CustomOptions; - AssertOption(-100, options.TryGetInt32, Int32Opt, d.GetOption); - AssertOption(12.3456789f, options.TryGetFloat, FloatOpt, d.GetOption); - AssertOption(1.234567890123456789d, options.TryGetDouble, DoubleOpt, d.GetOption); - AssertOption("Hello, \"World\"", options.TryGetString, StringOpt, d.GetOption); - AssertOption(ByteString.CopyFromUtf8("Hello\0World"), options.TryGetBytes, BytesOpt, d.GetOption); - AssertOption(TestEnumType.TestOptionEnumType2, EnumFetcher(options), EnumOpt, d.GetOption); + var customOptions = d.CustomOptions; + AssertOption(-100, customOptions.TryGetInt32, Int32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(12.3456789f, customOptions.TryGetFloat, FloatOpt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(1.234567890123456789d, customOptions.TryGetDouble, DoubleOpt, d.GetOption, d.GetOptions().GetExtension); + AssertOption("Hello, \"World\"", customOptions.TryGetString, StringOpt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(ByteString.CopyFromUtf8("Hello\0World"), customOptions.TryGetBytes, BytesOpt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(TestEnumType.TestOptionEnumType2, EnumFetcher(customOptions), EnumOpt, d.GetOption, d.GetOptions().GetExtension); } [Test] public void MessageOptions() { var d = VariousComplexOptions.Descriptor; - var options = d.CustomOptions; - AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, options.TryGetMessage, ComplexOpt1, d.GetOption); + var customOptions = d.CustomOptions; + AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, customOptions.TryGetMessage, ComplexOpt1, d.GetOption, d.GetOptions().GetExtension); AssertOption(new ComplexOptionType2 { Baz = 987, @@ -97,85 +121,84 @@ public void MessageOptions() Fred = new ComplexOptionType4 { Waldo = 321 }, Barney = { new ComplexOptionType4 { Waldo = 101 }, new ComplexOptionType4 { Waldo = 212 } } }, - options.TryGetMessage, ComplexOpt2, d.GetOption); - AssertOption(new ComplexOptionType3 { Qux = 9 }, options.TryGetMessage, ComplexOpt3, d.GetOption); + customOptions.TryGetMessage, ComplexOpt2, d.GetOption, d.GetOptions().GetExtension); + AssertOption(new ComplexOptionType3 { Qux = 9 }, customOptions.TryGetMessage, ComplexOpt3, d.GetOption, d.GetOptions().GetExtension); } [Test] public void OptionLocations() { - var fileOptions = UnittestCustomOptionsProto3Reflection.Descriptor.CustomOptions; - AssertOption(9876543210UL, fileOptions.TryGetUInt64, FileOpt1, UnittestCustomOptionsProto3Reflection.Descriptor.GetOption); + var fileDescriptor = UnittestCustomOptionsProto3Reflection.Descriptor; + AssertOption(9876543210UL, fileDescriptor.CustomOptions.TryGetUInt64, FileOpt1, fileDescriptor.GetOption, fileDescriptor.GetOptions().GetExtension); - var messageOptions = TestMessageWithCustomOptions.Descriptor.CustomOptions; - AssertOption(-56, messageOptions.TryGetInt32, MessageOpt1, TestMessageWithCustomOptions.Descriptor.GetOption); + var messageDescriptor = TestMessageWithCustomOptions.Descriptor; + AssertOption(-56, messageDescriptor.CustomOptions.TryGetInt32, MessageOpt1, messageDescriptor.GetOption, messageDescriptor.GetOptions().GetExtension); - var fieldOptions = TestMessageWithCustomOptions.Descriptor.Fields["field1"].CustomOptions; - AssertOption(8765432109UL, fieldOptions.TryGetFixed64, FieldOpt1, TestMessageWithCustomOptions.Descriptor.Fields["field1"].GetOption); + var fieldDescriptor = TestMessageWithCustomOptions.Descriptor.Fields["field1"]; + AssertOption(8765432109UL, fieldDescriptor.CustomOptions.TryGetFixed64, FieldOpt1, fieldDescriptor.GetOption, fieldDescriptor.GetOptions().GetExtension); - var oneofOptions = TestMessageWithCustomOptions.Descriptor.Oneofs[0].CustomOptions; - AssertOption(-99, oneofOptions.TryGetInt32, OneofOpt1, TestMessageWithCustomOptions.Descriptor.Oneofs[0].GetOption); + var oneofDescriptor = TestMessageWithCustomOptions.Descriptor.Oneofs[0]; + AssertOption(-99, oneofDescriptor.CustomOptions.TryGetInt32, OneofOpt1, oneofDescriptor.GetOption, oneofDescriptor.GetOptions().GetExtension); - var enumOptions = TestMessageWithCustomOptions.Descriptor.EnumTypes[0].CustomOptions; - AssertOption(-789, enumOptions.TryGetSFixed32, EnumOpt1, TestMessageWithCustomOptions.Descriptor.EnumTypes[0].GetOption); + var enumDescriptor = TestMessageWithCustomOptions.Descriptor.EnumTypes[0]; + AssertOption(-789, enumDescriptor.CustomOptions.TryGetSFixed32, EnumOpt1, enumDescriptor.GetOption, enumDescriptor.GetOptions().GetExtension); - var enumValueOptions = TestMessageWithCustomOptions.Descriptor.EnumTypes[0].FindValueByNumber(2).CustomOptions; - AssertOption(123, enumValueOptions.TryGetInt32, EnumValueOpt1, TestMessageWithCustomOptions.Descriptor.EnumTypes[0].FindValueByNumber(2).GetOption); + var enumValueDescriptor = TestMessageWithCustomOptions.Descriptor.EnumTypes[0].FindValueByNumber(2); + AssertOption(123, enumValueDescriptor.CustomOptions.TryGetInt32, EnumValueOpt1, enumValueDescriptor.GetOption, enumValueDescriptor.GetOptions().GetExtension); - var service = UnittestCustomOptionsProto3Reflection.Descriptor.Services + var serviceDescriptor = UnittestCustomOptionsProto3Reflection.Descriptor.Services .Single(s => s.Name == "TestServiceWithCustomOptions"); - var serviceOptions = service.CustomOptions; - AssertOption(-9876543210, serviceOptions.TryGetSInt64, ServiceOpt1, service.GetOption); + AssertOption(-9876543210, serviceDescriptor.CustomOptions.TryGetSInt64, ServiceOpt1, serviceDescriptor.GetOption, serviceDescriptor.GetOptions().GetExtension); - var methodOptions = service.Methods[0].CustomOptions; - AssertOption(UnitTest.Issues.TestProtos.MethodOpt1.Val2, EnumFetcher(methodOptions), UnittestCustomOptionsProto3Extensions.MethodOpt1, service.Methods[0].GetOption); + var methodDescriptor = serviceDescriptor.Methods[0]; + AssertOption(UnitTest.Issues.TestProtos.MethodOpt1.Val2, EnumFetcher(methodDescriptor.CustomOptions), UnittestCustomOptionsProto3Extensions.MethodOpt1, methodDescriptor.GetOption, methodDescriptor.GetOptions().GetExtension); } [Test] public void MinValues() { var d = CustomOptionMinIntegerValues.Descriptor; - var options = d.CustomOptions; - AssertOption(false, options.TryGetBool, BoolOpt, d.GetOption); - AssertOption(int.MinValue, options.TryGetInt32, Int32Opt, d.GetOption); - AssertOption(long.MinValue, options.TryGetInt64, Int64Opt, d.GetOption); - AssertOption(uint.MinValue, options.TryGetUInt32, Uint32Opt, d.GetOption); - AssertOption(ulong.MinValue, options.TryGetUInt64, Uint64Opt, d.GetOption); - AssertOption(int.MinValue, options.TryGetSInt32, Sint32Opt, d.GetOption); - AssertOption(long.MinValue, options.TryGetSInt64, Sint64Opt, d.GetOption); - AssertOption(uint.MinValue, options.TryGetUInt32, Fixed32Opt, d.GetOption); - AssertOption(ulong.MinValue, options.TryGetUInt64, Fixed64Opt, d.GetOption); - AssertOption(int.MinValue, options.TryGetInt32, Sfixed32Opt, d.GetOption); - AssertOption(long.MinValue, options.TryGetInt64, Sfixed64Opt, d.GetOption); + var customOptions = d.CustomOptions; + AssertOption(false, customOptions.TryGetBool, BoolOpt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(int.MinValue, customOptions.TryGetInt32, Int32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(long.MinValue, customOptions.TryGetInt64, Int64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(uint.MinValue, customOptions.TryGetUInt32, Uint32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(ulong.MinValue, customOptions.TryGetUInt64, Uint64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(int.MinValue, customOptions.TryGetSInt32, Sint32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(long.MinValue, customOptions.TryGetSInt64, Sint64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(uint.MinValue, customOptions.TryGetUInt32, Fixed32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(ulong.MinValue, customOptions.TryGetUInt64, Fixed64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(int.MinValue, customOptions.TryGetInt32, Sfixed32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(long.MinValue, customOptions.TryGetInt64, Sfixed64Opt, d.GetOption, d.GetOptions().GetExtension); } [Test] public void MaxValues() { var d = CustomOptionMaxIntegerValues.Descriptor; - var options = d.CustomOptions; - AssertOption(true, options.TryGetBool, BoolOpt, d.GetOption); - AssertOption(int.MaxValue, options.TryGetInt32, Int32Opt, d.GetOption); - AssertOption(long.MaxValue, options.TryGetInt64, Int64Opt, d.GetOption); - AssertOption(uint.MaxValue, options.TryGetUInt32, Uint32Opt, d.GetOption); - AssertOption(ulong.MaxValue, options.TryGetUInt64, Uint64Opt, d.GetOption); - AssertOption(int.MaxValue, options.TryGetSInt32, Sint32Opt, d.GetOption); - AssertOption(long.MaxValue, options.TryGetSInt64, Sint64Opt, d.GetOption); - AssertOption(uint.MaxValue, options.TryGetFixed32, Fixed32Opt, d.GetOption); - AssertOption(ulong.MaxValue, options.TryGetFixed64, Fixed64Opt, d.GetOption); - AssertOption(int.MaxValue, options.TryGetSFixed32, Sfixed32Opt, d.GetOption); - AssertOption(long.MaxValue, options.TryGetSFixed64, Sfixed64Opt, d.GetOption); + var customOptions = d.CustomOptions; + AssertOption(true, customOptions.TryGetBool, BoolOpt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(int.MaxValue, customOptions.TryGetInt32, Int32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(long.MaxValue, customOptions.TryGetInt64, Int64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(uint.MaxValue, customOptions.TryGetUInt32, Uint32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(ulong.MaxValue, customOptions.TryGetUInt64, Uint64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(int.MaxValue, customOptions.TryGetSInt32, Sint32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(long.MaxValue, customOptions.TryGetSInt64, Sint64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(uint.MaxValue, customOptions.TryGetFixed32, Fixed32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(ulong.MaxValue, customOptions.TryGetFixed64, Fixed64Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(int.MaxValue, customOptions.TryGetSFixed32, Sfixed32Opt, d.GetOption, d.GetOptions().GetExtension); + AssertOption(long.MaxValue, customOptions.TryGetSFixed64, Sfixed64Opt, d.GetOption, d.GetOptions().GetExtension); } [Test] public void AggregateOptions() { // Just two examples - var messageOptions = AggregateMessage.Descriptor.CustomOptions; - AssertOption(new Aggregate { I = 101, S = "MessageAnnotation" }, messageOptions.TryGetMessage, Msgopt, AggregateMessage.Descriptor.GetOption); + var messageDescriptor = AggregateMessage.Descriptor; + AssertOption(new Aggregate { I = 101, S = "MessageAnnotation" }, messageDescriptor.CustomOptions.TryGetMessage, Msgopt, messageDescriptor.GetOption, messageDescriptor.GetOptions().GetExtension); - var fieldOptions = AggregateMessage.Descriptor.Fields["fieldname"].CustomOptions; - AssertOption(new Aggregate { S = "FieldAnnotation" }, fieldOptions.TryGetMessage, Fieldopt, AggregateMessage.Descriptor.Fields["fieldname"].GetOption); + var fieldDescriptor = messageDescriptor.Fields["fieldname"]; + AssertOption(new Aggregate { S = "FieldAnnotation" }, fieldDescriptor.CustomOptions.TryGetMessage, Fieldopt, fieldDescriptor.GetOption, fieldDescriptor.GetOptions().GetExtension); } [Test] @@ -199,16 +222,41 @@ public void MultipleImportOfSameFileWithExtension() var descriptor = UnittestIssue6936CReflection.Descriptor; var foo = Foo.Descriptor; var bar = Bar.Descriptor; - AssertOption("foo", foo.CustomOptions.TryGetString, UnittestIssue6936AExtensions.Opt, foo.GetOption); - AssertOption("bar", bar.CustomOptions.TryGetString, UnittestIssue6936AExtensions.Opt, bar.GetOption); + AssertOption("foo", foo.CustomOptions.TryGetString, UnittestIssue6936AExtensions.Opt, foo.GetOption, foo.GetOptions().GetExtension); + AssertOption("bar", bar.CustomOptions.TryGetString, UnittestIssue6936AExtensions.Opt, bar.GetOption, bar.GetOptions().GetExtension); } - private void AssertOption(T expected, OptionFetcher fetcher, Extension extension, Func, T> descriptorOptionFetcher) where D : IExtendableMessage + [Test] + public void SelfReferentialOptions() { - T customOptionsValue; - T extensionValue = descriptorOptionFetcher(extension); - Assert.IsTrue(fetcher(extension.FieldNumber, out customOptionsValue)); + // Custom field option used in definition of the custom option's message. + var fooField = UnitTest.Issues.TestProtos.SelfreferentialOptions.FooOptions.Descriptor.FindFieldByName("foo"); + var fooFieldFooExtensionValue = fooField.GetOptions().GetExtension(UnitTest.Issues.TestProtos.SelfreferentialOptions.UnittestSelfreferentialOptionsExtensions.FooOptions); + Assert.AreEqual(1234, fooFieldFooExtensionValue.Foo); + + // Custom field option used on the definition of that field option. + var fileDescriptor = UnitTest.Issues.TestProtos.SelfreferentialOptions.UnittestSelfreferentialOptionsReflection.Descriptor; + var barOptionsField = fileDescriptor.Extensions.UnorderedExtensions.Single(field => field.Name == "bar_options"); + var barExtensionValue = barOptionsField.GetOptions().GetExtension(UnitTest.Issues.TestProtos.SelfreferentialOptions.UnittestSelfreferentialOptionsExtensions.BarOptions); + Assert.AreEqual(1234, barExtensionValue); + + // Custom field option used in definition of the extension message. + var intOptField = UnitTest.Issues.TestProtos.SelfreferentialOptions.FooOptions.Descriptor.FindFieldByName("int_opt"); + var intOptFieldFooExtensionValue = intOptField.GetOptions().GetExtension(UnitTest.Issues.TestProtos.SelfreferentialOptions.UnittestSelfreferentialOptionsExtensions.FooOptions); + Assert.AreEqual(1, intOptFieldFooExtensionValue.IntOpt); + Assert.AreEqual(2, intOptFieldFooExtensionValue.GetExtension(UnitTest.Issues.TestProtos.SelfreferentialOptions.UnittestSelfreferentialOptionsExtensions.FooIntOpt)); + Assert.AreEqual(3, intOptFieldFooExtensionValue.GetExtension(UnitTest.Issues.TestProtos.SelfreferentialOptions.UnittestSelfreferentialOptionsExtensions.FooFooOpt).IntOpt); + } + + private void AssertOption(T expected, OptionFetcher customOptionFetcher, Extension extension, Func, T> getOptionFetcher, Func, T> extensionFetcher) where D : IExtendableMessage + { + Assert.IsTrue(customOptionFetcher(extension.FieldNumber, out T customOptionsValue)); Assert.AreEqual(expected, customOptionsValue); + + T getOptionValue = getOptionFetcher(extension); + Assert.AreEqual(expected, getOptionValue); + + T extensionValue = extensionFetcher(extension); Assert.AreEqual(expected, extensionValue); } } diff --git a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs index 482db535e259..ebb8394d2355 100644 --- a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs +++ b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs @@ -32,6 +32,7 @@ using Google.Protobuf.TestProtos; using NUnit.Framework; +using ProtobufUnittest; using System; using System.Collections.Generic; using System.Linq; @@ -247,6 +248,7 @@ public void FieldDescriptor_BuildFromByteStrings() FieldDescriptor enumField = testAllTypesDescriptor.FindDescriptor("single_nested_enum"); FieldDescriptor foreignMessageField = testAllTypesDescriptor.FindDescriptor("single_foreign_message"); FieldDescriptor importMessageField = testAllTypesDescriptor.FindDescriptor("single_import_message"); + FieldDescriptor fieldInOneof = testAllTypesDescriptor.FindDescriptor("oneof_string"); Assert.AreEqual("single_int32", primitiveField.Name); Assert.AreEqual("protobuf_unittest3.TestAllTypes.single_int32", @@ -268,6 +270,10 @@ public void FieldDescriptor_BuildFromByteStrings() Assert.AreEqual("single_import_message", importMessageField.Name); Assert.AreEqual(FieldType.Message, importMessageField.FieldType); Assert.AreEqual(importMessageDescriptor, importMessageField.MessageType); + + // For a field in a regular onoef, ContainingOneof and RealContainingOneof should be the same. + Assert.AreEqual("oneof_field", fieldInOneof.ContainingOneof.Name); + Assert.AreSame(fieldInOneof.ContainingOneof, fieldInOneof.RealContainingOneof); } [Test] @@ -318,6 +324,7 @@ public void EnumDescriptor() public void OneofDescriptor() { OneofDescriptor descriptor = TestAllTypes.Descriptor.FindDescriptor("oneof_field"); + Assert.IsFalse(descriptor.IsSynthetic); Assert.AreEqual("oneof_field", descriptor.Name); Assert.AreEqual("protobuf_unittest3.TestAllTypes.oneof_field", descriptor.FullName); @@ -383,5 +390,48 @@ public void DescriptorImportingExtensionsFromOldCodeGen() var importingDescriptor = TestProtos.OldGenerator.OldExtensions1Reflection.Descriptor; Assert.NotNull(importingDescriptor); } + + [Test] + public void Proto3OptionalDescriptors() + { + var descriptor = TestProto3Optional.Descriptor; + var field = descriptor.Fields[TestProto3Optional.OptionalInt32FieldNumber]; + Assert.NotNull(field.ContainingOneof); + Assert.IsTrue(field.ContainingOneof.IsSynthetic); + Assert.Null(field.RealContainingOneof); + } + + + [Test] + public void SyntheticOneofReflection() + { + // Expect every oneof in TestProto3Optional to be synthetic + var proto3OptionalDescriptor = TestProto3Optional.Descriptor; + Assert.AreEqual(0, proto3OptionalDescriptor.RealOneofCount); + foreach (var oneof in proto3OptionalDescriptor.Oneofs) + { + Assert.True(oneof.IsSynthetic); + } + + // Expect no oneof in the original proto3 unit test file to be synthetic. + foreach (var descriptor in ProtobufTestMessages.Proto3.TestMessagesProto3Reflection.Descriptor.MessageTypes) + { + Assert.AreEqual(descriptor.Oneofs.Count, descriptor.RealOneofCount); + foreach (var oneof in descriptor.Oneofs) + { + Assert.False(oneof.IsSynthetic); + } + } + + // Expect no oneof in the original proto2 unit test file to be synthetic. + foreach (var descriptor in ProtobufTestMessages.Proto2.TestMessagesProto2Reflection.Descriptor.MessageTypes) + { + Assert.AreEqual(descriptor.Oneofs.Count, descriptor.RealOneofCount); + foreach (var oneof in descriptor.Oneofs) + { + Assert.False(oneof.IsSynthetic); + } + } + } } } diff --git a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs index 9651ec30d8c5..b4dcdabdc751 100644 --- a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs +++ b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs @@ -38,6 +38,7 @@ using System.Collections.Generic; using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions; +using ProtobufUnittest; namespace Google.Protobuf.Reflection { @@ -97,7 +98,48 @@ public void GetValue_IncorrectType() } [Test] - public void HasValue_Proto3() + public void HasValue_Proto3_Message() + { + var message = new TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[TestProtos.TestAllTypes.SingleForeignMessageFieldNumber].Accessor; + Assert.False(accessor.HasValue(message)); + message.SingleForeignMessage = new ForeignMessage(); + Assert.True(accessor.HasValue(message)); + message.SingleForeignMessage = null; + Assert.False(accessor.HasValue(message)); + } + + [Test] + public void HasValue_Proto3_Oneof() + { + TestAllTypes message = new TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[TestProtos.TestAllTypes.OneofStringFieldNumber].Accessor; + Assert.False(accessor.HasValue(message)); + // Even though it's the default value, we still have a value. + message.OneofString = ""; + Assert.True(accessor.HasValue(message)); + message.OneofString = "hello"; + Assert.True(accessor.HasValue(message)); + message.OneofUint32 = 10; + Assert.False(accessor.HasValue(message)); + } + + [Test] + public void HasValue_Proto3_Primitive_Optional() + { + var message = new TestProto3Optional(); + var accessor = ((IMessage) message).Descriptor.Fields[TestProto3Optional.OptionalInt64FieldNumber].Accessor; + Assert.IsFalse(accessor.HasValue(message)); + message.OptionalInt64 = 5L; + Assert.IsTrue(accessor.HasValue(message)); + message.ClearOptionalInt64(); + Assert.IsFalse(accessor.HasValue(message)); + message.OptionalInt64 = 0L; + Assert.IsTrue(accessor.HasValue(message)); + } + + [Test] + public void HasValue_Proto3_Primitive_NotOptional() { IMessage message = SampleMessages.CreateFullTestAllTypes(); var fields = message.Descriptor.Fields; @@ -105,19 +147,61 @@ public void HasValue_Proto3() } [Test] - public void HasValue() + public void HasValue_Proto3_Repeated() { - IMessage message = new Proto2.TestAllTypes(); - var fields = message.Descriptor.Fields; - var accessor = fields[Proto2.TestAllTypes.OptionalBoolFieldNumber].Accessor; + var message = new TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[TestProtos.TestAllTypes.RepeatedBoolFieldNumber].Accessor; + Assert.Throws(() => accessor.HasValue(message)); + } - Assert.False(accessor.HasValue(message)); + [Test] + public void HasValue_Proto2_Primitive() + { + var message = new Proto2.TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[Proto2.TestAllTypes.OptionalInt64FieldNumber].Accessor; + + Assert.IsFalse(accessor.HasValue(message)); + message.OptionalInt64 = 5L; + Assert.IsTrue(accessor.HasValue(message)); + message.ClearOptionalInt64(); + Assert.IsFalse(accessor.HasValue(message)); + message.OptionalInt64 = 0L; + Assert.IsTrue(accessor.HasValue(message)); + } - accessor.SetValue(message, true); - Assert.True(accessor.HasValue(message)); + [Test] + public void HasValue_Proto2_Message() + { + var message = new Proto2.TestAllTypes(); + var field = ((IMessage) message).Descriptor.Fields[Proto2.TestAllTypes.OptionalForeignMessageFieldNumber]; + Assert.False(field.Accessor.HasValue(message)); + message.OptionalForeignMessage = new Proto2.ForeignMessage(); + Assert.True(field.Accessor.HasValue(message)); + message.OptionalForeignMessage = null; + Assert.False(field.Accessor.HasValue(message)); + } - accessor.Clear(message); + [Test] + public void HasValue_Proto2_Oneof() + { + var message = new Proto2.TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[Proto2.TestAllTypes.OneofStringFieldNumber].Accessor; Assert.False(accessor.HasValue(message)); + // Even though it's the default value, we still have a value. + message.OneofString = ""; + Assert.True(accessor.HasValue(message)); + message.OneofString = "hello"; + Assert.True(accessor.HasValue(message)); + message.OneofUint32 = 10; + Assert.False(accessor.HasValue(message)); + } + + [Test] + public void HasValue_Proto2_Repeated() + { + var message = new Proto2.TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[Proto2.TestAllTypes.RepeatedBoolFieldNumber].Accessor; + Assert.Throws(() => accessor.HasValue(message)); } [Test] @@ -225,6 +309,63 @@ public void Clear() Assert.AreEqual(0, mapMessage.MapStringString.Count); } + [Test] + public void Clear_Proto3Optional() + { + TestProto3Optional message = new TestProto3Optional + { + OptionalInt32 = 0, + OptionalNestedMessage = new TestProto3Optional.Types.NestedMessage() + }; + var primitiveField = TestProto3Optional.Descriptor.Fields[TestProto3Optional.OptionalInt32FieldNumber]; + var messageField = TestProto3Optional.Descriptor.Fields[TestProto3Optional.OptionalNestedMessageFieldNumber]; + + Assert.True(message.HasOptionalInt32); + Assert.NotNull(message.OptionalNestedMessage); + + primitiveField.Accessor.Clear(message); + messageField.Accessor.Clear(message); + + Assert.False(message.HasOptionalInt32); + Assert.Null(message.OptionalNestedMessage); + } + + [Test] + public void Clear_Proto3_Oneof() + { + var message = new TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[TestProtos.TestAllTypes.OneofUint32FieldNumber].Accessor; + + // The field accessor Clear method only affects a oneof if the current case is the one being cleared. + message.OneofString = "hello"; + Assert.AreEqual(TestProtos.TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase); + accessor.Clear(message); + Assert.AreEqual(TestProtos.TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase); + + message.OneofUint32 = 100; + Assert.AreEqual(TestProtos.TestAllTypes.OneofFieldOneofCase.OneofUint32, message.OneofFieldCase); + accessor.Clear(message); + Assert.AreEqual(TestProtos.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase); + } + + [Test] + public void Clear_Proto2_Oneof() + { + var message = new Proto2.TestAllTypes(); + var accessor = ((IMessage) message).Descriptor.Fields[Proto2.TestAllTypes.OneofUint32FieldNumber].Accessor; + + // The field accessor Clear method only affects a oneof if the current case is the one being cleared. + message.OneofString = "hello"; + Assert.AreEqual(Proto2.TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase); + accessor.Clear(message); + Assert.AreEqual(Proto2.TestAllTypes.OneofFieldOneofCase.OneofString, message.OneofFieldCase); + + message.OneofUint32 = 100; + Assert.AreEqual(Proto2.TestAllTypes.OneofFieldOneofCase.OneofUint32, message.OneofFieldCase); + accessor.Clear(message); + Assert.AreEqual(Proto2.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase); + } + [Test] public void FieldDescriptor_ByName() { @@ -264,5 +405,32 @@ public void GetRepeatedExtensionValue() message.ClearExtension(RepeatedBoolExtension); Assert.IsNull(message.GetExtension(RepeatedBoolExtension)); } + + [Test] + public void HasPresence() + { + // Proto3 + var fields = TestProtos.TestAllTypes.Descriptor.Fields; + Assert.IsFalse(fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].HasPresence); + Assert.IsTrue(fields[TestProtos.TestAllTypes.OneofBytesFieldNumber].HasPresence); + Assert.IsTrue(fields[TestProtos.TestAllTypes.SingleForeignMessageFieldNumber].HasPresence); + Assert.IsFalse(fields[TestProtos.TestAllTypes.RepeatedBoolFieldNumber].HasPresence); + + fields = TestMap.Descriptor.Fields; + Assert.IsFalse(fields[TestMap.MapBoolBoolFieldNumber].HasPresence); + + fields = TestProto3Optional.Descriptor.Fields; + Assert.IsTrue(fields[TestProto3Optional.OptionalBoolFieldNumber].HasPresence); + + // Proto2 + fields = Proto2.TestAllTypes.Descriptor.Fields; + Assert.IsTrue(fields[Proto2.TestAllTypes.OptionalBoolFieldNumber].HasPresence); + Assert.IsTrue(fields[Proto2.TestAllTypes.OneofBytesFieldNumber].HasPresence); + Assert.IsTrue(fields[Proto2.TestAllTypes.OptionalForeignMessageFieldNumber].HasPresence); + Assert.IsFalse(fields[Proto2.TestAllTypes.RepeatedBoolFieldNumber].HasPresence); + + fields = Proto2.TestRequired.Descriptor.Fields; + Assert.IsTrue(fields[Proto2.TestRequired.AFieldNumber].HasPresence); + } } } diff --git a/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs b/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs index 886937d70620..15debc1b6c8e 100644 --- a/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs +++ b/csharp/src/Google.Protobuf.Test/UnknownFieldSetTest.cs @@ -161,10 +161,10 @@ public void TestDiscardUnknownFields(IMessage message) MessageParser discardingParser2 = retainingParser2.WithDiscardUnknownFields(true); // Test parse from byte[] - assertFull(retainingParser1.ParseFrom(data)); - assertFull(retainingParser2.ParseFrom(data)); - assertEmpty(discardingParser1.ParseFrom(data)); - assertEmpty(discardingParser2.ParseFrom(data)); + MessageParsingHelpers.AssertReadingMessage(retainingParser1, data, m => assertFull(m)); + MessageParsingHelpers.AssertReadingMessage(retainingParser2, data, m => assertFull(m)); + MessageParsingHelpers.AssertReadingMessage(discardingParser1, data, m => assertEmpty(m)); + MessageParsingHelpers.AssertReadingMessage(discardingParser2, data, m => assertEmpty(m)); // Test parse from byte[] with offset assertFull(retainingParser1.ParseFrom(data, 0, data.Length)); diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs index 4a425f79aa84..5b0e5e8fc1cb 100644 --- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs +++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs @@ -71,18 +71,42 @@ public void NonDefaultSingleValues() Uint64Field = 4 }; - var bytes = message.ToByteArray(); - var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes); - - Assert.AreEqual("x", parsed.StringField); - Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), parsed.BytesField); - Assert.AreEqual(true, parsed.BoolField); - Assert.AreEqual(12.5f, parsed.FloatField); - Assert.AreEqual(12.25d, parsed.DoubleField); - Assert.AreEqual(1, parsed.Int32Field); - Assert.AreEqual(2L, parsed.Int64Field); - Assert.AreEqual(3U, parsed.Uint32Field); - Assert.AreEqual(4UL, parsed.Uint64Field); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed => + { + Assert.AreEqual("x", parsed.StringField); + Assert.AreEqual(ByteString.CopyFrom(1, 2, 3), parsed.BytesField); + Assert.AreEqual(true, parsed.BoolField); + Assert.AreEqual(12.5f, parsed.FloatField); + Assert.AreEqual(12.25d, parsed.DoubleField); + Assert.AreEqual(1, parsed.Int32Field); + Assert.AreEqual(2L, parsed.Int64Field); + Assert.AreEqual(3U, parsed.Uint32Field); + Assert.AreEqual(4UL, parsed.Uint64Field); + }); + } + + [Test] + public void NegativeSingleValues() + { + var message = new TestWellKnownTypes + { + FloatField = -12.5f, + DoubleField = -12.25d, + Int32Field = -1, + Int64Field = -2 + }; + + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed => + { + Assert.AreEqual(-12.5f, parsed.FloatField); + Assert.AreEqual(-12.25d, parsed.DoubleField); + Assert.AreEqual(-1, parsed.Int32Field); + Assert.AreEqual(-2L, parsed.Int64Field); + }); } [Test] @@ -101,18 +125,20 @@ public void NonNullDefaultIsPreservedThroughSerialization() Uint64Field = 0 }; - var bytes = message.ToByteArray(); - var parsed = TestWellKnownTypes.Parser.ParseFrom(bytes); - - Assert.AreEqual("", parsed.StringField); - Assert.AreEqual(ByteString.Empty, parsed.BytesField); - Assert.AreEqual(false, parsed.BoolField); - Assert.AreEqual(0f, parsed.FloatField); - Assert.AreEqual(0d, parsed.DoubleField); - Assert.AreEqual(0, parsed.Int32Field); - Assert.AreEqual(0L, parsed.Int64Field); - Assert.AreEqual(0U, parsed.Uint32Field); - Assert.AreEqual(0UL, parsed.Uint64Field); + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(TestWellKnownTypes.Parser, message, parsed => + { + Assert.AreEqual("", parsed.StringField); + Assert.AreEqual(ByteString.Empty, parsed.BytesField); + Assert.AreEqual(false, parsed.BoolField); + Assert.AreEqual(0f, parsed.FloatField); + Assert.AreEqual(0d, parsed.DoubleField); + Assert.AreEqual(0, parsed.Int32Field); + Assert.AreEqual(0L, parsed.Int64Field); + Assert.AreEqual(0U, parsed.Uint32Field); + Assert.AreEqual(0UL, parsed.Uint64Field); + }); } [Test] @@ -140,12 +166,13 @@ public void RepeatedWrappersSerializeDeserialize() Uint32Field = { uint.MaxValue, uint.MinValue, 0U }, Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL }, }; - var bytes = message.ToByteArray(); - var parsed = RepeatedWellKnownTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, parsed); // Just to test a single value for sanity... Assert.AreEqual("Second", message.StringField[1]); + + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(RepeatedWellKnownTypes.Parser, message); } [Test] @@ -170,6 +197,8 @@ public void RepeatedWrappersBinaryFormat() var message = new RepeatedWellKnownTypes { Int32Field = { 5, 0 } }; var actualBytes = message.ToByteArray(); Assert.AreEqual(expectedBytes, actualBytes); + + MessageParsingHelpers.AssertWritingMessage(message); } [Test] @@ -194,12 +223,12 @@ public void MapWrappersSerializeDeserialize() Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } }, }; - var bytes = message.ToByteArray(); - var parsed = MapWellKnownTypes.Parser.ParseFrom(bytes); - - Assert.AreEqual(message, parsed); // Just to test a single value for sanity... Assert.AreEqual("Second", message.StringField[12]); + + MessageParsingHelpers.AssertWritingMessage(message); + + MessageParsingHelpers.AssertRoundtrip(MapWellKnownTypes.Parser, message); } [Test] @@ -288,10 +317,10 @@ public void Oneof() private void AssertOneofRoundTrip(OneofWellKnownTypes message) { // Normal roundtrip, but explicitly checking the case... - var bytes = message.ToByteArray(); - var parsed = OneofWellKnownTypes.Parser.ParseFrom(bytes); - Assert.AreEqual(message, parsed); - Assert.AreEqual(message.OneofFieldCase, parsed.OneofFieldCase); + MessageParsingHelpers.AssertRoundtrip(OneofWellKnownTypes.Parser, message, parsed => + { + Assert.AreEqual(message.OneofFieldCase, parsed.OneofFieldCase); + }); } [Test] @@ -406,8 +435,10 @@ public void UnknownFieldInWrapperInt32FastPath() Assert.AreEqual(8, stream.Length); // tag (1 byte) + length (1 byte) + message (6 bytes) stream.Position = 0; - var message = TestWellKnownTypes.Parser.ParseFrom(stream); - Assert.AreEqual(65536, message.Int32Field); + MessageParsingHelpers.AssertReadingMessage( + TestWellKnownTypes.Parser, + stream.ToArray(), + message => Assert.AreEqual(65536, message.Int32Field)); } [Test] @@ -431,8 +462,10 @@ public void UnknownFieldInWrapperInt32SlowPath() Assert.Less(stream.Length, 8); // tag (1 byte) + length (1 byte) + message stream.Position = 0; - var message = TestWellKnownTypes.Parser.ParseFrom(stream); - Assert.AreEqual(6, message.Int32Field); + MessageParsingHelpers.AssertReadingMessage( + TestWellKnownTypes.Parser, + stream.ToArray(), + message => Assert.AreEqual(6, message.Int32Field)); } [Test] @@ -456,8 +489,10 @@ public void UnknownFieldInWrapperInt64FastPath() Assert.AreEqual(13, stream.Length); // tag (1 byte) + length (1 byte) + message (11 bytes) stream.Position = 0; - var message = TestWellKnownTypes.Parser.ParseFrom(stream); - Assert.AreEqual(0xfffffffffffffL, message.Int64Field); + MessageParsingHelpers.AssertReadingMessage( + TestWellKnownTypes.Parser, + stream.ToArray(), + message => Assert.AreEqual(0xfffffffffffffL, message.Int64Field)); } [Test] @@ -481,8 +516,10 @@ public void UnknownFieldInWrapperInt64SlowPath() Assert.Less(stream.Length, 12); // tag (1 byte) + length (1 byte) + message stream.Position = 0; - var message = TestWellKnownTypes.Parser.ParseFrom(stream); - Assert.AreEqual(6L, message.Int64Field); + MessageParsingHelpers.AssertReadingMessage( + TestWellKnownTypes.Parser, + stream.ToArray(), + message => Assert.AreEqual(6L, message.Int64Field)); } [Test] diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index d00db7fdeb76..1569c1e8c81a 100644 Binary files a/csharp/src/Google.Protobuf.Test/testprotos.pb and b/csharp/src/Google.Protobuf.Test/testprotos.pb differ diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs index 3eb00e5bb5c7..7828658672fe 100644 --- a/csharp/src/Google.Protobuf/ByteString.cs +++ b/csharp/src/Google.Protobuf/ByteString.cs @@ -34,6 +34,8 @@ using System.Collections; using System.Collections.Generic; using System.IO; +using System.Runtime.InteropServices; +using System.Security; using System.Text; #if !NET35 using System.Threading; @@ -48,40 +50,36 @@ namespace Google.Protobuf /// /// Immutable array of bytes. /// + [SecuritySafeCritical] public sealed class ByteString : IEnumerable, IEquatable { private static readonly ByteString empty = new ByteString(new byte[0]); - private readonly byte[] bytes; + private readonly ReadOnlyMemory bytes; /// - /// Unsafe operations that can cause IO Failure and/or other catastrophic side-effects. + /// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. /// - internal static class Unsafe + internal static ByteString AttachBytes(ReadOnlyMemory bytes) { - /// - /// Constructs a new ByteString from the given byte array. The array is - /// *not* copied, and must not be modified after this constructor is called. - /// - internal static ByteString FromBytes(byte[] bytes) - { - return new ByteString(bytes); - } + return new ByteString(bytes); } /// - /// Internal use only. Ensure that the provided array is not mutated and belongs to this instance. + /// Internal use only. Ensure that the provided memory is not mutated and belongs to this instance. + /// This method encapsulates converting array to memory. Reduces need for SecuritySafeCritical + /// in .NET Framework. /// internal static ByteString AttachBytes(byte[] bytes) { - return new ByteString(bytes); + return AttachBytes(bytes.AsMemory()); } /// - /// Constructs a new ByteString from the given byte array. The array is + /// Constructs a new ByteString from the given memory. The memory is /// *not* copied, and must not be modified after this constructor is called. /// - private ByteString(byte[] bytes) + private ByteString(ReadOnlyMemory bytes) { this.bytes = bytes; } @@ -110,13 +108,23 @@ public bool IsEmpty get { return Length == 0; } } -#if GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY /// /// Provides read-only access to the data of this . /// No data is copied so this is the most efficient way of accessing. /// - public ReadOnlySpan Span => new ReadOnlySpan(bytes); -#endif + public ReadOnlySpan Span + { + get { return bytes.Span; } + } + + /// + /// Provides read-only access to the data of this . + /// No data is copied so this is the most efficient way of accessing. + /// + public ReadOnlyMemory Memory + { + get { return bytes; } + } /// /// Converts this into a byte array. @@ -125,7 +133,7 @@ public bool IsEmpty /// A byte array with the same data as this ByteString. public byte[] ToByteArray() { - return (byte[]) bytes.Clone(); + return bytes.ToArray(); } /// @@ -134,7 +142,16 @@ public byte[] ToByteArray() /// A base64 representation of this ByteString. public string ToBase64() { - return Convert.ToBase64String(bytes); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment)) + { + // Fast path. ByteString was created with an array, so pass the underlying array. + return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count); + } + else + { + // Slow path. BytesString is not an array. Convert memory and pass result to ToBase64String. + return Convert.ToBase64String(bytes.ToArray()); + } } /// @@ -160,7 +177,7 @@ public static ByteString FromStream(Stream stream) int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0; var memoryStream = new MemoryStream(capacity); stream.CopyTo(memoryStream); -#if NETSTANDARD1_0 || NETSTANDARD2_0 +#if NETSTANDARD1_1 || NETSTANDARD2_0 byte[] bytes = memoryStream.ToArray(); #else // Avoid an extra copy if we can. @@ -178,21 +195,10 @@ public static ByteString FromStream(Stream stream) /// The stream to copy into a ByteString. /// The cancellation token to use when reading from the stream, if any. /// A ByteString with content read from the given stream. - public async static Task FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) + public static Task FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { ProtoPreconditions.CheckNotNull(stream, nameof(stream)); - int capacity = stream.CanSeek ? checked((int) (stream.Length - stream.Position)) : 0; - var memoryStream = new MemoryStream(capacity); - // We have to specify the buffer size here, as there's no overload accepting the cancellation token - // alone. But it's documented to use 81920 by default if not specified. - await stream.CopyToAsync(memoryStream, 81920, cancellationToken); -#if NETSTANDARD1_0 || NETSTANDARD2_0 - byte[] bytes = memoryStream.ToArray(); -#else - // Avoid an extra copy if we can. - byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray(); -#endif - return AttachBytes(bytes); + return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken); } #endif @@ -218,7 +224,6 @@ public static ByteString CopyFrom(byte[] bytes, int offset, int count) return new ByteString(portion); } -#if GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY /// /// Constructs a from a read only span. The contents /// are copied, so further modifications to the span will not @@ -228,7 +233,6 @@ public static ByteString CopyFrom(ReadOnlySpan bytes) { return new ByteString(bytes.ToArray()); } -#endif /// /// Creates a new by encoding the specified text with @@ -248,11 +252,11 @@ public static ByteString CopyFromUtf8(string text) } /// - /// Retuns the byte at the given index. + /// Returns the byte at the given index. /// public byte this[int index] { - get { return bytes[index]; } + get { return bytes.Span[index]; } } /// @@ -266,7 +270,18 @@ public static ByteString CopyFromUtf8(string text) /// The result of decoding the binary data with the given decoding. public string ToString(Encoding encoding) { - return encoding.GetString(bytes, 0, bytes.Length); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment)) + { + // Fast path. ByteString was created with an array. + return encoding.GetString(segment.Array, segment.Offset, segment.Count); + } + else + { + // Slow path. BytesString is not an array. Convert memory and pass result to GetString. + // TODO: Consider using GetString overload that takes a pointer. + byte[] array = bytes.ToArray(); + return encoding.GetString(array, 0, array.Length); + } } /// @@ -286,9 +301,10 @@ public string ToStringUtf8() /// Returns an iterator over the bytes in this . /// /// An iterator over the bytes in this object. + [SecuritySafeCritical] public IEnumerator GetEnumerator() { - return ((IEnumerable) bytes).GetEnumerator(); + return MemoryMarshal.ToEnumerable(bytes).GetEnumerator(); } /// @@ -306,7 +322,17 @@ IEnumerator IEnumerable.GetEnumerator() public CodedInputStream CreateCodedInput() { // We trust CodedInputStream not to reveal the provided byte array or modify it - return new CodedInputStream(bytes); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment) && segment.Count == bytes.Length) + { + // Fast path. ByteString was created with a complete array. + return new CodedInputStream(segment.Array); + } + else + { + // Slow path. BytesString is not an array, or is a slice of an array. + // Convert memory and pass result to WriteRawBytes. + return new CodedInputStream(bytes.ToArray()); + } } /// @@ -325,18 +351,8 @@ public CodedInputStream CreateCodedInput() { return false; } - if (lhs.bytes.Length != rhs.bytes.Length) - { - return false; - } - for (int i = 0; i < lhs.Length; i++) - { - if (rhs.bytes[i] != lhs.bytes[i]) - { - return false; - } - } - return true; + + return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span); } /// @@ -355,6 +371,7 @@ public CodedInputStream CreateCodedInput() /// /// The object to compare this with. /// true if refers to an equal ; false otherwise. + [SecuritySafeCritical] public override bool Equals(object obj) { return this == (obj as ByteString); @@ -365,12 +382,15 @@ public override bool Equals(object obj) /// will return the same hash code. /// /// A hash code for this object. + [SecuritySafeCritical] public override int GetHashCode() { + ReadOnlySpan b = bytes.Span; + int ret = 23; - foreach (byte b in bytes) + for (int i = 0; i < b.Length; i++) { - ret = (ret * 31) + b; + ret = (ret * 31) + b[i]; } return ret; } @@ -385,20 +405,12 @@ public bool Equals(ByteString other) return this == other; } - /// - /// Used internally by CodedOutputStream to avoid creating a copy for the write - /// - internal void WriteRawBytesTo(CodedOutputStream outputStream) - { - outputStream.WriteRawBytes(bytes, 0, bytes.Length); - } - /// /// Copies the entire byte array to the destination array provided at the offset specified. /// public void CopyTo(byte[] array, int position) { - ByteArray.Copy(bytes, 0, array, position, bytes.Length); + bytes.CopyTo(array.AsMemory(position)); } /// @@ -406,7 +418,17 @@ public void CopyTo(byte[] array, int position) /// public void WriteTo(Stream outputStream) { - outputStream.Write(bytes, 0, bytes.Length); + if (MemoryMarshal.TryGetArray(bytes, out ArraySegment segment)) + { + // Fast path. ByteString was created with an array, so pass the underlying array. + outputStream.Write(segment.Array, segment.Offset, segment.Count); + } + else + { + // Slow path. BytesString is not an array. Convert memory and pass result to WriteRawBytes. + var array = bytes.ToArray(); + outputStream.Write(array, 0, array.Length); + } } } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/ByteStringAsync.cs b/csharp/src/Google.Protobuf/ByteStringAsync.cs new file mode 100644 index 000000000000..3465cc67b40f --- /dev/null +++ b/csharp/src/Google.Protobuf/ByteStringAsync.cs @@ -0,0 +1,64 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Google.Protobuf +{ + /// + /// SecuritySafeCritical attribute can not be placed on types with async methods. + /// This class has ByteString's async methods so it can be marked with SecuritySafeCritical. + /// + internal static class ByteStringAsync + { +#if !NET35 + internal static async Task FromStreamAsyncCore(Stream stream, CancellationToken cancellationToken) + { + int capacity = stream.CanSeek ? checked((int)(stream.Length - stream.Position)) : 0; + var memoryStream = new MemoryStream(capacity); + // We have to specify the buffer size here, as there's no overload accepting the cancellation token + // alone. But it's documented to use 81920 by default if not specified. + await stream.CopyToAsync(memoryStream, 81920, cancellationToken); +#if NETSTANDARD1_1 + byte[] bytes = memoryStream.ToArray(); +#else + // Avoid an extra copy if we can. + byte[] bytes = memoryStream.Length == memoryStream.Capacity ? memoryStream.GetBuffer() : memoryStream.ToArray(); +#endif + return ByteString.AttachBytes(bytes); + } +#endif + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs index bea6bff34f2b..b09f96ce280b 100644 --- a/csharp/src/Google.Protobuf/CodedInputStream.cs +++ b/csharp/src/Google.Protobuf/CodedInputStream.cs @@ -34,6 +34,9 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; namespace Google.Protobuf { @@ -51,6 +54,7 @@ namespace Google.Protobuf /// and to serialize such fields. /// /// + [SecuritySafeCritical] public sealed class CodedInputStream : IDisposable { /// @@ -64,17 +68,6 @@ public sealed class CodedInputStream : IDisposable /// private readonly byte[] buffer; - /// - /// The index of the buffer at which we need to refill from the stream (if there is one). - /// - private int bufferSize; - - private int bufferSizeAfterLimit = 0; - /// - /// The position within the current buffer (i.e. the next byte to read) - /// - private int bufferPos = 0; - /// /// The stream to read further input from, or null if the byte array buffer was provided /// directly on construction, with no further data available. @@ -82,38 +75,15 @@ public sealed class CodedInputStream : IDisposable private readonly Stream input; /// - /// The last tag we read. 0 indicates we've read to the end of the stream - /// (or haven't read anything yet). + /// The parser state is kept separately so that other parse implementations can reuse the same + /// parsing primitives. /// - private uint lastTag = 0; - - /// - /// The next tag, used to store the value read by PeekTag. - /// - private uint nextTag = 0; - private bool hasNextTag = false; + private ParserInternalState state; internal const int DefaultRecursionLimit = 100; internal const int DefaultSizeLimit = Int32.MaxValue; internal const int BufferSize = 4096; - /// - /// The total number of bytes read before the current buffer. The - /// total bytes read up to the current position can be computed as - /// totalBytesRetired + bufferPos. - /// - private int totalBytesRetired = 0; - - /// - /// The absolute position of the end of the current message. - /// - private int currentLimit = int.MaxValue; - - private int recursionDepth = 0; - - private readonly int recursionLimit; - private readonly int sizeLimit; - #region Construction // Note that the checks are performed such that we don't end up checking obviously-valid things // like non-null references for arrays we've just created. @@ -170,11 +140,14 @@ internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int buffer { this.input = input; this.buffer = buffer; - this.bufferPos = bufferPos; - this.bufferSize = bufferSize; - this.sizeLimit = DefaultSizeLimit; - this.recursionLimit = DefaultRecursionLimit; + this.state.bufferPos = bufferPos; + this.state.bufferSize = bufferSize; + this.state.sizeLimit = DefaultSizeLimit; + this.state.recursionLimit = DefaultRecursionLimit; + SegmentedBufferHelper.Initialize(this, out this.state.segmentedBufferHelper); this.leaveOpen = leaveOpen; + + this.state.currentLimit = int.MaxValue; } /// @@ -196,8 +169,8 @@ internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int buffer { throw new ArgumentOutOfRangeException("recursionLimit!", "Recursion limit must be positive"); } - this.sizeLimit = sizeLimit; - this.recursionLimit = recursionLimit; + this.state.sizeLimit = sizeLimit; + this.state.recursionLimit = recursionLimit; } #endregion @@ -230,9 +203,9 @@ public long Position { if (input != null) { - return input.Position - ((bufferSize + bufferSizeAfterLimit) - bufferPos); + return input.Position - ((state.bufferSize + state.bufferSizeAfterLimit) - state.bufferPos); } - return bufferPos; + return state.bufferPos; } } @@ -240,7 +213,7 @@ public long Position /// Returns the last tag read, or 0 if no tags have been read or we've read beyond /// the end of the stream. /// - internal uint LastTag { get { return lastTag; } } + internal uint LastTag { get { return state.lastTag; } } /// /// Returns the size limit for this stream. @@ -253,7 +226,7 @@ public long Position /// /// The size limit. /// - public int SizeLimit { get { return sizeLimit; } } + public int SizeLimit { get { return state.sizeLimit; } } /// /// Returns the recursion limit for this stream. This limit is applied whilst reading messages, @@ -265,17 +238,31 @@ public long Position /// /// The recursion limit for this stream. /// - public int RecursionLimit { get { return recursionLimit; } } + public int RecursionLimit { get { return state.recursionLimit; } } /// /// Internal-only property; when set to true, unknown fields will be discarded while parsing. /// - internal bool DiscardUnknownFields { get; set; } + internal bool DiscardUnknownFields + { + get { return state.DiscardUnknownFields; } + set { state.DiscardUnknownFields = value; } + } /// /// Internal-only property; provides extension identifiers to compatible messages while parsing. /// - internal ExtensionRegistry ExtensionRegistry { get; set; } + internal ExtensionRegistry ExtensionRegistry + { + get { return state.ExtensionRegistry; } + set { state.ExtensionRegistry = value; } + } + + internal byte[] InternalBuffer => buffer; + + internal Stream InternalInputStream => input; + + internal ref ParserInternalState InternalState => ref state; /// /// Disposes of this instance, potentially closing any underlying stream. @@ -302,10 +289,7 @@ public void Dispose() /// tag read was not the one specified internal void CheckReadEndOfStreamTag() { - if (lastTag != 0) - { - throw InvalidProtocolBufferException.MoreDataAvailable(); - } + ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref state); } #endregion @@ -318,16 +302,8 @@ internal void CheckReadEndOfStreamTag() /// public uint PeekTag() { - if (hasNextTag) - { - return nextTag; - } - - uint savedLast = lastTag; - nextTag = ReadTag(); - hasNextTag = true; - lastTag = savedLast; // Undo the side effect of ReadTag - return nextTag; + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.PeekTag(ref span, ref state); } /// @@ -341,58 +317,8 @@ public uint PeekTag() /// The next field tag, or 0 for end of stream. (0 is never a valid tag.) public uint ReadTag() { - if (hasNextTag) - { - lastTag = nextTag; - hasNextTag = false; - return lastTag; - } - - // Optimize for the incredibly common case of having at least two bytes left in the buffer, - // and those two bytes being enough to get the tag. This will be true for fields up to 4095. - if (bufferPos + 2 <= bufferSize) - { - int tmp = buffer[bufferPos++]; - if (tmp < 128) - { - lastTag = (uint)tmp; - } - else - { - int result = tmp & 0x7f; - if ((tmp = buffer[bufferPos++]) < 128) - { - result |= tmp << 7; - lastTag = (uint) result; - } - else - { - // Nope, rewind and go the potentially slow route. - bufferPos -= 2; - lastTag = ReadRawVarint32(); - } - } - } - else - { - if (IsAtEnd) - { - lastTag = 0; - return 0; - } - - lastTag = ReadRawVarint32(); - } - if (WireFormat.GetTagFieldNumber(lastTag) == 0) - { - // If we actually read a tag with a field of 0, that's not a valid tag. - throw InvalidProtocolBufferException.InvalidTag(); - } - if (ReachedLimit) - { - return 0; - } - return lastTag; + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseTag(ref span, ref state); } /// @@ -410,32 +336,8 @@ public uint ReadTag() /// The last read operation read to the end of the logical stream public void SkipLastField() { - if (lastTag == 0) - { - throw new InvalidOperationException("SkipLastField cannot be called at the end of a stream"); - } - switch (WireFormat.GetTagWireType(lastTag)) - { - case WireFormat.WireType.StartGroup: - SkipGroup(lastTag); - break; - case WireFormat.WireType.EndGroup: - throw new InvalidProtocolBufferException( - "SkipLastField called on an end-group tag, indicating that the corresponding start-group was missing"); - case WireFormat.WireType.Fixed32: - ReadFixed32(); - break; - case WireFormat.WireType.Fixed64: - ReadFixed64(); - break; - case WireFormat.WireType.LengthDelimited: - var length = ReadLength(); - SkipRawBytes(length); - break; - case WireFormat.WireType.Varint: - ReadRawVarint32(); - break; - } + var span = new ReadOnlySpan(buffer); + ParsingPrimitivesMessages.SkipLastField(ref span, ref state); } /// @@ -443,37 +345,8 @@ public void SkipLastField() /// internal void SkipGroup(uint startGroupTag) { - // Note: Currently we expect this to be the way that groups are read. We could put the recursion - // depth changes into the ReadTag method instead, potentially... - recursionDepth++; - if (recursionDepth >= recursionLimit) - { - throw InvalidProtocolBufferException.RecursionLimitExceeded(); - } - uint tag; - while (true) - { - tag = ReadTag(); - if (tag == 0) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - // Can't call SkipLastField for this case- that would throw. - if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup) - { - break; - } - // This recursion will allow us to handle nested groups. - SkipLastField(); - } - int startField = WireFormat.GetTagFieldNumber(startGroupTag); - int endField = WireFormat.GetTagFieldNumber(tag); - if (startField != endField) - { - throw new InvalidProtocolBufferException( - $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}"); - } - recursionDepth--; + var span = new ReadOnlySpan(buffer); + ParsingPrimitivesMessages.SkipGroup(ref span, ref state, startGroupTag); } /// @@ -481,33 +354,8 @@ internal void SkipGroup(uint startGroupTag) /// public double ReadDouble() { - if (bufferPos + 8 <= bufferSize) - { - if (BitConverter.IsLittleEndian) - { - var result = BitConverter.ToDouble(buffer, bufferPos); - bufferPos += 8; - return result; - } - else - { - var bytes = new byte[8]; - bytes[0] = buffer[bufferPos + 7]; - bytes[1] = buffer[bufferPos + 6]; - bytes[2] = buffer[bufferPos + 5]; - bytes[3] = buffer[bufferPos + 4]; - bytes[4] = buffer[bufferPos + 3]; - bytes[5] = buffer[bufferPos + 2]; - bytes[6] = buffer[bufferPos + 1]; - bytes[7] = buffer[bufferPos]; - bufferPos += 8; - return BitConverter.ToDouble(bytes, 0); - } - } - else - { - return BitConverter.Int64BitsToDouble((long)ReadRawLittleEndian64()); - } + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseDouble(ref span, ref state); } /// @@ -515,21 +363,8 @@ public double ReadDouble() /// public float ReadFloat() { - if (BitConverter.IsLittleEndian && 4 <= bufferSize - bufferPos) - { - float ret = BitConverter.ToSingle(buffer, bufferPos); - bufferPos += 4; - return ret; - } - else - { - byte[] rawBytes = ReadRawBytes(4); - if (!BitConverter.IsLittleEndian) - { - ByteArray.Reverse(rawBytes); - } - return BitConverter.ToSingle(rawBytes, 0); - } + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseFloat(ref span, ref state); } /// @@ -585,22 +420,8 @@ public bool ReadBool() /// public string ReadString() { - int length = ReadLength(); - // No need to read any data for an empty string. - if (length == 0) - { - return ""; - } - if (length <= bufferSize - bufferPos && length > 0) - { - // Fast path: We already have the bytes in a contiguous buffer, so - // just copy directly from it. - String result = CodedOutputStream.Utf8Encoding.GetString(buffer, bufferPos, length); - bufferPos += length; - return result; - } - // Slow path: Build a byte array first then copy it. - return CodedOutputStream.Utf8Encoding.GetString(ReadRawBytes(length), 0, length); + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ReadString(ref span, ref state); } /// @@ -608,22 +429,22 @@ public string ReadString() /// public void ReadMessage(IMessage builder) { - int length = ReadLength(); - if (recursionDepth >= recursionLimit) + // TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalMergeFrom method), + // what we're doing here works fine, but could be more efficient. + // What happends is that we first initialize a ParseContext from the current coded input stream only to parse the length of the message, at which point + // we will need to switch back again to CodedInputStream-based parsing (which involves copying and storing the state) to be able to + // invoke the legacy MergeFrom(CodedInputStream) method. + // For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it). + var span = new ReadOnlySpan(buffer); + ParseContext.Initialize(ref span, ref state, out ParseContext ctx); + try { - throw InvalidProtocolBufferException.RecursionLimitExceeded(); + ParsingPrimitivesMessages.ReadMessage(ref ctx, builder); } - int oldLimit = PushLimit(length); - ++recursionDepth; - builder.MergeFrom(this); - CheckReadEndOfStreamTag(); - // Check that we've read exactly as much data as expected. - if (!ReachedLimit) + finally { - throw InvalidProtocolBufferException.TruncatedMessage(); + ctx.CopyStateTo(this); } - --recursionDepth; - PopLimit(oldLimit); } /// @@ -631,13 +452,15 @@ public void ReadMessage(IMessage builder) /// public void ReadGroup(IMessage builder) { - if (recursionDepth >= recursionLimit) + ParseContext.Initialize(this, out ParseContext ctx); + try { - throw InvalidProtocolBufferException.RecursionLimitExceeded(); + ParsingPrimitivesMessages.ReadGroup(ref ctx, builder); + } + finally + { + ctx.CopyStateTo(this); } - ++recursionDepth; - builder.MergeFrom(this); - --recursionDepth; } /// @@ -645,20 +468,8 @@ public void ReadGroup(IMessage builder) /// public ByteString ReadBytes() { - int length = ReadLength(); - if (length <= bufferSize - bufferPos && length > 0) - { - // Fast path: We already have the bytes in a contiguous buffer, so - // just copy directly from it. - ByteString result = ByteString.CopyFrom(buffer, bufferPos, length); - bufferPos += length; - return result; - } - else - { - // Slow path: Build a byte array and attach it to a new ByteString. - return ByteString.AttachBytes(ReadRawBytes(length)); - } + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ReadBytes(ref span, ref state); } /// @@ -699,7 +510,7 @@ public long ReadSFixed64() /// public int ReadSInt32() { - return DecodeZigZag32(ReadRawVarint32()); + return ParsingPrimitives.DecodeZigZag32(ReadRawVarint32()); } /// @@ -707,7 +518,7 @@ public int ReadSInt32() /// public long ReadSInt64() { - return DecodeZigZag64(ReadRawVarint64()); + return ParsingPrimitives.DecodeZigZag64(ReadRawVarint64()); } /// @@ -719,7 +530,8 @@ public long ReadSInt64() /// public int ReadLength() { - return (int) ReadRawVarint32(); + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseLength(ref span, ref state); } /// @@ -729,323 +541,14 @@ public int ReadLength() /// public bool MaybeConsumeTag(uint tag) { - if (PeekTag() == tag) - { - hasNextTag = false; - return true; - } - return false; - } - - internal static float? ReadFloatWrapperLittleEndian(CodedInputStream input) - { - // length:1 + tag:1 + value:4 = 6 bytes - if (input.bufferPos + 6 <= input.bufferSize) - { - // The entire wrapper message is already contained in `buffer`. - int length = input.buffer[input.bufferPos]; - if (length == 0) - { - input.bufferPos++; - return 0F; - } - // tag:1 + value:4 = length of 5 bytes - // field=1, type=32-bit = tag of 13 - if (length != 5 || input.buffer[input.bufferPos + 1] != 13) - { - return ReadFloatWrapperSlow(input); - } - var result = BitConverter.ToSingle(input.buffer, input.bufferPos + 2); - input.bufferPos += 6; - return result; - } - else - { - return ReadFloatWrapperSlow(input); - } - } - - internal static float? ReadFloatWrapperSlow(CodedInputStream input) - { - int length = input.ReadLength(); - if (length == 0) - { - return 0F; - } - int finalBufferPos = input.totalBytesRetired + input.bufferPos + length; - float result = 0F; - do - { - // field=1, type=32-bit = tag of 13 - if (input.ReadTag() == 13) - { - result = input.ReadFloat(); - } - else - { - input.SkipLastField(); - } - } - while (input.totalBytesRetired + input.bufferPos < finalBufferPos); - return result; - } - - internal static double? ReadDoubleWrapperLittleEndian(CodedInputStream input) - { - // length:1 + tag:1 + value:8 = 10 bytes - if (input.bufferPos + 10 <= input.bufferSize) - { - // The entire wrapper message is already contained in `buffer`. - int length = input.buffer[input.bufferPos]; - if (length == 0) - { - input.bufferPos++; - return 0D; - } - // tag:1 + value:8 = length of 9 bytes - // field=1, type=64-bit = tag of 9 - if (length != 9 || input.buffer[input.bufferPos + 1] != 9) - { - return ReadDoubleWrapperSlow(input); - } - var result = BitConverter.ToDouble(input.buffer, input.bufferPos + 2); - input.bufferPos += 10; - return result; - } - else - { - return ReadDoubleWrapperSlow(input); - } - } - - internal static double? ReadDoubleWrapperSlow(CodedInputStream input) - { - int length = input.ReadLength(); - if (length == 0) - { - return 0D; - } - int finalBufferPos = input.totalBytesRetired + input.bufferPos + length; - double result = 0D; - do - { - // field=1, type=64-bit = tag of 9 - if (input.ReadTag() == 9) - { - result = input.ReadDouble(); - } - else - { - input.SkipLastField(); - } - } - while (input.totalBytesRetired + input.bufferPos < finalBufferPos); - return result; - } - - internal static bool? ReadBoolWrapper(CodedInputStream input) - { - return ReadUInt64Wrapper(input) != 0; - } - - internal static uint? ReadUInt32Wrapper(CodedInputStream input) - { - // length:1 + tag:1 + value:5(varint32-max) = 7 bytes - if (input.bufferPos + 7 <= input.bufferSize) - { - // The entire wrapper message is already contained in `buffer`. - int pos0 = input.bufferPos; - int length = input.buffer[input.bufferPos++]; - if (length == 0) - { - return 0; - } - // Length will always fit in a single byte. - if (length >= 128) - { - input.bufferPos = pos0; - return ReadUInt32WrapperSlow(input); - } - int finalBufferPos = input.bufferPos + length; - // field=1, type=varint = tag of 8 - if (input.buffer[input.bufferPos++] != 8) - { - input.bufferPos = pos0; - return ReadUInt32WrapperSlow(input); - } - var result = input.ReadUInt32(); - // Verify this message only contained a single field. - if (input.bufferPos != finalBufferPos) - { - input.bufferPos = pos0; - return ReadUInt32WrapperSlow(input); - } - return result; - } - else - { - return ReadUInt32WrapperSlow(input); - } - } - - private static uint? ReadUInt32WrapperSlow(CodedInputStream input) - { - int length = input.ReadLength(); - if (length == 0) - { - return 0; - } - int finalBufferPos = input.totalBytesRetired + input.bufferPos + length; - uint result = 0; - do - { - // field=1, type=varint = tag of 8 - if (input.ReadTag() == 8) - { - result = input.ReadUInt32(); - } - else - { - input.SkipLastField(); - } - } - while (input.totalBytesRetired + input.bufferPos < finalBufferPos); - return result; - } - - internal static int? ReadInt32Wrapper(CodedInputStream input) - { - return (int?)ReadUInt32Wrapper(input); - } - - internal static ulong? ReadUInt64Wrapper(CodedInputStream input) - { - // field=1, type=varint = tag of 8 - const int expectedTag = 8; - // length:1 + tag:1 + value:10(varint64-max) = 12 bytes - if (input.bufferPos + 12 <= input.bufferSize) - { - // The entire wrapper message is already contained in `buffer`. - int pos0 = input.bufferPos; - int length = input.buffer[input.bufferPos++]; - if (length == 0) - { - return 0L; - } - // Length will always fit in a single byte. - if (length >= 128) - { - input.bufferPos = pos0; - return ReadUInt64WrapperSlow(input); - } - int finalBufferPos = input.bufferPos + length; - if (input.buffer[input.bufferPos++] != expectedTag) - { - input.bufferPos = pos0; - return ReadUInt64WrapperSlow(input); - } - var result = input.ReadUInt64(); - // Verify this message only contained a single field. - if (input.bufferPos != finalBufferPos) - { - input.bufferPos = pos0; - return ReadUInt64WrapperSlow(input); - } - return result; - } - else - { - return ReadUInt64WrapperSlow(input); - } - } - - internal static ulong? ReadUInt64WrapperSlow(CodedInputStream input) - { - // field=1, type=varint = tag of 8 - const int expectedTag = 8; - int length = input.ReadLength(); - if (length == 0) - { - return 0L; - } - int finalBufferPos = input.totalBytesRetired + input.bufferPos + length; - ulong result = 0L; - do - { - if (input.ReadTag() == expectedTag) - { - result = input.ReadUInt64(); - } - else - { - input.SkipLastField(); - } - } - while (input.totalBytesRetired + input.bufferPos < finalBufferPos); - return result; - } - - internal static long? ReadInt64Wrapper(CodedInputStream input) - { - return (long?)ReadUInt64Wrapper(input); + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.MaybeConsumeTag(ref span, ref state, tag); } #endregion #region Underlying reading primitives - /// - /// Same code as ReadRawVarint32, but read each byte individually, checking for - /// buffer overflow. - /// - private uint SlowReadRawVarint32() - { - int tmp = ReadRawByte(); - if (tmp < 128) - { - return (uint) tmp; - } - int result = tmp & 0x7f; - if ((tmp = ReadRawByte()) < 128) - { - result |= tmp << 7; - } - else - { - result |= (tmp & 0x7f) << 7; - if ((tmp = ReadRawByte()) < 128) - { - result |= tmp << 14; - } - else - { - result |= (tmp & 0x7f) << 14; - if ((tmp = ReadRawByte()) < 128) - { - result |= tmp << 21; - } - else - { - result |= (tmp & 0x7f) << 21; - result |= (tmp = ReadRawByte()) << 28; - if (tmp >= 128) - { - // Discard upper 32 bits. - for (int i = 0; i < 5; i++) - { - if (ReadRawByte() < 128) - { - return (uint) result; - } - } - throw InvalidProtocolBufferException.MalformedVarint(); - } - } - } - } - return (uint) result; - } - /// /// Reads a raw Varint from the stream. If larger than 32 bits, discard the upper bits. /// This method is optimised for the case where we've got lots of data in the buffer. @@ -1054,58 +557,8 @@ private uint SlowReadRawVarint32() /// internal uint ReadRawVarint32() { - if (bufferPos + 5 > bufferSize) - { - return SlowReadRawVarint32(); - } - - int tmp = buffer[bufferPos++]; - if (tmp < 128) - { - return (uint) tmp; - } - int result = tmp & 0x7f; - if ((tmp = buffer[bufferPos++]) < 128) - { - result |= tmp << 7; - } - else - { - result |= (tmp & 0x7f) << 7; - if ((tmp = buffer[bufferPos++]) < 128) - { - result |= tmp << 14; - } - else - { - result |= (tmp & 0x7f) << 14; - if ((tmp = buffer[bufferPos++]) < 128) - { - result |= tmp << 21; - } - else - { - result |= (tmp & 0x7f) << 21; - result |= (tmp = buffer[bufferPos++]) << 28; - if (tmp >= 128) - { - // Discard upper 32 bits. - // Note that this has to use ReadRawByte() as we only ensure we've - // got at least 5 bytes at the start of the method. This lets us - // use the fast path in more cases, and we rarely hit this section of code. - for (int i = 0; i < 5; i++) - { - if (ReadRawByte() < 128) - { - return (uint) result; - } - } - throw InvalidProtocolBufferException.MalformedVarint(); - } - } - } - } - return (uint) result; + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseRawVarint32(ref span, ref state); } /// @@ -1119,35 +572,7 @@ internal uint ReadRawVarint32() /// internal static uint ReadRawVarint32(Stream input) { - int result = 0; - int offset = 0; - for (; offset < 32; offset += 7) - { - int b = input.ReadByte(); - if (b == -1) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - result |= (b & 0x7f) << offset; - if ((b & 0x80) == 0) - { - return (uint) result; - } - } - // Keep reading up to 64 bits. - for (; offset < 64; offset += 7) - { - int b = input.ReadByte(); - if (b == -1) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - if ((b & 0x80) == 0) - { - return (uint) result; - } - } - throw InvalidProtocolBufferException.MalformedVarint(); + return ParsingPrimitives.ReadRawVarint32(input); } /// @@ -1155,44 +580,8 @@ internal static uint ReadRawVarint32(Stream input) /// internal ulong ReadRawVarint64() { - if (bufferPos + 10 <= bufferSize) - { - ulong result = buffer[bufferPos++]; - if (result < 128) - { - return result; - } - result &= 0x7f; - int shift = 7; - do - { - byte b = buffer[bufferPos++]; - result |= (ulong)(b & 0x7F) << shift; - if (b < 0x80) - { - return result; - } - shift += 7; - } - while (shift < 64); - } - else - { - int shift = 0; - ulong result = 0; - do - { - byte b = ReadRawByte(); - result |= (ulong)(b & 0x7F) << shift; - if (b < 0x80) - { - return result; - } - shift += 7; - } - while (shift < 64); - } - throw InvalidProtocolBufferException.MalformedVarint(); + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseRawVarint64(ref span, ref state); } /// @@ -1200,32 +589,8 @@ internal ulong ReadRawVarint64() /// internal uint ReadRawLittleEndian32() { - if (bufferPos + 4 <= bufferSize) - { - if (BitConverter.IsLittleEndian) - { - var result = BitConverter.ToUInt32(buffer, bufferPos); - bufferPos += 4; - return result; - } - else - { - uint b1 = buffer[bufferPos]; - uint b2 = buffer[bufferPos + 1]; - uint b3 = buffer[bufferPos + 2]; - uint b4 = buffer[bufferPos + 3]; - bufferPos += 4; - return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24); - } - } - else - { - uint b1 = ReadRawByte(); - uint b2 = ReadRawByte(); - uint b3 = ReadRawByte(); - uint b4 = ReadRawByte(); - return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24); - } + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseRawLittleEndian32(ref span, ref state); } /// @@ -1233,70 +598,8 @@ internal uint ReadRawLittleEndian32() /// internal ulong ReadRawLittleEndian64() { - if (bufferPos + 8 <= bufferSize) - { - if (BitConverter.IsLittleEndian) - { - var result = BitConverter.ToUInt64(buffer, bufferPos); - bufferPos += 8; - return result; - } - else - { - ulong b1 = buffer[bufferPos]; - ulong b2 = buffer[bufferPos + 1]; - ulong b3 = buffer[bufferPos + 2]; - ulong b4 = buffer[bufferPos + 3]; - ulong b5 = buffer[bufferPos + 4]; - ulong b6 = buffer[bufferPos + 5]; - ulong b7 = buffer[bufferPos + 6]; - ulong b8 = buffer[bufferPos + 7]; - bufferPos += 8; - return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24) - | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56); - } - } - else - { - ulong b1 = ReadRawByte(); - ulong b2 = ReadRawByte(); - ulong b3 = ReadRawByte(); - ulong b4 = ReadRawByte(); - ulong b5 = ReadRawByte(); - ulong b6 = ReadRawByte(); - ulong b7 = ReadRawByte(); - ulong b8 = ReadRawByte(); - return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24) - | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56); - } - } - - /// - /// Decode a 32-bit value with ZigZag encoding. - /// - /// - /// ZigZag encodes signed integers into values that can be efficiently - /// encoded with varint. (Otherwise, negative values must be - /// sign-extended to 64 bits to be varint encoded, thus always taking - /// 10 bytes on the wire.) - /// - internal static int DecodeZigZag32(uint n) - { - return (int)(n >> 1) ^ -(int)(n & 1); - } - - /// - /// Decode a 32-bit value with ZigZag encoding. - /// - /// - /// ZigZag encodes signed integers into values that can be efficiently - /// encoded with varint. (Otherwise, negative values must be - /// sign-extended to 64 bits to be varint encoded, thus always taking - /// 10 bytes on the wire.) - /// - internal static long DecodeZigZag64(ulong n) - { - return (long)(n >> 1) ^ -(long)(n & 1); + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ParseRawLittleEndian64(ref span, ref state); } #endregion @@ -1310,37 +613,7 @@ internal static long DecodeZigZag64(ulong n) /// The old limit. internal int PushLimit(int byteLimit) { - if (byteLimit < 0) - { - throw InvalidProtocolBufferException.NegativeSize(); - } - byteLimit += totalBytesRetired + bufferPos; - int oldLimit = currentLimit; - if (byteLimit > oldLimit) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - currentLimit = byteLimit; - - RecomputeBufferSizeAfterLimit(); - - return oldLimit; - } - - private void RecomputeBufferSizeAfterLimit() - { - bufferSize += bufferSizeAfterLimit; - int bufferEnd = totalBytesRetired + bufferSize; - if (bufferEnd > currentLimit) - { - // Limit is in current buffer. - bufferSizeAfterLimit = bufferEnd - currentLimit; - bufferSize -= bufferSizeAfterLimit; - } - else - { - bufferSizeAfterLimit = 0; - } + return SegmentedBufferHelper.PushLimit(ref state, byteLimit); } /// @@ -1348,8 +621,7 @@ private void RecomputeBufferSizeAfterLimit() /// internal void PopLimit(int oldLimit) { - currentLimit = oldLimit; - RecomputeBufferSizeAfterLimit(); + SegmentedBufferHelper.PopLimit(ref state, oldLimit); } /// @@ -1360,12 +632,7 @@ internal bool ReachedLimit { get { - if (currentLimit == int.MaxValue) - { - return false; - } - int currentAbsolutePosition = totalBytesRetired + bufferPos; - return currentAbsolutePosition >= currentLimit; + return SegmentedBufferHelper.IsReachedLimit(ref state); } } @@ -1376,12 +643,16 @@ internal bool ReachedLimit /// public bool IsAtEnd { - get { return bufferPos == bufferSize && !RefillBuffer(false); } + get + { + var span = new ReadOnlySpan(buffer); + return SegmentedBufferHelper.IsAtEnd(ref span, ref state); + } } /// /// Called when buffer is empty to read more bytes from the - /// input. If is true, RefillBuffer() gurantees that + /// input. If is true, RefillBuffer() guarantees that /// either there will be at least one byte in the buffer when it returns /// or it will throw an exception. If is false, /// RefillBuffer() returns false if no more bytes were available. @@ -1390,69 +661,8 @@ public bool IsAtEnd /// private bool RefillBuffer(bool mustSucceed) { - if (bufferPos < bufferSize) - { - throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty."); - } - - if (totalBytesRetired + bufferSize == currentLimit) - { - // Oops, we hit a limit. - if (mustSucceed) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - else - { - return false; - } - } - - totalBytesRetired += bufferSize; - - bufferPos = 0; - bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length); - if (bufferSize < 0) - { - throw new InvalidOperationException("Stream.Read returned a negative count"); - } - if (bufferSize == 0) - { - if (mustSucceed) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - else - { - return false; - } - } - else - { - RecomputeBufferSizeAfterLimit(); - int totalBytesRead = - totalBytesRetired + bufferSize + bufferSizeAfterLimit; - if (totalBytesRead < 0 || totalBytesRead > sizeLimit) - { - throw InvalidProtocolBufferException.SizeLimitExceeded(); - } - return true; - } - } - - /// - /// Read one byte from the input. - /// - /// - /// the end of the stream or the current limit was reached - /// - internal byte ReadRawByte() - { - if (bufferPos == bufferSize) - { - RefillBuffer(true); - } - return buffer[bufferPos++]; + var span = new ReadOnlySpan(buffer); + return state.segmentedBufferHelper.RefillBuffer(ref span, ref state, mustSucceed); } /// @@ -1463,193 +673,25 @@ internal byte ReadRawByte() /// internal byte[] ReadRawBytes(int size) { - if (size < 0) - { - throw InvalidProtocolBufferException.NegativeSize(); - } - - if (totalBytesRetired + bufferPos + size > currentLimit) - { - // Read to the end of the stream (up to the current limit) anyway. - SkipRawBytes(currentLimit - totalBytesRetired - bufferPos); - // Then fail. - throw InvalidProtocolBufferException.TruncatedMessage(); - } - - if (size <= bufferSize - bufferPos) - { - // We have all the bytes we need already. - byte[] bytes = new byte[size]; - ByteArray.Copy(buffer, bufferPos, bytes, 0, size); - bufferPos += size; - return bytes; - } - else if (size < buffer.Length) - { - // Reading more bytes than are in the buffer, but not an excessive number - // of bytes. We can safely allocate the resulting array ahead of time. - - // First copy what we have. - byte[] bytes = new byte[size]; - int pos = bufferSize - bufferPos; - ByteArray.Copy(buffer, bufferPos, bytes, 0, pos); - bufferPos = bufferSize; - - // We want to use RefillBuffer() and then copy from the buffer into our - // byte array rather than reading directly into our byte array because - // the input may be unbuffered. - RefillBuffer(true); - - while (size - pos > bufferSize) - { - Buffer.BlockCopy(buffer, 0, bytes, pos, bufferSize); - pos += bufferSize; - bufferPos = bufferSize; - RefillBuffer(true); - } - - ByteArray.Copy(buffer, 0, bytes, pos, size - pos); - bufferPos = size - pos; - - return bytes; - } - else - { - // The size is very large. For security reasons, we can't allocate the - // entire byte array yet. The size comes directly from the input, so a - // maliciously-crafted message could provide a bogus very large size in - // order to trick the app into allocating a lot of memory. We avoid this - // by allocating and reading only a small chunk at a time, so that the - // malicious message must actually *be* extremely large to cause - // problems. Meanwhile, we limit the allowed size of a message elsewhere. - - // Remember the buffer markers since we'll have to copy the bytes out of - // it later. - int originalBufferPos = bufferPos; - int originalBufferSize = bufferSize; - - // Mark the current buffer consumed. - totalBytesRetired += bufferSize; - bufferPos = 0; - bufferSize = 0; - - // Read all the rest of the bytes we need. - int sizeLeft = size - (originalBufferSize - originalBufferPos); - List chunks = new List(); - - while (sizeLeft > 0) - { - byte[] chunk = new byte[Math.Min(sizeLeft, buffer.Length)]; - int pos = 0; - while (pos < chunk.Length) - { - int n = (input == null) ? -1 : input.Read(chunk, pos, chunk.Length - pos); - if (n <= 0) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - totalBytesRetired += n; - pos += n; - } - sizeLeft -= chunk.Length; - chunks.Add(chunk); - } - - // OK, got everything. Now concatenate it all into one buffer. - byte[] bytes = new byte[size]; - - // Start by copying the leftover bytes from this.buffer. - int newPos = originalBufferSize - originalBufferPos; - ByteArray.Copy(buffer, originalBufferPos, bytes, 0, newPos); - - // And now all the chunks. - foreach (byte[] chunk in chunks) - { - Buffer.BlockCopy(chunk, 0, bytes, newPos, chunk.Length); - newPos += chunk.Length; - } - - // Done. - return bytes; - } + var span = new ReadOnlySpan(buffer); + return ParsingPrimitives.ReadRawBytes(ref span, ref state, size); } /// - /// Reads and discards bytes. + /// Reads a top-level message or a nested message after the limits for this message have been pushed. + /// (parser will proceed until the end of the current limit) + /// NOTE: this method needs to be public because it's invoked by the generated code - e.g. msg.MergeFrom(CodedInputStream input) method /// - /// the end of the stream - /// or the current limit was reached - private void SkipRawBytes(int size) + public void ReadRawMessage(IMessage message) { - if (size < 0) - { - throw InvalidProtocolBufferException.NegativeSize(); - } - - if (totalBytesRetired + bufferPos + size > currentLimit) - { - // Read to the end of the stream anyway. - SkipRawBytes(currentLimit - totalBytesRetired - bufferPos); - // Then fail. - throw InvalidProtocolBufferException.TruncatedMessage(); - } - - if (size <= bufferSize - bufferPos) + ParseContext.Initialize(this, out ParseContext ctx); + try { - // We have all the bytes we need already. - bufferPos += size; + ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message); } - else + finally { - // Skipping more bytes than are in the buffer. First skip what we have. - int pos = bufferSize - bufferPos; - - // ROK 5/7/2013 Issue #54: should retire all bytes in buffer (bufferSize) - // totalBytesRetired += pos; - totalBytesRetired += bufferSize; - - bufferPos = 0; - bufferSize = 0; - - // Then skip directly from the InputStream for the rest. - if (pos < size) - { - if (input == null) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - SkipImpl(size - pos); - totalBytesRetired += size - pos; - } - } - } - - /// - /// Abstraction of skipping to cope with streams which can't really skip. - /// - private void SkipImpl(int amountToSkip) - { - if (input.CanSeek) - { - long previousPosition = input.Position; - input.Position += amountToSkip; - if (input.Position != previousPosition + amountToSkip) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - } - else - { - byte[] skipBuffer = new byte[Math.Min(1024, amountToSkip)]; - while (amountToSkip > 0) - { - int bytesRead = input.Read(skipBuffer, 0, Math.Min(skipBuffer.Length, amountToSkip)); - if (bytesRead <= 0) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } - amountToSkip -= bytesRead; - } + ctx.CopyStateTo(this); } } #endregion diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs b/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs index aa7932470ba3..cb923549d42e 100644 --- a/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs +++ b/csharp/src/Google.Protobuf/CodedOutputStream.ComputeSize.cs @@ -132,7 +132,7 @@ public static int ComputeBoolSize(bool value) /// public static int ComputeStringSize(String value) { - int byteArraySize = Utf8Encoding.GetByteCount(value); + int byteArraySize = WritingPrimitives.Utf8Encoding.GetByteCount(value); return ComputeLengthSize(byteArraySize) + byteArraySize; } @@ -208,7 +208,7 @@ public static int ComputeSFixed64Size(long value) /// public static int ComputeSInt32Size(int value) { - return ComputeRawVarint32Size(EncodeZigZag32(value)); + return ComputeRawVarint32Size(WritingPrimitives.EncodeZigZag32(value)); } /// @@ -217,7 +217,7 @@ public static int ComputeSInt32Size(int value) /// public static int ComputeSInt64Size(long value) { - return ComputeRawVarint64Size(EncodeZigZag64(value)); + return ComputeRawVarint64Size(WritingPrimitives.EncodeZigZag64(value)); } /// diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.cs b/csharp/src/Google.Protobuf/CodedOutputStream.cs index 1d76d276029d..20d88ea7dc9b 100644 --- a/csharp/src/Google.Protobuf/CodedOutputStream.cs +++ b/csharp/src/Google.Protobuf/CodedOutputStream.cs @@ -33,6 +33,7 @@ using Google.Protobuf.Collections; using System; using System.IO; +using System.Security; using System.Text; namespace Google.Protobuf @@ -55,11 +56,9 @@ namespace Google.Protobuf /// and MapField<TKey, TValue> to serialize such fields. /// /// + [SecuritySafeCritical] public sealed partial class CodedOutputStream : IDisposable { - // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.) - internal static readonly Encoding Utf8Encoding = Encoding.UTF8; - /// /// The buffer size used by CreateInstance(Stream). /// @@ -67,8 +66,8 @@ public sealed partial class CodedOutputStream : IDisposable private readonly bool leaveOpen; private readonly byte[] buffer; - private readonly int limit; - private int position; + private WriterInternalState state; + private readonly Stream output; #region Construction @@ -90,8 +89,9 @@ private CodedOutputStream(byte[] buffer, int offset, int length) { this.output = null; this.buffer = ProtoPreconditions.CheckNotNull(buffer, nameof(buffer)); - this.position = offset; - this.limit = offset + length; + this.state.position = offset; + this.state.limit = offset + length; + WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper); leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference } @@ -99,8 +99,9 @@ private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen) { this.output = ProtoPreconditions.CheckNotNull(output, nameof(output)); this.buffer = buffer; - this.position = 0; - this.limit = buffer.Length; + this.state.position = 0; + this.state.limit = buffer.Length; + WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper); this.leaveOpen = leaveOpen; } @@ -155,9 +156,9 @@ public long Position { if (output != null) { - return output.Position + position; + return output.Position + state.position; } - return position; + return state.position; } } @@ -169,7 +170,8 @@ public long Position /// The value to write public void WriteDouble(double value) { - WriteRawLittleEndian64((ulong)BitConverter.DoubleToInt64Bits(value)); + var span = new Span(buffer); + WritingPrimitives.WriteDouble(ref span, ref state, value); } /// @@ -178,23 +180,8 @@ public void WriteDouble(double value) /// The value to write public void WriteFloat(float value) { - byte[] rawBytes = BitConverter.GetBytes(value); - if (!BitConverter.IsLittleEndian) - { - ByteArray.Reverse(rawBytes); - } - - if (limit - position >= 4) - { - buffer[position++] = rawBytes[0]; - buffer[position++] = rawBytes[1]; - buffer[position++] = rawBytes[2]; - buffer[position++] = rawBytes[3]; - } - else - { - WriteRawBytes(rawBytes, 0, 4); - } + var span = new Span(buffer); + WritingPrimitives.WriteFloat(ref span, ref state, value); } /// @@ -203,7 +190,8 @@ public void WriteFloat(float value) /// The value to write public void WriteUInt64(ulong value) { - WriteRawVarint64(value); + var span = new Span(buffer); + WritingPrimitives.WriteUInt64(ref span, ref state, value); } /// @@ -212,7 +200,8 @@ public void WriteUInt64(ulong value) /// The value to write public void WriteInt64(long value) { - WriteRawVarint64((ulong) value); + var span = new Span(buffer); + WritingPrimitives.WriteInt64(ref span, ref state, value); } /// @@ -221,15 +210,8 @@ public void WriteInt64(long value) /// The value to write public void WriteInt32(int value) { - if (value >= 0) - { - WriteRawVarint32((uint) value); - } - else - { - // Must sign-extend. - WriteRawVarint64((ulong) value); - } + var span = new Span(buffer); + WritingPrimitives.WriteInt32(ref span, ref state, value); } /// @@ -238,7 +220,8 @@ public void WriteInt32(int value) /// The value to write public void WriteFixed64(ulong value) { - WriteRawLittleEndian64(value); + var span = new Span(buffer); + WritingPrimitives.WriteFixed64(ref span, ref state, value); } /// @@ -247,7 +230,8 @@ public void WriteFixed64(ulong value) /// The value to write public void WriteFixed32(uint value) { - WriteRawLittleEndian32(value); + var span = new Span(buffer); + WritingPrimitives.WriteFixed32(ref span, ref state, value); } /// @@ -256,7 +240,8 @@ public void WriteFixed32(uint value) /// The value to write public void WriteBool(bool value) { - WriteRawByte(value ? (byte) 1 : (byte) 0); + var span = new Span(buffer); + WritingPrimitives.WriteBool(ref span, ref state, value); } /// @@ -266,41 +251,52 @@ public void WriteBool(bool value) /// The value to write public void WriteString(string value) { - // Optimise the case where we have enough space to write - // the string directly to the buffer, which should be common. - int length = Utf8Encoding.GetByteCount(value); - WriteLength(length); - if (limit - position >= length) + var span = new Span(buffer); + WritingPrimitives.WriteString(ref span, ref state, value); + } + + /// + /// Writes a message, without a tag, to the stream. + /// The data is length-prefixed. + /// + /// The value to write + public void WriteMessage(IMessage value) + { + // TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalWriteTo method), + // what we're doing here works fine, but could be more efficient. + // For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it). + var span = new Span(buffer); + WriteContext.Initialize(ref span, ref state, out WriteContext ctx); + try { - if (length == value.Length) // Must be all ASCII... - { - for (int i = 0; i < length; i++) - { - buffer[position + i] = (byte)value[i]; - } - } - else - { - Utf8Encoding.GetBytes(value, 0, value.Length, buffer, position); - } - position += length; + WritingPrimitivesMessages.WriteMessage(ref ctx, value); } - else + finally { - byte[] bytes = Utf8Encoding.GetBytes(value); - WriteRawBytes(bytes); + ctx.CopyStateTo(this); } } /// /// Writes a message, without a tag, to the stream. - /// The data is length-prefixed. + /// Only the message data is written, without a length-delimiter. /// /// The value to write - public void WriteMessage(IMessage value) - { - WriteLength(value.CalculateSize()); - value.WriteTo(this); + public void WriteRawMessage(IMessage value) + { + // TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalWriteTo method), + // what we're doing here works fine, but could be more efficient. + // For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it). + var span = new Span(buffer); + WriteContext.Initialize(ref span, ref state, out WriteContext ctx); + try + { + WritingPrimitivesMessages.WriteRawMessage(ref ctx, value); + } + finally + { + ctx.CopyStateTo(this); + } } /// @@ -309,7 +305,16 @@ public void WriteMessage(IMessage value) /// The value to write public void WriteGroup(IMessage value) { - value.WriteTo(this); + var span = new Span(buffer); + WriteContext.Initialize(ref span, ref state, out WriteContext ctx); + try + { + WritingPrimitivesMessages.WriteGroup(ref ctx, value); + } + finally + { + ctx.CopyStateTo(this); + } } /// @@ -319,8 +324,8 @@ public void WriteGroup(IMessage value) /// The value to write public void WriteBytes(ByteString value) { - WriteLength(value.Length); - value.WriteRawBytesTo(this); + var span = new Span(buffer); + WritingPrimitives.WriteBytes(ref span, ref state, value); } /// @@ -329,7 +334,8 @@ public void WriteBytes(ByteString value) /// The value to write public void WriteUInt32(uint value) { - WriteRawVarint32(value); + var span = new Span(buffer); + WritingPrimitives.WriteUInt32(ref span, ref state, value); } /// @@ -338,7 +344,8 @@ public void WriteUInt32(uint value) /// The value to write public void WriteEnum(int value) { - WriteInt32(value); + var span = new Span(buffer); + WritingPrimitives.WriteEnum(ref span, ref state, value); } /// @@ -347,7 +354,8 @@ public void WriteEnum(int value) /// The value to write. public void WriteSFixed32(int value) { - WriteRawLittleEndian32((uint) value); + var span = new Span(buffer); + WritingPrimitives.WriteSFixed32(ref span, ref state, value); } /// @@ -356,7 +364,8 @@ public void WriteSFixed32(int value) /// The value to write public void WriteSFixed64(long value) { - WriteRawLittleEndian64((ulong) value); + var span = new Span(buffer); + WritingPrimitives.WriteSFixed64(ref span, ref state, value); } /// @@ -365,7 +374,8 @@ public void WriteSFixed64(long value) /// The value to write public void WriteSInt32(int value) { - WriteRawVarint32(EncodeZigZag32(value)); + var span = new Span(buffer); + WritingPrimitives.WriteSInt32(ref span, ref state, value); } /// @@ -374,7 +384,8 @@ public void WriteSInt32(int value) /// The value to write public void WriteSInt64(long value) { - WriteRawVarint64(EncodeZigZag64(value)); + var span = new Span(buffer); + WritingPrimitives.WriteSInt64(ref span, ref state, value); } /// @@ -386,7 +397,8 @@ public void WriteSInt64(long value) /// Length value, in bytes. public void WriteLength(int length) { - WriteRawVarint32((uint) length); + var span = new Span(buffer); + WritingPrimitives.WriteLength(ref span, ref state, length); } #endregion @@ -399,7 +411,8 @@ public void WriteLength(int length) /// The wire format type of the tag to write public void WriteTag(int fieldNumber, WireFormat.WireType type) { - WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type)); + var span = new Span(buffer); + WritingPrimitives.WriteTag(ref span, ref state, fieldNumber, type); } /// @@ -408,7 +421,8 @@ public void WriteTag(int fieldNumber, WireFormat.WireType type) /// The encoded tag public void WriteTag(uint tag) { - WriteRawVarint32(tag); + var span = new Span(buffer); + WritingPrimitives.WriteTag(ref span, ref state, tag); } /// @@ -417,7 +431,8 @@ public void WriteTag(uint tag) /// The encoded tag public void WriteRawTag(byte b1) { - WriteRawByte(b1); + var span = new Span(buffer); + WritingPrimitives.WriteRawTag(ref span, ref state, b1); } /// @@ -427,8 +442,8 @@ public void WriteRawTag(byte b1) /// The second byte of the encoded tag public void WriteRawTag(byte b1, byte b2) { - WriteRawByte(b1); - WriteRawByte(b2); + var span = new Span(buffer); + WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2); } /// @@ -439,9 +454,8 @@ public void WriteRawTag(byte b1, byte b2) /// The third byte of the encoded tag public void WriteRawTag(byte b1, byte b2, byte b3) { - WriteRawByte(b1); - WriteRawByte(b2); - WriteRawByte(b3); + var span = new Span(buffer); + WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3); } /// @@ -453,10 +467,8 @@ public void WriteRawTag(byte b1, byte b2, byte b3) /// The fourth byte of the encoded tag public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) { - WriteRawByte(b1); - WriteRawByte(b2); - WriteRawByte(b3); - WriteRawByte(b4); + var span = new Span(buffer); + WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4); } /// @@ -469,15 +481,13 @@ public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) /// The fifth byte of the encoded tag public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) { - WriteRawByte(b1); - WriteRawByte(b2); - WriteRawByte(b3); - WriteRawByte(b4); - WriteRawByte(b5); + var span = new Span(buffer); + WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4, b5); } #endregion #region Underlying writing primitives + /// /// Writes a 32 bit value as a varint. The fast route is taken when /// there's enough buffer space left to whizz through without checking @@ -485,112 +495,26 @@ public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) /// internal void WriteRawVarint32(uint value) { - // Optimize for the common case of a single byte value - if (value < 128 && position < limit) - { - buffer[position++] = (byte)value; - return; - } - - while (value > 127 && position < limit) - { - buffer[position++] = (byte) ((value & 0x7F) | 0x80); - value >>= 7; - } - while (value > 127) - { - WriteRawByte((byte) ((value & 0x7F) | 0x80)); - value >>= 7; - } - if (position < limit) - { - buffer[position++] = (byte) value; - } - else - { - WriteRawByte((byte) value); - } + var span = new Span(buffer); + WritingPrimitives.WriteRawVarint32(ref span, ref state, value); } internal void WriteRawVarint64(ulong value) { - while (value > 127 && position < limit) - { - buffer[position++] = (byte) ((value & 0x7F) | 0x80); - value >>= 7; - } - while (value > 127) - { - WriteRawByte((byte) ((value & 0x7F) | 0x80)); - value >>= 7; - } - if (position < limit) - { - buffer[position++] = (byte) value; - } - else - { - WriteRawByte((byte) value); - } + var span = new Span(buffer); + WritingPrimitives.WriteRawVarint64(ref span, ref state, value); } internal void WriteRawLittleEndian32(uint value) { - if (position + 4 > limit) - { - WriteRawByte((byte) value); - WriteRawByte((byte) (value >> 8)); - WriteRawByte((byte) (value >> 16)); - WriteRawByte((byte) (value >> 24)); - } - else - { - buffer[position++] = ((byte) value); - buffer[position++] = ((byte) (value >> 8)); - buffer[position++] = ((byte) (value >> 16)); - buffer[position++] = ((byte) (value >> 24)); - } + var span = new Span(buffer); + WritingPrimitives.WriteRawLittleEndian32(ref span, ref state, value); } internal void WriteRawLittleEndian64(ulong value) { - if (position + 8 > limit) - { - WriteRawByte((byte) value); - WriteRawByte((byte) (value >> 8)); - WriteRawByte((byte) (value >> 16)); - WriteRawByte((byte) (value >> 24)); - WriteRawByte((byte) (value >> 32)); - WriteRawByte((byte) (value >> 40)); - WriteRawByte((byte) (value >> 48)); - WriteRawByte((byte) (value >> 56)); - } - else - { - buffer[position++] = ((byte) value); - buffer[position++] = ((byte) (value >> 8)); - buffer[position++] = ((byte) (value >> 16)); - buffer[position++] = ((byte) (value >> 24)); - buffer[position++] = ((byte) (value >> 32)); - buffer[position++] = ((byte) (value >> 40)); - buffer[position++] = ((byte) (value >> 48)); - buffer[position++] = ((byte) (value >> 56)); - } - } - - internal void WriteRawByte(byte value) - { - if (position == limit) - { - RefreshBuffer(); - } - - buffer[position++] = value; - } - - internal void WriteRawByte(uint value) - { - WriteRawByte((byte) value); + var span = new Span(buffer); + WritingPrimitives.WriteRawLittleEndian64(ref span, ref state, value); } /// @@ -606,85 +530,12 @@ internal void WriteRawBytes(byte[] value) /// internal void WriteRawBytes(byte[] value, int offset, int length) { - if (limit - position >= length) - { - ByteArray.Copy(value, offset, buffer, position, length); - // We have room in the current buffer. - position += length; - } - else - { - // Write extends past current buffer. Fill the rest of this buffer and - // flush. - int bytesWritten = limit - position; - ByteArray.Copy(value, offset, buffer, position, bytesWritten); - offset += bytesWritten; - length -= bytesWritten; - position = limit; - RefreshBuffer(); - - // Now deal with the rest. - // Since we have an output stream, this is our buffer - // and buffer offset == 0 - if (length <= limit) - { - // Fits in new buffer. - ByteArray.Copy(value, offset, buffer, 0, length); - position = length; - } - else - { - // Write is very big. Let's do it all at once. - output.Write(value, offset, length); - } - } + var span = new Span(buffer); + WritingPrimitives.WriteRawBytes(ref span, ref state, value, offset, length); } #endregion - /// - /// Encode a 32-bit value with ZigZag encoding. - /// - /// - /// ZigZag encodes signed integers into values that can be efficiently - /// encoded with varint. (Otherwise, negative values must be - /// sign-extended to 64 bits to be varint encoded, thus always taking - /// 10 bytes on the wire.) - /// - internal static uint EncodeZigZag32(int n) - { - // Note: the right-shift must be arithmetic - return (uint) ((n << 1) ^ (n >> 31)); - } - - /// - /// Encode a 64-bit value with ZigZag encoding. - /// - /// - /// ZigZag encodes signed integers into values that can be efficiently - /// encoded with varint. (Otherwise, negative values must be - /// sign-extended to 64 bits to be varint encoded, thus always taking - /// 10 bytes on the wire.) - /// - internal static ulong EncodeZigZag64(long n) - { - return (ulong) ((n << 1) ^ (n >> 63)); - } - - private void RefreshBuffer() - { - if (output == null) - { - // We're writing to a single buffer. - throw new OutOfSpaceException(); - } - - // Since we have an output stream, this is our buffer - // and buffer offset == 0 - output.Write(buffer, 0, position); - position = 0; - } - /// /// Indicates that a CodedOutputStream wrapping a flat byte array /// ran out of space. @@ -726,45 +577,31 @@ public void Dispose() /// public void Flush() { - if (output != null) - { - RefreshBuffer(); - } + var span = new Span(buffer); + WriteBufferHelper.Flush(ref span, ref state); } /// /// Verifies that SpaceLeft returns zero. It's common to create a byte array /// that is exactly big enough to hold a message, then write to it with /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that - /// the message was actually as big as expected, which can help bugs. + /// the message was actually as big as expected, which can help finding bugs. /// public void CheckNoSpaceLeft() { - if (SpaceLeft != 0) - { - throw new InvalidOperationException("Did not write as much data as expected."); - } + WriteBufferHelper.CheckNoSpaceLeft(ref state); } /// /// If writing to a flat array, returns the space left in the array. Otherwise, /// throws an InvalidOperationException. /// - public int SpaceLeft - { - get - { - if (output == null) - { - return limit - position; - } - else - { - throw new InvalidOperationException( - "SpaceLeft can only be called on CodedOutputStreams that are " + - "writing to a flat array."); - } - } - } + public int SpaceLeft => WriteBufferHelper.GetSpaceLeft(ref state); + + internal byte[] InternalBuffer => buffer; + + internal Stream InternalOutputStream => output; + + internal ref WriterInternalState InternalState => ref state; } } diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs index 1924439e5cad..d60ebc5a8a58 100644 --- a/csharp/src/Google.Protobuf/Collections/MapField.cs +++ b/csharp/src/Google.Protobuf/Collections/MapField.cs @@ -33,10 +33,12 @@ using Google.Protobuf.Compatibility; using Google.Protobuf.Reflection; using System; +using System.Buffers; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Security; namespace Google.Protobuf.Collections { @@ -421,14 +423,38 @@ public bool Equals(MapField other) /// Stream to read from /// Codec describing how the key/value pairs are encoded public void AddEntriesFrom(CodedInputStream input, Codec codec) + { + ParseContext.Initialize(input, out ParseContext ctx); + try + { + AddEntriesFrom(ref ctx, codec); + } + finally + { + ctx.CopyStateTo(input); + } + } + + /// + /// Adds entries to the map from the given parse context. + /// + /// + /// It is assumed that the input is initially positioned after the tag specified by the codec. + /// This method will continue reading entries from the input until the end is reached, or + /// a different tag is encountered. + /// + /// Input to read from + /// Codec describing how the key/value pairs are encoded + [SecuritySafeCritical] + public void AddEntriesFrom(ref ParseContext ctx, Codec codec) { var adapter = new Codec.MessageAdapter(codec); do { adapter.Reset(); - input.ReadMessage(adapter); + ctx.ReadMessage(adapter); this[adapter.Key] = adapter.Value; - } while (input.MaybeConsumeTag(codec.MapTag)); + } while (ParsingPrimitives.MaybeConsumeTag(ref ctx.buffer, ref ctx.state, codec.MapTag)); } /// @@ -438,14 +464,34 @@ public void AddEntriesFrom(CodedInputStream input, Codec codec) /// The output stream to write to. /// The codec to use for each entry. public void WriteTo(CodedOutputStream output, Codec codec) + { + WriteContext.Initialize(output, out WriteContext ctx); + try + { + WriteTo(ref ctx, codec); + } + finally + { + ctx.CopyStateTo(output); + } + } + + /// + /// Writes the contents of this map to the given write context, using the specified codec + /// to encode each entry. + /// + /// The write context to write to. + /// The codec to use for each entry. + [SecuritySafeCritical] + public void WriteTo(ref WriteContext ctx, Codec codec) { var message = new Codec.MessageAdapter(codec); foreach (var entry in list) { message.Key = entry.Key; message.Value = entry.Value; - output.WriteTag(codec.MapTag); - output.WriteMessage(message); + ctx.WriteTag(codec.MapTag); + ctx.WriteMessage(message); } } @@ -620,7 +666,7 @@ public Codec(FieldCodec keyCodec, FieldCodec valueCodec, uint mapT /// This is nested inside Codec as it's tightly coupled to the associated codec, /// and it's simpler if it has direct access to all its fields. /// - internal class MessageAdapter : IMessage + internal class MessageAdapter : IMessage, IBufferMessage { private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 }; @@ -640,36 +686,60 @@ internal void Reset() } public void MergeFrom(CodedInputStream input) + { + // Message adapter is an internal class and we know that all the parsing will happen via InternalMergeFrom. + throw new NotImplementedException(); + } + + [SecuritySafeCritical] + public void InternalMergeFrom(ref ParseContext ctx) { uint tag; - while ((tag = input.ReadTag()) != 0) + while ((tag = ctx.ReadTag()) != 0) { if (tag == codec.keyCodec.Tag) { - Key = codec.keyCodec.Read(input); + Key = codec.keyCodec.Read(ref ctx); } else if (tag == codec.valueCodec.Tag) { - Value = codec.valueCodec.Read(input); + Value = codec.valueCodec.Read(ref ctx); } else { - input.SkipLastField(); + ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state); } } // Corner case: a map entry with a key but no value, where the value type is a message. - // Read it as if we'd seen an input stream with no data (i.e. create a "default" message). + // Read it as if we'd seen input with no data (i.e. create a "default" message). if (Value == null) { - Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData)); + if (ctx.state.CodedInputStream != null) + { + // the decoded message might not support parsing from ParseContext, so + // we need to allow fallback to the legacy MergeFrom(CodedInputStream) parsing. + Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData)); + } + else + { + ParseContext.Initialize(new ReadOnlySequence(ZeroLengthMessageStreamData), out ParseContext zeroLengthCtx); + Value = codec.valueCodec.Read(ref zeroLengthCtx); + } } } public void WriteTo(CodedOutputStream output) { - codec.keyCodec.WriteTagAndValue(output, Key); - codec.valueCodec.WriteTagAndValue(output, Value); + // Message adapter is an internal class and we know that all the writing will happen via InternalWriteTo. + throw new NotImplementedException(); + } + + [SecuritySafeCritical] + public void InternalWriteTo(ref WriteContext ctx) + { + codec.keyCodec.WriteTagAndValue(ref ctx, Key); + codec.valueCodec.WriteTagAndValue(ref ctx, Value); } public int CalculateSize() diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs index 0e8bb617647b..19114caa2475 100644 --- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs +++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs @@ -34,6 +34,8 @@ using System.Collections; using System.Collections.Generic; using System.IO; +using System.Security; +using System.Threading; namespace Google.Protobuf.Collections { @@ -94,23 +96,64 @@ public RepeatedField Clone() /// The input stream to read from. /// The codec to use in order to read each entry. public void AddEntriesFrom(CodedInputStream input, FieldCodec codec) + { + ParseContext.Initialize(input, out ParseContext ctx); + try + { + AddEntriesFrom(ref ctx, codec); + } + finally + { + ctx.CopyStateTo(input); + } + } + + /// + /// Adds the entries from the given parse context, decoding them with the specified codec. + /// + /// The input to read from. + /// The codec to use in order to read each entry. + [SecuritySafeCritical] + public void AddEntriesFrom(ref ParseContext ctx, FieldCodec codec) { // TODO: Inline some of the Add code, so we can avoid checking the size on every // iteration. - uint tag = input.LastTag; + uint tag = ctx.state.lastTag; var reader = codec.ValueReader; // Non-nullable value types can be packed or not. if (FieldCodec.IsPackedRepeatedField(tag)) { - int length = input.ReadLength(); + int length = ctx.ReadLength(); if (length > 0) { - int oldLimit = input.PushLimit(length); - while (!input.ReachedLimit) + int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length); + + // If the content is fixed size then we can calculate the length + // of the repeated field and pre-initialize the underlying collection. + // + // Check that the supplied length doesn't exceed the underlying buffer. + // That prevents a malicious length from initializing a very large collection. + if (codec.FixedSize > 0 && length % codec.FixedSize == 0 && ParsingPrimitives.IsDataAvailable(ref ctx.state, length)) + { + EnsureSize(count + (length / codec.FixedSize)); + + while (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) + { + // Only FieldCodecs with a fixed size can reach here, and they are all known + // types that don't allow the user to specify a custom reader action. + // reader action will never return null. + array[count++] = reader(ref ctx); + } + } + else { - Add(reader(input)); + // Content is variable size so add until we reach the limit. + while (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) + { + Add(reader(ref ctx)); + } } - input.PopLimit(oldLimit); + SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); } // Empty packed field. Odd, but valid - just ignore. } @@ -119,8 +162,8 @@ public void AddEntriesFrom(CodedInputStream input, FieldCodec codec) // Not packed... (possibly not packable) do { - Add(reader(input)); - } while (input.MaybeConsumeTag(tag)); + Add(reader(ref ctx)); + } while (ParsingPrimitives.MaybeConsumeTag(ref ctx.buffer, ref ctx.state, tag)); } } @@ -128,7 +171,7 @@ public void AddEntriesFrom(CodedInputStream input, FieldCodec codec) /// Calculates the size of this collection based on the given codec. /// /// The codec to use when encoding each field. - /// The number of bytes that would be written to a by , + /// The number of bytes that would be written to an output by one of the WriteTo methods, /// using the same codec. public int CalculateSize(FieldCodec codec) { @@ -186,6 +229,26 @@ private int CalculatePackedDataSize(FieldCodec codec) /// The output stream to write to. /// The codec to use when encoding each value. public void WriteTo(CodedOutputStream output, FieldCodec codec) + { + WriteContext.Initialize(output, out WriteContext ctx); + try + { + WriteTo(ref ctx, codec); + } + finally + { + ctx.CopyStateTo(output); + } + } + + /// + /// Writes the contents of this collection to the given write context, + /// encoding each value using the specified codec. + /// + /// The write context to write to. + /// The codec to use when encoding each value. + [SecuritySafeCritical] + public void WriteTo(ref WriteContext ctx, FieldCodec codec) { if (count == 0) { @@ -196,12 +259,12 @@ public void WriteTo(CodedOutputStream output, FieldCodec codec) if (codec.PackedRepeatedField) { // Packed primitive type - uint size = (uint)CalculatePackedDataSize(codec); - output.WriteTag(tag); - output.WriteRawVarint32(size); + int size = CalculatePackedDataSize(codec); + ctx.WriteTag(tag); + ctx.WriteLength(size); for (int i = 0; i < count; i++) { - writer(output, array[i]); + writer(ref ctx, array[i]); } } else @@ -210,11 +273,11 @@ public void WriteTo(CodedOutputStream output, FieldCodec codec) // Can't use codec.WriteTagAndValue, as that omits default values. for (int i = 0; i < count; i++) { - output.WriteTag(tag); - writer(output, array[i]); + ctx.WriteTag(tag); + writer(ref ctx, array[i]); if (codec.EndTag != 0) { - output.WriteTag(codec.EndTag); + ctx.WriteTag(codec.EndTag); } } } diff --git a/csharp/src/Google.Protobuf/Extension.cs b/csharp/src/Google.Protobuf/Extension.cs index a96f8d29b6a8..6dd1ceaa8ee1 100644 --- a/csharp/src/Google.Protobuf/Extension.cs +++ b/csharp/src/Google.Protobuf/Extension.cs @@ -55,6 +55,8 @@ protected Extension(int fieldNumber) /// Gets the field number of this extension /// public int FieldNumber { get; } + + internal abstract bool IsRepeated { get; } } /// @@ -79,6 +81,8 @@ public Extension(int fieldNumber, FieldCodec codec) : base(fieldNumber) internal override Type TargetType => typeof(TTarget); + internal override bool IsRepeated => false; + internal override IExtensionValue CreateValue() { return new ExtensionValue(codec); @@ -105,6 +109,8 @@ public RepeatedExtension(int fieldNumber, FieldCodec codec) : base(field internal override Type TargetType => typeof(TTarget); + internal override bool IsRepeated => true; + internal override IExtensionValue CreateValue() { return new RepeatedExtensionValue(codec); diff --git a/csharp/src/Google.Protobuf/ExtensionRegistry.cs b/csharp/src/Google.Protobuf/ExtensionRegistry.cs index d3d7ebdc5dd6..e72314b22c29 100644 --- a/csharp/src/Google.Protobuf/ExtensionRegistry.cs +++ b/csharp/src/Google.Protobuf/ExtensionRegistry.cs @@ -80,9 +80,9 @@ private ExtensionRegistry(IDictionary, Extension> collection /// bool ICollection.IsReadOnly => false; - internal bool ContainsInputField(CodedInputStream stream, Type target, out Extension extension) + internal bool ContainsInputField(uint lastTag, Type target, out Extension extension) { - return extensions.TryGetValue(new ObjectIntPair(target, WireFormat.GetTagFieldNumber(stream.LastTag)), out extension); + return extensions.TryGetValue(new ObjectIntPair(target, WireFormat.GetTagFieldNumber(lastTag)), out extension); } /// diff --git a/csharp/src/Google.Protobuf/ExtensionSet.cs b/csharp/src/Google.Protobuf/ExtensionSet.cs index d1bbf6910247..895b9ae6ea4a 100644 --- a/csharp/src/Google.Protobuf/ExtensionSet.cs +++ b/csharp/src/Google.Protobuf/ExtensionSet.cs @@ -34,6 +34,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security; namespace Google.Protobuf { @@ -182,20 +183,37 @@ public static class ExtensionSet /// If the set is null or the field was not otherwise merged, this returns false. /// public static bool TryMergeFieldFrom(ref ExtensionSet set, CodedInputStream stream) where TTarget : IExtendableMessage + { + ParseContext.Initialize(stream, out ParseContext ctx); + try + { + return TryMergeFieldFrom(ref set, ref ctx); + } + finally + { + ctx.CopyStateTo(stream); + } + } + + /// + /// Tries to merge a field from the coded input, returning true if the field was merged. + /// If the set is null or the field was not otherwise merged, this returns false. + /// + public static bool TryMergeFieldFrom(ref ExtensionSet set, ref ParseContext ctx) where TTarget : IExtendableMessage { Extension extension; - int lastFieldNumber = WireFormat.GetTagFieldNumber(stream.LastTag); - + int lastFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag); + IExtensionValue extensionValue; if (set != null && set.ValuesByNumber.TryGetValue(lastFieldNumber, out extensionValue)) { - extensionValue.MergeFrom(stream); + extensionValue.MergeFrom(ref ctx); return true; } - else if (stream.ExtensionRegistry != null && stream.ExtensionRegistry.ContainsInputField(stream, typeof(TTarget), out extension)) + else if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out extension)) { IExtensionValue value = extension.CreateValue(); - value.MergeFrom(stream); + value.MergeFrom(ref ctx); set = (set ?? new ExtensionSet()); set.ValuesByNumber.Add(extension.FieldNumber, value); return true; @@ -326,10 +344,28 @@ public int CalculateSize() /// Writes the extension values in this set to the output stream /// public void WriteTo(CodedOutputStream stream) + { + + WriteContext.Initialize(stream, out WriteContext ctx); + try + { + WriteTo(ref ctx); + } + finally + { + ctx.CopyStateTo(stream); + } + } + + /// + /// Writes the extension values in this set to the write context + /// + [SecuritySafeCritical] + public void WriteTo(ref WriteContext ctx) { foreach (var value in ValuesByNumber.Values) { - value.WriteTo(stream); + value.WriteTo(ref ctx); } } diff --git a/csharp/src/Google.Protobuf/ExtensionValue.cs b/csharp/src/Google.Protobuf/ExtensionValue.cs index 6ee737a7b0c9..ada5d79c8083 100644 --- a/csharp/src/Google.Protobuf/ExtensionValue.cs +++ b/csharp/src/Google.Protobuf/ExtensionValue.cs @@ -38,9 +38,10 @@ namespace Google.Protobuf { internal interface IExtensionValue : IEquatable, IDeepCloneable { - void MergeFrom(CodedInputStream input); + void MergeFrom(ref ParseContext ctx); + void MergeFrom(IExtensionValue value); - void WriteTo(CodedOutputStream output); + void WriteTo(ref WriteContext ctx); int CalculateSize(); bool IsInitialized(); } @@ -91,27 +92,27 @@ public override int GetHashCode() } } - public void MergeFrom(CodedInputStream input) + public void MergeFrom(ref ParseContext ctx) { - codec.ValueMerger(input, ref field); + codec.ValueMerger(ref ctx, ref field); } public void MergeFrom(IExtensionValue value) { if (value is ExtensionValue) { - var extensionValue = value as ExtensionValue; + var extensionValue = value as ExtensionValue; codec.FieldMerger(ref field, extensionValue.field); } } - public void WriteTo(CodedOutputStream output) + public void WriteTo(ref WriteContext ctx) { - output.WriteTag(codec.Tag); - codec.ValueWriter(output, field); + ctx.WriteTag(codec.Tag); + codec.ValueWriter(ref ctx, field); if (codec.EndTag != 0) { - output.WriteTag(codec.EndTag); + ctx.WriteTag(codec.EndTag); } } @@ -124,13 +125,13 @@ public void SetValue(T value) public bool IsInitialized() { - if (field is IMessage) - { - return (field as IMessage).IsInitialized(); + if (field is IMessage) + { + return (field as IMessage).IsInitialized(); } - else - { - return true; + else + { + return true; } } } @@ -180,9 +181,9 @@ public override int GetHashCode() } } - public void MergeFrom(CodedInputStream input) + public void MergeFrom(ref ParseContext ctx) { - field.AddEntriesFrom(input, codec); + field.AddEntriesFrom(ref ctx, codec); } public void MergeFrom(IExtensionValue value) @@ -193,29 +194,29 @@ public void MergeFrom(IExtensionValue value) } } - public void WriteTo(CodedOutputStream output) + public void WriteTo(ref WriteContext ctx) { - field.WriteTo(output, codec); + field.WriteTo(ref ctx, codec); } public RepeatedField GetValue() => field; public bool IsInitialized() { - for (int i = 0; i < field.Count; i++) - { - var element = field[i]; - if (element is IMessage) - { - if (!(element as IMessage).IsInitialized()) - { - return false; - } - } - else - { - break; - } + for (int i = 0; i < field.Count; i++) + { + var element = field[i]; + if (element is IMessage) + { + if (!(element as IMessage).IsInitialized()) + { + return false; + } + } + else + { + break; + } } return true; diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs index 1971261649a0..158739d50ae2 100644 --- a/csharp/src/Google.Protobuf/FieldCodec.cs +++ b/csharp/src/Google.Protobuf/FieldCodec.cs @@ -35,6 +35,7 @@ using Google.Protobuf.WellKnownTypes; using System; using System.Collections.Generic; +using System.Security; namespace Google.Protobuf { @@ -218,7 +219,7 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, FuncA codec for the given tag. public static FieldCodec ForString(uint tag, string defaultValue) { - return new FieldCodec(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadString(), (ref WriteContext ctx, string value) => ctx.WriteString(value), CodedOutputStream.ComputeStringSize, tag, defaultValue); } /// @@ -229,7 +230,7 @@ public static FieldCodec ForString(uint tag, string defaultValue) /// A codec for the given tag. public static FieldCodec ForBytes(uint tag, ByteString defaultValue) { - return new FieldCodec(input => input.ReadBytes(), (output, value) => output.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadBytes(), (ref WriteContext ctx, ByteString value) => ctx.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag, defaultValue); } /// @@ -240,7 +241,7 @@ public static FieldCodec ForBytes(uint tag, ByteString defaultValue) /// A codec for the given tag. public static FieldCodec ForBool(uint tag, bool defaultValue) { - return new FieldCodec(input => input.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.BoolSize, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadBool(), (ref WriteContext ctx, bool value) => ctx.WriteBool(value), CodedOutputStream.BoolSize, tag, defaultValue); } /// @@ -251,7 +252,7 @@ public static FieldCodec ForBool(uint tag, bool defaultValue) /// A codec for the given tag. public static FieldCodec ForInt32(uint tag, int defaultValue) { - return new FieldCodec(input => input.ReadInt32(), (output, value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadInt32(), (ref WriteContext output, int value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag, defaultValue); } /// @@ -262,7 +263,7 @@ public static FieldCodec ForInt32(uint tag, int defaultValue) /// A codec for the given tag. public static FieldCodec ForSInt32(uint tag, int defaultValue) { - return new FieldCodec(input => input.ReadSInt32(), (output, value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadSInt32(), (ref WriteContext output, int value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag, defaultValue); } /// @@ -273,7 +274,7 @@ public static FieldCodec ForSInt32(uint tag, int defaultValue) /// A codec for the given tag. public static FieldCodec ForFixed32(uint tag, uint defaultValue) { - return new FieldCodec(input => input.ReadFixed32(), (output, value) => output.WriteFixed32(value), 4, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadFixed32(), (ref WriteContext output, uint value) => output.WriteFixed32(value), 4, tag, defaultValue); } /// @@ -284,7 +285,7 @@ public static FieldCodec ForFixed32(uint tag, uint defaultValue) /// A codec for the given tag. public static FieldCodec ForSFixed32(uint tag, int defaultValue) { - return new FieldCodec(input => input.ReadSFixed32(), (output, value) => output.WriteSFixed32(value), 4, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadSFixed32(), (ref WriteContext output, int value) => output.WriteSFixed32(value), 4, tag, defaultValue); } /// @@ -295,7 +296,7 @@ public static FieldCodec ForSFixed32(uint tag, int defaultValue) /// A codec for the given tag. public static FieldCodec ForUInt32(uint tag, uint defaultValue) { - return new FieldCodec(input => input.ReadUInt32(), (output, value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadUInt32(), (ref WriteContext output, uint value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag, defaultValue); } /// @@ -306,7 +307,7 @@ public static FieldCodec ForUInt32(uint tag, uint defaultValue) /// A codec for the given tag. public static FieldCodec ForInt64(uint tag, long defaultValue) { - return new FieldCodec(input => input.ReadInt64(), (output, value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadInt64(), (ref WriteContext output, long value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag, defaultValue); } /// @@ -317,7 +318,7 @@ public static FieldCodec ForInt64(uint tag, long defaultValue) /// A codec for the given tag. public static FieldCodec ForSInt64(uint tag, long defaultValue) { - return new FieldCodec(input => input.ReadSInt64(), (output, value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadSInt64(), (ref WriteContext output, long value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag, defaultValue); } /// @@ -328,7 +329,7 @@ public static FieldCodec ForSInt64(uint tag, long defaultValue) /// A codec for the given tag. public static FieldCodec ForFixed64(uint tag, ulong defaultValue) { - return new FieldCodec(input => input.ReadFixed64(), (output, value) => output.WriteFixed64(value), 8, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadFixed64(), (ref WriteContext output, ulong value) => output.WriteFixed64(value), 8, tag, defaultValue); } /// @@ -339,7 +340,7 @@ public static FieldCodec ForFixed64(uint tag, ulong defaultValue) /// A codec for the given tag. public static FieldCodec ForSFixed64(uint tag, long defaultValue) { - return new FieldCodec(input => input.ReadSFixed64(), (output, value) => output.WriteSFixed64(value), 8, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadSFixed64(), (ref WriteContext output, long value) => output.WriteSFixed64(value), 8, tag, defaultValue); } /// @@ -350,7 +351,7 @@ public static FieldCodec ForSFixed64(uint tag, long defaultValue) /// A codec for the given tag. public static FieldCodec ForUInt64(uint tag, ulong defaultValue) { - return new FieldCodec(input => input.ReadUInt64(), (output, value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadUInt64(), (ref WriteContext output, ulong value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag, defaultValue); } /// @@ -361,7 +362,7 @@ public static FieldCodec ForUInt64(uint tag, ulong defaultValue) /// A codec for the given tag. public static FieldCodec ForFloat(uint tag, float defaultValue) { - return new FieldCodec(input => input.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadFloat(), (ref WriteContext output, float value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag, defaultValue); } /// @@ -372,7 +373,7 @@ public static FieldCodec ForFloat(uint tag, float defaultValue) /// A codec for the given tag. public static FieldCodec ForDouble(uint tag, double defaultValue) { - return new FieldCodec(input => input.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag, defaultValue); + return new FieldCodec((ref ParseContext ctx) => ctx.ReadDouble(), (ref WriteContext output, double value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag, defaultValue); } // Enums are tricky. We can probably use expression trees to build these delegates automatically, @@ -388,9 +389,9 @@ public static FieldCodec ForDouble(uint tag, double defaultValue) /// A codec for the given tag. public static FieldCodec ForEnum(uint tag, Func toInt32, Func fromInt32, T defaultValue) { - return new FieldCodec(input => fromInt32( - input.ReadEnum()), - (output, value) => output.WriteEnum(toInt32(value)), + return new FieldCodec((ref ParseContext ctx) => fromInt32( + ctx.ReadEnum()), + (ref WriteContext output, T value) => output.WriteEnum(toInt32(value)), value => CodedOutputStream.ComputeEnumSize(toInt32(value)), tag, defaultValue); } @@ -403,21 +404,21 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func ForMessage(uint tag, MessageParser parser) where T : class, IMessage { return new FieldCodec( - input => + (ref ParseContext ctx) => { T message = parser.CreateTemplate(); - input.ReadMessage(message); + ctx.ReadMessage(message); return message; }, - (output, value) => output.WriteMessage(value), - (CodedInputStream i, ref T v) => + (ref WriteContext output, T value) => output.WriteMessage(value), + (ref ParseContext ctx, ref T v) => { if (v == null) { v = parser.CreateTemplate(); } - i.ReadMessage(v); + ctx.ReadMessage(v); }, (ref T v, T v2) => { @@ -448,21 +449,21 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func ForGroup(uint startTag, uint endTag, MessageParser parser) where T : class, IMessage { return new FieldCodec( - input => + (ref ParseContext ctx) => { T message = parser.CreateTemplate(); - input.ReadGroup(message); + ctx.ReadGroup(message); return message; }, - (output, value) => output.WriteGroup(value), - (CodedInputStream i, ref T v) => + (ref WriteContext output, T value) => output.WriteGroup(value), + (ref ParseContext ctx, ref T v) => { if (v == null) { v = parser.CreateTemplate(); } - i.ReadGroup(v); + ctx.ReadGroup(v); }, (ref T v, T v2) => { @@ -490,9 +491,9 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func(); return new FieldCodec( - input => WrapperCodecs.Read(input, nestedCodec), - (output, value) => WrapperCodecs.Write(output, value, nestedCodec), - (CodedInputStream i, ref T v) => v = WrapperCodecs.Read(i, nestedCodec), + (ref ParseContext ctx) => WrapperCodecs.Read(ref ctx, nestedCodec), + (ref WriteContext output, T value) => WrapperCodecs.Write(ref output, value, nestedCodec), + (ref ParseContext ctx, ref T v) => v = WrapperCodecs.Read(ref ctx, nestedCodec), (ref T v, T v2) => { v = v2; return v == null; }, value => WrapperCodecs.CalculateSize(value, nestedCodec), tag, 0, @@ -508,8 +509,8 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func(); return new FieldCodec( WrapperCodecs.GetReader(), - (output, value) => WrapperCodecs.Write(output, value.Value, nestedCodec), - (CodedInputStream i, ref T? v) => v = WrapperCodecs.Read(i, nestedCodec), + (ref WriteContext output, T? value) => WrapperCodecs.Write(ref output, value.Value, nestedCodec), + (ref ParseContext ctx, ref T? v) => v = WrapperCodecs.Read(ref ctx, nestedCodec), (ref T? v, T? v2) => { if (v2.HasValue) { v = v2; } return v.HasValue; }, value => value == null ? 0 : WrapperCodecs.CalculateSize(value.Value, nestedCodec), tag, 0, @@ -542,17 +543,17 @@ private static class WrapperCodecs private static readonly Dictionary Readers = new Dictionary { // TODO: Provide more optimized readers. - { typeof(bool), (Func)CodedInputStream.ReadBoolWrapper }, - { typeof(int), (Func)CodedInputStream.ReadInt32Wrapper }, - { typeof(long), (Func)CodedInputStream.ReadInt64Wrapper }, - { typeof(uint), (Func)CodedInputStream.ReadUInt32Wrapper }, - { typeof(ulong), (Func)CodedInputStream.ReadUInt64Wrapper }, + { typeof(bool), (ValueReader)ParsingPrimitivesWrappers.ReadBoolWrapper }, + { typeof(int), (ValueReader)ParsingPrimitivesWrappers.ReadInt32Wrapper }, + { typeof(long), (ValueReader)ParsingPrimitivesWrappers.ReadInt64Wrapper }, + { typeof(uint), (ValueReader)ParsingPrimitivesWrappers.ReadUInt32Wrapper }, + { typeof(ulong), (ValueReader)ParsingPrimitivesWrappers.ReadUInt64Wrapper }, { typeof(float), BitConverter.IsLittleEndian ? - (Func)CodedInputStream.ReadFloatWrapperLittleEndian : - (Func)CodedInputStream.ReadFloatWrapperSlow }, + (ValueReader)ParsingPrimitivesWrappers.ReadFloatWrapperLittleEndian : + (ValueReader)ParsingPrimitivesWrappers.ReadFloatWrapperSlow }, { typeof(double), BitConverter.IsLittleEndian ? - (Func)CodedInputStream.ReadDoubleWrapperLittleEndian : - (Func)CodedInputStream.ReadDoubleWrapperSlow }, + (ValueReader)ParsingPrimitivesWrappers.ReadDoubleWrapperLittleEndian : + (ValueReader)ParsingPrimitivesWrappers.ReadDoubleWrapperSlow }, // `string` and `ByteString` less performance-sensitive. Do not implement for now. { typeof(string), null }, { typeof(ByteString), null }, @@ -572,7 +573,7 @@ internal static FieldCodec GetCodec() return (FieldCodec) value; } - internal static Func GetReader() where T : struct + internal static ValueReader GetReader() where T : struct { object value; if (!Readers.TryGetValue(typeof(T), out value)) @@ -583,41 +584,42 @@ internal static FieldCodec GetCodec() { // Return default unoptimized reader for the wrapper type. var nestedCoded = GetCodec(); - return input => Read(input, nestedCoded); + return (ref ParseContext ctx) => Read(ref ctx, nestedCoded); } // Return optimized read for the wrapper type. - return (Func)value; + return (ValueReader)value; } - internal static T Read(CodedInputStream input, FieldCodec codec) + [SecuritySafeCritical] + internal static T Read(ref ParseContext ctx, FieldCodec codec) { - int length = input.ReadLength(); - int oldLimit = input.PushLimit(length); + int length = ctx.ReadLength(); + int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length); uint tag; T value = codec.DefaultValue; - while ((tag = input.ReadTag()) != 0) + while ((tag = ctx.ReadTag()) != 0) { if (tag == codec.Tag) { - value = codec.Read(input); + value = codec.Read(ref ctx); } else { - input.SkipLastField(); + ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state); } } - input.CheckReadEndOfStreamTag(); - input.PopLimit(oldLimit); + ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state); + SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); return value; } - internal static void Write(CodedOutputStream output, T value, FieldCodec codec) + internal static void Write(ref WriteContext ctx, T value, FieldCodec codec) { - output.WriteLength(codec.CalculateSizeWithTag(value)); - codec.WriteTagAndValue(output, value); + ctx.WriteLength(codec.CalculateSizeWithTag(value)); + codec.WriteTagAndValue(ref ctx, value); } internal static int CalculateSize(T value, FieldCodec codec) @@ -628,6 +630,9 @@ internal static int CalculateSize(T value, FieldCodec codec) } } + internal delegate TValue ValueReader(ref ParseContext ctx); + internal delegate void ValueWriter(ref WriteContext ctx, T value); + /// /// /// An encode/decode pair for a single field. This effectively encapsulates @@ -653,7 +658,7 @@ public sealed class FieldCodec /// /// Merges an input stream into a value /// - internal delegate void InputMerger(CodedInputStream input, ref T value); + internal delegate void InputMerger(ref ParseContext ctx, ref T value); /// /// Merges a value into a reference to another value, returning a boolean if the value was set @@ -681,7 +686,7 @@ static FieldCodec() /// /// Returns a delegate to write a value (unconditionally) to a coded output stream. /// - internal Action ValueWriter { get; } + internal ValueWriter ValueWriter { get; } /// /// Returns the size calculator for just a value. @@ -692,7 +697,7 @@ static FieldCodec() /// Returns a delegate to read a value from a coded input stream. It is assumed that /// the stream is already positioned on the appropriate tag. /// - internal Func ValueReader { get; } + internal ValueReader ValueReader { get; } /// /// Returns a delegate to merge a value from a coded input stream. @@ -739,8 +744,8 @@ static FieldCodec() private readonly int tagSize; internal FieldCodec( - Func reader, - Action writer, + ValueReader reader, + ValueWriter writer, int fixedSize, uint tag, T defaultValue) : this(reader, writer, _ => fixedSize, tag, defaultValue) @@ -749,17 +754,17 @@ static FieldCodec() } internal FieldCodec( - Func reader, - Action writer, + ValueReader reader, + ValueWriter writer, Func sizeCalculator, uint tag, - T defaultValue) : this(reader, writer, (CodedInputStream i, ref T v) => v = reader(i), (ref T v, T v2) => { v = v2; return true; }, sizeCalculator, tag, 0, defaultValue) + T defaultValue) : this(reader, writer, (ref ParseContext ctx, ref T v) => v = reader(ref ctx), (ref T v, T v2) => { v = v2; return true; }, sizeCalculator, tag, 0, defaultValue) { } internal FieldCodec( - Func reader, - Action writer, + ValueReader reader, + ValueWriter writer, InputMerger inputMerger, ValuesMerger valuesMerger, Func sizeCalculator, @@ -769,8 +774,8 @@ static FieldCodec() } internal FieldCodec( - Func reader, - Action writer, + ValueReader reader, + ValueWriter writer, InputMerger inputMerger, ValuesMerger valuesMerger, Func sizeCalculator, @@ -798,14 +803,41 @@ static FieldCodec() /// Write a tag and the given value, *if* the value is not the default. /// public void WriteTagAndValue(CodedOutputStream output, T value) + { + WriteContext.Initialize(output, out WriteContext ctx); + try + { + WriteTagAndValue(ref ctx, value); + } + finally + { + ctx.CopyStateTo(output); + } + + + //if (!IsDefault(value)) + //{ + // output.WriteTag(Tag); + // ValueWriter(output, value); + // if (EndTag != 0) + // { + // output.WriteTag(EndTag); + // } + //} + } + + /// + /// Write a tag and the given value, *if* the value is not the default. + /// + public void WriteTagAndValue(ref WriteContext ctx, T value) { if (!IsDefault(value)) { - output.WriteTag(Tag); - ValueWriter(output, value); + ctx.WriteTag(Tag); + ValueWriter(ref ctx, value); if (EndTag != 0) { - output.WriteTag(EndTag); + ctx.WriteTag(EndTag); } } } @@ -815,7 +847,28 @@ public void WriteTagAndValue(CodedOutputStream output, T value) /// /// The input stream to read from. /// The value read from the stream. - public T Read(CodedInputStream input) => ValueReader(input); + public T Read(CodedInputStream input) + { + ParseContext.Initialize(input, out ParseContext ctx); + try + { + return ValueReader(ref ctx); + } + finally + { + ctx.CopyStateTo(input); + } + } + + /// + /// Reads a value of the codec type from the given . + /// + /// The parse context to read from. + /// The value read. + public T Read(ref ParseContext ctx) + { + return ValueReader(ref ctx); + } /// /// Calculates the size required to write the given value, with a tag, diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index e8e33e27e6ff..45541c537a8b 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -4,10 +4,11 @@ C# runtime library for Protocol Buffers - Google's data interchange format. Copyright 2015, Google Inc. Google Protocol Buffers - 3.11.2 - 6 + 3.14.0 + + 7.2 Google Inc. - netstandard1.0;netstandard2.0;net45 + netstandard1.1;netstandard2.0;net45 true ../../keys/Google.Protobuf.snk true @@ -18,25 +19,25 @@ https://github.com/protocolbuffers/protobuf/blob/master/LICENSE git https://github.com/protocolbuffers/protobuf.git + True $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - - $(DefineConstants);GOOGLE_PROTOBUF_SUPPORT_SYSTEM_MEMORY + + $(DefineConstants);GOOGLE_PROTOBUF_SUPPORT_FAST_STRING - - + + + + - - - - - - + + + diff --git a/csharp/src/Google.Protobuf/IBufferMessage.cs b/csharp/src/Google.Protobuf/IBufferMessage.cs new file mode 100644 index 000000000000..05c15db4c62a --- /dev/null +++ b/csharp/src/Google.Protobuf/IBufferMessage.cs @@ -0,0 +1,53 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +namespace Google.Protobuf +{ + /// + /// Interface for a Protocol Buffers message, supporting + /// parsing from and writing to . + /// + public interface IBufferMessage : IMessage + { + /// + /// Internal implementation of merging data from given parse context into this message. + /// Users should never invoke this method directly. + /// + void InternalMergeFrom(ref ParseContext ctx); + + /// + /// Internal implementation of writing this message to a given write context. + /// Users should never invoke this method directly. + /// + void InternalWriteTo(ref WriteContext ctx); + } +} diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs index 5aaefe7a890f..4bffd58c1f40 100644 --- a/csharp/src/Google.Protobuf/JsonFormatter.cs +++ b/csharp/src/Google.Protobuf/JsonFormatter.cs @@ -221,19 +221,12 @@ private bool WriteMessageFields(TextWriter writer, IMessage message, bool assume foreach (var field in fields.InFieldNumberOrder()) { var accessor = field.Accessor; - if (field.ContainingOneof != null && field.ContainingOneof.Accessor.GetCaseFieldDescriptor(message) != field) - { - continue; - } - // Omit default values unless we're asked to format them, or they're oneofs (where the default - // value is still formatted regardless, because that's how we preserve the oneof case). - object value = accessor.GetValue(message); - if (field.ContainingOneof == null && !settings.FormatDefaultValues && IsDefaultValue(accessor, value)) + var value = accessor.GetValue(message); + if (!ShouldFormatFieldValue(message, field, value)) { continue; } - // Okay, all tests complete: let's write the field value... if (!first) { writer.Write(PropertySeparator); @@ -248,6 +241,18 @@ private bool WriteMessageFields(TextWriter writer, IMessage message, bool assume return !first; } + /// + /// Determines whether or not a field value should be serialized according to the field, + /// its value in the message, and the settings of this formatter. + /// + private bool ShouldFormatFieldValue(IMessage message, FieldDescriptor field, object value) => + field.HasPresence + // Fields that support presence *just* use that + ? field.Accessor.HasValue(message) + // Otherwise, format if either we've been asked to format default values, or if it's + // not a default value anyway. + : settings.FormatDefaultValues || !IsDefaultValue(field, value); + // Converted from java/core/src/main/java/com/google/protobuf/Descriptors.java internal static string ToJsonName(string name) { @@ -295,19 +300,19 @@ private static void WriteNull(TextWriter writer) writer.Write("null"); } - private static bool IsDefaultValue(IFieldAccessor accessor, object value) + private static bool IsDefaultValue(FieldDescriptor descriptor, object value) { - if (accessor.Descriptor.IsMap) + if (descriptor.IsMap) { IDictionary dictionary = (IDictionary) value; return dictionary.Count == 0; } - if (accessor.Descriptor.IsRepeated) + if (descriptor.IsRepeated) { IList list = (IList) value; return list.Count == 0; } - switch (accessor.Descriptor.FieldType) + switch (descriptor.FieldType) { case FieldType.Bool: return (bool) value == false; @@ -352,7 +357,7 @@ private static bool IsDefaultValue(IFieldAccessor accessor, object value) /// The value to write. May be null. public void WriteValue(TextWriter writer, object value) { - if (value == null) + if (value == null || value is NullValue) { WriteNull(writer); } @@ -793,8 +798,10 @@ static Settings() } /// - /// Whether fields whose values are the default for the field type (e.g. 0 for integers) - /// should be formatted (true) or omitted (false). + /// Whether fields which would otherwise not be included in the formatted data + /// should be formatted even when the value is not present, or has the default value. + /// This option only affects fields which don't support "presence" (e.g. + /// singular non-optional proto3 primitive fields). /// public bool FormatDefaultValues { get; } diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs index 3f88ea38f177..cb5f5a8f21a7 100644 --- a/csharp/src/Google.Protobuf/JsonParser.cs +++ b/csharp/src/Google.Protobuf/JsonParser.cs @@ -37,6 +37,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -63,6 +64,7 @@ public sealed class JsonParser private static readonly Regex DurationRegex = new Regex(@"^(?-)?(?[0-9]{1,12})(?\.[0-9]{1,9})?s$", FrameworkPortability.CompiledRegexWhereAvailable); private static readonly int[] SubsecondScalingFactors = { 0, 100000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; private static readonly char[] FieldMaskPathSeparators = new[] { ',' }; + private static readonly EnumDescriptor NullValueDescriptor = StructReflection.Descriptor.EnumTypes.Single(ed => ed.ClrType == typeof(NullValue)); private static readonly JsonParser defaultInstance = new JsonParser(Settings.Default); @@ -221,10 +223,11 @@ private void MergeField(IMessage message, FieldDescriptor field, JsonTokenizer t if (token.Type == JsonToken.TokenType.Null) { // Clear the field if we see a null token, unless it's for a singular field of type - // google.protobuf.Value. + // google.protobuf.Value or google.protobuf.NullValue. // Note: different from Java API, which just ignores it. // TODO: Bring it more in line? Discuss... - if (field.IsMap || field.IsRepeated || !IsGoogleProtobufValueField(field)) + if (field.IsMap || field.IsRepeated || + !(IsGoogleProtobufValueField(field) || IsGoogleProtobufNullValueField(field))) { field.Accessor.Clear(message); return; @@ -314,6 +317,12 @@ private static bool IsGoogleProtobufValueField(FieldDescriptor field) field.MessageType.FullName == Value.Descriptor.FullName; } + private static bool IsGoogleProtobufNullValueField(FieldDescriptor field) + { + return field.FieldType == FieldType.Enum && + field.EnumType.FullName == NullValueDescriptor.FullName; + } + private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer) { var token = tokenizer.Next(); @@ -325,6 +334,10 @@ private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer) { return Value.ForNull(); } + if (IsGoogleProtobufNullValueField(field)) + { + return NullValue.NullValue; + } return null; } diff --git a/csharp/src/Google.Protobuf/MessageExtensions.cs b/csharp/src/Google.Protobuf/MessageExtensions.cs index 06e0980ec2b1..36a9df7286ed 100644 --- a/csharp/src/Google.Protobuf/MessageExtensions.cs +++ b/csharp/src/Google.Protobuf/MessageExtensions.cs @@ -31,9 +31,12 @@ #endregion using Google.Protobuf.Reflection; +using System.Buffers; using System.Collections; +using System; using System.IO; using System.Linq; +using System.Security; namespace Google.Protobuf { @@ -127,7 +130,7 @@ public static void WriteDelimitedTo(this IMessage message, Stream output) ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(output, "output"); CodedOutputStream codedOutput = new CodedOutputStream(output); - codedOutput.WriteRawVarint32((uint)message.CalculateSize()); + codedOutput.WriteLength(message.CalculateSize()); message.WriteTo(codedOutput); codedOutput.Flush(); } @@ -143,6 +146,39 @@ public static ByteString ToByteString(this IMessage message) return ByteString.AttachBytes(message.ToByteArray()); } + /// + /// Writes the given message data to the given buffer writer in protobuf encoding. + /// + /// The message to write to the stream. + /// The stream to write to. + [SecuritySafeCritical] + public static void WriteTo(this IMessage message, IBufferWriter output) + { + ProtoPreconditions.CheckNotNull(message, nameof(message)); + ProtoPreconditions.CheckNotNull(output, nameof(output)); + + WriteContext.Initialize(output, out WriteContext ctx); + WritingPrimitivesMessages.WriteRawMessage(ref ctx, message); + ctx.Flush(); + } + + /// + /// Writes the given message data to the given span in protobuf encoding. + /// The size of the destination span needs to fit the serialized size + /// of the message exactly, otherwise an exception is thrown. + /// + /// The message to write to the stream. + /// The span to write to. Size must match size of the message exactly. + [SecuritySafeCritical] + public static void WriteTo(this IMessage message, Span output) + { + ProtoPreconditions.CheckNotNull(message, nameof(message)); + + WriteContext.Initialize(ref output, out WriteContext ctx); + WritingPrimitivesMessages.WriteRawMessage(ref ctx, message); + ctx.CheckNoSpaceLeft(); + } + /// /// Checks if all required fields in a message have values set. For proto3 messages, this returns true /// @@ -248,6 +284,16 @@ internal static void MergeFrom(this IMessage message, Stream input, bool discard codedInput.CheckReadEndOfStreamTag(); } + [SecuritySafeCritical] + internal static void MergeFrom(this IMessage message, ReadOnlySequence data, bool discardUnknownFields, ExtensionRegistry registry) + { + ParseContext.Initialize(data, out ParseContext ctx); + ctx.DiscardUnknownFields = discardUnknownFields; + ctx.ExtensionRegistry = registry; + ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message); + ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state); + } + internal static void MergeDelimitedFrom(this IMessage message, Stream input, bool discardUnknownFields, ExtensionRegistry registry) { ProtoPreconditions.CheckNotNull(message, "message"); diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs index 06d0f1059c7a..f8b26c2348ed 100644 --- a/csharp/src/Google.Protobuf/MessageParser.cs +++ b/csharp/src/Google.Protobuf/MessageParser.cs @@ -31,7 +31,9 @@ #endregion using System; +using System.Buffers; using System.IO; +using System.Security; namespace Google.Protobuf { @@ -113,6 +115,19 @@ public IMessage ParseFrom(Stream input) return message; } + /// + /// Parses a message from the given sequence. + /// + /// The data to parse. + /// The parsed message. + [SecuritySafeCritical] + public IMessage ParseFrom(ReadOnlySequence data) + { + IMessage message = factory(); + message.MergeFrom(data, DiscardUnknownFields, Extensions); + return message; + } + /// /// Parses a length-delimited message from the given stream. /// @@ -287,6 +302,19 @@ public new T ParseFrom(Stream input) return message; } + /// + /// Parses a message from the given sequence. + /// + /// The data to parse. + /// The parsed message. + [SecuritySafeCritical] + public new T ParseFrom(ReadOnlySequence data) + { + T message = factory(); + message.MergeFrom(data, DiscardUnknownFields, Extensions); + return message; + } + /// /// Parses a length-delimited message from the given stream. /// diff --git a/csharp/src/Google.Protobuf/ParseContext.cs b/csharp/src/Google.Protobuf/ParseContext.cs new file mode 100644 index 000000000000..bf4623656525 --- /dev/null +++ b/csharp/src/Google.Protobuf/ParseContext.cs @@ -0,0 +1,329 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Google.Protobuf.Collections; + +namespace Google.Protobuf +{ + /// + /// An opaque struct that represents the current parsing state and is passed along + /// as the parsing proceeds. + /// All the public methods are intended to be invoked only by the generated code, + /// users should never invoke them directly. + /// + [SecuritySafeCritical] + public ref struct ParseContext + { + internal const int DefaultRecursionLimit = 100; + internal const int DefaultSizeLimit = Int32.MaxValue; + + internal ReadOnlySpan buffer; + internal ParserInternalState state; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(ref ReadOnlySpan buffer, ref ParserInternalState state, out ParseContext ctx) + { + ctx.buffer = buffer; + ctx.state = state; + } + + /// + /// Creates a ParseContext instance from CodedInputStream. + /// WARNING: internally this copies the CodedInputStream's state, so after done with the ParseContext, + /// the CodedInputStream's state needs to be updated. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(CodedInputStream input, out ParseContext ctx) + { + ctx.buffer = new ReadOnlySpan(input.InternalBuffer); + // ideally we would use a reference to the original state, but that doesn't seem possible + // so we just copy the struct that holds the state. We will need to later store the state back + // into CodedInputStream if we want to keep it usable. + ctx.state = input.InternalState; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(ReadOnlySequence input, out ParseContext ctx) + { + Initialize(input, DefaultRecursionLimit, out ctx); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(ReadOnlySequence input, int recursionLimit, out ParseContext ctx) + { + ctx.buffer = default; + ctx.state = default; + ctx.state.lastTag = 0; + ctx.state.recursionDepth = 0; + ctx.state.sizeLimit = DefaultSizeLimit; + ctx.state.recursionLimit = recursionLimit; + ctx.state.currentLimit = int.MaxValue; + SegmentedBufferHelper.Initialize(input, out ctx.state.segmentedBufferHelper, out ctx.buffer); + ctx.state.bufferPos = 0; + ctx.state.bufferSize = ctx.buffer.Length; + + ctx.state.DiscardUnknownFields = false; + ctx.state.ExtensionRegistry = null; + } + + /// + /// Returns the last tag read, or 0 if no tags have been read or we've read beyond + /// the end of the input. + /// + internal uint LastTag { get { return state.lastTag; } } + + /// + /// Internal-only property; when set to true, unknown fields will be discarded while parsing. + /// + internal bool DiscardUnknownFields { + get { return state.DiscardUnknownFields; } + set { state.DiscardUnknownFields = value; } + } + + /// + /// Internal-only property; provides extension identifiers to compatible messages while parsing. + /// + internal ExtensionRegistry ExtensionRegistry + { + get { return state.ExtensionRegistry; } + set { state.ExtensionRegistry = value; } + } + + /// + /// Reads a field tag, returning the tag of 0 for "end of input". + /// + /// + /// If this method returns 0, it doesn't necessarily mean the end of all + /// the data in this CodedInputReader; it may be the end of the logical input + /// for an embedded message, for example. + /// + /// The next field tag, or 0 for end of input. (0 is never a valid tag.) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public uint ReadTag() + { + return ParsingPrimitives.ParseTag(ref buffer, ref state); + } + + /// + /// Reads a double field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public double ReadDouble() + { + return ParsingPrimitives.ParseDouble(ref buffer, ref state); + } + + /// + /// Reads a float field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public float ReadFloat() + { + return ParsingPrimitives.ParseFloat(ref buffer, ref state); + } + + /// + /// Reads a uint64 field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ulong ReadUInt64() + { + return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); + } + + /// + /// Reads an int64 field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public long ReadInt64() + { + return (long)ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); + } + + /// + /// Reads an int32 field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadInt32() + { + return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + } + + /// + /// Reads a fixed64 field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ulong ReadFixed64() + { + return ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state); + } + + /// + /// Reads a fixed32 field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public uint ReadFixed32() + { + return ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state); + } + + /// + /// Reads a bool field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool ReadBool() + { + return ParsingPrimitives.ParseRawVarint64(ref buffer, ref state) != 0; + } + /// + /// Reads a string field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public string ReadString() + { + return ParsingPrimitives.ReadString(ref buffer, ref state); + } + + /// + /// Reads an embedded message field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadMessage(IMessage message) + { + ParsingPrimitivesMessages.ReadMessage(ref this, message); + } + + /// + /// Reads an embedded group field from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ReadGroup(IMessage message) + { + ParsingPrimitivesMessages.ReadGroup(ref this, message); + } + + /// + /// Reads a bytes field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ByteString ReadBytes() + { + return ParsingPrimitives.ReadBytes(ref buffer, ref state); + } + /// + /// Reads a uint32 field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public uint ReadUInt32() + { + return ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + } + + /// + /// Reads an enum field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadEnum() + { + // Currently just a pass-through, but it's nice to separate it logically from WriteInt32. + return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + } + + /// + /// Reads an sfixed32 field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadSFixed32() + { + return (int)ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state); + } + + /// + /// Reads an sfixed64 field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public long ReadSFixed64() + { + return (long)ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state); + } + + /// + /// Reads an sint32 field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadSInt32() + { + return ParsingPrimitives.DecodeZigZag32(ParsingPrimitives.ParseRawVarint32(ref buffer, ref state)); + } + + /// + /// Reads an sint64 field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public long ReadSInt64() + { + return ParsingPrimitives.DecodeZigZag64(ParsingPrimitives.ParseRawVarint64(ref buffer, ref state)); + } + + /// + /// Reads a length for length-delimited data. + /// + /// + /// This is internally just reading a varint, but this method exists + /// to make the calling code clearer. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int ReadLength() + { + return (int)ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + } + + internal void CopyStateTo(CodedInputStream input) + { + input.InternalState = state; + } + + internal void LoadStateFrom(CodedInputStream input) + { + state = input.InternalState; + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/ParserInternalState.cs b/csharp/src/Google.Protobuf/ParserInternalState.cs new file mode 100644 index 000000000000..cb4f47143cd8 --- /dev/null +++ b/csharp/src/Google.Protobuf/ParserInternalState.cs @@ -0,0 +1,115 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Google.Protobuf.Collections; + +namespace Google.Protobuf +{ + + // warning: this is a mutable struct, so it needs to be only passed as a ref! + internal struct ParserInternalState + { + // NOTE: the Span representing the current buffer is kept separate so that this doesn't have to be a ref struct and so it can + // be included in CodedInputStream's internal state + + /// + /// The position within the current buffer (i.e. the next byte to read) + /// + internal int bufferPos; + + /// + /// Size of the current buffer + /// + internal int bufferSize; + + /// + /// If we are currently inside a length-delimited block, this is the number of + /// bytes in the buffer that are still available once we leave the delimited block. + /// + internal int bufferSizeAfterLimit; + + /// + /// The absolute position of the end of the current length-delimited block (including totalBytesRetired) + /// + internal int currentLimit; + + /// + /// The total number of consumed before the start of the current buffer. The + /// total bytes read up to the current position can be computed as + /// totalBytesRetired + bufferPos. + /// + internal int totalBytesRetired; + + internal int recursionDepth; // current recursion depth + + internal SegmentedBufferHelper segmentedBufferHelper; + + /// + /// The last tag we read. 0 indicates we've read to the end of the stream + /// (or haven't read anything yet). + /// + internal uint lastTag; + + /// + /// The next tag, used to store the value read by PeekTag. + /// + internal uint nextTag; + internal bool hasNextTag; + + // these fields are configuration, they should be readonly + internal int sizeLimit; + internal int recursionLimit; + + // If non-null, the top level parse method was started with given coded input stream as an argument + // which also means we can potentially fallback to calling MergeFrom(CodedInputStream cis) if needed. + internal CodedInputStream CodedInputStream => segmentedBufferHelper.CodedInputStream; + + /// + /// Internal-only property; when set to true, unknown fields will be discarded while parsing. + /// + internal bool DiscardUnknownFields { get; set; } + + /// + /// Internal-only property; provides extension identifiers to compatible messages while parsing. + /// + internal ExtensionRegistry ExtensionRegistry { get; set; } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/ParsingPrimitives.cs b/csharp/src/Google.Protobuf/ParsingPrimitives.cs new file mode 100644 index 000000000000..e270ed8aa1f4 --- /dev/null +++ b/csharp/src/Google.Protobuf/ParsingPrimitives.cs @@ -0,0 +1,815 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Google.Protobuf.Collections; + +namespace Google.Protobuf +{ + /// + /// Primitives for parsing protobuf wire format. + /// + [SecuritySafeCritical] + internal static class ParsingPrimitives + { + private const int StackallocThreshold = 256; + + /// + /// Reads a length for length-delimited data. + /// + /// + /// This is internally just reading a varint, but this method exists + /// to make the calling code clearer. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ParseLength(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + return (int)ParseRawVarint32(ref buffer, ref state); + } + + /// + /// Parses the next tag. + /// If the end of logical stream was reached, an invalid tag of 0 is returned. + /// + public static uint ParseTag(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + // The "nextTag" logic is there only as an optimization for reading non-packed repeated / map + // fields and is strictly speaking not necessary. + // TODO(jtattermusch): look into simplifying the ParseTag logic. + if (state.hasNextTag) + { + state.lastTag = state.nextTag; + state.hasNextTag = false; + return state.lastTag; + } + + // Optimize for the incredibly common case of having at least two bytes left in the buffer, + // and those two bytes being enough to get the tag. This will be true for fields up to 4095. + if (state.bufferPos + 2 <= state.bufferSize) + { + int tmp = buffer[state.bufferPos++]; + if (tmp < 128) + { + state.lastTag = (uint)tmp; + } + else + { + int result = tmp & 0x7f; + if ((tmp = buffer[state.bufferPos++]) < 128) + { + result |= tmp << 7; + state.lastTag = (uint) result; + } + else + { + // Nope, rewind and go the potentially slow route. + state.bufferPos -= 2; + state.lastTag = ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + } + } + } + else + { + if (SegmentedBufferHelper.IsAtEnd(ref buffer, ref state)) + { + state.lastTag = 0; + return 0; + } + + state.lastTag = ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + } + if (WireFormat.GetTagFieldNumber(state.lastTag) == 0) + { + // If we actually read a tag with a field of 0, that's not a valid tag. + throw InvalidProtocolBufferException.InvalidTag(); + } + return state.lastTag; + } + + /// + /// Peeks at the next tag in the stream. If it matches , + /// the tag is consumed and the method returns true; otherwise, the + /// stream is left in the original position and the method returns false. + /// + public static bool MaybeConsumeTag(ref ReadOnlySpan buffer, ref ParserInternalState state, uint tag) + { + if (PeekTag(ref buffer, ref state) == tag) + { + state.hasNextTag = false; + return true; + } + return false; + } + + /// + /// Peeks at the next field tag. This is like calling , but the + /// tag is not consumed. (So a subsequent call to will return the + /// same value.) + /// + public static uint PeekTag(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + if (state.hasNextTag) + { + return state.nextTag; + } + + uint savedLast = state.lastTag; + state.nextTag = ParseTag(ref buffer, ref state); + state.hasNextTag = true; + state.lastTag = savedLast; // Undo the side effect of ReadTag + return state.nextTag; + } + + /// + /// Parses a raw varint. + /// + public static ulong ParseRawVarint64(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + if (state.bufferPos + 10 > state.bufferSize) + { + return ParseRawVarint64SlowPath(ref buffer, ref state); + } + + ulong result = buffer[state.bufferPos++]; + if (result < 128) + { + return result; + } + result &= 0x7f; + int shift = 7; + do + { + byte b = buffer[state.bufferPos++]; + result |= (ulong)(b & 0x7F) << shift; + if (b < 0x80) + { + return result; + } + shift += 7; + } + while (shift < 64); + + throw InvalidProtocolBufferException.MalformedVarint(); + } + + private static ulong ParseRawVarint64SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + int shift = 0; + ulong result = 0; + do + { + byte b = ReadRawByte(ref buffer, ref state); + result |= (ulong)(b & 0x7F) << shift; + if (b < 0x80) + { + return result; + } + shift += 7; + } + while (shift < 64); + + throw InvalidProtocolBufferException.MalformedVarint(); + } + + /// + /// Parses a raw Varint. If larger than 32 bits, discard the upper bits. + /// This method is optimised for the case where we've got lots of data in the buffer. + /// That means we can check the size just once, then just read directly from the buffer + /// without constant rechecking of the buffer length. + /// + public static uint ParseRawVarint32(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + if (state.bufferPos + 5 > state.bufferSize) + { + return ParseRawVarint32SlowPath(ref buffer, ref state); + } + + int tmp = buffer[state.bufferPos++]; + if (tmp < 128) + { + return (uint)tmp; + } + int result = tmp & 0x7f; + if ((tmp = buffer[state.bufferPos++]) < 128) + { + result |= tmp << 7; + } + else + { + result |= (tmp & 0x7f) << 7; + if ((tmp = buffer[state.bufferPos++]) < 128) + { + result |= tmp << 14; + } + else + { + result |= (tmp & 0x7f) << 14; + if ((tmp = buffer[state.bufferPos++]) < 128) + { + result |= tmp << 21; + } + else + { + result |= (tmp & 0x7f) << 21; + result |= (tmp = buffer[state.bufferPos++]) << 28; + if (tmp >= 128) + { + // Discard upper 32 bits. + // Note that this has to use ReadRawByte() as we only ensure we've + // got at least 5 bytes at the start of the method. This lets us + // use the fast path in more cases, and we rarely hit this section of code. + for (int i = 0; i < 5; i++) + { + if (ReadRawByte(ref buffer, ref state) < 128) + { + return (uint) result; + } + } + throw InvalidProtocolBufferException.MalformedVarint(); + } + } + } + } + return (uint)result; + } + + private static uint ParseRawVarint32SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + int tmp = ReadRawByte(ref buffer, ref state); + if (tmp < 128) + { + return (uint) tmp; + } + int result = tmp & 0x7f; + if ((tmp = ReadRawByte(ref buffer, ref state)) < 128) + { + result |= tmp << 7; + } + else + { + result |= (tmp & 0x7f) << 7; + if ((tmp = ReadRawByte(ref buffer, ref state)) < 128) + { + result |= tmp << 14; + } + else + { + result |= (tmp & 0x7f) << 14; + if ((tmp = ReadRawByte(ref buffer, ref state)) < 128) + { + result |= tmp << 21; + } + else + { + result |= (tmp & 0x7f) << 21; + result |= (tmp = ReadRawByte(ref buffer, ref state)) << 28; + if (tmp >= 128) + { + // Discard upper 32 bits. + for (int i = 0; i < 5; i++) + { + if (ReadRawByte(ref buffer, ref state) < 128) + { + return (uint) result; + } + } + throw InvalidProtocolBufferException.MalformedVarint(); + } + } + } + } + return (uint) result; + } + + /// + /// Parses a 32-bit little-endian integer. + /// + public static uint ParseRawLittleEndian32(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + const int uintLength = sizeof(uint); + const int ulongLength = sizeof(ulong); + if (state.bufferPos + ulongLength > state.bufferSize) + { + return ParseRawLittleEndian32SlowPath(ref buffer, ref state); + } + // ReadUInt32LittleEndian is many times slower than ReadUInt64LittleEndian (at least on some runtimes) + // so it's faster better to use ReadUInt64LittleEndian and truncate the result. + uint result = (uint) BinaryPrimitives.ReadUInt64LittleEndian(buffer.Slice(state.bufferPos, ulongLength)); + state.bufferPos += uintLength; + return result; + } + + private static uint ParseRawLittleEndian32SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + uint b1 = ReadRawByte(ref buffer, ref state); + uint b2 = ReadRawByte(ref buffer, ref state); + uint b3 = ReadRawByte(ref buffer, ref state); + uint b4 = ReadRawByte(ref buffer, ref state); + return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24); + } + + /// + /// Parses a 64-bit little-endian integer. + /// + public static ulong ParseRawLittleEndian64(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + const int length = sizeof(ulong); + if (state.bufferPos + length > state.bufferSize) + { + return ParseRawLittleEndian64SlowPath(ref buffer, ref state); + } + ulong result = BinaryPrimitives.ReadUInt64LittleEndian(buffer.Slice(state.bufferPos, length)); + state.bufferPos += length; + return result; + } + + private static ulong ParseRawLittleEndian64SlowPath(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + ulong b1 = ReadRawByte(ref buffer, ref state); + ulong b2 = ReadRawByte(ref buffer, ref state); + ulong b3 = ReadRawByte(ref buffer, ref state); + ulong b4 = ReadRawByte(ref buffer, ref state); + ulong b5 = ReadRawByte(ref buffer, ref state); + ulong b6 = ReadRawByte(ref buffer, ref state); + ulong b7 = ReadRawByte(ref buffer, ref state); + ulong b8 = ReadRawByte(ref buffer, ref state); + return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24) + | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56); + } + + /// + /// Parses a double value. + /// + public static double ParseDouble(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + const int length = sizeof(double); + if (!BitConverter.IsLittleEndian || state.bufferPos + length > state.bufferSize) + { + return BitConverter.Int64BitsToDouble((long)ParseRawLittleEndian64(ref buffer, ref state)); + } + // ReadUnaligned uses processor architecture for endianness. + double result = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(buffer.Slice(state.bufferPos, length))); + state.bufferPos += length; + return result; + } + + /// + /// Parses a float value. + /// + public static float ParseFloat(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + const int length = sizeof(float); + if (!BitConverter.IsLittleEndian || state.bufferPos + length > state.bufferSize) + { + return ParseFloatSlow(ref buffer, ref state); + } + // ReadUnaligned uses processor architecture for endianness. + float result = Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(buffer.Slice(state.bufferPos, length))); + state.bufferPos += length; + return result; + } + + private static unsafe float ParseFloatSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + const int length = sizeof(float); + byte* stackBuffer = stackalloc byte[length]; + Span tempSpan = new Span(stackBuffer, length); + for (int i = 0; i < length; i++) + { + tempSpan[i] = ReadRawByte(ref buffer, ref state); + } + + // Content is little endian. Reverse if needed to match endianness of architecture. + if (!BitConverter.IsLittleEndian) + { + tempSpan.Reverse(); + } + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(tempSpan)); + } + + /// + /// Reads a fixed size of bytes from the input. + /// + /// + /// the end of the stream or the current limit was reached + /// + public static byte[] ReadRawBytes(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) + { + if (size < 0) + { + throw InvalidProtocolBufferException.NegativeSize(); + } + + if (size <= state.bufferSize - state.bufferPos) + { + // We have all the bytes we need already. + byte[] bytes = new byte[size]; + buffer.Slice(state.bufferPos, size).CopyTo(bytes); + state.bufferPos += size; + return bytes; + } + + return ReadRawBytesSlow(ref buffer, ref state, size); + } + + private static byte[] ReadRawBytesSlow(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) + { + ValidateCurrentLimit(ref buffer, ref state, size); + + if ((!state.segmentedBufferHelper.TotalLength.HasValue && size < buffer.Length) || + IsDataAvailableInSource(ref state, size)) + { + // Reading more bytes than are in the buffer, but not an excessive number + // of bytes. We can safely allocate the resulting array ahead of time. + + byte[] bytes = new byte[size]; + ReadRawBytesIntoSpan(ref buffer, ref state, size, bytes); + return bytes; + } + else + { + // The size is very large. For security reasons, we can't allocate the + // entire byte array yet. The size comes directly from the input, so a + // maliciously-crafted message could provide a bogus very large size in + // order to trick the app into allocating a lot of memory. We avoid this + // by allocating and reading only a small chunk at a time, so that the + // malicious message must actually *be* extremely large to cause + // problems. Meanwhile, we limit the allowed size of a message elsewhere. + + List chunks = new List(); + + int pos = state.bufferSize - state.bufferPos; + byte[] firstChunk = new byte[pos]; + buffer.Slice(state.bufferPos, pos).CopyTo(firstChunk); + chunks.Add(firstChunk); + state.bufferPos = state.bufferSize; + + // Read all the rest of the bytes we need. + int sizeLeft = size - pos; + while (sizeLeft > 0) + { + state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, true); + byte[] chunk = new byte[Math.Min(sizeLeft, state.bufferSize)]; + + buffer.Slice(0, chunk.Length) + .CopyTo(chunk); + state.bufferPos += chunk.Length; + sizeLeft -= chunk.Length; + chunks.Add(chunk); + } + + // OK, got everything. Now concatenate it all into one buffer. + byte[] bytes = new byte[size]; + int newPos = 0; + foreach (byte[] chunk in chunks) + { + Buffer.BlockCopy(chunk, 0, bytes, newPos, chunk.Length); + newPos += chunk.Length; + } + + // Done. + return bytes; + } + } + + /// + /// Reads and discards bytes. + /// + /// the end of the stream + /// or the current limit was reached + public static void SkipRawBytes(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) + { + if (size < 0) + { + throw InvalidProtocolBufferException.NegativeSize(); + } + + ValidateCurrentLimit(ref buffer, ref state, size); + + if (size <= state.bufferSize - state.bufferPos) + { + // We have all the bytes we need already. + state.bufferPos += size; + } + else + { + // Skipping more bytes than are in the buffer. First skip what we have. + int pos = state.bufferSize - state.bufferPos; + state.bufferPos = state.bufferSize; + + // TODO: If our segmented buffer is backed by a Stream that is seekable, we could skip the bytes more efficiently + // by simply updating stream's Position property. This used to be supported in the past, but the support was dropped + // because it would make the segmentedBufferHelper more complex. Support can be reintroduced if needed. + state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, true); + + while (size - pos > state.bufferSize) + { + pos += state.bufferSize; + state.bufferPos = state.bufferSize; + state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, true); + } + + state.bufferPos = size - pos; + } + } + + /// + /// Reads a string field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static string ReadString(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + int length = ParsingPrimitives.ParseLength(ref buffer, ref state); + return ParsingPrimitives.ReadRawString(ref buffer, ref state, length); + } + + /// + /// Reads a bytes field value from the input. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ByteString ReadBytes(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + int length = ParsingPrimitives.ParseLength(ref buffer, ref state); + return ByteString.AttachBytes(ParsingPrimitives.ReadRawBytes(ref buffer, ref state, length)); + } + + /// + /// Reads a UTF-8 string from the next "length" bytes. + /// + /// + /// the end of the stream or the current limit was reached + /// + [SecuritySafeCritical] + public static string ReadRawString(ref ReadOnlySpan buffer, ref ParserInternalState state, int length) + { + // No need to read any data for an empty string. + if (length == 0) + { + return string.Empty; + } + + if (length < 0) + { + throw InvalidProtocolBufferException.NegativeSize(); + } + +#if GOOGLE_PROTOBUF_SUPPORT_FAST_STRING + if (length <= state.bufferSize - state.bufferPos) + { + // Fast path: all bytes to decode appear in the same span. + ReadOnlySpan data = buffer.Slice(state.bufferPos, length); + + string value; + unsafe + { + fixed (byte* sourceBytes = &MemoryMarshal.GetReference(data)) + { + value = WritingPrimitives.Utf8Encoding.GetString(sourceBytes, length); + } + } + + state.bufferPos += length; + return value; + } +#endif + + return ReadStringSlow(ref buffer, ref state, length); + } + + /// + /// Reads a string assuming that it is spread across multiple spans in a . + /// + private static string ReadStringSlow(ref ReadOnlySpan buffer, ref ParserInternalState state, int length) + { + ValidateCurrentLimit(ref buffer, ref state, length); + +#if GOOGLE_PROTOBUF_SUPPORT_FAST_STRING + if (IsDataAvailable(ref state, length)) + { + // Read string data into a temporary buffer, either stackalloc'ed or from ArrayPool + // Once all data is read then call Encoding.GetString on buffer and return to pool if needed. + + byte[] byteArray = null; + Span byteSpan = length <= StackallocThreshold ? + stackalloc byte[length] : + (byteArray = ArrayPool.Shared.Rent(length)); + + try + { + unsafe + { + fixed (byte* pByteSpan = &MemoryMarshal.GetReference(byteSpan)) + { + // Compiler doesn't like that a potentially stackalloc'd Span is being used + // in a method with a "ref Span buffer" argument. If the stackalloc'd span was assigned + // to the ref argument then bad things would happen. We'll never do that so it is ok. + // Make compiler happy by passing a new span created from pointer. + var tempSpan = new Span(pByteSpan, byteSpan.Length); + ReadRawBytesIntoSpan(ref buffer, ref state, length, tempSpan); + + return WritingPrimitives.Utf8Encoding.GetString(pByteSpan, length); + } + } + } + finally + { + if (byteArray != null) + { + ArrayPool.Shared.Return(byteArray); + } + } + } +#endif + + // Slow path: Build a byte array first then copy it. + // This will be called when reading from a Stream because we don't know the length of the stream, + // or there is not enough data in the sequence. If there is not enough data then ReadRawBytes will + // throw an exception. + return WritingPrimitives.Utf8Encoding.GetString(ReadRawBytes(ref buffer, ref state, length), 0, length); + } + + /// + /// Validates that the specified size doesn't exceed the current limit. If it does then remaining bytes + /// are skipped and an error is thrown. + /// + private static void ValidateCurrentLimit(ref ReadOnlySpan buffer, ref ParserInternalState state, int size) + { + if (state.totalBytesRetired + state.bufferPos + size > state.currentLimit) + { + // Read to the end of the stream (up to the current limit) anyway. + SkipRawBytes(ref buffer, ref state, state.currentLimit - state.totalBytesRetired - state.bufferPos); + // Then fail. + throw InvalidProtocolBufferException.TruncatedMessage(); + } + } + + [SecuritySafeCritical] + private static byte ReadRawByte(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + if (state.bufferPos == state.bufferSize) + { + state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, true); + } + return buffer[state.bufferPos++]; + } + + /// + /// Reads a varint from the input one byte at a time, so that it does not + /// read any bytes after the end of the varint. If you simply wrapped the + /// stream in a CodedInputStream and used ReadRawVarint32(Stream) + /// then you would probably end up reading past the end of the varint since + /// CodedInputStream buffers its input. + /// + /// + /// + public static uint ReadRawVarint32(Stream input) + { + int result = 0; + int offset = 0; + for (; offset < 32; offset += 7) + { + int b = input.ReadByte(); + if (b == -1) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + result |= (b & 0x7f) << offset; + if ((b & 0x80) == 0) + { + return (uint) result; + } + } + // Keep reading up to 64 bits. + for (; offset < 64; offset += 7) + { + int b = input.ReadByte(); + if (b == -1) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + if ((b & 0x80) == 0) + { + return (uint) result; + } + } + throw InvalidProtocolBufferException.MalformedVarint(); + } + + /// + /// Decode a 32-bit value with ZigZag encoding. + /// + /// + /// ZigZag encodes signed integers into values that can be efficiently + /// encoded with varint. (Otherwise, negative values must be + /// sign-extended to 32 bits to be varint encoded, thus always taking + /// 5 bytes on the wire.) + /// + public static int DecodeZigZag32(uint n) + { + return (int)(n >> 1) ^ -(int)(n & 1); + } + + /// + /// Decode a 64-bit value with ZigZag encoding. + /// + /// + /// ZigZag encodes signed integers into values that can be efficiently + /// encoded with varint. (Otherwise, negative values must be + /// sign-extended to 64 bits to be varint encoded, thus always taking + /// 10 bytes on the wire.) + /// + public static long DecodeZigZag64(ulong n) + { + return (long)(n >> 1) ^ -(long)(n & 1); + } + + /// + /// Checks whether there is known data available of the specified size remaining to parse. + /// When parsing from a Stream this can return false because we have no knowledge of the amount + /// of data remaining in the stream until it is read. + /// + public static bool IsDataAvailable(ref ParserInternalState state, int size) + { + // Data fits in remaining buffer + if (size <= state.bufferSize - state.bufferPos) + { + return true; + } + + return IsDataAvailableInSource(ref state, size); + } + + /// + /// Checks whether there is known data available of the specified size remaining to parse + /// in the underlying data source. + /// When parsing from a Stream this will return false because we have no knowledge of the amount + /// of data remaining in the stream until it is read. + /// + private static bool IsDataAvailableInSource(ref ParserInternalState state, int size) + { + // Data fits in remaining source data. + // Note that this will never be true when reading from a stream as the total length is unknown. + return size <= state.segmentedBufferHelper.TotalLength - state.totalBytesRetired - state.bufferPos; + } + + /// + /// Read raw bytes of the specified length into a span. The amount of data available and the current limit should + /// be checked before calling this method. + /// + private static void ReadRawBytesIntoSpan(ref ReadOnlySpan buffer, ref ParserInternalState state, int length, Span byteSpan) + { + int remainingByteLength = length; + while (remainingByteLength > 0) + { + if (state.bufferSize - state.bufferPos == 0) + { + state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, true); + } + + ReadOnlySpan unreadSpan = buffer.Slice(state.bufferPos, Math.Min(remainingByteLength, state.bufferSize - state.bufferPos)); + unreadSpan.CopyTo(byteSpan.Slice(length - remainingByteLength)); + + remainingByteLength -= unreadSpan.Length; + state.bufferPos += unreadSpan.Length; + } + } + } +} diff --git a/csharp/src/Google.Protobuf/ParsingPrimitivesMessages.cs b/csharp/src/Google.Protobuf/ParsingPrimitivesMessages.cs new file mode 100644 index 000000000000..b7097a2ad04f --- /dev/null +++ b/csharp/src/Google.Protobuf/ParsingPrimitivesMessages.cs @@ -0,0 +1,229 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.IO; +using System.Runtime.CompilerServices; +using System.Security; + +namespace Google.Protobuf +{ + /// + /// Reading and skipping messages / groups + /// + [SecuritySafeCritical] + internal static class ParsingPrimitivesMessages + { + public static void SkipLastField(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + if (state.lastTag == 0) + { + throw new InvalidOperationException("SkipLastField cannot be called at the end of a stream"); + } + switch (WireFormat.GetTagWireType(state.lastTag)) + { + case WireFormat.WireType.StartGroup: + SkipGroup(ref buffer, ref state, state.lastTag); + break; + case WireFormat.WireType.EndGroup: + throw new InvalidProtocolBufferException( + "SkipLastField called on an end-group tag, indicating that the corresponding start-group was missing"); + case WireFormat.WireType.Fixed32: + ParsingPrimitives.ParseRawLittleEndian32(ref buffer, ref state); + break; + case WireFormat.WireType.Fixed64: + ParsingPrimitives.ParseRawLittleEndian64(ref buffer, ref state); + break; + case WireFormat.WireType.LengthDelimited: + var length = ParsingPrimitives.ParseLength(ref buffer, ref state); + ParsingPrimitives.SkipRawBytes(ref buffer, ref state, length); + break; + case WireFormat.WireType.Varint: + ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + break; + } + } + + /// + /// Skip a group. + /// + public static void SkipGroup(ref ReadOnlySpan buffer, ref ParserInternalState state, uint startGroupTag) + { + // Note: Currently we expect this to be the way that groups are read. We could put the recursion + // depth changes into the ReadTag method instead, potentially... + state.recursionDepth++; + if (state.recursionDepth >= state.recursionLimit) + { + throw InvalidProtocolBufferException.RecursionLimitExceeded(); + } + uint tag; + while (true) + { + tag = ParsingPrimitives.ParseTag(ref buffer, ref state); + if (tag == 0) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + // Can't call SkipLastField for this case- that would throw. + if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup) + { + break; + } + // This recursion will allow us to handle nested groups. + SkipLastField(ref buffer, ref state); + } + int startField = WireFormat.GetTagFieldNumber(startGroupTag); + int endField = WireFormat.GetTagFieldNumber(tag); + if (startField != endField) + { + throw new InvalidProtocolBufferException( + $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}"); + } + state.recursionDepth--; + } + + public static void ReadMessage(ref ParseContext ctx, IMessage message) + { + int length = ParsingPrimitives.ParseLength(ref ctx.buffer, ref ctx.state); + if (ctx.state.recursionDepth >= ctx.state.recursionLimit) + { + throw InvalidProtocolBufferException.RecursionLimitExceeded(); + } + int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, length); + ++ctx.state.recursionDepth; + + ReadRawMessage(ref ctx, message); + + CheckReadEndOfStreamTag(ref ctx.state); + // Check that we've read exactly as much data as expected. + if (!SegmentedBufferHelper.IsReachedLimit(ref ctx.state)) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + --ctx.state.recursionDepth; + SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); + } + + public static void ReadGroup(ref ParseContext ctx, IMessage message) + { + if (ctx.state.recursionDepth >= ctx.state.recursionLimit) + { + throw InvalidProtocolBufferException.RecursionLimitExceeded(); + } + ++ctx.state.recursionDepth; + + uint tag = ctx.state.lastTag; + int fieldNumber = WireFormat.GetTagFieldNumber(tag); + ReadRawMessage(ref ctx, message); + CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup)); + + --ctx.state.recursionDepth; + } + + public static void ReadGroup(ref ParseContext ctx, int fieldNumber, UnknownFieldSet set) + { + if (ctx.state.recursionDepth >= ctx.state.recursionLimit) + { + throw InvalidProtocolBufferException.RecursionLimitExceeded(); + } + ++ctx.state.recursionDepth; + + set.MergeGroupFrom(ref ctx); + CheckLastTagWas(ref ctx.state, WireFormat.MakeTag(fieldNumber, WireFormat.WireType.EndGroup)); + + --ctx.state.recursionDepth; + } + + public static void ReadRawMessage(ref ParseContext ctx, IMessage message) + { + if (message is IBufferMessage bufferMessage) + { + bufferMessage.InternalMergeFrom(ref ctx); + } + else + { + // If we reached here, it means we've ran into a nested message with older generated code + // which doesn't provide the InternalMergeFrom method that takes a ParseContext. + // With a slight performance overhead, we can still parse this message just fine, + // but we need to find the original CodedInputStream instance that initiated this + // parsing process and make sure its internal state is up to date. + // Note that this performance overhead is not very high (basically copying contents of a struct) + // and it will only be incurred in case the application mixes older and newer generated code. + // Regenerating the code from .proto files will remove this overhead because it will + // generate the InternalMergeFrom method we need. + + if (ctx.state.CodedInputStream == null) + { + // This can only happen when the parsing started without providing a CodedInputStream instance + // (e.g. ParseContext was created directly from a ReadOnlySequence). + // That also means that one of the new parsing APIs was used at the top level + // and in such case it is reasonable to require that all the nested message provide + // up-to-date generated code with ParseContext support (and fail otherwise). + throw new InvalidProtocolBufferException($"Message {message.GetType().Name} doesn't provide the generated method that enables ParseContext-based parsing. You might need to regenerate the generated protobuf code."); + } + + ctx.CopyStateTo(ctx.state.CodedInputStream); + try + { + // fallback parse using the CodedInputStream that started current parsing tree + message.MergeFrom(ctx.state.CodedInputStream); + } + finally + { + ctx.LoadStateFrom(ctx.state.CodedInputStream); + } + } + } + + /// + /// Verifies that the last call to ReadTag() returned tag 0 - in other words, + /// we've reached the end of the stream when we expected to. + /// + /// The + /// tag read was not the one specified + public static void CheckReadEndOfStreamTag(ref ParserInternalState state) + { + if (state.lastTag != 0) + { + throw InvalidProtocolBufferException.MoreDataAvailable(); + } + } + + private static void CheckLastTagWas(ref ParserInternalState state, uint expectedTag) + { + if (state.lastTag != expectedTag) { + throw InvalidProtocolBufferException.InvalidEndTag(); + } + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs b/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs new file mode 100644 index 000000000000..629ec32bd81e --- /dev/null +++ b/csharp/src/Google.Protobuf/ParsingPrimitivesWrappers.cs @@ -0,0 +1,355 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Google.Protobuf.Collections; + +namespace Google.Protobuf +{ + /// + /// Fast parsing primitives for wrapper types + /// + [SecuritySafeCritical] + internal static class ParsingPrimitivesWrappers + { + internal static float? ReadFloatWrapperLittleEndian(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + // length:1 + tag:1 + value:4 = 6 bytes + if (state.bufferPos + 6 <= state.bufferSize) + { + // The entire wrapper message is already contained in `buffer`. + int length = buffer[state.bufferPos]; + if (length == 0) + { + state.bufferPos++; + return 0F; + } + // tag:1 + value:4 = length of 5 bytes + // field=1, type=32-bit = tag of 13 + if (length != 5 || buffer[state.bufferPos + 1] != 13) + { + return ReadFloatWrapperSlow(ref buffer, ref state); + } + state.bufferPos += 2; + return ParsingPrimitives.ParseFloat(ref buffer, ref state); + } + else + { + return ReadFloatWrapperSlow(ref buffer, ref state); + } + } + + internal static float? ReadFloatWrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + int length = ParsingPrimitives.ParseLength(ref buffer, ref state); + if (length == 0) + { + return 0F; + } + int finalBufferPos = state.totalBytesRetired + state.bufferPos + length; + float result = 0F; + do + { + // field=1, type=32-bit = tag of 13 + if (ParsingPrimitives.ParseTag(ref buffer, ref state) == 13) + { + result = ParsingPrimitives.ParseFloat(ref buffer, ref state); + } + else + { + ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); + } + } + while (state.totalBytesRetired + state.bufferPos < finalBufferPos); + return result; + } + + internal static double? ReadDoubleWrapperLittleEndian(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + // length:1 + tag:1 + value:8 = 10 bytes + if (state.bufferPos + 10 <= state.bufferSize) + { + // The entire wrapper message is already contained in `buffer`. + int length = buffer[state.bufferPos]; + if (length == 0) + { + state.bufferPos++; + return 0D; + } + // tag:1 + value:8 = length of 9 bytes + // field=1, type=64-bit = tag of 9 + if (length != 9 || buffer[state.bufferPos + 1] != 9) + { + return ReadDoubleWrapperSlow(ref buffer, ref state); + } + state.bufferPos += 2; + return ParsingPrimitives.ParseDouble(ref buffer, ref state); + } + else + { + return ReadDoubleWrapperSlow(ref buffer, ref state); + } + } + + internal static double? ReadDoubleWrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + int length = ParsingPrimitives.ParseLength(ref buffer, ref state); + if (length == 0) + { + return 0D; + } + int finalBufferPos = state.totalBytesRetired + state.bufferPos + length; + double result = 0D; + do + { + // field=1, type=64-bit = tag of 9 + if (ParsingPrimitives.ParseTag(ref buffer, ref state) == 9) + { + result = ParsingPrimitives.ParseDouble(ref buffer, ref state); + } + else + { + ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); + } + } + while (state.totalBytesRetired + state.bufferPos < finalBufferPos); + return result; + } + + internal static bool? ReadBoolWrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + return ReadUInt64Wrapper(ref buffer, ref state) != 0; + } + + internal static uint? ReadUInt32Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + // field=1, type=varint = tag of 8 + const int expectedTag = 8; + // length:1 + tag:1 + value:10(varint64-max) = 12 bytes + // Value can be 64 bits for negative integers + if (state.bufferPos + 12 <= state.bufferSize) + { + // The entire wrapper message is already contained in `buffer`. + int pos0 = state.bufferPos; + int length = buffer[state.bufferPos++]; + if (length == 0) + { + return 0; + } + // Length will always fit in a single byte. + if (length >= 128) + { + state.bufferPos = pos0; + return ReadUInt32WrapperSlow(ref buffer, ref state); + } + int finalBufferPos = state.bufferPos + length; + if (buffer[state.bufferPos++] != expectedTag) + { + state.bufferPos = pos0; + return ReadUInt32WrapperSlow(ref buffer, ref state); + } + var result = ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + // Verify this message only contained a single field. + if (state.bufferPos != finalBufferPos) + { + state.bufferPos = pos0; + return ReadUInt32WrapperSlow(ref buffer, ref state); + } + return result; + } + else + { + return ReadUInt32WrapperSlow(ref buffer, ref state); + } + } + + internal static uint? ReadUInt32WrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + int length = ParsingPrimitives.ParseLength(ref buffer, ref state); + if (length == 0) + { + return 0; + } + int finalBufferPos = state.totalBytesRetired + state.bufferPos + length; + uint result = 0; + do + { + // field=1, type=varint = tag of 8 + if (ParsingPrimitives.ParseTag(ref buffer, ref state) == 8) + { + result = ParsingPrimitives.ParseRawVarint32(ref buffer, ref state); + } + else + { + ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); + } + } + while (state.totalBytesRetired + state.bufferPos < finalBufferPos); + return result; + } + + internal static int? ReadInt32Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + return (int?)ReadUInt32Wrapper(ref buffer, ref state); + } + + internal static ulong? ReadUInt64Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + // field=1, type=varint = tag of 8 + const int expectedTag = 8; + // length:1 + tag:1 + value:10(varint64-max) = 12 bytes + if (state.bufferPos + 12 <= state.bufferSize) + { + // The entire wrapper message is already contained in `buffer`. + int pos0 = state.bufferPos; + int length = buffer[state.bufferPos++]; + if (length == 0) + { + return 0L; + } + // Length will always fit in a single byte. + if (length >= 128) + { + state.bufferPos = pos0; + return ReadUInt64WrapperSlow(ref buffer, ref state); + } + int finalBufferPos = state.bufferPos + length; + if (buffer[state.bufferPos++] != expectedTag) + { + state.bufferPos = pos0; + return ReadUInt64WrapperSlow(ref buffer, ref state); + } + var result = ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); + // Verify this message only contained a single field. + if (state.bufferPos != finalBufferPos) + { + state.bufferPos = pos0; + return ReadUInt64WrapperSlow(ref buffer, ref state); + } + return result; + } + else + { + return ReadUInt64WrapperSlow(ref buffer, ref state); + } + } + + internal static ulong? ReadUInt64WrapperSlow(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + // field=1, type=varint = tag of 8 + const int expectedTag = 8; + int length = ParsingPrimitives.ParseLength(ref buffer, ref state); + if (length == 0) + { + return 0L; + } + int finalBufferPos = state.totalBytesRetired + state.bufferPos + length; + ulong result = 0L; + do + { + if (ParsingPrimitives.ParseTag(ref buffer, ref state) == expectedTag) + { + result = ParsingPrimitives.ParseRawVarint64(ref buffer, ref state); + } + else + { + ParsingPrimitivesMessages.SkipLastField(ref buffer, ref state); + } + } + while (state.totalBytesRetired + state.bufferPos < finalBufferPos); + return result; + } + + internal static long? ReadInt64Wrapper(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + return (long?)ReadUInt64Wrapper(ref buffer, ref state); + } + + internal static float? ReadFloatWrapperLittleEndian(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadFloatWrapperLittleEndian(ref ctx.buffer, ref ctx.state); + } + + internal static float? ReadFloatWrapperSlow(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadFloatWrapperSlow(ref ctx.buffer, ref ctx.state); + } + + internal static double? ReadDoubleWrapperLittleEndian(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadDoubleWrapperLittleEndian(ref ctx.buffer, ref ctx.state); + } + + internal static double? ReadDoubleWrapperSlow(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadDoubleWrapperSlow(ref ctx.buffer, ref ctx.state); + } + + internal static bool? ReadBoolWrapper(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadBoolWrapper(ref ctx.buffer, ref ctx.state); + } + + internal static uint? ReadUInt32Wrapper(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadUInt32Wrapper(ref ctx.buffer, ref ctx.state); + } + + internal static int? ReadInt32Wrapper(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadInt32Wrapper(ref ctx.buffer, ref ctx.state); + } + + internal static ulong? ReadUInt64Wrapper(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadUInt64Wrapper(ref ctx.buffer, ref ctx.state); + } + + internal static ulong? ReadUInt64WrapperSlow(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadUInt64WrapperSlow(ref ctx.buffer, ref ctx.state); + } + + internal static long? ReadInt64Wrapper(ref ParseContext ctx) + { + return ParsingPrimitivesWrappers.ReadInt64Wrapper(ref ctx.buffer, ref ctx.state); + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs b/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs index 9b179bd7cd60..130bcf00041d 100644 --- a/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs +++ b/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs @@ -47,3 +47,10 @@ "981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" + "b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" + "c5ae9cb6")] + +[assembly: InternalsVisibleTo("Google.Protobuf.Benchmarks, PublicKey=" + + "002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a1" + + "7c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd" + + "981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dc" + + "b6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665" + + "c5ae9cb6")] diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index 59c260018c04..0a1f4a74408a 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -54,7 +54,7 @@ public static partial class DescriptorReflection { "b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnMaKwoNUmVzZXJ2ZWRSYW5nZRIN", "CgVzdGFydBgBIAEoBRILCgNlbmQYAiABKAUiZwoVRXh0ZW5zaW9uUmFuZ2VP", "cHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2ds", - "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIivAUK", + "ZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi1QUK", "FEZpZWxkRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoGbnVtYmVy", "GAMgASgFEjoKBWxhYmVsGAQgASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxk", "RGVzY3JpcHRvclByb3RvLkxhYmVsEjgKBHR5cGUYBSABKA4yKi5nb29nbGUu", @@ -62,102 +62,102 @@ public static partial class DescriptorReflection { "bWUYBiABKAkSEAoIZXh0ZW5kZWUYAiABKAkSFQoNZGVmYXVsdF92YWx1ZRgH", "IAEoCRITCgtvbmVvZl9pbmRleBgJIAEoBRIRCglqc29uX25hbWUYCiABKAkS", "LgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlv", - "bnMitgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQARIOCgpUWVBFX0ZMT0FUEAIS", - "DgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0EAQSDgoKVFlQRV9JTlQz", - "MhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVfRklYRUQzMhAHEg0KCVRZ", - "UEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoKVFlQRV9HUk9VUBAKEhAK", - "DFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQDBIPCgtUWVBFX1VJTlQz", - "MhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJWEVEMzIQDxIRCg1UWVBF", - "X1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIPCgtUWVBFX1NJTlQ2NBAS", - "IkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFMEAESEgoOTEFCRUxfUkVRVUlS", - "RUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIlQKFE9uZW9mRGVzY3JpcHRvclBy", - "b3RvEgwKBG5hbWUYASABKAkSLgoHb3B0aW9ucxgCIAEoCzIdLmdvb2dsZS5w", - "cm90b2J1Zi5PbmVvZk9wdGlvbnMipAIKE0VudW1EZXNjcmlwdG9yUHJvdG8S", - "DAoEbmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMoCzIpLmdvb2dsZS5wcm90b2J1", - "Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SLQoHb3B0aW9ucxgDIAEoCzIc", - "Lmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxJOCg5yZXNlcnZlZF9yYW5n", - "ZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3Rv", - "LkVudW1SZXNlcnZlZFJhbmdlEhUKDXJlc2VydmVkX25hbWUYBSADKAkaLwoR", - "RW51bVJlc2VydmVkUmFuZ2USDQoFc3RhcnQYASABKAUSCwoDZW5kGAIgASgF", - "ImwKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEg4K", - "Bm51bWJlchgCIAEoBRIyCgdvcHRpb25zGAMgASgLMiEuZ29vZ2xlLnByb3Rv", - "YnVmLkVudW1WYWx1ZU9wdGlvbnMikAEKFlNlcnZpY2VEZXNjcmlwdG9yUHJv", - "dG8SDAoEbmFtZRgBIAEoCRI2CgZtZXRob2QYAiADKAsyJi5nb29nbGUucHJv", - "dG9idWYuTWV0aG9kRGVzY3JpcHRvclByb3RvEjAKB29wdGlvbnMYAyABKAsy", - "Hy5nb29nbGUucHJvdG9idWYuU2VydmljZU9wdGlvbnMiwQEKFU1ldGhvZERl", - "c2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEhIKCmlucHV0X3R5cGUYAiAB", - "KAkSEwoLb3V0cHV0X3R5cGUYAyABKAkSLwoHb3B0aW9ucxgEIAEoCzIeLmdv", - "b2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zEh8KEGNsaWVudF9zdHJlYW1p", - "bmcYBSABKAg6BWZhbHNlEh8KEHNlcnZlcl9zdHJlYW1pbmcYBiABKAg6BWZh", - "bHNlIqYGCgtGaWxlT3B0aW9ucxIUCgxqYXZhX3BhY2thZ2UYASABKAkSHAoU", - "amF2YV9vdXRlcl9jbGFzc25hbWUYCCABKAkSIgoTamF2YV9tdWx0aXBsZV9m", - "aWxlcxgKIAEoCDoFZmFsc2USKQodamF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5k", - "X2hhc2gYFCABKAhCAhgBEiUKFmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgYGyAB", - "KAg6BWZhbHNlEkYKDG9wdGltaXplX2ZvchgJIAEoDjIpLmdvb2dsZS5wcm90", - "b2J1Zi5GaWxlT3B0aW9ucy5PcHRpbWl6ZU1vZGU6BVNQRUVEEhIKCmdvX3Bh", - "Y2thZ2UYCyABKAkSIgoTY2NfZ2VuZXJpY19zZXJ2aWNlcxgQIAEoCDoFZmFs", - "c2USJAoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZRIiChNw", - "eV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZRIjChRwaHBfZ2VuZXJp", - "Y19zZXJ2aWNlcxgqIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgXIAEoCDoF", - "ZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2USGQoRb2Jq", - "Y19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVzcGFjZRglIAEo", - "CRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSGAoQcGhwX2NsYXNzX3ByZWZpeBgo", - "IAEoCRIVCg1waHBfbmFtZXNwYWNlGCkgASgJEh4KFnBocF9tZXRhZGF0YV9u", - "YW1lc3BhY2UYLCABKAkSFAoMcnVieV9wYWNrYWdlGC0gASgJEkMKFHVuaW50", - "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu", - "dGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0K", - "CUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAJKBAgm", - "ECci8gEKDk1lc3NhZ2VPcHRpb25zEiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9y", - "bWF0GAEgASgIOgVmYWxzZRIuCh9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2Fj", - "Y2Vzc29yGAIgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxz", - "ZRIRCgltYXBfZW50cnkYByABKAgSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y", - "5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24q", - "CQjoBxCAgICAAkoECAgQCUoECAkQCiKeAwoMRmllbGRPcHRpb25zEjoKBWN0", - "eXBlGAEgASgOMiMuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlw", - "ZToGU1RSSU5HEg4KBnBhY2tlZBgCIAEoCBI/CgZqc3R5cGUYBiABKA4yJC5n", - "b29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkpTVHlwZToJSlNfTk9STUFM", - "EhMKBGxhenkYBSABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZh", - "bHNlEhMKBHdlYWsYCiABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0", - "aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0", - "aW9uIi8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxTVFJJTkdf", - "UElFQ0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNfU1RSSU5H", - "EAESDQoJSlNfTlVNQkVSEAIqCQjoBxCAgICAAkoECAQQBSJeCgxPbmVvZk9w", - "dGlvbnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xl", - "LnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoL", - "RW51bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMYAiABKAgSGQoKZGVwcmVjYXRl", - "ZBgDIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygL", - "MiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCA", - "gICAAkoECAUQBiJ9ChBFbnVtVmFsdWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQY", - "ASABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIk", - "Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICA", - "gAIiewoOU2VydmljZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFs", - "c2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy", - "b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKtAgoNTWV0", - "aG9kT3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJfChFpZGVt", - "cG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RP", - "cHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV04S", + "bnMSFwoPcHJvdG8zX29wdGlvbmFsGBEgASgIIrYCCgRUeXBlEg8KC1RZUEVf", + "RE9VQkxFEAESDgoKVFlQRV9GTE9BVBACEg4KClRZUEVfSU5UNjQQAxIPCgtU", + "WVBFX1VJTlQ2NBAEEg4KClRZUEVfSU5UMzIQBRIQCgxUWVBFX0ZJWEVENjQQ", + "BhIQCgxUWVBFX0ZJWEVEMzIQBxINCglUWVBFX0JPT0wQCBIPCgtUWVBFX1NU", + "UklORxAJEg4KClRZUEVfR1JPVVAQChIQCgxUWVBFX01FU1NBR0UQCxIOCgpU", + "WVBFX0JZVEVTEAwSDwoLVFlQRV9VSU5UMzIQDRINCglUWVBFX0VOVU0QDhIR", + "Cg1UWVBFX1NGSVhFRDMyEA8SEQoNVFlQRV9TRklYRUQ2NBAQEg8KC1RZUEVf", + "U0lOVDMyEBESDwoLVFlQRV9TSU5UNjQQEiJDCgVMYWJlbBISCg5MQUJFTF9P", + "UFRJT05BTBABEhIKDkxBQkVMX1JFUVVJUkVEEAISEgoOTEFCRUxfUkVQRUFU", + "RUQQAyJUChRPbmVvZkRlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEi4K", + "B29wdGlvbnMYAiABKAsyHS5nb29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25z", + "IqQCChNFbnVtRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSOAoFdmFs", + "dWUYAiADKAsyKS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRv", + "clByb3RvEi0KB29wdGlvbnMYAyABKAsyHC5nb29nbGUucHJvdG9idWYuRW51", + "bU9wdGlvbnMSTgoOcmVzZXJ2ZWRfcmFuZ2UYBCADKAsyNi5nb29nbGUucHJv", + "dG9idWYuRW51bURlc2NyaXB0b3JQcm90by5FbnVtUmVzZXJ2ZWRSYW5nZRIV", + "Cg1yZXNlcnZlZF9uYW1lGAUgAygJGi8KEUVudW1SZXNlcnZlZFJhbmdlEg0K", + "BXN0YXJ0GAEgASgFEgsKA2VuZBgCIAEoBSJsChhFbnVtVmFsdWVEZXNjcmlw", + "dG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIOCgZudW1iZXIYAiABKAUSMgoHb3B0", + "aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVPcHRpb25z", + "IpABChZTZXJ2aWNlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSNgoG", + "bWV0aG9kGAIgAygLMiYuZ29vZ2xlLnByb3RvYnVmLk1ldGhvZERlc2NyaXB0", + "b3JQcm90bxIwCgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNl", + "cnZpY2VPcHRpb25zIsEBChVNZXRob2REZXNjcmlwdG9yUHJvdG8SDAoEbmFt", + "ZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJEhMKC291dHB1dF90eXBlGAMg", + "ASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29nbGUucHJvdG9idWYuTWV0aG9k", + "T3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5nGAUgASgIOgVmYWxzZRIfChBz", + "ZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxzZSKlBgoLRmlsZU9wdGlvbnMS", + "FAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGphdmFfb3V0ZXJfY2xhc3NuYW1l", + "GAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlEikK", + "HWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoGBQgASgIQgIYARIlChZq", + "YXZhX3N0cmluZ19jaGVja191dGY4GBsgASgIOgVmYWxzZRJGCgxvcHRpbWl6", + "ZV9mb3IYCSABKA4yKS5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMuT3B0", + "aW1pemVNb2RlOgVTUEVFRBISCgpnb19wYWNrYWdlGAsgASgJEiIKE2NjX2dl", + "bmVyaWNfc2VydmljZXMYECABKAg6BWZhbHNlEiQKFWphdmFfZ2VuZXJpY19z", + "ZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoTcHlfZ2VuZXJpY19zZXJ2aWNlcxgS", + "IAEoCDoFZmFsc2USIwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZh", + "bHNlEhkKCmRlcHJlY2F0ZWQYFyABKAg6BWZhbHNlEh4KEGNjX2VuYWJsZV9h", + "cmVuYXMYHyABKAg6BHRydWUSGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkS", + "GAoQY3NoYXJwX25hbWVzcGFjZRglIAEoCRIUCgxzd2lmdF9wcmVmaXgYJyAB", + "KAkSGAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCRIVCg1waHBfbmFtZXNwYWNl", + "GCkgASgJEh4KFnBocF9tZXRhZGF0YV9uYW1lc3BhY2UYLCABKAkSFAoMcnVi", + "eV9wYWNrYWdlGC0gASgJEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMo", + "CzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIjoKDE9w", + "dGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVf", + "UlVOVElNRRADKgkI6AcQgICAgAJKBAgmECci8gEKDk1lc3NhZ2VPcHRpb25z", + "EiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZRIuCh9u", + "b19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vzc29yGAIgASgIOgVmYWxzZRIZ", + "CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIRCgltYXBfZW50cnkYByABKAgS", "QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv", - "YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIX", - "ChNJREVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAES", - "DgoKSURFTVBPVEVOVBACKgkI6AcQgICAgAIingIKE1VuaW50ZXJwcmV0ZWRP", - "cHRpb24SOwoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy", - "cHJldGVkT3B0aW9uLk5hbWVQYXJ0EhgKEGlkZW50aWZpZXJfdmFsdWUYAyAB", - "KAkSGgoScG9zaXRpdmVfaW50X3ZhbHVlGAQgASgEEhoKEm5lZ2F0aXZlX2lu", - "dF92YWx1ZRgFIAEoAxIUCgxkb3VibGVfdmFsdWUYBiABKAESFAoMc3RyaW5n", - "X3ZhbHVlGAcgASgMEhcKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCRozCghOYW1l", - "UGFydBIRCgluYW1lX3BhcnQYASACKAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigI", - "ItUBCg5Tb3VyY2VDb2RlSW5mbxI6Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2ds", - "ZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbhqGAQoITG9jYXRp", - "b24SEAoEcGF0aBgBIAMoBUICEAESEAoEc3BhbhgCIAMoBUICEAESGAoQbGVh", - "ZGluZ19jb21tZW50cxgDIAEoCRIZChF0cmFpbGluZ19jb21tZW50cxgEIAEo", - "CRIhChlsZWFkaW5nX2RldGFjaGVkX2NvbW1lbnRzGAYgAygJIqcBChFHZW5l", - "cmF0ZWRDb2RlSW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29vZ2xlLnBy", - "b3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24aTwoKQW5ub3Rh", - "dGlvbhIQCgRwYXRoGAEgAygFQgIQARITCgtzb3VyY2VfZmlsZRgCIAEoCRIN", - "CgViZWdpbhgDIAEoBRILCgNlbmQYBCABKAVCjwEKE2NvbS5nb29nbGUucHJv", - "dG9idWZCEERlc2NyaXB0b3JQcm90b3NIAVo+Z2l0aHViLmNvbS9nb2xhbmcv", - "cHJvdG9idWYvcHJvdG9jLWdlbi1nby9kZXNjcmlwdG9yO2Rlc2NyaXB0b3L4", - "AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbg==")); + "YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAgQCUoECAkQ", + "CiKeAwoMRmllbGRPcHRpb25zEjoKBWN0eXBlGAEgASgOMiMuZ29vZ2xlLnBy", + "b3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToGU1RSSU5HEg4KBnBhY2tlZBgC", + "IAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29nbGUucHJvdG9idWYuRmllbGRP", + "cHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMKBGxhenkYBSABKAg6BWZhbHNl", + "EhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhMKBHdlYWsYCiABKAg6BWZh", + "bHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5w", + "cm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIi8KBUNUeXBlEgoKBlNUUklO", + "RxAAEggKBENPUkQQARIQCgxTVFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJ", + "SlNfTk9STUFMEAASDQoJSlNfU1RSSU5HEAESDQoJSlNfTlVNQkVSEAIqCQjo", + "BxCAgICAAkoECAQQBSJeCgxPbmVvZk9wdGlvbnMSQwoUdW5pbnRlcnByZXRl", + "ZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0", + "ZWRPcHRpb24qCQjoBxCAgICAAiKTAQoLRW51bU9wdGlvbnMSEwoLYWxsb3df", + "YWxpYXMYAiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USQwoUdW5p", + "bnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVu", + "aW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiJ9ChBFbnVtVmFs", + "dWVPcHRpb25zEhkKCmRlcHJlY2F0ZWQYASABKAg6BWZhbHNlEkMKFHVuaW50", + "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu", + "dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiewoOU2VydmljZU9wdGlvbnMS", + "GQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9v", + "cHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRP", + "cHRpb24qCQjoBxCAgICAAiKtAgoNTWV0aG9kT3B0aW9ucxIZCgpkZXByZWNh", + "dGVkGCEgASgIOgVmYWxzZRJfChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIv", + "Lmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2", + "ZWw6E0lERU1QT1RFTkNZX1VOS05PV04SQwoUdW5pbnRlcnByZXRlZF9vcHRp", + "b24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRp", + "b24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dO", + "EAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQ", + "gICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFtZRgCIAMoCzIt", + "Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0", + "EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRpdmVfaW50X3Zh", + "bHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEoAxIUCgxkb3Vi", + "bGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgMEhcKD2FnZ3Jl", + "Z2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFydBIRCgluYW1lX3BhcnQYASAC", + "KAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIItUBCg5Tb3VyY2VDb2RlSW5mbxI6", + "Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2Rl", + "SW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24SEAoEcGF0aBgBIAMoBUICEAES", + "EAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGluZ19jb21tZW50cxgDIAEoCRIZ", + "ChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIhChlsZWFkaW5nX2RldGFjaGVk", + "X2NvbW1lbnRzGAYgAygJIqcBChFHZW5lcmF0ZWRDb2RlSW5mbxJBCgphbm5v", + "dGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJ", + "bmZvLkFubm90YXRpb24aTwoKQW5ub3RhdGlvbhIQCgRwYXRoGAEgAygFQgIQ", + "ARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgViZWdpbhgDIAEoBRILCgNlbmQY", + "BCABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rv", + "c0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9kZXNjcmlw", + "dG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbg==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -166,7 +166,7 @@ public static partial class DescriptorReflection { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End", "Options" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null, null)}), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Parser, new[]{ "UninterpretedOption" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options", "Proto3Optional" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name", "Options" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options", "ReservedRange", "ReservedName" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange), global::Google.Protobuf.Reflection.EnumDescriptorProto.Types.EnumReservedRange.Parser, new[]{ "Start", "End" }, null, null, null, null)}), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null, null), @@ -193,7 +193,11 @@ public static partial class DescriptorReflection { /// The protocol compiler can output a FileDescriptorSet containing the .proto /// files it parses. /// - public sealed partial class FileDescriptorSet : pb::IMessage { + public sealed partial class FileDescriptorSet : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileDescriptorSet()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -271,11 +275,25 @@ public sealed partial class FileDescriptorSet : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else file_.WriteTo(output, _repeated_file_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + file_.WriteTo(ref output, _repeated_file_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -298,6 +316,9 @@ public sealed partial class FileDescriptorSet : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -310,14 +331,37 @@ public sealed partial class FileDescriptorSet : pb::IMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + file_.AddEntriesFrom(ref input, _repeated_file_codec); + break; + } + } + } } + #endif } /// /// Describes a complete .proto file. /// - public sealed partial class FileDescriptorProto : pb::IMessage { + public sealed partial class FileDescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileDescriptorProto()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -351,8 +395,8 @@ public sealed partial class FileDescriptorProto : pb::IMessageGets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } /// Field number for the "source_code_info" field. public const int SourceCodeInfoFieldNumber = 9; @@ -534,16 +568,6 @@ public sealed partial class FileDescriptorProto : pb::IMessageGets whether the source_code_info field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasSourceCodeInfo { - get { return sourceCodeInfo_ != null; } - } - /// Clears the value of the source_code_info field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearSourceCodeInfo() { - sourceCodeInfo_ = null; - } /// Field number for the "syntax" field. public const int SyntaxFieldNumber = 12; @@ -612,8 +636,8 @@ public sealed partial class FileDescriptorProto : pb::IMessage /// Describes a message type. /// - public sealed partial class DescriptorProto : pb::IMessage { + public sealed partial class DescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DescriptorProto()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -832,7 +974,7 @@ public sealed partial class DescriptorProto : pb::IMessage { enumType_ = other.enumType_.Clone(); extensionRange_ = other.extensionRange_.Clone(); oneofDecl_ = other.oneofDecl_.Clone(); - options_ = other.HasOptions ? other.options_.Clone() : null; + options_ = other.options_ != null ? other.options_.Clone() : null; reservedRange_ = other.reservedRange_.Clone(); reservedName_ = other.reservedName_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); @@ -936,16 +1078,6 @@ public sealed partial class DescriptorProto : pb::IMessage { options_ = value; } } - /// Gets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } /// Field number for the "reserved_range" field. public const int ReservedRangeFieldNumber = 9; @@ -1007,7 +1139,7 @@ public sealed partial class DescriptorProto : pb::IMessage { hash ^= enumType_.GetHashCode(); hash ^= extensionRange_.GetHashCode(); hash ^= oneofDecl_.GetHashCode(); - if (HasOptions) hash ^= Options.GetHashCode(); + if (options_ != null) hash ^= Options.GetHashCode(); hash ^= reservedRange_.GetHashCode(); hash ^= reservedName_.GetHashCode(); if (_unknownFields != null) { @@ -1023,6 +1155,9 @@ public sealed partial class DescriptorProto : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasName) { output.WriteRawTag(10); output.WriteString(Name); @@ -1032,7 +1167,7 @@ public sealed partial class DescriptorProto : pb::IMessage { enumType_.WriteTo(output, _repeated_enumType_codec); extensionRange_.WriteTo(output, _repeated_extensionRange_codec); extension_.WriteTo(output, _repeated_extension_codec); - if (HasOptions) { + if (options_ != null) { output.WriteRawTag(58); output.WriteMessage(Options); } @@ -1042,8 +1177,34 @@ public sealed partial class DescriptorProto : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasName) { + output.WriteRawTag(10); + output.WriteString(Name); + } + field_.WriteTo(ref output, _repeated_field_codec); + nestedType_.WriteTo(ref output, _repeated_nestedType_codec); + enumType_.WriteTo(ref output, _repeated_enumType_codec); + extensionRange_.WriteTo(ref output, _repeated_extensionRange_codec); + extension_.WriteTo(ref output, _repeated_extension_codec); + if (options_ != null) { + output.WriteRawTag(58); + output.WriteMessage(Options); + } + oneofDecl_.WriteTo(ref output, _repeated_oneofDecl_codec); + reservedRange_.WriteTo(ref output, _repeated_reservedRange_codec); + reservedName_.WriteTo(ref output, _repeated_reservedName_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -1056,7 +1217,7 @@ public sealed partial class DescriptorProto : pb::IMessage { size += enumType_.CalculateSize(_repeated_enumType_codec); size += extensionRange_.CalculateSize(_repeated_extensionRange_codec); size += oneofDecl_.CalculateSize(_repeated_oneofDecl_codec); - if (HasOptions) { + if (options_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options); } size += reservedRange_.CalculateSize(_repeated_reservedRange_codec); @@ -1081,8 +1242,8 @@ public sealed partial class DescriptorProto : pb::IMessage { enumType_.Add(other.enumType_); extensionRange_.Add(other.extensionRange_); oneofDecl_.Add(other.oneofDecl_); - if (other.HasOptions) { - if (!HasOptions) { + if (other.options_ != null) { + if (options_ == null) { Options = new global::Google.Protobuf.Reflection.MessageOptions(); } Options.MergeFrom(other.Options); @@ -1094,6 +1255,9 @@ public sealed partial class DescriptorProto : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1125,7 +1289,7 @@ public sealed partial class DescriptorProto : pb::IMessage { break; } case 58: { - if (!HasOptions) { + if (options_ == null) { Options = new global::Google.Protobuf.Reflection.MessageOptions(); } input.ReadMessage(Options); @@ -1145,13 +1309,75 @@ public sealed partial class DescriptorProto : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + field_.AddEntriesFrom(ref input, _repeated_field_codec); + break; + } + case 26: { + nestedType_.AddEntriesFrom(ref input, _repeated_nestedType_codec); + break; + } + case 34: { + enumType_.AddEntriesFrom(ref input, _repeated_enumType_codec); + break; + } + case 42: { + extensionRange_.AddEntriesFrom(ref input, _repeated_extensionRange_codec); + break; + } + case 50: { + extension_.AddEntriesFrom(ref input, _repeated_extension_codec); + break; + } + case 58: { + if (options_ == null) { + Options = new global::Google.Protobuf.Reflection.MessageOptions(); + } + input.ReadMessage(Options); + break; + } + case 66: { + oneofDecl_.AddEntriesFrom(ref input, _repeated_oneofDecl_codec); + break; + } + case 74: { + reservedRange_.AddEntriesFrom(ref input, _repeated_reservedRange_codec); + break; + } + case 82: { + reservedName_.AddEntriesFrom(ref input, _repeated_reservedName_codec); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the DescriptorProto message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class ExtensionRange : pb::IMessage { + public sealed partial class ExtensionRange : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ExtensionRange()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -1180,7 +1406,7 @@ public sealed partial class ExtensionRange : pb::IMessage { _hasBits0 = other._hasBits0; start_ = other.start_; end_ = other.end_; - options_ = other.HasOptions ? other.options_.Clone() : null; + options_ = other.options_ != null ? other.options_.Clone() : null; _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -1253,16 +1479,6 @@ public sealed partial class ExtensionRange : pb::IMessage { options_ = value; } } - /// Gets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -1288,7 +1504,7 @@ public sealed partial class ExtensionRange : pb::IMessage { int hash = 1; if (HasStart) hash ^= Start.GetHashCode(); if (HasEnd) hash ^= End.GetHashCode(); - if (HasOptions) hash ^= Options.GetHashCode(); + if (options_ != null) hash ^= Options.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } @@ -1302,6 +1518,9 @@ public sealed partial class ExtensionRange : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasStart) { output.WriteRawTag(8); output.WriteInt32(Start); @@ -1310,14 +1529,36 @@ public sealed partial class ExtensionRange : pb::IMessage { output.WriteRawTag(16); output.WriteInt32(End); } - if (HasOptions) { + if (options_ != null) { output.WriteRawTag(26); output.WriteMessage(Options); } if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasStart) { + output.WriteRawTag(8); + output.WriteInt32(Start); + } + if (HasEnd) { + output.WriteRawTag(16); + output.WriteInt32(End); + } + if (options_ != null) { + output.WriteRawTag(26); + output.WriteMessage(Options); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1328,7 +1569,7 @@ public sealed partial class ExtensionRange : pb::IMessage { if (HasEnd) { size += 1 + pb::CodedOutputStream.ComputeInt32Size(End); } - if (HasOptions) { + if (options_ != null) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options); } if (_unknownFields != null) { @@ -1348,8 +1589,8 @@ public sealed partial class ExtensionRange : pb::IMessage { if (other.HasEnd) { End = other.End; } - if (other.HasOptions) { - if (!HasOptions) { + if (other.options_ != null) { + if (options_ == null) { Options = new global::Google.Protobuf.Reflection.ExtensionRangeOptions(); } Options.MergeFrom(other.Options); @@ -1359,6 +1600,9 @@ public sealed partial class ExtensionRange : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1374,7 +1618,36 @@ public sealed partial class ExtensionRange : pb::IMessage { break; } case 26: { - if (!HasOptions) { + if (options_ == null) { + Options = new global::Google.Protobuf.Reflection.ExtensionRangeOptions(); + } + input.ReadMessage(Options); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Start = input.ReadInt32(); + break; + } + case 16: { + End = input.ReadInt32(); + break; + } + case 26: { + if (options_ == null) { Options = new global::Google.Protobuf.Reflection.ExtensionRangeOptions(); } input.ReadMessage(Options); @@ -1383,6 +1656,7 @@ public sealed partial class ExtensionRange : pb::IMessage { } } } + #endif } @@ -1391,7 +1665,11 @@ public sealed partial class ExtensionRange : pb::IMessage { /// fields or extension ranges in the same message. Reserved ranges may /// not overlap. /// - public sealed partial class ReservedRange : pb::IMessage { + public sealed partial class ReservedRange : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ReservedRange()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -1518,6 +1796,9 @@ public sealed partial class ReservedRange : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasStart) { output.WriteRawTag(8); output.WriteInt32(Start); @@ -1529,7 +1810,25 @@ public sealed partial class ReservedRange : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasStart) { + output.WriteRawTag(8); + output.WriteInt32(Start); + } + if (HasEnd) { + output.WriteRawTag(16); + output.WriteInt32(End); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1562,6 +1861,9 @@ public sealed partial class ReservedRange : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1578,7 +1880,30 @@ public sealed partial class ReservedRange : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Start = input.ReadInt32(); + break; + } + case 16: { + End = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -1587,7 +1912,11 @@ public sealed partial class ReservedRange : pb::IMessage { } - public sealed partial class ExtensionRangeOptions : pb::IExtendableMessage { + public sealed partial class ExtensionRangeOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ExtensionRangeOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -1677,6 +2006,9 @@ public sealed partial class ExtensionRangeOptions : pb::IExtendableMessage(pb::Extension extension) { - return pb::ExtensionSet.Get(ref _extensions, extension); - } - public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { - return pb::ExtensionSet.Get(ref _extensions, extension); - } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + case 7994: { + uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec); + break; + } + } + } + } + #endif + + public TValue GetExtension(pb::Extension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } + public pbc::RepeatedField GetExtension(pb::RepeatedExtension extension) { + return pb::ExtensionSet.Get(ref _extensions, extension); + } public pbc::RepeatedField GetOrInitializeExtension(pb::RepeatedExtension extension) { return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension); } @@ -1754,7 +2124,11 @@ public sealed partial class ExtensionRangeOptions : pb::IExtendableMessage /// Describes a field within a message. /// - public sealed partial class FieldDescriptorProto : pb::IMessage { + public sealed partial class FieldDescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FieldDescriptorProto()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -1790,7 +2164,8 @@ public sealed partial class FieldDescriptorProto : pb::IMessageGets whether the options field is set + + /// Field number for the "proto3_optional" field. + public const int Proto3OptionalFieldNumber = 17; + private readonly static bool Proto3OptionalDefaultValue = false; + + private bool proto3Optional_; + /// + /// If true, this is a proto3 "optional". When a proto3 field is optional, it + /// tracks presence regardless of field type. + /// + /// When proto3_optional is true, this field must be belong to a oneof to + /// signal to old proto3 clients that presence is tracked for this field. This + /// oneof is known as a "synthetic" oneof, and this field must be its sole + /// member (each proto3 optional field gets its own synthetic oneof). Synthetic + /// oneofs exist in the descriptor only, and do not generate any API. Synthetic + /// oneofs must be ordered after all "real" oneofs. + /// + /// For message fields, proto3_optional doesn't create any semantic change, + /// since non-repeated message fields always track presence. However it still + /// indicates the semantic detail of whether the user wrote "optional" or not. + /// This can be useful for round-tripping the .proto file. For consistency we + /// give message fields a synthetic oneof also, even though it is not required + /// to track presence. This is especially important because the parser can't + /// tell if a field is a message or an enum, so it must always create a + /// synthetic oneof. + /// + /// Proto2 optional fields do not set this flag, because they already indicate + /// optional with `LABEL_OPTIONAL`. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public bool Proto3Optional { + get { if ((_hasBits0 & 16) != 0) { return proto3Optional_; } else { return Proto3OptionalDefaultValue; } } + set { + _hasBits0 |= 16; + proto3Optional_ = value; + } + } + /// Gets whether the "proto3_optional" field is set [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } + public bool HasProto3Optional { + get { return (_hasBits0 & 16) != 0; } } - /// Clears the value of the options field + /// Clears the value of the "proto3_optional" field [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; + public void ClearProto3Optional() { + _hasBits0 &= ~16; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2086,6 +2498,7 @@ public sealed partial class FieldDescriptorProto : pb::IMessageContainer for nested types declared in the FieldDescriptorProto message type. @@ -2367,7 +2917,11 @@ public enum Label { /// /// Describes a oneof. /// - public sealed partial class OneofDescriptorProto : pb::IMessage { + public sealed partial class OneofDescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneofDescriptorProto()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2393,7 +2947,7 @@ public sealed partial class OneofDescriptorProto : pb::IMessageGets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -2468,7 +3012,7 @@ public sealed partial class OneofDescriptorProto : pb::IMessage /// Describes an enum type. /// - public sealed partial class EnumDescriptorProto : pb::IMessage { + public sealed partial class EnumDescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumDescriptorProto()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -2582,7 +3180,7 @@ public sealed partial class EnumDescriptorProto : pb::IMessageGets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } /// Field number for the "reserved_range" field. public const int ReservedRangeFieldNumber = 4; @@ -2702,7 +3290,7 @@ public sealed partial class EnumDescriptorProto : pb::IMessageContainer for nested types declared in the EnumDescriptorProto message type. @@ -2819,7 +3472,11 @@ public static partial class Types { /// is inclusive such that it can appropriately represent the entire int32 /// domain. /// - public sealed partial class EnumReservedRange : pb::IMessage { + public sealed partial class EnumReservedRange : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumReservedRange()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -2946,6 +3603,9 @@ public sealed partial class EnumReservedRange : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasStart) { output.WriteRawTag(8); output.WriteInt32(Start); @@ -2957,8 +3617,26 @@ public sealed partial class EnumReservedRange : pb::IMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasStart) { + output.WriteRawTag(8); + output.WriteInt32(Start); + } + if (HasEnd) { + output.WriteRawTag(16); + output.WriteInt32(End); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -2990,6 +3668,9 @@ public sealed partial class EnumReservedRange : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -3006,7 +3687,30 @@ public sealed partial class EnumReservedRange : pb::IMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Start = input.ReadInt32(); + break; + } + case 16: { + End = input.ReadInt32(); + break; + } + } + } } + #endif } @@ -3018,7 +3722,11 @@ public sealed partial class EnumReservedRange : pb::IMessage /// /// Describes a value within an enum. /// - public sealed partial class EnumValueDescriptorProto : pb::IMessage { + public sealed partial class EnumValueDescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumValueDescriptorProto()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -3047,7 +3755,7 @@ public sealed partial class EnumValueDescriptorProto : pb::IMessageGets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } - + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as EnumValueDescriptorProto); @@ -3148,7 +3846,7 @@ public sealed partial class EnumValueDescriptorProto : pb::IMessage /// Describes a service. /// - public sealed partial class ServiceDescriptorProto : pb::IMessage { + public sealed partial class ServiceDescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServiceDescriptorProto()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -3276,7 +4036,7 @@ public sealed partial class ServiceDescriptorProto : pb::IMessageGets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { @@ -3363,7 +4113,7 @@ public sealed partial class ServiceDescriptorProto : pb::IMessage /// Describes a method of a service. /// - public sealed partial class MethodDescriptorProto : pb::IMessage { + public sealed partial class MethodDescriptorProto : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MethodDescriptorProto()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -3487,7 +4296,7 @@ public sealed partial class MethodDescriptorProto : pb::IMessageGets whether the options field is set - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public bool HasOptions { - get { return options_ != null; } - } - /// Clears the value of the options field - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void ClearOptions() { - options_ = null; - } /// Field number for the "client_streaming" field. public const int ClientStreamingFieldNumber = 5; @@ -3674,7 +4473,7 @@ public sealed partial class MethodDescriptorProto : pb::IMessage { + public sealed partial class FileOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FileOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -4222,7 +5107,7 @@ public sealed partial class FileOptions : pb::IExtendableMessage { /// Field number for the "cc_enable_arenas" field. public const int CcEnableArenasFieldNumber = 31; - private readonly static bool CcEnableArenasDefaultValue = false; + private readonly static bool CcEnableArenasDefaultValue = true; private bool ccEnableArenas_; /// @@ -4535,6 +5420,9 @@ public sealed partial class FileOptions : pb::IExtendableMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasJavaPackage) { output.WriteRawTag(10); output.WriteString(JavaPackage); @@ -4622,7 +5510,101 @@ public sealed partial class FileOptions : pb::IExtendableMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasJavaPackage) { + output.WriteRawTag(10); + output.WriteString(JavaPackage); + } + if (HasJavaOuterClassname) { + output.WriteRawTag(66); + output.WriteString(JavaOuterClassname); + } + if (HasOptimizeFor) { + output.WriteRawTag(72); + output.WriteEnum((int) OptimizeFor); + } + if (HasJavaMultipleFiles) { + output.WriteRawTag(80); + output.WriteBool(JavaMultipleFiles); + } + if (HasGoPackage) { + output.WriteRawTag(90); + output.WriteString(GoPackage); + } + if (HasCcGenericServices) { + output.WriteRawTag(128, 1); + output.WriteBool(CcGenericServices); + } + if (HasJavaGenericServices) { + output.WriteRawTag(136, 1); + output.WriteBool(JavaGenericServices); + } + if (HasPyGenericServices) { + output.WriteRawTag(144, 1); + output.WriteBool(PyGenericServices); + } + if (HasJavaGenerateEqualsAndHash) { + output.WriteRawTag(160, 1); + output.WriteBool(JavaGenerateEqualsAndHash); + } + if (HasDeprecated) { + output.WriteRawTag(184, 1); + output.WriteBool(Deprecated); + } + if (HasJavaStringCheckUtf8) { + output.WriteRawTag(216, 1); + output.WriteBool(JavaStringCheckUtf8); + } + if (HasCcEnableArenas) { + output.WriteRawTag(248, 1); + output.WriteBool(CcEnableArenas); + } + if (HasObjcClassPrefix) { + output.WriteRawTag(162, 2); + output.WriteString(ObjcClassPrefix); + } + if (HasCsharpNamespace) { + output.WriteRawTag(170, 2); + output.WriteString(CsharpNamespace); + } + if (HasSwiftPrefix) { + output.WriteRawTag(186, 2); + output.WriteString(SwiftPrefix); + } + if (HasPhpClassPrefix) { + output.WriteRawTag(194, 2); + output.WriteString(PhpClassPrefix); + } + if (HasPhpNamespace) { + output.WriteRawTag(202, 2); + output.WriteString(PhpNamespace); + } + if (HasPhpGenericServices) { + output.WriteRawTag(208, 2); + output.WriteBool(PhpGenericServices); + } + if (HasPhpMetadataNamespace) { + output.WriteRawTag(226, 2); + output.WriteString(PhpMetadataNamespace); + } + if (HasRubyPackage) { + output.WriteRawTag(234, 2); + output.WriteString(RubyPackage); + } + uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -4762,19 +5744,122 @@ public sealed partial class FileOptions : pb::IExtendableMessage { if (other.HasRubyPackage) { RubyPackage = other.RubyPackage; } - uninterpretedOption_.Add(other.uninterpretedOption_); - pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); - _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + uninterpretedOption_.Add(other.uninterpretedOption_); + pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + } + break; + case 10: { + JavaPackage = input.ReadString(); + break; + } + case 66: { + JavaOuterClassname = input.ReadString(); + break; + } + case 72: { + OptimizeFor = (global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) input.ReadEnum(); + break; + } + case 80: { + JavaMultipleFiles = input.ReadBool(); + break; + } + case 90: { + GoPackage = input.ReadString(); + break; + } + case 128: { + CcGenericServices = input.ReadBool(); + break; + } + case 136: { + JavaGenericServices = input.ReadBool(); + break; + } + case 144: { + PyGenericServices = input.ReadBool(); + break; + } + case 160: { + JavaGenerateEqualsAndHash = input.ReadBool(); + break; + } + case 184: { + Deprecated = input.ReadBool(); + break; + } + case 216: { + JavaStringCheckUtf8 = input.ReadBool(); + break; + } + case 248: { + CcEnableArenas = input.ReadBool(); + break; + } + case 290: { + ObjcClassPrefix = input.ReadString(); + break; + } + case 298: { + CsharpNamespace = input.ReadString(); + break; + } + case 314: { + SwiftPrefix = input.ReadString(); + break; + } + case 322: { + PhpClassPrefix = input.ReadString(); + break; + } + case 330: { + PhpNamespace = input.ReadString(); + break; + } + case 336: { + PhpGenericServices = input.ReadBool(); + break; + } + case 354: { + PhpMetadataNamespace = input.ReadString(); + break; + } + case 362: { + RubyPackage = input.ReadString(); + break; + } + case 7994: { + uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); + break; + } + } + } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public void MergeFrom(pb::CodedInputStream input) { + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) { - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); } break; case 10: { @@ -4858,12 +5943,13 @@ public sealed partial class FileOptions : pb::IExtendableMessage { break; } case 7994: { - uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec); + uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec); break; } } } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -4914,7 +6000,11 @@ public enum OptimizeMode { } - public sealed partial class MessageOptions : pb::IExtendableMessage { + public sealed partial class MessageOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MessageOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -5168,6 +6258,9 @@ public sealed partial class MessageOptions : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -5298,7 +6461,11 @@ public sealed partial class MessageOptions : pb::IExtendableMessage { + public sealed partial class FieldOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FieldOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -5616,6 +6783,9 @@ public sealed partial class FieldOptions : pb::IExtendableMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasCtype) { output.WriteRawTag(8); output.WriteEnum((int) Ctype); @@ -5647,7 +6817,45 @@ public sealed partial class FieldOptions : pb::IExtendableMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasCtype) { + output.WriteRawTag(8); + output.WriteEnum((int) Ctype); + } + if (HasPacked) { + output.WriteRawTag(16); + output.WriteBool(Packed); + } + if (HasDeprecated) { + output.WriteRawTag(24); + output.WriteBool(Deprecated); + } + if (HasLazy) { + output.WriteRawTag(40); + output.WriteBool(Lazy); + } + if (HasJstype) { + output.WriteRawTag(48); + output.WriteEnum((int) Jstype); + } + if (HasWeak) { + output.WriteRawTag(80); + output.WriteBool(Weak); + } + uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5710,6 +6918,9 @@ public sealed partial class FieldOptions : pb::IExtendableMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5748,7 +6959,52 @@ public sealed partial class FieldOptions : pb::IExtendableMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + case 8: { + Ctype = (global::Google.Protobuf.Reflection.FieldOptions.Types.CType) input.ReadEnum(); + break; + } + case 16: { + Packed = input.ReadBool(); + break; + } + case 24: { + Deprecated = input.ReadBool(); + break; + } + case 40: { + Lazy = input.ReadBool(); + break; + } + case 48: { + Jstype = (global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) input.ReadEnum(); + break; + } + case 80: { + Weak = input.ReadBool(); + break; + } + case 7994: { + uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec); + break; + } + } + } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -5805,7 +7061,11 @@ public enum JSType { } - public sealed partial class OneofOptions : pb::IExtendableMessage { + public sealed partial class OneofOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new OneofOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -5895,6 +7155,9 @@ public sealed partial class OneofOptions : pb::IExtendableMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec); if (_extensions != null) { _extensions.WriteTo(output); @@ -5902,7 +7165,21 @@ public sealed partial class OneofOptions : pb::IExtendableMessage if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -5929,6 +7206,9 @@ public sealed partial class OneofOptions : pb::IExtendableMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -5943,7 +7223,28 @@ public sealed partial class OneofOptions : pb::IExtendableMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + case 7994: { + uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec); + break; + } + } + } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -5969,7 +7270,11 @@ public sealed partial class OneofOptions : pb::IExtendableMessage } - public sealed partial class EnumOptions : pb::IExtendableMessage { + public sealed partial class EnumOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -6125,6 +7430,9 @@ public sealed partial class EnumOptions : pb::IExtendableMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasAllowAlias) { output.WriteRawTag(16); output.WriteBool(AllowAlias); @@ -6140,8 +7448,30 @@ public sealed partial class EnumOptions : pb::IExtendableMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasAllowAlias) { + output.WriteRawTag(16); + output.WriteBool(AllowAlias); + } + if (HasDeprecated) { + output.WriteRawTag(24); + output.WriteBool(Deprecated); + } + uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec); + if (_extensions != null) { + _extensions.WriteTo(ref output); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -6179,6 +7509,9 @@ public sealed partial class EnumOptions : pb::IExtendableMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -6201,7 +7534,36 @@ public sealed partial class EnumOptions : pb::IExtendableMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) { + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + } + break; + case 16: { + AllowAlias = input.ReadBool(); + break; + } + case 24: { + Deprecated = input.ReadBool(); + break; + } + case 7994: { + uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec); + break; + } + } + } } + #endif public TValue GetExtension(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -6227,7 +7589,11 @@ public sealed partial class EnumOptions : pb::IExtendableMessage { } - public sealed partial class EnumValueOptions : pb::IExtendableMessage { + public sealed partial class EnumValueOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumValueOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -6352,6 +7718,9 @@ public sealed partial class EnumValueOptions : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -6440,7 +7855,11 @@ public sealed partial class EnumValueOptions : pb::IExtendableMessage { + public sealed partial class ServiceOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ServiceOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -6565,6 +7984,9 @@ public sealed partial class ServiceOptions : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -6653,7 +8121,11 @@ public sealed partial class ServiceOptions : pb::IExtendableMessage { + public sealed partial class MethodOptions : pb::IExtendableMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new MethodOptions()); private pb::UnknownFieldSet _unknownFields; internal pb::ExtensionSet _extensions; @@ -6805,6 +8277,9 @@ public sealed partial class MethodOptions : pb::IExtendableMessage(pb::Extension extension) { return pb::ExtensionSet.Get(ref _extensions, extension); @@ -6939,7 +8468,11 @@ public enum IdempotencyLevel { /// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions /// in them. /// - public sealed partial class UninterpretedOption : pb::IMessage { + public sealed partial class UninterpretedOption : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new UninterpretedOption()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -7182,6 +8715,9 @@ public sealed partial class UninterpretedOption : pb::IMessageContainer for nested types declared in the UninterpretedOption message type. @@ -7318,7 +8935,11 @@ public static partial class Types { /// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents /// "foo.(bar.baz).qux". /// - public sealed partial class NamePart : pb::IMessage { + public sealed partial class NamePart : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new NamePart()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -7438,6 +9059,9 @@ public sealed partial class NamePart : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (HasNamePart_) { output.WriteRawTag(10); output.WriteString(NamePart_); @@ -7449,7 +9073,25 @@ public sealed partial class NamePart : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasNamePart_) { + output.WriteRawTag(10); + output.WriteString(NamePart_); + } + if (HasIsExtension) { + output.WriteRawTag(16); + output.WriteBool(IsExtension); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7482,6 +9124,9 @@ public sealed partial class NamePart : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7498,7 +9143,30 @@ public sealed partial class NamePart : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + NamePart_ = input.ReadString(); + break; + } + case 16: { + IsExtension = input.ReadBool(); + break; + } + } + } } + #endif } @@ -7511,7 +9179,11 @@ public sealed partial class NamePart : pb::IMessage { /// Encapsulates information about the original source file from which a /// FileDescriptorProto was generated. /// - public sealed partial class SourceCodeInfo : pb::IMessage { + public sealed partial class SourceCodeInfo : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SourceCodeInfo()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -7634,11 +9306,25 @@ public sealed partial class SourceCodeInfo : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else location_.WriteTo(output, _repeated_location_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + location_.WriteTo(ref output, _repeated_location_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7661,6 +9347,9 @@ public sealed partial class SourceCodeInfo : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7673,13 +9362,36 @@ public sealed partial class SourceCodeInfo : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + location_.AddEntriesFrom(ref input, _repeated_location_codec); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the SourceCodeInfo message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class Location : pb::IMessage { + public sealed partial class Location : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Location()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -7916,6 +9628,9 @@ public sealed partial class Location : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else path_.WriteTo(output, _repeated_path_codec); span_.WriteTo(output, _repeated_span_codec); if (HasLeadingComments) { @@ -7930,7 +9645,28 @@ public sealed partial class Location : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + path_.WriteTo(ref output, _repeated_path_codec); + span_.WriteTo(ref output, _repeated_span_codec); + if (HasLeadingComments) { + output.WriteRawTag(26); + output.WriteString(LeadingComments); + } + if (HasTrailingComments) { + output.WriteRawTag(34); + output.WriteString(TrailingComments); + } + leadingDetachedComments_.WriteTo(ref output, _repeated_leadingDetachedComments_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -7969,6 +9705,9 @@ public sealed partial class Location : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -7999,7 +9738,44 @@ public sealed partial class Location : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: + case 8: { + path_.AddEntriesFrom(ref input, _repeated_path_codec); + break; + } + case 18: + case 16: { + span_.AddEntriesFrom(ref input, _repeated_span_codec); + break; + } + case 26: { + LeadingComments = input.ReadString(); + break; + } + case 34: { + TrailingComments = input.ReadString(); + break; + } + case 50: { + leadingDetachedComments_.AddEntriesFrom(ref input, _repeated_leadingDetachedComments_codec); + break; + } + } + } } + #endif } @@ -8013,7 +9789,11 @@ public sealed partial class Location : pb::IMessage { /// file. A GeneratedCodeInfo message is associated with only one generated /// source file, but may contain references to different source .proto files. /// - public sealed partial class GeneratedCodeInfo : pb::IMessage { + public sealed partial class GeneratedCodeInfo : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new GeneratedCodeInfo()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -8095,11 +9875,25 @@ public sealed partial class GeneratedCodeInfo : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else annotation_.WriteTo(output, _repeated_annotation_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + annotation_.WriteTo(ref output, _repeated_annotation_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -8122,6 +9916,9 @@ public sealed partial class GeneratedCodeInfo : pb::IMessage [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -8134,13 +9931,36 @@ public sealed partial class GeneratedCodeInfo : pb::IMessage } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + annotation_.AddEntriesFrom(ref input, _repeated_annotation_codec); + break; + } + } + } } + #endif #region Nested types /// Container for nested types declared in the GeneratedCodeInfo message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public static partial class Types { - public sealed partial class Annotation : pb::IMessage { + public sealed partial class Annotation : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Annotation()); private pb::UnknownFieldSet _unknownFields; private int _hasBits0; @@ -8316,6 +10136,9 @@ public sealed partial class Annotation : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else path_.WriteTo(output, _repeated_path_codec); if (HasSourceFile) { output.WriteRawTag(18); @@ -8332,7 +10155,30 @@ public sealed partial class Annotation : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + path_.WriteTo(ref output, _repeated_path_codec); + if (HasSourceFile) { + output.WriteRawTag(18); + output.WriteString(SourceFile); + } + if (HasBegin) { + output.WriteRawTag(24); + output.WriteInt32(Begin); + } + if (HasEnd) { + output.WriteRawTag(32); + output.WriteInt32(End); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -8373,6 +10219,9 @@ public sealed partial class Annotation : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -8398,7 +10247,39 @@ public sealed partial class Annotation : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: + case 8: { + path_.AddEntriesFrom(ref input, _repeated_path_codec); + break; + } + case 18: { + SourceFile = input.ReadString(); + break; + } + case 24: { + Begin = input.ReadInt32(); + break; + } + case 32: { + End = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs index 264a88a063bc..f7e8b5b5f28d 100644 --- a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs @@ -128,12 +128,21 @@ public EnumValueDescriptor FindValueByName(string name) /// /// The (possibly empty) set of custom options for this enum. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions() method.")] public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); + /// + /// The EnumOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public EnumOptions GetOptions() => Proto.Options?.Clone(); + /// /// Gets a single value enum option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = Proto.Options.GetExtension(extension); @@ -143,6 +152,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value enum option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { return Proto.Options.GetExtension(extension).Clone(); diff --git a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs index 393382010559..05097bd1da3d 100644 --- a/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/EnumValueDescriptor.cs @@ -73,12 +73,21 @@ public sealed class EnumValueDescriptor : DescriptorBase /// /// The (possibly empty) set of custom options for this enum value. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions() method.")] public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); + /// + /// The EnumValueOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public EnumValueOptions GetOptions() => Proto.Options?.Clone(); + /// /// Gets a single value enum value option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = Proto.Options.GetExtension(extension); @@ -88,6 +97,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value enum value option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { return Proto.Options.GetExtension(extension).Clone(); diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs index ddd671aadba7..7324e3dfc638 100644 --- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs @@ -58,12 +58,33 @@ public sealed class FieldDescriptor : DescriptorBase, IComparable public OneofDescriptor ContainingOneof { get; } + /// + /// Returns the oneof containing this field if it's a "real" oneof, or null if either this + /// field is not part of a oneof, or the oneof is synthetic. + /// + public OneofDescriptor RealContainingOneof => ContainingOneof?.IsSynthetic == false ? ContainingOneof : null; + /// /// The effective JSON name for this field. This is usually the lower-camel-cased form of the field name, /// but can be overridden using the json_name option in the .proto file. /// public string JsonName { get; } + /// + /// Indicates whether this field supports presence, either implicitly (e.g. due to it being a message + /// type field) or explicitly via Has/Clear members. If this returns true, it is safe to call + /// and + /// on this field's accessor with a suitable message. + /// + public bool HasPresence => + Extension != null ? !Extension.IsRepeated + : IsRepeated ? false + : IsMap ? false + : FieldType == FieldType.Message ? true + // This covers "real oneof members" and "proto3 optional fields" + : ContainingOneof != null ? true + : File.Syntax == Syntax.Proto2; + internal FieldDescriptorProto Proto { get; } /// @@ -298,12 +319,21 @@ public MessageDescriptor ExtendeeType /// /// The (possibly empty) set of custom options for this field. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions() method.")] public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); + /// + /// The FieldOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public FieldOptions GetOptions() => Proto.Options?.Clone(); + /// /// Gets a single value field option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = Proto.Options.GetExtension(extension); @@ -313,6 +343,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value field option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { return Proto.Options.GetExtension(extension).Clone(); @@ -388,7 +419,7 @@ internal void CrossLink() File.DescriptorPool.AddFieldByNumber(this); - if (ContainingType != null && ContainingType.Proto.HasOptions && ContainingType.Proto.Options.MessageSetWireFormat) + if (ContainingType != null && ContainingType.Proto.Options != null && ContainingType.Proto.Options.MessageSetWireFormat) { throw new DescriptorValidationException(this, "MessageSet format is not supported."); } diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs index 56c0caacfde3..88e4a9de9621 100644 --- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs @@ -547,12 +547,21 @@ public override string ToString() /// /// The (possibly empty) set of custom options for this file. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions() method.")] public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); + /// + /// The FileOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public FileOptions GetOptions() => Proto.Options?.Clone(); + /// /// Gets a single value file option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = Proto.Options.GetExtension(extension); @@ -562,6 +571,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value file option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { return Proto.Options.GetExtension(extension).Clone(); diff --git a/csharp/src/Google.Protobuf/Reflection/IFieldAccessor.cs b/csharp/src/Google.Protobuf/Reflection/IFieldAccessor.cs index b48c4f9df576..d73427b73b69 100644 --- a/csharp/src/Google.Protobuf/Reflection/IFieldAccessor.cs +++ b/csharp/src/Google.Protobuf/Reflection/IFieldAccessor.cs @@ -59,7 +59,8 @@ public interface IFieldAccessor object GetValue(IMessage message); /// - /// Indicates whether the field in the specified message is set. For proto3 fields, this throws an + /// Indicates whether the field in the specified message is set. + /// For proto3 fields that aren't explicitly optional, this throws an /// bool HasValue(IMessage message); diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs index eda1965c5423..7b5ab2fb48e7 100644 --- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs @@ -80,6 +80,20 @@ internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDe (oneof, index) => new OneofDescriptor(oneof, file, this, index, generatedCodeInfo?.OneofNames[index])); + int syntheticOneofCount = 0; + foreach (var oneof in Oneofs) + { + if (oneof.IsSynthetic) + { + syntheticOneofCount++; + } + else if (syntheticOneofCount != 0) + { + throw new ArgumentException("All synthetic oneofs should come after real oneofs"); + } + } + RealOneofCount = Oneofs.Count - syntheticOneofCount; + NestedTypes = DescriptorUtil.ConvertAndMakeReadOnly( proto.NestedType, (type, index) => @@ -234,9 +248,19 @@ internal bool IsExtensionsInitialized(IMessage message) /// /// An unmodifiable list of the "oneof" field collections in this message type. + /// All "real" oneofs (where returns false) + /// come before synthetic ones. /// public IList Oneofs { get; } + /// + /// The number of real "oneof" descriptors in this message type. Every element in + /// with an index less than this will have a property value + /// of false; every element with an index greater than or equal to this will have a + /// property value of true. + /// + public int RealOneofCount { get; } + /// /// Finds a field by field name. /// @@ -263,12 +287,21 @@ internal bool IsExtensionsInitialized(IMessage message) /// /// The (possibly empty) set of custom options for this message. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions() method.")] public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); + /// + /// The MessageOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public MessageOptions GetOptions() => Proto.Options?.Clone(); + /// /// Gets a single value message option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = Proto.Options.GetExtension(extension); @@ -278,6 +311,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value message option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public Collections.RepeatedField GetOption(RepeatedExtension extension) { return Proto.Options.GetExtension(extension).Clone(); diff --git a/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs index 92250ba662e0..8e1503767bd7 100644 --- a/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/MethodDescriptor.cs @@ -73,12 +73,21 @@ public sealed class MethodDescriptor : DescriptorBase /// /// The (possibly empty) set of custom options for this method. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions() method.")] public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); + /// + /// The MethodOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public MethodOptions GetOptions() => Proto.Options?.Clone(); + /// /// Gets a single value method option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = Proto.Options.GetExtension(extension); @@ -88,6 +97,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value method option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { return Proto.Options.GetExtension(extension).Clone(); diff --git a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs index f4bf628a6f56..7523426dc5f5 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofAccessor.cs @@ -43,19 +43,31 @@ public sealed class OneofAccessor { private readonly Func caseDelegate; private readonly Action clearDelegate; - private OneofDescriptor descriptor; - internal OneofAccessor(PropertyInfo caseProperty, MethodInfo clearMethod, OneofDescriptor descriptor) + private OneofAccessor(OneofDescriptor descriptor, Func caseDelegate, Action clearDelegate) { - if (!caseProperty.CanRead) - { - throw new ArgumentException("Cannot read from property"); - } - this.descriptor = descriptor; - caseDelegate = ReflectionUtil.CreateFuncIMessageInt32(caseProperty.GetGetMethod()); + Descriptor = descriptor; + this.caseDelegate = caseDelegate; + this.clearDelegate = clearDelegate; + } + + internal static OneofAccessor ForRegularOneof( + OneofDescriptor descriptor, + PropertyInfo caseProperty, + MethodInfo clearMethod) => + new OneofAccessor( + descriptor, + ReflectionUtil.CreateFuncIMessageInt32(caseProperty.GetGetMethod()), + ReflectionUtil.CreateActionIMessage(clearMethod)); - this.descriptor = descriptor; - clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod); + internal static OneofAccessor ForSyntheticOneof(OneofDescriptor descriptor) + { + // Note: descriptor.Fields will be null when this method is called, because we haven't + // cross-linked yet. But by the time the delegates are called by user code, all will be + // well. (That's why we capture the descriptor itself rather than a field.) + return new OneofAccessor(descriptor, + message => descriptor.Fields[0].Accessor.HasValue(message) ? descriptor.Fields[0].FieldNumber : 0, + message => descriptor.Fields[0].Accessor.Clear(message)); } /// @@ -64,15 +76,12 @@ internal OneofAccessor(PropertyInfo caseProperty, MethodInfo clearMethod, OneofD /// /// The descriptor of the oneof. /// - public OneofDescriptor Descriptor { get { return descriptor; } } + public OneofDescriptor Descriptor { get; } /// /// Clears the oneof in the specified message. /// - public void Clear(IMessage message) - { - clearDelegate(message); - } + public void Clear(IMessage message) => clearDelegate(message); /// /// Indicates which field in the oneof is set for specified message @@ -80,11 +89,9 @@ public void Clear(IMessage message) public FieldDescriptor GetCaseFieldDescriptor(IMessage message) { int fieldNumber = caseDelegate(message); - if (fieldNumber > 0) - { - return descriptor.ContainingType.FindFieldByNumber(fieldNumber); - } - return null; + return fieldNumber > 0 + ? Descriptor.ContainingType.FindFieldByNumber(fieldNumber) + : null; } } } diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs index 1e30b92ed627..b41d5205158c 100644 --- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using Google.Protobuf.Collections; using Google.Protobuf.Compatibility; @@ -54,8 +55,13 @@ internal OneofDescriptor(OneofDescriptorProto proto, FileDescriptor file, Messag { this.proto = proto; containingType = parent; - file.DescriptorPool.AddSymbol(this); + + // It's useful to determine whether or not this is a synthetic oneof before cross-linking. That means + // diving into the proto directly rather than using FieldDescriptor, but that's okay. + var firstFieldInOneof = parent.Proto.Field.FirstOrDefault(fieldProto => fieldProto.HasOneofIndex && fieldProto.OneofIndex == index); + IsSynthetic = firstFieldInOneof?.Proto3Optional ?? false; + accessor = CreateAccessor(clrName); } @@ -83,6 +89,12 @@ public MessageDescriptor ContainingType /// public IList Fields { get { return fields; } } + /// + /// Returns true if this oneof is a synthetic oneof containing a proto3 optional field; + /// false otherwise. + /// + public bool IsSynthetic { get; } + /// /// Gets an accessor for reflective access to the values associated with the oneof /// in a particular message. @@ -105,12 +117,21 @@ public MessageDescriptor ContainingType /// /// The (possibly empty) set of custom options for this oneof. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions method.")] public CustomOptions CustomOptions => new CustomOptions(proto.Options?._extensions?.ValuesByNumber); + /// + /// The OneofOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public OneofOptions GetOptions() => proto.Options?.Clone(); + /// /// Gets a single value oneof option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = proto.Options.GetExtension(extension); @@ -120,6 +141,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value oneof option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { return proto.Options.GetExtension(extension).Clone(); @@ -146,18 +168,28 @@ private OneofAccessor CreateAccessor(string clrName) { return null; } - var caseProperty = containingType.ClrType.GetProperty(clrName + "Case"); - if (caseProperty == null) + if (IsSynthetic) { - throw new DescriptorValidationException(this, $"Property {clrName}Case not found in {containingType.ClrType}"); + return OneofAccessor.ForSyntheticOneof(this); } - var clearMethod = containingType.ClrType.GetMethod("Clear" + clrName); - if (clearMethod == null) + else { - throw new DescriptorValidationException(this, $"Method Clear{clrName} not found in {containingType.ClrType}"); + var caseProperty = containingType.ClrType.GetProperty(clrName + "Case"); + if (caseProperty == null) + { + throw new DescriptorValidationException(this, $"Property {clrName}Case not found in {containingType.ClrType}"); + } + if (!caseProperty.CanRead) + { + throw new ArgumentException($"Cannot read from property {clrName}Case in {containingType.ClrType}"); + } + var clearMethod = containingType.ClrType.GetMethod("Clear" + clrName); + if (clearMethod == null) + { + throw new DescriptorValidationException(this, $"Method Clear{clrName} not found in {containingType.ClrType}"); + } + return OneofAccessor.ForRegularOneof(this, caseProperty, clearMethod); } - - return new OneofAccessor(caseProperty, clearMethod, this); } } } diff --git a/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs index 21417ec641e4..dab348b6f8ec 100644 --- a/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/ServiceDescriptor.cs @@ -94,12 +94,21 @@ public MethodDescriptor FindMethodByName(String name) /// /// The (possibly empty) set of custom options for this service. /// - [Obsolete("CustomOptions are obsolete. Use GetOption")] + [Obsolete("CustomOptions are obsolete. Use the GetOptions() method.")] public CustomOptions CustomOptions => new CustomOptions(Proto.Options?._extensions?.ValuesByNumber); + /// + /// The ServiceOptions, defined in descriptor.proto. + /// If the options message is not present (i.e. there are no options), null is returned. + /// Custom options can be retrieved as extensions of the returned message. + /// NOTE: A defensive copy is created each time this property is retrieved. + /// + public ServiceOptions GetOptions() => Proto.Options?.Clone(); + /// /// Gets a single value service option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public T GetOption(Extension extension) { var value = Proto.Options.GetExtension(extension); @@ -109,6 +118,7 @@ public T GetOption(Extension extension) /// /// Gets a repeated value service option for this descriptor /// + [Obsolete("GetOption is obsolete. Use the GetOptions() method.")] public RepeatedField GetOption(RepeatedExtension extension) { return Proto.Options.GetExtension(extension).Clone(); diff --git a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs index de10226511f1..07d84d7fb914 100644 --- a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs +++ b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs @@ -57,49 +57,68 @@ internal SingleFieldAccessor(PropertyInfo property, FieldDescriptor descriptor) throw new ArgumentException("Not all required properties/methods available"); } setValueDelegate = ReflectionUtil.CreateActionIMessageObject(property.GetSetMethod()); - if (descriptor.File.Syntax == Syntax.Proto3) + + // Note: this looks worrying in that we access the containing oneof, which isn't valid until cross-linking + // is complete... but field accessors aren't created until after cross-linking. + // The oneof itself won't be cross-linked yet, but that's okay: the oneof accessor is created + // earlier. + + // Message fields always support presence, via null checks. + if (descriptor.FieldType == FieldType.Message) + { + hasDelegate = message => GetValue(message) != null; + clearDelegate = message => SetValue(message, null); + } + // Oneof fields always support presence, via case checks. + // Note that clearing the field is a no-op unless that specific field is the current "case". + else if (descriptor.RealContainingOneof != null) { - hasDelegate = message => { - throw new InvalidOperationException("HasValue is not implemented for proto3 fields"); + var oneofAccessor = descriptor.RealContainingOneof.Accessor; + hasDelegate = message => oneofAccessor.GetCaseFieldDescriptor(message) == descriptor; + clearDelegate = message => + { + // Clear on a field only affects the oneof itself if the current case is the field we're accessing. + if (oneofAccessor.GetCaseFieldDescriptor(message) == descriptor) + { + oneofAccessor.Clear(message); + } }; - var clrType = property.PropertyType; - - // TODO: Validate that this is a reasonable single field? (Should be a value type, a message type, or string/ByteString.) - object defaultValue = - descriptor.FieldType == FieldType.Message ? null - : clrType == typeof(string) ? "" - : clrType == typeof(ByteString) ? ByteString.Empty - : Activator.CreateInstance(clrType); - clearDelegate = message => SetValue(message, defaultValue); } - else + // Primitive fields always support presence in proto2, and support presence in proto3 for optional fields. + else if (descriptor.File.Syntax == Syntax.Proto2 || descriptor.Proto.Proto3Optional) { MethodInfo hasMethod = property.DeclaringType.GetRuntimeProperty("Has" + property.Name).GetMethod; - if (hasMethod == null) { - throw new ArgumentException("Not all required properties/methods are available"); + if (hasMethod == null) + { + throw new ArgumentException("Not all required properties/methods are available"); } hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod); MethodInfo clearMethod = property.DeclaringType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes); - if (clearMethod == null) { - throw new ArgumentException("Not all required properties/methods are available"); + if (clearMethod == null) + { + throw new ArgumentException("Not all required properties/methods are available"); } clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod); } - } + // What's left? + // Primitive proto3 fields without the optional keyword, which aren't in oneofs. + else + { + hasDelegate = message => { throw new InvalidOperationException("Presence is not implemented for this field"); }; - public override void Clear(IMessage message) - { - clearDelegate(message); - } + // While presence isn't supported, clearing still is; it's just setting to a default value. + var clrType = property.PropertyType; - public override bool HasValue(IMessage message) - { - return hasDelegate(message); + object defaultValue = + clrType == typeof(string) ? "" + : clrType == typeof(ByteString) ? ByteString.Empty + : Activator.CreateInstance(clrType); + clearDelegate = message => SetValue(message, defaultValue); + } } - public override void SetValue(IMessage message, object value) - { - setValueDelegate(message, value); - } + public override void Clear(IMessage message) => clearDelegate(message); + public override bool HasValue(IMessage message) => hasDelegate(message); + public override void SetValue(IMessage message, object value) => setValueDelegate(message, value); } } diff --git a/csharp/src/Google.Protobuf/SegmentedBufferHelper.cs b/csharp/src/Google.Protobuf/SegmentedBufferHelper.cs new file mode 100644 index 000000000000..b5441d34211d --- /dev/null +++ b/csharp/src/Google.Protobuf/SegmentedBufferHelper.cs @@ -0,0 +1,296 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.IO; +using System.Runtime.CompilerServices; +using System.Security; + +namespace Google.Protobuf +{ + /// + /// Abstraction for reading from a stream / read only sequence. + /// Parsing from the buffer is a loop of reading from current buffer / refreshing the buffer once done. + /// + [SecuritySafeCritical] + internal struct SegmentedBufferHelper + { + private int? totalLength; + private ReadOnlySequence.Enumerator readOnlySequenceEnumerator; + private CodedInputStream codedInputStream; + + /// + /// Initialize an instance with a coded input stream. + /// This approach is faster than using a constructor because the instance to initialize is passed by reference + /// and we can write directly into it without copying. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Initialize(CodedInputStream codedInputStream, out SegmentedBufferHelper instance) + { + instance.totalLength = codedInputStream.InternalInputStream == null ? (int?)codedInputStream.InternalBuffer.Length : null; + instance.readOnlySequenceEnumerator = default; + instance.codedInputStream = codedInputStream; + } + + /// + /// Initialize an instance with a read only sequence. + /// This approach is faster than using a constructor because the instance to initialize is passed by reference + /// and we can write directly into it without copying. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Initialize(ReadOnlySequence sequence, out SegmentedBufferHelper instance, out ReadOnlySpan firstSpan) + { + instance.codedInputStream = null; + if (sequence.IsSingleSegment) + { + firstSpan = sequence.First.Span; + instance.totalLength = firstSpan.Length; + instance.readOnlySequenceEnumerator = default; + } + else + { + instance.readOnlySequenceEnumerator = sequence.GetEnumerator(); + instance.totalLength = (int) sequence.Length; + + // set firstSpan to the first segment + instance.readOnlySequenceEnumerator.MoveNext(); + firstSpan = instance.readOnlySequenceEnumerator.Current.Span; + } + } + + public bool RefillBuffer(ref ReadOnlySpan buffer, ref ParserInternalState state, bool mustSucceed) + { + if (codedInputStream != null) + { + return RefillFromCodedInputStream(ref buffer, ref state, mustSucceed); + } + else + { + return RefillFromReadOnlySequence(ref buffer, ref state, mustSucceed); + } + } + + public int? TotalLength => totalLength; + + public CodedInputStream CodedInputStream => codedInputStream; + + /// + /// Sets currentLimit to (current position) + byteLimit. This is called + /// when descending into a length-delimited embedded message. The previous + /// limit is returned. + /// + /// The old limit. + public static int PushLimit(ref ParserInternalState state, int byteLimit) + { + if (byteLimit < 0) + { + throw InvalidProtocolBufferException.NegativeSize(); + } + byteLimit += state.totalBytesRetired + state.bufferPos; + int oldLimit = state.currentLimit; + if (byteLimit > oldLimit) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + state.currentLimit = byteLimit; + + RecomputeBufferSizeAfterLimit(ref state); + + return oldLimit; + } + + /// + /// Discards the current limit, returning the previous limit. + /// + public static void PopLimit(ref ParserInternalState state, int oldLimit) + { + state.currentLimit = oldLimit; + RecomputeBufferSizeAfterLimit(ref state); + } + + /// + /// Returns whether or not all the data before the limit has been read. + /// + /// + public static bool IsReachedLimit(ref ParserInternalState state) + { + if (state.currentLimit == int.MaxValue) + { + return false; + } + int currentAbsolutePosition = state.totalBytesRetired + state.bufferPos; + return currentAbsolutePosition >= state.currentLimit; + } + + /// + /// Returns true if the stream has reached the end of the input. This is the + /// case if either the end of the underlying input source has been reached or + /// the stream has reached a limit created using PushLimit. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool IsAtEnd(ref ReadOnlySpan buffer, ref ParserInternalState state) + { + return state.bufferPos == state.bufferSize && !state.segmentedBufferHelper.RefillBuffer(ref buffer, ref state, false); + } + + private bool RefillFromReadOnlySequence(ref ReadOnlySpan buffer, ref ParserInternalState state, bool mustSucceed) + { + CheckCurrentBufferIsEmpty(ref state); + + if (state.totalBytesRetired + state.bufferSize == state.currentLimit) + { + // Oops, we hit a limit. + if (mustSucceed) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + else + { + return false; + } + } + + state.totalBytesRetired += state.bufferSize; + + state.bufferPos = 0; + state.bufferSize = 0; + while (readOnlySequenceEnumerator.MoveNext()) + { + buffer = readOnlySequenceEnumerator.Current.Span; + state.bufferSize = buffer.Length; + if (buffer.Length != 0) + { + break; + } + } + + if (state.bufferSize == 0) + { + if (mustSucceed) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + else + { + return false; + } + } + else + { + RecomputeBufferSizeAfterLimit(ref state); + int totalBytesRead = + state.totalBytesRetired + state.bufferSize + state.bufferSizeAfterLimit; + if (totalBytesRead < 0 || totalBytesRead > state.sizeLimit) + { + throw InvalidProtocolBufferException.SizeLimitExceeded(); + } + return true; + } + } + + private bool RefillFromCodedInputStream(ref ReadOnlySpan buffer, ref ParserInternalState state, bool mustSucceed) + { + CheckCurrentBufferIsEmpty(ref state); + + if (state.totalBytesRetired + state.bufferSize == state.currentLimit) + { + // Oops, we hit a limit. + if (mustSucceed) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + else + { + return false; + } + } + + Stream input = codedInputStream.InternalInputStream; + + state.totalBytesRetired += state.bufferSize; + + state.bufferPos = 0; + state.bufferSize = (input == null) ? 0 : input.Read(codedInputStream.InternalBuffer, 0, buffer.Length); + if (state.bufferSize < 0) + { + throw new InvalidOperationException("Stream.Read returned a negative count"); + } + if (state.bufferSize == 0) + { + if (mustSucceed) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + else + { + return false; + } + } + else + { + RecomputeBufferSizeAfterLimit(ref state); + int totalBytesRead = + state.totalBytesRetired + state.bufferSize + state.bufferSizeAfterLimit; + if (totalBytesRead < 0 || totalBytesRead > state.sizeLimit) + { + throw InvalidProtocolBufferException.SizeLimitExceeded(); + } + return true; + } + } + + private static void RecomputeBufferSizeAfterLimit(ref ParserInternalState state) + { + state.bufferSize += state.bufferSizeAfterLimit; + int bufferEnd = state.totalBytesRetired + state.bufferSize; + if (bufferEnd > state.currentLimit) + { + // Limit is in current buffer. + state.bufferSizeAfterLimit = bufferEnd - state.currentLimit; + state.bufferSize -= state.bufferSizeAfterLimit; + } + else + { + state.bufferSizeAfterLimit = 0; + } + } + + private static void CheckCurrentBufferIsEmpty(ref ParserInternalState state) + { + if (state.bufferPos < state.bufferSize) + { + throw new InvalidOperationException("RefillBuffer() called when buffer wasn't empty."); + } + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/UnknownField.cs b/csharp/src/Google.Protobuf/UnknownField.cs index e3ce0e86efce..4793a6419d96 100644 --- a/csharp/src/Google.Protobuf/UnknownField.cs +++ b/csharp/src/Google.Protobuf/UnknownField.cs @@ -101,8 +101,8 @@ public override int GetHashCode() /// /// /// The unknown field number. - /// The CodedOutputStream to write to. - internal void WriteTo(int fieldNumber, CodedOutputStream output) + /// The write context to write to. + internal void WriteTo(int fieldNumber, ref WriteContext output) { if (varintList != null) { @@ -141,7 +141,7 @@ internal void WriteTo(int fieldNumber, CodedOutputStream output) foreach (UnknownFieldSet value in groupList) { output.WriteTag(fieldNumber, WireFormat.WireType.StartGroup); - value.WriteTo(output); + value.WriteTo(ref output); output.WriteTag(fieldNumber, WireFormat.WireType.EndGroup); } } @@ -209,13 +209,13 @@ internal UnknownField MergeFrom(UnknownField other) /// /// Returns a new list containing all of the given specified values from /// both the and lists. - /// If is null and is empty, + /// If is null and is null or empty, /// null is returned. Otherwise, either a new list is created (if /// is null) or the elements of are added to . /// private static List AddAll(List current, IList extras) { - if (extras.Count == 0) + if (extras == null || extras.Count == 0) { return current; } diff --git a/csharp/src/Google.Protobuf/UnknownFieldSet.cs b/csharp/src/Google.Protobuf/UnknownFieldSet.cs index d136cf1e6572..9888dd1c3d09 100644 --- a/csharp/src/Google.Protobuf/UnknownFieldSet.cs +++ b/csharp/src/Google.Protobuf/UnknownFieldSet.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Security; using Google.Protobuf.Reflection; namespace Google.Protobuf @@ -70,10 +71,27 @@ internal bool HasField(int field) /// Serializes the set and writes it to . /// public void WriteTo(CodedOutputStream output) + { + WriteContext.Initialize(output, out WriteContext ctx); + try + { + WriteTo(ref ctx); + } + finally + { + ctx.CopyStateTo(output); + } + } + + /// + /// Serializes the set and writes it to . + /// + [SecuritySafeCritical] + public void WriteTo(ref WriteContext ctx) { foreach (KeyValuePair entry in fields) { - entry.Value.WriteTo(entry.Key, output); + entry.Value.WriteTo(entry.Key, ref ctx); } } @@ -176,51 +194,47 @@ internal UnknownFieldSet AddOrReplaceField(int number, UnknownField field) fields[number] = field; return this; } - + /// - /// Parse a single field from and merge it + /// Parse a single field from and merge it /// into this set. /// - /// The coded input stream containing the field + /// The parse context from which to read the field /// false if the tag is an "end group" tag, true otherwise - private bool MergeFieldFrom(CodedInputStream input) + private bool MergeFieldFrom(ref ParseContext ctx) { - uint tag = input.LastTag; + uint tag = ctx.LastTag; int number = WireFormat.GetTagFieldNumber(tag); switch (WireFormat.GetTagWireType(tag)) { case WireFormat.WireType.Varint: { - ulong uint64 = input.ReadUInt64(); + ulong uint64 = ctx.ReadUInt64(); GetOrAddField(number).AddVarint(uint64); return true; } case WireFormat.WireType.Fixed32: { - uint uint32 = input.ReadFixed32(); + uint uint32 = ctx.ReadFixed32(); GetOrAddField(number).AddFixed32(uint32); return true; } case WireFormat.WireType.Fixed64: { - ulong uint64 = input.ReadFixed64(); + ulong uint64 = ctx.ReadFixed64(); GetOrAddField(number).AddFixed64(uint64); return true; } case WireFormat.WireType.LengthDelimited: { - ByteString bytes = input.ReadBytes(); + ByteString bytes = ctx.ReadBytes(); GetOrAddField(number).AddLengthDelimited(bytes); return true; } case WireFormat.WireType.StartGroup: { - uint endTag = WireFormat.MakeTag(number, WireFormat.WireType.EndGroup); UnknownFieldSet set = new UnknownFieldSet(); - while (input.ReadTag() != endTag) - { - set.MergeFieldFrom(input); - } + ParsingPrimitivesMessages.ReadGroup(ref ctx, number, set); GetOrAddField(number).AddGroup(set); return true; } @@ -233,6 +247,22 @@ private bool MergeFieldFrom(CodedInputStream input) } } + internal void MergeGroupFrom(ref ParseContext ctx) + { + while (true) + { + uint tag = ctx.ReadTag(); + if (tag == 0) + { + break; + } + if (!MergeFieldFrom(ref ctx)) + { + break; + } + } + } + /// /// Create a new UnknownFieldSet if unknownFields is null. /// Parse a single field from and merge it @@ -245,21 +275,45 @@ private bool MergeFieldFrom(CodedInputStream input) public static UnknownFieldSet MergeFieldFrom(UnknownFieldSet unknownFields, CodedInputStream input) { - if (input.DiscardUnknownFields) + ParseContext.Initialize(input, out ParseContext ctx); + try + { + return MergeFieldFrom(unknownFields, ref ctx); + } + finally + { + ctx.CopyStateTo(input); + } + } + + /// + /// Create a new UnknownFieldSet if unknownFields is null. + /// Parse a single field from and merge it + /// into unknownFields. If is configured to discard unknown fields, + /// will be returned as-is and the field will be skipped. + /// + /// The UnknownFieldSet which need to be merged + /// The parse context from which to read the field + /// The merged UnknownFieldSet + [SecuritySafeCritical] + public static UnknownFieldSet MergeFieldFrom(UnknownFieldSet unknownFields, + ref ParseContext ctx) + { + if (ctx.DiscardUnknownFields) { - input.SkipLastField(); + ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state); return unknownFields; } if (unknownFields == null) { unknownFields = new UnknownFieldSet(); } - if (!unknownFields.MergeFieldFrom(input)) - { - throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); // match the old code-gen + if (!unknownFields.MergeFieldFrom(ref ctx)) + { + throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); // match the old code-gen } return unknownFields; - } + } /// /// Merges the fields from into this set. diff --git a/csharp/src/Google.Protobuf/UnsafeByteOperations.cs b/csharp/src/Google.Protobuf/UnsafeByteOperations.cs new file mode 100644 index 000000000000..865ea067b8c8 --- /dev/null +++ b/csharp/src/Google.Protobuf/UnsafeByteOperations.cs @@ -0,0 +1,81 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Security; + +namespace Google.Protobuf +{ + /// + /// Provides a number of unsafe byte operations to be used by advanced applications with high performance + /// requirements. These methods are referred to as "unsafe" due to the fact that they potentially expose + /// the backing buffer of a to the application. + /// + /// + /// + /// The methods in this class should only be called if it is guaranteed that the buffer backing the + /// will never change! Mutation of a can lead to unexpected + /// and undesirable consequences in your application, and will likely be difficult to debug. Proceed with caution! + /// + /// + /// This can have a number of significant side affects that have spooky-action-at-a-distance-like behavior. In + /// particular, if the bytes value changes out from under a Protocol Buffer: + /// + /// + /// + /// serialization may throw + /// + /// + /// serialization may succeed but the wrong bytes may be written out + /// + /// + /// objects that are normally immutable (such as ByteString) are no longer immutable + /// + /// + /// hashCode may be incorrect + /// + /// + /// + [SecuritySafeCritical] + public static class UnsafeByteOperations + { + /// + /// Constructs a new from the given bytes. The bytes are not copied, + /// and must not be modified while the is in use. + /// This API is experimental and subject to change. + /// + public static ByteString UnsafeWrap(ReadOnlyMemory bytes) + { + return ByteString.AttachBytes(bytes); + } + } +} diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs index 09e0e29f0de9..60ae03da942f 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs @@ -25,10 +25,10 @@ public static partial class AnyReflection { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi", - "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQm8KE2Nv", - "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaJWdpdGh1Yi5jb20vZ29s", - "YW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmiAgNHUEKqAh5Hb29nbGUuUHJvdG9i", - "dWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw==")); + "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnYKE2Nv", + "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaLGdvb2dsZS5nb2xhbmcu", + "b3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2FueXBiogIDR1BCqgIeR29vZ2xl", + "LlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -78,10 +78,13 @@ public static partial class AnyReflection { /// Example 4: Pack and unpack a message in Go /// /// foo := &pb.Foo{...} - /// any, err := ptypes.MarshalAny(foo) + /// any, err := anypb.New(foo) + /// if err != nil { + /// ... + /// } /// ... /// foo := &pb.Foo{} - /// if err := ptypes.UnmarshalAny(any, foo); err != nil { + /// if err := any.UnmarshalTo(foo); err != nil { /// ... /// } /// @@ -119,7 +122,11 @@ public static partial class AnyReflection { /// "value": "1.212s" /// } /// - public sealed partial class Any : pb::IMessage { + public sealed partial class Any : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Any()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -244,6 +251,9 @@ public sealed partial class Any : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (TypeUrl.Length != 0) { output.WriteRawTag(10); output.WriteString(TypeUrl); @@ -255,8 +265,26 @@ public sealed partial class Any : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (TypeUrl.Length != 0) { + output.WriteRawTag(10); + output.WriteString(TypeUrl); + } + if (Value.Length != 0) { + output.WriteRawTag(18); + output.WriteBytes(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -288,6 +316,9 @@ public sealed partial class Any : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -304,7 +335,30 @@ public sealed partial class Any : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + TypeUrl = input.ReadString(); + break; + } + case 18: { + Value = input.ReadBytes(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs index 06a990591940..7c65ac761d67 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs @@ -37,10 +37,10 @@ public static partial class ApiReflection { "ChFyZXNwb25zZV90eXBlX3VybBgEIAEoCRIaChJyZXNwb25zZV9zdHJlYW1p", "bmcYBSABKAgSKAoHb3B0aW9ucxgGIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5P", "cHRpb24SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3RvYnVmLlN5bnRh", - "eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCdQoTY29t", - "Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAVorZ29vZ2xlLmdvbGFuZy5v", - "cmcvZ2VucHJvdG8vcHJvdG9idWYvYXBpO2FwaaICA0dQQqoCHkdvb2dsZS5Q", - "cm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z")); + "eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCdgoTY29t", + "Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAVosZ29vZ2xlLmdvbGFuZy5v", + "cmcvcHJvdG9idWYvdHlwZXMva25vd24vYXBpcGKiAgNHUEKqAh5Hb29nbGUu", + "UHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -64,7 +64,11 @@ public static partial class ApiReflection { /// this message itself. See https://cloud.google.com/apis/design/glossary for /// detailed terminology. /// - public sealed partial class Api : pb::IMessage { + public sealed partial class Api : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Api()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -265,6 +269,9 @@ public sealed partial class Api : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -287,8 +294,37 @@ public sealed partial class Api : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + methods_.WriteTo(ref output, _repeated_methods_codec); + options_.WriteTo(ref output, _repeated_options_codec); + if (Version.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Version); + } + if (sourceContext_ != null) { + output.WriteRawTag(42); + output.WriteMessage(SourceContext); + } + mixins_.WriteTo(ref output, _repeated_mixins_codec); + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { + output.WriteRawTag(56); + output.WriteEnum((int) Syntax); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -341,6 +377,9 @@ public sealed partial class Api : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -380,14 +419,64 @@ public sealed partial class Api : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + methods_.AddEntriesFrom(ref input, _repeated_methods_codec); + break; + } + case 26: { + options_.AddEntriesFrom(ref input, _repeated_options_codec); + break; + } + case 34: { + Version = input.ReadString(); + break; + } + case 42: { + if (sourceContext_ == null) { + SourceContext = new global::Google.Protobuf.WellKnownTypes.SourceContext(); + } + input.ReadMessage(SourceContext); + break; + } + case 50: { + mixins_.AddEntriesFrom(ref input, _repeated_mixins_codec); + break; + } + case 56: { + Syntax = (global::Google.Protobuf.WellKnownTypes.Syntax) input.ReadEnum(); + break; + } + } + } } + #endif } /// /// Method represents a method of an API interface. /// - public sealed partial class Method : pb::IMessage { + public sealed partial class Method : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Method()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -570,6 +659,9 @@ public sealed partial class Method : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -598,7 +690,42 @@ public sealed partial class Method : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (RequestTypeUrl.Length != 0) { + output.WriteRawTag(18); + output.WriteString(RequestTypeUrl); + } + if (RequestStreaming != false) { + output.WriteRawTag(24); + output.WriteBool(RequestStreaming); + } + if (ResponseTypeUrl.Length != 0) { + output.WriteRawTag(34); + output.WriteString(ResponseTypeUrl); + } + if (ResponseStreaming != false) { + output.WriteRawTag(40); + output.WriteBool(ResponseStreaming); + } + options_.WriteTo(ref output, _repeated_options_codec); + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { + output.WriteRawTag(56); + output.WriteEnum((int) Syntax); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -657,6 +784,9 @@ public sealed partial class Method : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -693,7 +823,50 @@ public sealed partial class Method : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + RequestTypeUrl = input.ReadString(); + break; + } + case 24: { + RequestStreaming = input.ReadBool(); + break; + } + case 34: { + ResponseTypeUrl = input.ReadString(); + break; + } + case 40: { + ResponseStreaming = input.ReadBool(); + break; + } + case 50: { + options_.AddEntriesFrom(ref input, _repeated_options_codec); + break; + } + case 56: { + Syntax = (global::Google.Protobuf.WellKnownTypes.Syntax) input.ReadEnum(); + break; + } + } + } } + #endif } @@ -745,7 +918,7 @@ public sealed partial class Method : pb::IMessage { /// The mixin construct implies that all methods in `AccessControl` are /// also declared with same name and request/response types in /// `Storage`. A documentation generator or annotation processor will - /// see the effective `Storage.GetAcl` method after inherting + /// see the effective `Storage.GetAcl` method after inheriting /// documentation and annotations as follows: /// /// service Storage { @@ -777,7 +950,11 @@ public sealed partial class Method : pb::IMessage { /// ... /// } /// - public sealed partial class Mixin : pb::IMessage { + public sealed partial class Mixin : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Mixin()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -877,6 +1054,9 @@ public sealed partial class Mixin : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -888,8 +1068,26 @@ public sealed partial class Mixin : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (Root.Length != 0) { + output.WriteRawTag(18); + output.WriteString(Root); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -921,6 +1119,9 @@ public sealed partial class Mixin : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -937,7 +1138,30 @@ public sealed partial class Mixin : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + Root = input.ReadString(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs index f0078c4dd4e0..2a653a37547b 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs @@ -26,10 +26,10 @@ public static partial class DurationReflection { string.Concat( "Ch5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8SD2dvb2dsZS5wcm90", "b2J1ZiIqCghEdXJhdGlvbhIPCgdzZWNvbmRzGAEgASgDEg0KBW5hbm9zGAIg", - "ASgFQnwKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoq", - "Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9u+AEB", - "ogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90", - "bzM=")); + "ASgFQoMBChNjb20uZ29vZ2xlLnByb3RvYnVmQg1EdXJhdGlvblByb3RvUAFa", + "MWdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2R1cmF0", + "aW9ucGL4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw", + "ZXNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -100,7 +100,11 @@ public static partial class DurationReflection { /// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 /// microsecond should be expressed in JSON format as "3.000001s". /// - public sealed partial class Duration : pb::IMessage { + public sealed partial class Duration : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Duration()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -206,6 +210,9 @@ public sealed partial class Duration : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Seconds != 0L) { output.WriteRawTag(8); output.WriteInt64(Seconds); @@ -217,8 +224,26 @@ public sealed partial class Duration : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Seconds != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Seconds); + } + if (Nanos != 0) { + output.WriteRawTag(16); + output.WriteInt32(Nanos); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -250,6 +275,9 @@ public sealed partial class Duration : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -266,7 +294,30 @@ public sealed partial class Duration : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Seconds = input.ReadInt64(); + break; + } + case 16: { + Nanos = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs index fa435cd23edf..e2e35182fd92 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs @@ -25,10 +25,10 @@ public static partial class EmptyReflection { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1", - "ZiIHCgVFbXB0eUJ2ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv", - "UAFaJ2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9lbXB0efgB", - "AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv", - "dG8z")); + "ZiIHCgVFbXB0eUJ9ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv", + "UAFaLmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2Vt", + "cHR5cGL4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw", + "ZXNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -50,7 +50,11 @@ public static partial class EmptyReflection { /// /// The JSON representation for `Empty` is empty JSON object `{}`. /// - public sealed partial class Empty : pb::IMessage { + public sealed partial class Empty : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Empty()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -115,11 +119,24 @@ public sealed partial class Empty : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -139,6 +156,9 @@ public sealed partial class Empty : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -147,7 +167,22 @@ public sealed partial class Empty : pb::IMessage { break; } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs index 00e1e9faa453..d5da31441e3c 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs @@ -25,11 +25,10 @@ public static partial class FieldMaskReflection { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "CiBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bxIPZ29vZ2xlLnBy", - "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUKMAQoTY29tLmdv", - "b2dsZS5wcm90b2J1ZkIORmllbGRNYXNrUHJvdG9QAVo5Z29vZ2xlLmdvbGFu", - "Zy5vcmcvZ2VucHJvdG8vcHJvdG9idWYvZmllbGRfbWFzaztmaWVsZF9tYXNr", - "+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZw", - "cm90bzM=")); + "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUKFAQoTY29tLmdv", + "b2dsZS5wcm90b2J1ZkIORmllbGRNYXNrUHJvdG9QAVoyZ29vZ2xlLmdvbGFu", + "Zy5vcmcvcHJvdG9idWYvdHlwZXMva25vd24vZmllbGRtYXNrcGL4AQGiAgNH", + "UEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -240,7 +239,11 @@ public static partial class FieldMaskReflection { /// request should verify the included field paths, and return an /// `INVALID_ARGUMENT` error if any path is unmappable. /// - public sealed partial class FieldMask : pb::IMessage { + public sealed partial class FieldMask : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FieldMask()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -321,12 +324,26 @@ public sealed partial class FieldMask : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else paths_.WriteTo(output, _repeated_paths_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + paths_.WriteTo(ref output, _repeated_paths_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -348,6 +365,9 @@ public sealed partial class FieldMask : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -360,7 +380,26 @@ public sealed partial class FieldMask : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + paths_.AddEntriesFrom(ref input, _repeated_paths_codec); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs index d7076196e0fd..5fe9b895364d 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs @@ -26,10 +26,10 @@ public static partial class SourceContextReflection { string.Concat( "CiRnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8SD2dvb2ds", "ZS5wcm90b2J1ZiIiCg1Tb3VyY2VDb250ZXh0EhEKCWZpbGVfbmFtZRgBIAEo", - "CUKVAQoTY29tLmdvb2dsZS5wcm90b2J1ZkISU291cmNlQ29udGV4dFByb3Rv", - "UAFaQWdvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL3Byb3RvYnVmL3NvdXJj", - "ZV9jb250ZXh0O3NvdXJjZV9jb250ZXh0ogIDR1BCqgIeR29vZ2xlLlByb3Rv", - "YnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM=")); + "CUKKAQoTY29tLmdvb2dsZS5wcm90b2J1ZkISU291cmNlQ29udGV4dFByb3Rv", + "UAFaNmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL3Nv", + "dXJjZWNvbnRleHRwYqICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25v", + "d25UeXBlc2IGcHJvdG8z")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -44,7 +44,11 @@ public static partial class SourceContextReflection { /// `SourceContext` represents information about the source of a /// protobuf element, like the file in which it is defined. /// - public sealed partial class SourceContext : pb::IMessage { + public sealed partial class SourceContext : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new SourceContext()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -127,6 +131,9 @@ public sealed partial class SourceContext : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (FileName.Length != 0) { output.WriteRawTag(10); output.WriteString(FileName); @@ -134,8 +141,22 @@ public sealed partial class SourceContext : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (FileName.Length != 0) { + output.WriteRawTag(10); + output.WriteString(FileName); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -161,6 +182,9 @@ public sealed partial class SourceContext : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -173,7 +197,26 @@ public sealed partial class SourceContext : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + FileName = input.ReadString(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs index b1dbe239cc9c..0bbb1fcdf9d5 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs @@ -35,10 +35,10 @@ public static partial class StructReflection { "ABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RW", "YWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIW", "Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W", - "QUxVRRAAQoEBChNjb20uZ29vZ2xlLnByb3RvYnVmQgtTdHJ1Y3RQcm90b1AB", - "WjFnaXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wdHlwZXMvc3RydWN0O3N0", - "cnVjdHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5", - "cGVzYgZwcm90bzM=")); + "QUxVRRAAQn8KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAFa", + "L2dvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL3N0cnVj", + "dHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVz", + "YgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, null, new pbr::GeneratedClrTypeInfo[] { @@ -77,7 +77,11 @@ public enum NullValue { /// /// The JSON representation for `Struct` is JSON object. /// - public sealed partial class Struct : pb::IMessage { + public sealed partial class Struct : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Struct()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -158,12 +162,26 @@ public sealed partial class Struct : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else fields_.WriteTo(output, _map_fields_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + fields_.WriteTo(ref output, _map_fields_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -185,6 +203,9 @@ public sealed partial class Struct : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -197,7 +218,26 @@ public sealed partial class Struct : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + fields_.AddEntriesFrom(ref input, _map_fields_codec); + break; + } + } + } } + #endif } @@ -209,7 +249,11 @@ public sealed partial class Struct : pb::IMessage { /// /// The JSON representation for `Value` is JSON value. /// - public sealed partial class Value : pb::IMessage { + public sealed partial class Value : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Value()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -416,6 +460,9 @@ public enum KindOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (kindCase_ == KindOneofCase.NullValue) { output.WriteRawTag(8); output.WriteEnum((int) NullValue); @@ -443,8 +490,42 @@ public enum KindOneofCase { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (kindCase_ == KindOneofCase.NullValue) { + output.WriteRawTag(8); + output.WriteEnum((int) NullValue); + } + if (kindCase_ == KindOneofCase.NumberValue) { + output.WriteRawTag(17); + output.WriteDouble(NumberValue); + } + if (kindCase_ == KindOneofCase.StringValue) { + output.WriteRawTag(26); + output.WriteString(StringValue); + } + if (kindCase_ == KindOneofCase.BoolValue) { + output.WriteRawTag(32); + output.WriteBool(BoolValue); + } + if (kindCase_ == KindOneofCase.StructValue) { + output.WriteRawTag(42); + output.WriteMessage(StructValue); + } + if (kindCase_ == KindOneofCase.ListValue) { + output.WriteRawTag(50); + output.WriteMessage(ListValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -509,6 +590,9 @@ public enum KindOneofCase { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -552,7 +636,57 @@ public enum KindOneofCase { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + kind_ = input.ReadEnum(); + kindCase_ = KindOneofCase.NullValue; + break; + } + case 17: { + NumberValue = input.ReadDouble(); + break; + } + case 26: { + StringValue = input.ReadString(); + break; + } + case 32: { + BoolValue = input.ReadBool(); + break; + } + case 42: { + global::Google.Protobuf.WellKnownTypes.Struct subBuilder = new global::Google.Protobuf.WellKnownTypes.Struct(); + if (kindCase_ == KindOneofCase.StructValue) { + subBuilder.MergeFrom(StructValue); + } + input.ReadMessage(subBuilder); + StructValue = subBuilder; + break; + } + case 50: { + global::Google.Protobuf.WellKnownTypes.ListValue subBuilder = new global::Google.Protobuf.WellKnownTypes.ListValue(); + if (kindCase_ == KindOneofCase.ListValue) { + subBuilder.MergeFrom(ListValue); + } + input.ReadMessage(subBuilder); + ListValue = subBuilder; + break; + } + } + } } + #endif } @@ -561,7 +695,11 @@ public enum KindOneofCase { /// /// The JSON representation for `ListValue` is JSON array. /// - public sealed partial class ListValue : pb::IMessage { + public sealed partial class ListValue : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new ListValue()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -642,11 +780,25 @@ public sealed partial class ListValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else values_.WriteTo(output, _repeated_values_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + values_.WriteTo(ref output, _repeated_values_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -669,6 +821,9 @@ public sealed partial class ListValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -681,7 +836,26 @@ public sealed partial class ListValue : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + values_.AddEntriesFrom(ref input, _repeated_values_codec); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs index 12f4812af37f..2fb1b4d16428 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs @@ -26,10 +26,10 @@ public static partial class TimestampReflection { string.Concat( "Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv", "dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY", - "AiABKAVCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q", - "AVorZ2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL3RpbWVzdGFt", - "cPgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG", - "cHJvdG8z")); + "AiABKAVChQEKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3Rv", + "UAFaMmdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL3Rp", + "bWVzdGFtcHBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93", + "blR5cGVzYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { @@ -91,7 +91,15 @@ public static partial class TimestampReflection { /// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) /// .setNanos((int) ((millis % 1000) * 1000000)).build(); /// - /// Example 5: Compute Timestamp from current time in Python. + /// Example 5: Compute Timestamp from Java `Instant.now()`. + /// + /// Instant now = Instant.now(); + /// + /// Timestamp timestamp = + /// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + /// .setNanos(now.getNano()).build(); + /// + /// Example 6: Compute Timestamp from current time in Python. /// /// timestamp = Timestamp() /// timestamp.GetCurrentTime() @@ -123,7 +131,11 @@ public static partial class TimestampReflection { /// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D /// ) to obtain a formatter capable of generating timestamps in this format. /// - public sealed partial class Timestamp : pb::IMessage { + public sealed partial class Timestamp : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Timestamp()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -227,6 +239,9 @@ public sealed partial class Timestamp : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Seconds != 0L) { output.WriteRawTag(8); output.WriteInt64(Seconds); @@ -238,8 +253,26 @@ public sealed partial class Timestamp : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Seconds != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Seconds); + } + if (Nanos != 0) { + output.WriteRawTag(16); + output.WriteInt32(Nanos); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -271,6 +304,9 @@ public sealed partial class Timestamp : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -287,7 +323,30 @@ public sealed partial class Timestamp : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Seconds = input.ReadInt64(); + break; + } + case 16: { + Nanos = input.ReadInt32(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs index bfd4b8ec8221..f5dfdb7e3e76 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs @@ -56,10 +56,10 @@ public static partial class TypeReflection { "ASgFEigKB29wdGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9u", "IjsKBk9wdGlvbhIMCgRuYW1lGAEgASgJEiMKBXZhbHVlGAIgASgLMhQuZ29v", "Z2xlLnByb3RvYnVmLkFueSouCgZTeW50YXgSEQoNU1lOVEFYX1BST1RPMhAA", - "EhEKDVNZTlRBWF9QUk9UTzMQAUJ9ChNjb20uZ29vZ2xlLnByb3RvYnVmQglU", - "eXBlUHJvdG9QAVovZ29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vcHJvdG9i", - "dWYvcHR5cGU7cHR5cGX4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2Vs", - "bEtub3duVHlwZXNiBnByb3RvMw==")); + "EhEKDVNZTlRBWF9QUk9UTzMQAUJ7ChNjb20uZ29vZ2xlLnByb3RvYnVmQglU", + "eXBlUHJvdG9QAVotZ29vZ2xlLmdvbGFuZy5vcmcvcHJvdG9idWYvdHlwZXMv", + "a25vd24vdHlwZXBi+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxL", + "bm93blR5cGVzYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, null, new pbr::GeneratedClrTypeInfo[] { @@ -94,7 +94,11 @@ public enum Syntax { /// /// A protocol buffer message type. /// - public sealed partial class Type : pb::IMessage { + public sealed partial class Type : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Type()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -258,6 +262,9 @@ public sealed partial class Type : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -276,8 +283,33 @@ public sealed partial class Type : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + fields_.WriteTo(ref output, _repeated_fields_codec); + oneofs_.WriteTo(ref output, _repeated_oneofs_codec); + options_.WriteTo(ref output, _repeated_options_codec); + if (sourceContext_ != null) { + output.WriteRawTag(42); + output.WriteMessage(SourceContext); + } + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { + output.WriteRawTag(48); + output.WriteEnum((int) Syntax); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -324,6 +356,9 @@ public sealed partial class Type : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -359,14 +394,60 @@ public sealed partial class Type : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + fields_.AddEntriesFrom(ref input, _repeated_fields_codec); + break; + } + case 26: { + oneofs_.AddEntriesFrom(ref input, _repeated_oneofs_codec); + break; + } + case 34: { + options_.AddEntriesFrom(ref input, _repeated_options_codec); + break; + } + case 42: { + if (sourceContext_ == null) { + SourceContext = new global::Google.Protobuf.WellKnownTypes.SourceContext(); + } + input.ReadMessage(SourceContext); + break; + } + case 48: { + Syntax = (global::Google.Protobuf.WellKnownTypes.Syntax) input.ReadEnum(); + break; + } + } + } + } + #endif + } /// /// A single field of a message type. /// - public sealed partial class Field : pb::IMessage { + public sealed partial class Field : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Field()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -602,6 +683,9 @@ public sealed partial class Field : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) { output.WriteRawTag(8); output.WriteEnum((int) Kind); @@ -642,8 +726,55 @@ public sealed partial class Field : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TypeUnknown) { + output.WriteRawTag(8); + output.WriteEnum((int) Kind); + } + if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.Unknown) { + output.WriteRawTag(16); + output.WriteEnum((int) Cardinality); + } + if (Number != 0) { + output.WriteRawTag(24); + output.WriteInt32(Number); + } + if (Name.Length != 0) { + output.WriteRawTag(34); + output.WriteString(Name); + } + if (TypeUrl.Length != 0) { + output.WriteRawTag(50); + output.WriteString(TypeUrl); + } + if (OneofIndex != 0) { + output.WriteRawTag(56); + output.WriteInt32(OneofIndex); + } + if (Packed != false) { + output.WriteRawTag(64); + output.WriteBool(Packed); + } + options_.WriteTo(ref output, _repeated_options_codec); + if (JsonName.Length != 0) { + output.WriteRawTag(82); + output.WriteString(JsonName); + } + if (DefaultValue.Length != 0) { + output.WriteRawTag(90); + output.WriteString(DefaultValue); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -719,6 +850,9 @@ public sealed partial class Field : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -767,8 +901,63 @@ public sealed partial class Field : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Kind = (global::Google.Protobuf.WellKnownTypes.Field.Types.Kind) input.ReadEnum(); + break; + } + case 16: { + Cardinality = (global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) input.ReadEnum(); + break; + } + case 24: { + Number = input.ReadInt32(); + break; + } + case 34: { + Name = input.ReadString(); + break; + } + case 50: { + TypeUrl = input.ReadString(); + break; + } + case 56: { + OneofIndex = input.ReadInt32(); + break; + } + case 64: { + Packed = input.ReadBool(); + break; + } + case 74: { + options_.AddEntriesFrom(ref input, _repeated_options_codec); + break; + } + case 82: { + JsonName = input.ReadString(); + break; + } + case 90: { + DefaultValue = input.ReadString(); + break; + } + } + } + } + #endif + #region Nested types /// Container for nested types declared in the Field message type. [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -885,7 +1074,11 @@ public enum Cardinality { /// /// Enum type definition. /// - public sealed partial class Enum : pb::IMessage { + public sealed partial class Enum : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Enum()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1033,6 +1226,9 @@ public sealed partial class Enum : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -1050,7 +1246,31 @@ public sealed partial class Enum : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + enumvalue_.WriteTo(ref output, _repeated_enumvalue_codec); + options_.WriteTo(ref output, _repeated_options_codec); + if (sourceContext_ != null) { + output.WriteRawTag(34); + output.WriteMessage(SourceContext); + } + if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.Proto2) { + output.WriteRawTag(40); + output.WriteEnum((int) Syntax); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1096,6 +1316,9 @@ public sealed partial class Enum : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1127,14 +1350,56 @@ public sealed partial class Enum : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 18: { + enumvalue_.AddEntriesFrom(ref input, _repeated_enumvalue_codec); + break; + } + case 26: { + options_.AddEntriesFrom(ref input, _repeated_options_codec); + break; + } + case 34: { + if (sourceContext_ == null) { + SourceContext = new global::Google.Protobuf.WellKnownTypes.SourceContext(); + } + input.ReadMessage(SourceContext); + break; + } + case 40: { + Syntax = (global::Google.Protobuf.WellKnownTypes.Syntax) input.ReadEnum(); + break; + } + } + } } + #endif } /// /// Enum value definition. /// - public sealed partial class EnumValue : pb::IMessage { + public sealed partial class EnumValue : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new EnumValue()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1249,6 +1514,9 @@ public sealed partial class EnumValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Name.Length != 0) { output.WriteRawTag(10); output.WriteString(Name); @@ -1261,7 +1529,26 @@ public sealed partial class EnumValue : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + if (Number != 0) { + output.WriteRawTag(16); + output.WriteInt32(Number); + } + options_.WriteTo(ref output, _repeated_options_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1296,6 +1583,9 @@ public sealed partial class EnumValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1316,7 +1606,34 @@ public sealed partial class EnumValue : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Name = input.ReadString(); + break; + } + case 16: { + Number = input.ReadInt32(); + break; + } + case 26: { + options_.AddEntriesFrom(ref input, _repeated_options_codec); + break; + } + } + } } + #endif } @@ -1324,7 +1641,11 @@ public sealed partial class EnumValue : pb::IMessage { /// A protocol buffer option, which can be attached to a message, field, /// enumeration, etc. /// - public sealed partial class Option : pb::IMessage - public sealed partial class DoubleValue : pb::IMessage { + public sealed partial class DoubleValue : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new DoubleValue()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -139,6 +144,9 @@ public sealed partial class DoubleValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value != 0D) { output.WriteRawTag(9); output.WriteDouble(Value); @@ -146,8 +154,22 @@ public sealed partial class DoubleValue : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0D) { + output.WriteRawTag(9); + output.WriteDouble(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -173,6 +195,9 @@ public sealed partial class DoubleValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -185,7 +210,26 @@ public sealed partial class DoubleValue : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 9: { + Value = input.ReadDouble(); + break; + } + } + } } + #endif } @@ -194,7 +238,11 @@ public sealed partial class DoubleValue : pb::IMessage { /// /// The JSON representation for `FloatValue` is JSON number. /// - public sealed partial class FloatValue : pb::IMessage { + public sealed partial class FloatValue : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new FloatValue()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -276,6 +324,9 @@ public sealed partial class FloatValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value != 0F) { output.WriteRawTag(13); output.WriteFloat(Value); @@ -283,7 +334,21 @@ public sealed partial class FloatValue : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0F) { + output.WriteRawTag(13); + output.WriteFloat(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -310,6 +375,9 @@ public sealed partial class FloatValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -322,7 +390,26 @@ public sealed partial class FloatValue : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 13: { + Value = input.ReadFloat(); + break; + } + } + } } + #endif } @@ -331,7 +418,11 @@ public sealed partial class FloatValue : pb::IMessage { /// /// The JSON representation for `Int64Value` is JSON string. /// - public sealed partial class Int64Value : pb::IMessage { + public sealed partial class Int64Value : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int64Value()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -413,6 +504,9 @@ public sealed partial class Int64Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value != 0L) { output.WriteRawTag(8); output.WriteInt64(Value); @@ -420,7 +514,21 @@ public sealed partial class Int64Value : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0L) { + output.WriteRawTag(8); + output.WriteInt64(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -447,6 +555,9 @@ public sealed partial class Int64Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -459,7 +570,26 @@ public sealed partial class Int64Value : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadInt64(); + break; + } + } + } } + #endif } @@ -468,7 +598,11 @@ public sealed partial class Int64Value : pb::IMessage { /// /// The JSON representation for `UInt64Value` is JSON string. /// - public sealed partial class UInt64Value : pb::IMessage { + public sealed partial class UInt64Value : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new UInt64Value()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -550,6 +684,9 @@ public sealed partial class UInt64Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value != 0UL) { output.WriteRawTag(8); output.WriteUInt64(Value); @@ -557,7 +694,21 @@ public sealed partial class UInt64Value : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0UL) { + output.WriteRawTag(8); + output.WriteUInt64(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -584,6 +735,9 @@ public sealed partial class UInt64Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -596,8 +750,27 @@ public sealed partial class UInt64Value : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadUInt64(); + break; + } + } + } + } + #endif + } /// @@ -605,7 +778,11 @@ public sealed partial class UInt64Value : pb::IMessage { /// /// The JSON representation for `Int32Value` is JSON number. /// - public sealed partial class Int32Value : pb::IMessage { + public sealed partial class Int32Value : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Int32Value()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -687,6 +864,9 @@ public sealed partial class Int32Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value != 0) { output.WriteRawTag(8); output.WriteInt32(Value); @@ -694,8 +874,22 @@ public sealed partial class Int32Value : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0) { + output.WriteRawTag(8); + output.WriteInt32(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -721,6 +915,9 @@ public sealed partial class Int32Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -733,8 +930,27 @@ public sealed partial class Int32Value : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadInt32(); + break; + } + } + } + } + #endif + } /// @@ -742,7 +958,11 @@ public sealed partial class Int32Value : pb::IMessage { /// /// The JSON representation for `UInt32Value` is JSON number. /// - public sealed partial class UInt32Value : pb::IMessage { + public sealed partial class UInt32Value : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new UInt32Value()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -824,6 +1044,9 @@ public sealed partial class UInt32Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value != 0) { output.WriteRawTag(8); output.WriteUInt32(Value); @@ -831,7 +1054,21 @@ public sealed partial class UInt32Value : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != 0) { + output.WriteRawTag(8); + output.WriteUInt32(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -858,6 +1095,9 @@ public sealed partial class UInt32Value : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -870,7 +1110,26 @@ public sealed partial class UInt32Value : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadUInt32(); + break; + } + } + } } + #endif } @@ -879,7 +1138,11 @@ public sealed partial class UInt32Value : pb::IMessage { /// /// The JSON representation for `BoolValue` is JSON `true` and `false`. /// - public sealed partial class BoolValue : pb::IMessage { + public sealed partial class BoolValue : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BoolValue()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -961,6 +1224,9 @@ public sealed partial class BoolValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value != false) { output.WriteRawTag(8); output.WriteBool(Value); @@ -968,7 +1234,21 @@ public sealed partial class BoolValue : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value != false) { + output.WriteRawTag(8); + output.WriteBool(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -995,6 +1275,9 @@ public sealed partial class BoolValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1007,8 +1290,27 @@ public sealed partial class BoolValue : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Value = input.ReadBool(); + break; + } + } + } + } + #endif + } /// @@ -1016,7 +1318,11 @@ public sealed partial class BoolValue : pb::IMessage { /// /// The JSON representation for `StringValue` is JSON string. /// - public sealed partial class StringValue : pb::IMessage { + public sealed partial class StringValue : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new StringValue()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1098,6 +1404,9 @@ public sealed partial class StringValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value.Length != 0) { output.WriteRawTag(10); output.WriteString(Value); @@ -1105,7 +1414,21 @@ public sealed partial class StringValue : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } } + #endif [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { @@ -1132,6 +1455,9 @@ public sealed partial class StringValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1144,8 +1470,27 @@ public sealed partial class StringValue : pb::IMessage { } } } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Value = input.ReadString(); + break; + } + } + } + } + #endif + } /// @@ -1153,7 +1498,11 @@ public sealed partial class StringValue : pb::IMessage { /// /// The JSON representation for `BytesValue` is JSON string. /// - public sealed partial class BytesValue : pb::IMessage { + public sealed partial class BytesValue : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new BytesValue()); private pb::UnknownFieldSet _unknownFields; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -1235,6 +1584,9 @@ public sealed partial class BytesValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else if (Value.Length != 0) { output.WriteRawTag(10); output.WriteBytes(Value); @@ -1242,8 +1594,22 @@ public sealed partial class BytesValue : pb::IMessage { if (_unknownFields != null) { _unknownFields.WriteTo(output); } + #endif } + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (Value.Length != 0) { + output.WriteRawTag(10); + output.WriteBytes(Value); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public int CalculateSize() { int size = 0; @@ -1269,6 +1635,9 @@ public sealed partial class BytesValue : pb::IMessage { [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else uint tag; while ((tag = input.ReadTag()) != 0) { switch(tag) { @@ -1281,7 +1650,26 @@ public sealed partial class BytesValue : pb::IMessage { } } } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + Value = input.ReadBytes(); + break; + } + } + } } + #endif } diff --git a/csharp/src/Google.Protobuf/WriteBufferHelper.cs b/csharp/src/Google.Protobuf/WriteBufferHelper.cs new file mode 100644 index 000000000000..f2a59bc56f44 --- /dev/null +++ b/csharp/src/Google.Protobuf/WriteBufferHelper.cs @@ -0,0 +1,166 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.IO; +using System.Runtime.CompilerServices; +using System.Security; + +namespace Google.Protobuf +{ + /// + /// Abstraction for writing to a steam / IBufferWriter + /// + [SecuritySafeCritical] + internal struct WriteBufferHelper + { + private IBufferWriter bufferWriter; + private CodedOutputStream codedOutputStream; + + public CodedOutputStream CodedOutputStream => codedOutputStream; + + /// + /// Initialize an instance with a coded output stream. + /// This approach is faster than using a constructor because the instance to initialize is passed by reference + /// and we can write directly into it without copying. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Initialize(CodedOutputStream codedOutputStream, out WriteBufferHelper instance) + { + instance.bufferWriter = null; + instance.codedOutputStream = codedOutputStream; + } + + /// + /// Initialize an instance with a buffer writer. + /// This approach is faster than using a constructor because the instance to initialize is passed by reference + /// and we can write directly into it without copying. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Initialize(IBufferWriter bufferWriter, out WriteBufferHelper instance, out Span buffer) + { + instance.bufferWriter = bufferWriter; + instance.codedOutputStream = null; + buffer = default; // TODO: initialize the initial buffer so that the first write is not via slowpath. + } + + /// + /// Initialize an instance with a buffer represented by a single span (i.e. buffer cannot be refreshed) + /// This approach is faster than using a constructor because the instance to initialize is passed by reference + /// and we can write directly into it without copying. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void InitializeNonRefreshable(out WriteBufferHelper instance) + { + instance.bufferWriter = null; + instance.codedOutputStream = null; + } + + /// + /// Verifies that SpaceLeft returns zero. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void CheckNoSpaceLeft(ref WriterInternalState state) + { + if (GetSpaceLeft(ref state) != 0) + { + throw new InvalidOperationException("Did not write as much data as expected."); + } + } + + /// + /// If writing to a flat array, returns the space left in the array. Otherwise, + /// throws an InvalidOperationException. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetSpaceLeft(ref WriterInternalState state) + { + if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream == null && state.writeBufferHelper.bufferWriter == null) + { + return state.limit - state.position; + } + else + { + throw new InvalidOperationException( + "SpaceLeft can only be called on CodedOutputStreams that are " + + "writing to a flat array or when writing to a single span."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void RefreshBuffer(ref Span buffer, ref WriterInternalState state) + { + if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream != null) + { + // because we're using coded output stream, we know that "buffer" and codedOutputStream.InternalBuffer are identical. + state.writeBufferHelper.codedOutputStream.InternalOutputStream.Write(state.writeBufferHelper.codedOutputStream.InternalBuffer, 0, state.position); + // reset position, limit stays the same because we are reusing the codedOutputStream's internal buffer. + state.position = 0; + } + else if (state.writeBufferHelper.bufferWriter != null) + { + // commit the bytes and get a new buffer to write to. + state.writeBufferHelper.bufferWriter.Advance(state.position); + state.position = 0; + buffer = state.writeBufferHelper.bufferWriter.GetSpan(); + state.limit = buffer.Length; + } + else + { + // We're writing to a single buffer. + throw new CodedOutputStream.OutOfSpaceException(); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Flush(ref Span buffer, ref WriterInternalState state) + { + if (state.writeBufferHelper.codedOutputStream?.InternalOutputStream != null) + { + // because we're using coded output stream, we know that "buffer" and codedOutputStream.InternalBuffer are identical. + state.writeBufferHelper.codedOutputStream.InternalOutputStream.Write(state.writeBufferHelper.codedOutputStream.InternalBuffer, 0, state.position); + state.position = 0; + } + else if (state.writeBufferHelper.bufferWriter != null) + { + // calling Advance invalidates the current buffer and we must not continue writing to it, + // so we set the current buffer to point to an empty Span. If any subsequent writes happen, + // the first subsequent write will trigger refresing of the buffer. + state.writeBufferHelper.bufferWriter.Advance(state.position); + state.position = 0; + state.limit = 0; + buffer = default; // invalidate the current buffer + } + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/WriteContext.cs b/csharp/src/Google.Protobuf/WriteContext.cs new file mode 100644 index 000000000000..e822e1d6da4c --- /dev/null +++ b/csharp/src/Google.Protobuf/WriteContext.cs @@ -0,0 +1,371 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Google.Protobuf.Collections; + +namespace Google.Protobuf +{ + /// + /// An opaque struct that represents the current serialization state and is passed along + /// as the serialization proceeds. + /// All the public methods are intended to be invoked only by the generated code, + /// users should never invoke them directly. + /// + [SecuritySafeCritical] + public ref struct WriteContext + { + internal Span buffer; + internal WriterInternalState state; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(ref Span buffer, ref WriterInternalState state, out WriteContext ctx) + { + ctx.buffer = buffer; + ctx.state = state; + } + + /// + /// Creates a WriteContext instance from CodedOutputStream. + /// WARNING: internally this copies the CodedOutputStream's state, so after done with the WriteContext, + /// the CodedOutputStream's state needs to be updated. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(CodedOutputStream output, out WriteContext ctx) + { + ctx.buffer = new Span(output.InternalBuffer); + // ideally we would use a reference to the original state, but that doesn't seem possible + // so we just copy the struct that holds the state. We will need to later store the state back + // into CodedOutputStream if we want to keep it usable. + ctx.state = output.InternalState; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(IBufferWriter output, out WriteContext ctx) + { + ctx.buffer = default; + ctx.state = default; + WriteBufferHelper.Initialize(output, out ctx.state.writeBufferHelper, out ctx.buffer); + ctx.state.limit = ctx.buffer.Length; + ctx.state.position = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static void Initialize(ref Span buffer, out WriteContext ctx) + { + ctx.buffer = buffer; + ctx.state = default; + ctx.state.limit = ctx.buffer.Length; + ctx.state.position = 0; + WriteBufferHelper.InitializeNonRefreshable(out ctx.state.writeBufferHelper); + } + + /// + /// Writes a double field value, without a tag. + /// + /// The value to write + public void WriteDouble(double value) + { + WritingPrimitives.WriteDouble(ref buffer, ref state, value); + } + + /// + /// Writes a float field value, without a tag. + /// + /// The value to write + public void WriteFloat(float value) + { + WritingPrimitives.WriteFloat(ref buffer, ref state, value); + } + + /// + /// Writes a uint64 field value, without a tag. + /// + /// The value to write + public void WriteUInt64(ulong value) + { + WritingPrimitives.WriteUInt64(ref buffer, ref state, value); + } + + /// + /// Writes an int64 field value, without a tag. + /// + /// The value to write + public void WriteInt64(long value) + { + WritingPrimitives.WriteInt64(ref buffer, ref state, value); + } + + /// + /// Writes an int32 field value, without a tag. + /// + /// The value to write + public void WriteInt32(int value) + { + WritingPrimitives.WriteInt32(ref buffer, ref state, value); + } + + /// + /// Writes a fixed64 field value, without a tag. + /// + /// The value to write + public void WriteFixed64(ulong value) + { + WritingPrimitives.WriteFixed64(ref buffer, ref state, value); + } + + /// + /// Writes a fixed32 field value, without a tag. + /// + /// The value to write + public void WriteFixed32(uint value) + { + WritingPrimitives.WriteFixed32(ref buffer, ref state, value); + } + + /// + /// Writes a bool field value, without a tag. + /// + /// The value to write + public void WriteBool(bool value) + { + WritingPrimitives.WriteBool(ref buffer, ref state, value); + } + + /// + /// Writes a string field value, without a tag. + /// The data is length-prefixed. + /// + /// The value to write + public void WriteString(string value) + { + WritingPrimitives.WriteString(ref buffer, ref state, value); + } + + /// + /// Writes a message, without a tag. + /// The data is length-prefixed. + /// + /// The value to write + public void WriteMessage(IMessage value) + { + WritingPrimitivesMessages.WriteMessage(ref this, value); + } + + /// + /// Writes a group, without a tag, to the stream. + /// + /// The value to write + public void WriteGroup(IMessage value) + { + WritingPrimitivesMessages.WriteGroup(ref this, value); + } + + /// + /// Write a byte string, without a tag, to the stream. + /// The data is length-prefixed. + /// + /// The value to write + public void WriteBytes(ByteString value) + { + WritingPrimitives.WriteBytes(ref buffer, ref state, value); + } + + /// + /// Writes a uint32 value, without a tag. + /// + /// The value to write + public void WriteUInt32(uint value) + { + WritingPrimitives.WriteUInt32(ref buffer, ref state, value); + } + + /// + /// Writes an enum value, without a tag. + /// + /// The value to write + public void WriteEnum(int value) + { + WritingPrimitives.WriteEnum(ref buffer, ref state, value); + } + + /// + /// Writes an sfixed32 value, without a tag. + /// + /// The value to write. + public void WriteSFixed32(int value) + { + WritingPrimitives.WriteSFixed32(ref buffer, ref state, value); + } + + /// + /// Writes an sfixed64 value, without a tag. + /// + /// The value to write + public void WriteSFixed64(long value) + { + WritingPrimitives.WriteSFixed64(ref buffer, ref state, value); + } + + /// + /// Writes an sint32 value, without a tag. + /// + /// The value to write + public void WriteSInt32(int value) + { + WritingPrimitives.WriteSInt32(ref buffer, ref state, value); + } + + /// + /// Writes an sint64 value, without a tag. + /// + /// The value to write + public void WriteSInt64(long value) + { + WritingPrimitives.WriteSInt64(ref buffer, ref state, value); + } + + /// + /// Writes a length (in bytes) for length-delimited data. + /// + /// + /// This method simply writes a rawint, but exists for clarity in calling code. + /// + /// Length value, in bytes. + public void WriteLength(int length) + { + WritingPrimitives.WriteLength(ref buffer, ref state, length); + } + + /// + /// Encodes and writes a tag. + /// + /// The number of the field to write the tag for + /// The wire format type of the tag to write + public void WriteTag(int fieldNumber, WireFormat.WireType type) + { + WritingPrimitives.WriteTag(ref buffer, ref state, fieldNumber, type); + } + + /// + /// Writes an already-encoded tag. + /// + /// The encoded tag + public void WriteTag(uint tag) + { + WritingPrimitives.WriteTag(ref buffer, ref state, tag); + } + + /// + /// Writes the given single-byte tag. + /// + /// The encoded tag + public void WriteRawTag(byte b1) + { + WritingPrimitives.WriteRawTag(ref buffer, ref state, b1); + } + + /// + /// Writes the given two-byte tag. + /// + /// The first byte of the encoded tag + /// The second byte of the encoded tag + public void WriteRawTag(byte b1, byte b2) + { + WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2); + } + + /// + /// Writes the given three-byte tag. + /// + /// The first byte of the encoded tag + /// The second byte of the encoded tag + /// The third byte of the encoded tag + public void WriteRawTag(byte b1, byte b2, byte b3) + { + WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3); + } + + /// + /// Writes the given four-byte tag. + /// + /// The first byte of the encoded tag + /// The second byte of the encoded tag + /// The third byte of the encoded tag + /// The fourth byte of the encoded tag + public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) + { + WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4); + } + + /// + /// Writes the given five-byte tag. + /// + /// The first byte of the encoded tag + /// The second byte of the encoded tag + /// The third byte of the encoded tag + /// The fourth byte of the encoded tag + /// The fifth byte of the encoded tag + public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) + { + WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4, b5); + } + + internal void Flush() + { + WriteBufferHelper.Flush(ref buffer, ref state); + } + + internal void CheckNoSpaceLeft() + { + WriteBufferHelper.CheckNoSpaceLeft(ref state); + } + + internal void CopyStateTo(CodedOutputStream output) + { + output.InternalState = state; + } + + internal void LoadStateFrom(CodedOutputStream output) + { + state = output.InternalState; + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/WriterInternalState.cs b/csharp/src/Google.Protobuf/WriterInternalState.cs new file mode 100644 index 000000000000..a779305bb730 --- /dev/null +++ b/csharp/src/Google.Protobuf/WriterInternalState.cs @@ -0,0 +1,62 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers; +using System.Buffers.Binary; +using System.Collections.Generic; +using System.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using Google.Protobuf.Collections; + +namespace Google.Protobuf +{ + + // warning: this is a mutable struct, so it needs to be only passed as a ref! + internal struct WriterInternalState + { + // NOTE: the Span representing the current buffer is kept separate so that this doesn't have to be a ref struct and so it can + // be included in CodedOutputStream's internal state + + internal int limit; // the size of the current buffer + internal int position; // position in the current buffer + + internal WriteBufferHelper writeBufferHelper; + + // If non-null, the top level parse method was started with given coded output stream as an argument + // which also means we can potentially fallback to calling WriteTo(CodedOutputStream cos) if needed. + internal CodedOutputStream CodedOutputStream => writeBufferHelper.CodedOutputStream; + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/WritingPrimitives.cs b/csharp/src/Google.Protobuf/WritingPrimitives.cs new file mode 100644 index 000000000000..846df7350260 --- /dev/null +++ b/csharp/src/Google.Protobuf/WritingPrimitives.cs @@ -0,0 +1,628 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Buffers.Binary; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; + +namespace Google.Protobuf +{ + /// + /// Primitives for encoding protobuf wire format. + /// + [SecuritySafeCritical] + internal static class WritingPrimitives + { + // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.) + internal static readonly Encoding Utf8Encoding = Encoding.UTF8; + + #region Writing of values (not including tags) + + /// + /// Writes a double field value, without a tag, to the stream. + /// + public static void WriteDouble(ref Span buffer, ref WriterInternalState state, double value) + { + WriteRawLittleEndian64(ref buffer, ref state, (ulong)BitConverter.DoubleToInt64Bits(value)); + } + + /// + /// Writes a float field value, without a tag, to the stream. + /// + public static unsafe void WriteFloat(ref Span buffer, ref WriterInternalState state, float value) + { + const int length = sizeof(float); + if (buffer.Length - state.position >= length) + { + // if there's enough space in the buffer, write the float directly into the buffer + var floatSpan = buffer.Slice(state.position, length); + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value); + + if (!BitConverter.IsLittleEndian) + { + floatSpan.Reverse(); + } + state.position += length; + } + else + { + WriteFloatSlowPath(ref buffer, ref state, value); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static unsafe void WriteFloatSlowPath(ref Span buffer, ref WriterInternalState state, float value) + { + const int length = sizeof(float); + + // TODO(jtattermusch): deduplicate the code. Populating the span is the same as for the fastpath. + Span floatSpan = stackalloc byte[length]; + Unsafe.WriteUnaligned(ref MemoryMarshal.GetReference(floatSpan), value); + if (!BitConverter.IsLittleEndian) + { + floatSpan.Reverse(); + } + + WriteRawByte(ref buffer, ref state, floatSpan[0]); + WriteRawByte(ref buffer, ref state, floatSpan[1]); + WriteRawByte(ref buffer, ref state, floatSpan[2]); + WriteRawByte(ref buffer, ref state, floatSpan[3]); + } + + /// + /// Writes a uint64 field value, without a tag, to the stream. + /// + public static void WriteUInt64(ref Span buffer, ref WriterInternalState state, ulong value) + { + WriteRawVarint64(ref buffer, ref state, value); + } + + /// + /// Writes an int64 field value, without a tag, to the stream. + /// + public static void WriteInt64(ref Span buffer, ref WriterInternalState state, long value) + { + WriteRawVarint64(ref buffer, ref state, (ulong)value); + } + + /// + /// Writes an int32 field value, without a tag, to the stream. + /// + public static void WriteInt32(ref Span buffer, ref WriterInternalState state, int value) + { + if (value >= 0) + { + WriteRawVarint32(ref buffer, ref state, (uint)value); + } + else + { + // Must sign-extend. + WriteRawVarint64(ref buffer, ref state, (ulong)value); + } + } + + /// + /// Writes a fixed64 field value, without a tag, to the stream. + /// + public static void WriteFixed64(ref Span buffer, ref WriterInternalState state, ulong value) + { + WriteRawLittleEndian64(ref buffer, ref state, value); + } + + /// + /// Writes a fixed32 field value, without a tag, to the stream. + /// + public static void WriteFixed32(ref Span buffer, ref WriterInternalState state, uint value) + { + WriteRawLittleEndian32(ref buffer, ref state, value); + } + + /// + /// Writes a bool field value, without a tag, to the stream. + /// + public static void WriteBool(ref Span buffer, ref WriterInternalState state, bool value) + { + WriteRawByte(ref buffer, ref state, value ? (byte)1 : (byte)0); + } + + /// + /// Writes a string field value, without a tag, to the stream. + /// The data is length-prefixed. + /// + public static void WriteString(ref Span buffer, ref WriterInternalState state, string value) + { + // Optimise the case where we have enough space to write + // the string directly to the buffer, which should be common. + int length = Utf8Encoding.GetByteCount(value); + WriteLength(ref buffer, ref state, length); + if (buffer.Length - state.position >= length) + { + if (length == value.Length) // Must be all ASCII... + { + for (int i = 0; i < length; i++) + { + buffer[state.position + i] = (byte)value[i]; + } + state.position += length; + } + else + { +#if NETSTANDARD1_1 + // slowpath when Encoding.GetBytes(Char*, Int32, Byte*, Int32) is not available + byte[] bytes = Utf8Encoding.GetBytes(value); + WriteRawBytes(ref buffer, ref state, bytes); +#else + ReadOnlySpan source = value.AsSpan(); + int bytesUsed; + unsafe + { + fixed (char* sourceChars = &MemoryMarshal.GetReference(source)) + fixed (byte* destinationBytes = &MemoryMarshal.GetReference(buffer.Slice(state.position))) + { + bytesUsed = Utf8Encoding.GetBytes(sourceChars, source.Length, destinationBytes, buffer.Length); + } + } + state.position += bytesUsed; +#endif + } + } + else + { + // Opportunity for future optimization: + // Large strings that don't fit into the current buffer segment + // can probably be optimized by using Utf8Encoding.GetEncoder() + // but more benchmarks would need to be added as evidence. + byte[] bytes = Utf8Encoding.GetBytes(value); + WriteRawBytes(ref buffer, ref state, bytes); + } + } + + /// + /// Write a byte string, without a tag, to the stream. + /// The data is length-prefixed. + /// + public static void WriteBytes(ref Span buffer, ref WriterInternalState state, ByteString value) + { + WriteLength(ref buffer, ref state, value.Length); + WriteRawBytes(ref buffer, ref state, value.Span); + } + + /// + /// Writes a uint32 value, without a tag, to the stream. + /// + public static void WriteUInt32(ref Span buffer, ref WriterInternalState state, uint value) + { + WriteRawVarint32(ref buffer, ref state, value); + } + + /// + /// Writes an enum value, without a tag, to the stream. + /// + public static void WriteEnum(ref Span buffer, ref WriterInternalState state, int value) + { + WriteInt32(ref buffer, ref state, value); + } + + /// + /// Writes an sfixed32 value, without a tag, to the stream. + /// + public static void WriteSFixed32(ref Span buffer, ref WriterInternalState state, int value) + { + WriteRawLittleEndian32(ref buffer, ref state, (uint)value); + } + + /// + /// Writes an sfixed64 value, without a tag, to the stream. + /// + public static void WriteSFixed64(ref Span buffer, ref WriterInternalState state, long value) + { + WriteRawLittleEndian64(ref buffer, ref state, (ulong)value); + } + + /// + /// Writes an sint32 value, without a tag, to the stream. + /// + public static void WriteSInt32(ref Span buffer, ref WriterInternalState state, int value) + { + WriteRawVarint32(ref buffer, ref state, EncodeZigZag32(value)); + } + + /// + /// Writes an sint64 value, without a tag, to the stream. + /// + public static void WriteSInt64(ref Span buffer, ref WriterInternalState state, long value) + { + WriteRawVarint64(ref buffer, ref state, EncodeZigZag64(value)); + } + + /// + /// Writes a length (in bytes) for length-delimited data. + /// + /// + /// This method simply writes a rawint, but exists for clarity in calling code. + /// + public static void WriteLength(ref Span buffer, ref WriterInternalState state, int length) + { + WriteRawVarint32(ref buffer, ref state, (uint)length); + } + + #endregion + + #region Writing primitives + /// + /// Writes a 32 bit value as a varint. The fast route is taken when + /// there's enough buffer space left to whizz through without checking + /// for each byte; otherwise, we resort to calling WriteRawByte each time. + /// + public static void WriteRawVarint32(ref Span buffer, ref WriterInternalState state, uint value) + { + // Optimize for the common case of a single byte value + if (value < 128 && state.position < buffer.Length) + { + buffer[state.position++] = (byte)value; + return; + } + + // Fast path when capacity is available + while (state.position < buffer.Length) + { + if (value > 127) + { + buffer[state.position++] = (byte)((value & 0x7F) | 0x80); + value >>= 7; + } + else + { + buffer[state.position++] = (byte)value; + return; + } + } + + while (value > 127) + { + WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80)); + value >>= 7; + } + + WriteRawByte(ref buffer, ref state, (byte)value); + } + + public static void WriteRawVarint64(ref Span buffer, ref WriterInternalState state, ulong value) + { + // Optimize for the common case of a single byte value + if (value < 128 && state.position < buffer.Length) + { + buffer[state.position++] = (byte)value; + return; + } + + // Fast path when capacity is available + while (state.position < buffer.Length) + { + if (value > 127) + { + buffer[state.position++] = (byte)((value & 0x7F) | 0x80); + value >>= 7; + } + else + { + buffer[state.position++] = (byte)value; + return; + } + } + + while (value > 127) + { + WriteRawByte(ref buffer, ref state, (byte)((value & 0x7F) | 0x80)); + value >>= 7; + } + + WriteRawByte(ref buffer, ref state, (byte)value); + } + + public static void WriteRawLittleEndian32(ref Span buffer, ref WriterInternalState state, uint value) + { + const int length = sizeof(uint); + if (state.position + length > buffer.Length) + { + WriteRawLittleEndian32SlowPath(ref buffer, ref state, value); + } + else + { + BinaryPrimitives.WriteUInt32LittleEndian(buffer.Slice(state.position), value); + state.position += length; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void WriteRawLittleEndian32SlowPath(ref Span buffer, ref WriterInternalState state, uint value) + { + WriteRawByte(ref buffer, ref state, (byte)value); + WriteRawByte(ref buffer, ref state, (byte)(value >> 8)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 16)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 24)); + } + + public static void WriteRawLittleEndian64(ref Span buffer, ref WriterInternalState state, ulong value) + { + const int length = sizeof(ulong); + if (state.position + length > buffer.Length) + { + WriteRawLittleEndian64SlowPath(ref buffer, ref state, value); + } + else + { + BinaryPrimitives.WriteUInt64LittleEndian(buffer.Slice(state.position), value); + state.position += length; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WriteRawLittleEndian64SlowPath(ref Span buffer, ref WriterInternalState state, ulong value) + { + WriteRawByte(ref buffer, ref state, (byte)value); + WriteRawByte(ref buffer, ref state, (byte)(value >> 8)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 16)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 24)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 32)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 40)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 48)); + WriteRawByte(ref buffer, ref state, (byte)(value >> 56)); + } + + private static void WriteRawByte(ref Span buffer, ref WriterInternalState state, byte value) + { + if (state.position == buffer.Length) + { + WriteBufferHelper.RefreshBuffer(ref buffer, ref state); + } + + buffer[state.position++] = value; + } + + /// + /// Writes out an array of bytes. + /// + public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, byte[] value) + { + WriteRawBytes(ref buffer, ref state, new ReadOnlySpan(value)); + } + + /// + /// Writes out part of an array of bytes. + /// + public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, byte[] value, int offset, int length) + { + WriteRawBytes(ref buffer, ref state, new ReadOnlySpan(value, offset, length)); + } + + /// + /// Writes out part of an array of bytes. + /// + public static void WriteRawBytes(ref Span buffer, ref WriterInternalState state, ReadOnlySpan value) + { + if (buffer.Length - state.position >= value.Length) + { + // We have room in the current buffer. + value.CopyTo(buffer.Slice(state.position, value.Length)); + state.position += value.Length; + } + else + { + // When writing to a CodedOutputStream backed by a Stream, we could avoid + // copying the data twice (first copying to the current buffer and + // and later writing from the current buffer to the underlying Stream) + // in some circumstances by writing the data directly to the underlying Stream. + // Current this is not being done to avoid specialcasing the code for + // CodedOutputStream vs IBufferWriter. + int bytesWritten = 0; + while (buffer.Length - state.position < value.Length - bytesWritten) + { + int length = buffer.Length - state.position; + value.Slice(bytesWritten, length).CopyTo(buffer.Slice(state.position, length)); + bytesWritten += length; + state.position += length; + WriteBufferHelper.RefreshBuffer(ref buffer, ref state); + } + + // copy the remaining data + int remainderLength = value.Length - bytesWritten; + value.Slice(bytesWritten, remainderLength).CopyTo(buffer.Slice(state.position, remainderLength)); + state.position += remainderLength; + } + } + #endregion + + #region Raw tag writing + /// + /// Encodes and writes a tag. + /// + public static void WriteTag(ref Span buffer, ref WriterInternalState state, int fieldNumber, WireFormat.WireType type) + { + WriteRawVarint32(ref buffer, ref state, WireFormat.MakeTag(fieldNumber, type)); + } + + /// + /// Writes an already-encoded tag. + /// + public static void WriteTag(ref Span buffer, ref WriterInternalState state, uint tag) + { + WriteRawVarint32(ref buffer, ref state, tag); + } + + /// + /// Writes the given single-byte tag directly to the stream. + /// + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1) + { + WriteRawByte(ref buffer, ref state, b1); + } + + /// + /// Writes the given two-byte tag directly to the stream. + /// + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2) + { + if (state.position + 2 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2) + { + WriteRawByte(ref buffer, ref state, b1); + WriteRawByte(ref buffer, ref state, b2); + } + + /// + /// Writes the given three-byte tag directly to the stream. + /// + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3) + { + if (state.position + 3 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + buffer[state.position++] = b3; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3) + { + WriteRawByte(ref buffer, ref state, b1); + WriteRawByte(ref buffer, ref state, b2); + WriteRawByte(ref buffer, ref state, b3); + } + + /// + /// Writes the given four-byte tag directly to the stream. + /// + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4) + { + if (state.position + 4 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + buffer[state.position++] = b3; + buffer[state.position++] = b4; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4) + { + WriteRawByte(ref buffer, ref state, b1); + WriteRawByte(ref buffer, ref state, b2); + WriteRawByte(ref buffer, ref state, b3); + WriteRawByte(ref buffer, ref state, b4); + } + + /// + /// Writes the given five-byte tag directly to the stream. + /// + public static void WriteRawTag(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) + { + if (state.position + 5 > buffer.Length) + { + WriteRawTagSlowPath(ref buffer, ref state, b1, b2, b3, b4, b5); + } + else + { + buffer[state.position++] = b1; + buffer[state.position++] = b2; + buffer[state.position++] = b3; + buffer[state.position++] = b4; + buffer[state.position++] = b5; + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void WriteRawTagSlowPath(ref Span buffer, ref WriterInternalState state, byte b1, byte b2, byte b3, byte b4, byte b5) + { + WriteRawByte(ref buffer, ref state, b1); + WriteRawByte(ref buffer, ref state, b2); + WriteRawByte(ref buffer, ref state, b3); + WriteRawByte(ref buffer, ref state, b4); + WriteRawByte(ref buffer, ref state, b5); + } + #endregion + + /// + /// Encode a 32-bit value with ZigZag encoding. + /// + /// + /// ZigZag encodes signed integers into values that can be efficiently + /// encoded with varint. (Otherwise, negative values must be + /// sign-extended to 64 bits to be varint encoded, thus always taking + /// 10 bytes on the wire.) + /// + public static uint EncodeZigZag32(int n) + { + // Note: the right-shift must be arithmetic + return (uint)((n << 1) ^ (n >> 31)); + } + + /// + /// Encode a 64-bit value with ZigZag encoding. + /// + /// + /// ZigZag encodes signed integers into values that can be efficiently + /// encoded with varint. (Otherwise, negative values must be + /// sign-extended to 64 bits to be varint encoded, thus always taking + /// 10 bytes on the wire.) + /// + public static ulong EncodeZigZag64(long n) + { + return (ulong)((n << 1) ^ (n >> 63)); + } + } +} \ No newline at end of file diff --git a/csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs b/csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs new file mode 100644 index 000000000000..cd2d4379154e --- /dev/null +++ b/csharp/src/Google.Protobuf/WritingPrimitivesMessages.cs @@ -0,0 +1,112 @@ +#region Copyright notice and license +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. +#endregion + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices.ComTypes; +using System.Security; + +namespace Google.Protobuf +{ + /// + /// Writing messages / groups. + /// + [SecuritySafeCritical] + internal static class WritingPrimitivesMessages + { + /// + /// Writes a message, without a tag. + /// The data is length-prefixed. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteMessage(ref WriteContext ctx, IMessage value) + { + WritingPrimitives.WriteLength(ref ctx.buffer, ref ctx.state, value.CalculateSize()); + WriteRawMessage(ref ctx, value); + } + + /// + /// Writes a group, without a tag. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteGroup(ref WriteContext ctx, IMessage value) + { + WriteRawMessage(ref ctx, value); + } + + /// + /// Writes a message, without a tag. + /// Message will be written without a length prefix. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteRawMessage(ref WriteContext ctx, IMessage message) + { + if (message is IBufferMessage bufferMessage) + { + bufferMessage.InternalWriteTo(ref ctx); + } + else + { + // If we reached here, it means we've ran into a nested message with older generated code + // which doesn't provide the InternalWriteTo method that takes a WriteContext. + // With a slight performance overhead, we can still serialize this message just fine, + // but we need to find the original CodedOutputStream instance that initiated this + // serialization process and make sure its internal state is up to date. + // Note that this performance overhead is not very high (basically copying contents of a struct) + // and it will only be incurred in case the application mixes older and newer generated code. + // Regenerating the code from .proto files will remove this overhead because it will + // generate the InternalWriteTo method we need. + + if (ctx.state.CodedOutputStream == null) + { + // This can only happen when the serialization started without providing a CodedOutputStream instance + // (e.g. WriteContext was created directly from a IBufferWriter). + // That also means that one of the new parsing APIs was used at the top level + // and in such case it is reasonable to require that all the nested message provide + // up-to-date generated code with WriteContext support (and fail otherwise). + throw new InvalidProtocolBufferException($"Message {message.GetType().Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code."); + } + + ctx.CopyStateTo(ctx.state.CodedOutputStream); + try + { + // fallback parse using the CodedOutputStream that started current serialization tree + message.WriteTo(ctx.state.CodedOutputStream); + } + finally + { + ctx.LoadStateFrom(ctx.state.CodedOutputStream); + } + } + } + } +} \ No newline at end of file diff --git a/docs/csharp/proto2.md b/docs/csharp/proto2.md index 0d9159de73d2..53fc43c7ebb1 100644 --- a/docs/csharp/proto2.md +++ b/docs/csharp/proto2.md @@ -97,7 +97,7 @@ foo.GetOrInitializeExtension(RepeatedFooExt).Add(new Baz()); ### Message initialization -Initialization refers to checking the status of required fields in a proto2 message. If a message is uninitialized, not all required fields are set in either the message itself or any of its submessages. In other languages, missing required fields throw errors depending on the merge method used. This could cause unforseen errors at runtime if the incorrect method is used. +Initialization refers to checking the status of required fields in a proto2 message. If a message is uninitialized, not all required fields are set in either the message itself or any of its submessages. In other languages, missing required fields throw errors depending on the merge method used. This could cause unforeseen errors at runtime if the incorrect method is used. However, in this implementation, parsers and input streams don't check messages for initialization on their own and throw errors. Instead it's up to you to handle messages with missing required fields in whatever way you see fit. Checking message initialization can be done manually via the `IsInitialized` extension method in `MessageExtensions`. diff --git a/docs/field_presence.md b/docs/field_presence.md new file mode 100644 index 000000000000..dc16292c8511 --- /dev/null +++ b/docs/field_presence.md @@ -0,0 +1,476 @@ +# Application note: Field presence + +This application note explains the various presence tracking disciplines for protobuf fields. It also explains how to enable experimental support for explicit presence tracking for singular proto3 fields with basic types. + +## Background + +_Field presence_ is the notion of whether a protobuf field has a value. There are two different manifestations of presence for protobufs: _no presence_, where the generated message API stores field values (only), and _explicit presence_, where the API also stores whether or not a field has been set. + +Historically, proto2 has mostly followed _explicit presence_, while proto3 exposes only _no presence_ semantics. Singular proto3 fields of basic types (numeric, string, bytes, and enums) which are defined with the `optional` label have _explicit presence_, like proto2 (this is an experimental feature added as of release 3.12, and must be enabled by passing a flag to `protoc`). + +### Presence disciplines + +_Presence disciplines_ define the semantics for translating between the _API representation_ and the _serialized representation_. The _no presence_ discipline relies upon the field value itself to make decisions at (de)serialization time, while the _explicit presence_ discipline relies upon the explicit tracking state instead. + +### Presence in _tag-value stream_ (wire format) serialization + +The wire format is a stream of tagged, _self-delimiting_ values. By definition, the wire format represents a sequence of _present_ values. In other words, every value found within a serialization represents a _present_ field; furthermore, the serialization contains no information about not-present values. + +The generated API for a proto message includes (de)serialization definitions which translate between API types and a stream of definitionally _present_ (tag, value) pairs. This translation is designed to be forward- and backward-compatibile across changes to the message definition; however, this compatibility introduces some (perhaps surprising) considerations when deserializing wire-formatted messages: + +- When serializing, fields with _no presence_ are not serialized if they contain their default value. + - For numeric types, the default is 0. + - For enums, the default is the zero-valued enumerator. + - For strings, bytes, and repeated fields, the default is the zero-length value. + - For messages, the default is the language-specific null value. +- "Empty" length-delimited values (such as empty strings) can be validly represented in serialized values: the field is "present," in the sense that it appears in the wire format. However, if the generated API does not track presence, then these values may not be re-serialized; i.e., the empty field may be "not present" after a serialization round-trip. +- When deserializing, duplicate field values may be handled in different ways depending on the field definition. + - Duplicate `repeated` fields are typically appended to the field's API representation. (Note that serializing a _packed_ repeated field produces only one, length-delimited value in the tag stream.) + - Duplicate `optional` field values follow the rule that "the last one wins." +- `oneof` fields expose the API-level invariant that only one field is set at a time. However, the wire format may include multiple (tag, value) pairs which notionally belong to the `oneof`. Similar to `optional` fields, the generated API follows the "last one wins" rule. +- Out-of-range values are not returned for enum fields in generated proto2 APIs. However, out-of-range values may be stored as _unknown fields_ in the API, even though the wire-format tag was recognized. + +### Presence in _named-field mapping_ formats + +Protobufs can be represented in human-readable, textual forms. Two notable formats are TextFormat (the output format produced by generated message `DebugString` methods) and JSON. + +These formats have correctness requirements of their own, and are generally stricter than _tagged-value stream_ formats. However, TextFormat more closely mimics the semantics of the wire format, and does, in certain cases, provide similar semantics (for example, appending repeated name-value mappings to a repeated field). In particular, similar to the wire format, TextFormat only includes fields which are present. + +JSON is a much stricter format, however, and cannot validly represent some semantics of the wire format or TextFormat. + +- Notably, JSON _elements_ are semantically unordered, and each member must have a unique name. This is different from TextFormat rules for repeated fields. +- JSON may include fields that are "not present," unlike the _no presence_ discipline for other formats: + - JSON defines a `null` value, which may be used to represent a _defined but not-present field_. + - Repeated field values may be included in the formatted output, even if they are equal to the default (an empty list). +- Because JSON elements are unordered, there is no way to unambiguously interpret the "last one wins" rule. + - In most cases, this is fine: JSON elements must have unique names: repeated field values are not valid JSON, so they do not need to be resolved as they are for TextFormat. + - However, this means that it may not be possible to interpret `oneof` fields unambiguously: if multiple cases are present, they are unordered. + +In theory, JSON _can_ represent presence in a semantic-preserving fashion. In practice, however, presence correctness can vary depending upon implementation choices, especially if JSON was chosen as a means to interoperate with clients not using protobufs. + +### Presence in proto2 APIs + +This table outlines whether presence is tracked for fields in proto2 APIs (both for generated APIs and using dynamic reflection): + +Field type | Explicit Presence +-------------------------------------------- | ----------------- +Singular numeric (integer or floating point) | ✔️ +Singular enum | ✔️ +Singular string or bytes | ✔️ +Singular message | ✔️ +Repeated | +Oneofs | ✔️ +Maps | + +Singular fields (of all types) track presence explicitly in the generated API. The generated message interface includes methods to query presence of fields. For example, the field `foo` has a corresponding `has_foo` method. (The specific name follows the same language-specific naming convention as the field accessors.) These methods are sometimes referred to as "hazzers" within the protobuf implementation. + +Similar to singular fields, `oneof` fields explicitly track which one of the members, if any, contains a value. For example, consider this example `oneof`: + +``` +oneof foo { + int32 a = 1; + float b = 2; +} +``` + +Depending on the target language, the generated API would generally include several methods: + +- A hazzer for the oneof: `has_foo` +- A _oneof case_ method: `foo` +- Hazzers for the members: `has_a`, `has_b` +- Getters for the members: `a`, `b` + +Repeated fields and maps do not track presence: there is no distinction between an _empty_ and a _not-present_ repeated field. + +### Presence in proto3 APIs + +This table outlines whether presence is tracked for fields in proto3 APIs (both for generated APIs and using dynamic reflection): + +Field type | `optional` | Explicit Presence +-------------------------------------------- | ---------- | ----------------- +Singular numeric (integer or floating point) | No | +Singular enum | No | +Singular string or bytes | No | +Singular numeric (integer or floating point) | Yes | ✔️ +Singular enum | Yes | ✔️ +Singular string or bytes | Yes | ✔️ +Singular message | Yes | ✔️ +Singular message | No | ✔️ +Repeated | N/A | +Oneofs | N/A | ✔️ +Maps | N/A | + +Similar to proto2 APIs, proto3 does not track presence explicitly for repeated fields. Without the `optional` label, proto3 APIs do not track presence for basic types (numeric, string, bytes, and enums), either. (Note that `optional` for proto3 fields is only experimentally available as of release 3.12.) Oneof fields affirmatively expose presence, although the same set of hazzer methods may not generated as in proto2 APIs. + +Under the _no presence_ discipline, the default value is synonymous with "not present" for purposes of serialization. To notionally "clear" a field (so it won't be serialized), an API user would set it to the default value. + +The default value for enum-typed fields under _no presence_ is the corresponding 0-valued enumerator. Under proto3 syntax rules, all enum types are required to have an enumerator value which maps to 0. By convention, this is an `UNKNOWN` or similarly-named enumerator. If the zero value is notionally outside the domain of valid values for the application, this behavior can be thought of as tantamount to _explicit presence_. + +## Semantic differences + +The _no presence_ serialization discipline results in visible differences from the _explicit presence_ tracking discipline, when the default value is set. For a singular field with numeric, enum, or string type: + +- _No presence_ discipline: + - Default values are not serialized. + - Default values are _not_ merged-from. + - To "clear" a field, it is set to its default value. + - The default value may mean: + - the field was explicitly set to its default value, which is valid in the application-specific domain of values; + - the field was notionally "cleared" by setting its default; or + - the field was never set. +- _Explicit presence_ discipline: + - Explicitly set values are always serialized, including default values. + - Un-set fields are never merged-from. + - Explicitly set fields -- including default values -- _are_ merged-from. + - A generated `has_foo` method indicates whether or not the field `foo` has been set (and not cleared). + - A generated `clear_foo` method must be used to clear (i.e., un-set) the value. + +### Considerations for merging + +Under the _no presence_ rules, it is effectively impossible for a target field to merge-from its default value (using the protobuf's API merging functions). This is because default values are skipped, similar to the _no presence_ serialization discipline. Merging only updates the target (merged-to) message using the non-skipped values from the update (merged-from) message. + +The difference in merging behavior has further implications for protocols which rely on partial "patch" updates. If field presence is not tracked, then an update patch alone cannot represent an update to the default value, because only non-default values are merged-from. + +Updating to set a default value in this case requires some external mechanism, such as `FieldMask`. However, if presence _is_ tracked, then all explicitly-set values -- even default values -- will be merged into the target. + +### Considerations for change-compatibility + +Changing a field between _explicit presence_ and _no presence_ is a binary-compatible change for serialized values in wire format. However, the serialized representation of the message may differ, depending on which version of the message definition was used for serialization. Specifically, when a "sender" explicitly sets a field to its default value: + +- The serialized value following _no presence_ discipline does not contain the default value, even though it was explicitly set. +- The serialized value following _explicit presence_ discipline contains every "present" field, even if it contains the default value. + +This change may or may not be safe, depending on the application's semantics. For example, consider two clients with different versions of a message definition. + +Client A uses this definition of the message, which follows the _explicit presence_ serialization discipline for field `foo`: + +``` +syntax = "proto3"; +message Msg { + optional int32 foo = 1; +} +``` + +Client B uses a definition of the same message, except that it follows the _no presence_ discipline: + +``` +syntax = "proto3"; +message Msg { + int32 foo = 1; +} +``` + +Now, consider a scenario where client A observes `foo`'s presence as the clients repeatedly exchange the "same" message by deserializing and reserializing: + +``` +// Client A: +Msg m_a; +m_a.set_foo(1); // non-default value +assert(m_a.has_foo()); // OK +Send(m_a.SerializeAsString()); // to client B + +// Client B: +Msg m_b; +m_b.ParseFromString(Receive()); // from client A +assert(m_b.foo() == 1); // OK +Send(m_b.SerializeAsString()); // to client A + +// Client A: +m_a.ParseFromString(Receive()); // from client B +assert(m_a.foo() == 1); // OK +assert(m_a.has_foo()); // OK +m_a.set_foo(0); // default value +Send(m_a.SerializeAsString()); // to client B + +// Client B: +Msg m_b; +m_b.ParseFromString(Receive()); // from client A +assert(m_b.foo() == 0); // OK +Send(m_b.SerializeAsString()); // to client A + +// Client A: +m_a.ParseFromString(Receive()); // from client B +assert(m_a.foo() == 0); // OK +assert(m_a.has_foo()); // FAIL +``` + +If client A depends on _explicit presence_ for `foo`, then a "round trip" through client B will be lossy from the perspective of client A. In the example, this is not a safe change: client A requires (by `assert`) that the field is present; even without any modifications through the API, that requirement fails in a value- and peer-dependent case. + +## How to enable _explicit presence_ in proto3 + +These are the general steps to use the experimental field tracking support for proto3: + +1. Add an `optional` field to a `.proto` file. +1. Run `protoc` (from release 3.12 or later) with an extra flag to recognize `optional` (i.e,. explicit presence) in proto3 files. +1. Use the generated "hazzer" methods and "clear" methods in application code, instead of comparing or setting default values. + +### `.proto` file changes + +This is an example of a proto3 message with fields which follow both _no presence_ and _explicit presence_ semantics: + +``` +syntax = "proto3"; +package example; + +message MyMessage { + // No presence: + int32 not_tracked = 1; + + // Explicit presence: + optional int32 tracked = 2; +} +``` + +### `protoc` invocation + +To enable presence tracking for proto3 messages, pass the `--experimental_allow_proto3_optional` flag to protoc. Without this flag, the `optional` label is an error in files using proto3 syntax. This flag is available in protobuf release 3.12 or later (or at HEAD, if you are reading this application note from Git). + +### Using the generated code + +The generated code for proto3 fields with _explicit presence_ (the `optional` label) will be the same as it would be in a proto2 file. + +This is the definition used in the "no presence" examples below: + +``` +syntax = "proto3"; +package example; +message Msg { + int32 foo = 1; +} +``` + +This is the definition used in the "explicit presence" examples below: + +``` +syntax = "proto3"; +package example; +message Msg { + optional int32 foo = 1; +} +``` + +In the examples, a function `GetProto` constructs and returns a message of type `Msg` with unspecified contents. + +#### C++ example + +No presence: + +``` +Msg m = GetProto(); +if (m.foo() != 0) { + // "Clear" the field: + m.set_foo(0); +} else { + // Default value: field may not have been present. + m.set_foo(1); +} +``` + +Explicit presence: + +``` +Msg m = GetProto(); +if (m.has_foo()) { + // Clear the field: + m.clear_foo(); +} else { + // Field is not present, so set it. + m.set_foo(1); +} +``` + +#### C# example + +No presence: + +``` +var m = GetProto(); +if (m.Foo != 0) { + // "Clear" the field: + m.Foo = 0; +} else { + // Default value: field may not have been present. + m.Foo = 1; +} +``` + +Explicit presence: + +``` +var m = GetProto(); +if (m.HasFoo) { + // Clear the field: + m.ClearFoo(); +} else { + // Field is not present, so set it. + m.Foo = 1; +} +``` + +#### Go example + +No presence: + +``` +m := GetProto() +if (m.GetFoo() != 0) { + // "Clear" the field: + m.Foo = 0; +} else { + // Default value: field may not have been present. + m.Foo = 1; +} +``` + +Explicit presence: + +``` +m := GetProto() +if (m.HasFoo()) { + // Clear the field: + m.Foo = nil +} else { + // Field is not present, so set it. + m.Foo = proto.Int32(1); +} +``` + +#### Java example + +These examples use a `Builder` to demonstrate clearing. Simply checking presence and getting values from a `Builder` follows the same API as the message type. + +No presence: + +``` +Msg.Builder m = GetProto().toBuilder(); +if (m.getFoo() != 0) { + // "Clear" the field: + m.setFoo(0); +} else { + // Default value: field may not have been present. + m.setFoo(1); +} +``` + +Explicit presence: + +``` +Msg.Builder m = GetProto().toBuilder(); +if (m.hasFoo()) { + // Clear the field: + m.clearFoo() +} else { + // Field is not present, so set it. + m.setFoo(1); +} +``` + +#### Python example + +No presence: + +``` +m = example.Msg() +if m.foo != 0: + // "Clear" the field: + m.foo = 0 +else: + // Default value: field may not have been present. + m.foo = 1 +``` + +Explicit presence: + +``` +m = example.Msg() +if m.HasField('foo'): + // Clear the field: + m.ClearField('foo') +else: + // Field is not present, so set it. + m.foo = 1 +``` + +#### Ruby example + +No presence: + +``` +m = Msg.new +if m.foo != 0 + // "Clear" the field: + m.foo = 0 +else + // Default value: field may not have been present. + m.foo = 1 +end +``` + +Explicit presence: + +``` +m = Msg.new +if m.has_foo? + // Clear the field: + m.clear_foo +else + // Field is not present, so set it. + m.foo = 1 +end +``` + +#### Javascript example + +No presence: + +``` +var m = new Msg(); +if (m.getFoo() != 0) { + // "Clear" the field: + m.setFoo(0); +} else { + // Default value: field may not have been present. + m.setFoo(1); +} +``` + +Explicit presence: + +``` +var m = new Msg(); +if (m.hasFoo()) { + // Clear the field: + m.clearFoo() +} else { + // Field is not present, so set it. + m.setFoo(1); +} +``` + +#### Objective C example + +No presence: + +``` +Msg *m = [[Msg alloc] init]; +if (m.foo != 0) { + // "Clear" the field: + m.foo = 0; +} else { + // Default value: field may not have been present. + m.foo = 1; +} +``` + +Explicit presence: + +``` +Msg *m = [[Msg alloc] init]; +if (m.hasFoo()) { + // Clear the field: + [m clearFoo]; +} else { + // Field is not present, so set it. + [m setFoo:1]; +} +``` diff --git a/docs/implementing_proto3_presence.md b/docs/implementing_proto3_presence.md new file mode 100644 index 000000000000..73f21a382984 --- /dev/null +++ b/docs/implementing_proto3_presence.md @@ -0,0 +1,400 @@ +# How To Implement Field Presence for Proto3 + +Protobuf release 3.12 adds experimental support for `optional` fields in +proto3. Proto3 optional fields track presence like in proto2. For background +information about what presence tracking means, please see +[docs/field_presence](field_presence.md). + +## Document Summary + +This document is targeted at developers who own or maintain protobuf code +generators. All code generators will need to be updated to support proto3 +optional fields. First-party code generators developed by Google are being +updated already. However third-party code generators will need to be updated +independently by their authors. This includes: + +- implementations of Protocol Buffers for other languages. +- alternate implementations of Protocol Buffers that target specialized use + cases. +- RPC code generators that create generated APIs for service calls. +- code generators that implement some utility code on top of protobuf generated + classes. + +While this document speaks in terms of "code generators", these same principles +apply to implementations that dynamically generate a protocol buffer API "on the +fly", directly from a descriptor, in languages that support this kind of usage. + +## Background + +Presence tracking was added to proto3 in response to user feedback, both from +inside Google and [from open-source +users](https://github.com/protocolbuffers/protobuf/issues/1606). The [proto3 +wrapper +types](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/wrappers.proto) +were previously the only supported presence mechanism for proto3. Users have +pointed to both efficiency and usability issues with the wrapper types. + +Presence in proto3 uses exactly the same syntax and semantics as in proto2. +Proto3 Fields marked `optional` will track presence like proto2, while fields +without any label (known as "singular fields"), will continue to omit presence +information. The `optional` keyword was chosen to minimize differences with +proto2. + +Unfortunately, for the current descriptor protos and `Descriptor` API (as of +3.11.4) it is not possible to use the same representation as proto2. Proto3 +descriptors already use `LABEL_OPTIONAL` for proto3 singular fields, which do +not track presence. There is a lot of existing code that reflects over proto3 +protos and assumes that `LABEL_OPTIONAL` in proto3 means "no presence." Changing +the semantics now would be risky, since old software would likely drop proto3 +presence information, which would be a data loss bug. + +To minimize this risk we chose a descriptor representation that is semantically +compatible with existing proto3 reflection. Every proto3 optional field is +placed into a one-field `oneof`. We call this a "synthetic" oneof, as it was not +present in the source `.proto` file. + +Since oneof fields in proto3 already track presence, existing proto3 +reflection-based algorithms should correctly preserve presence for proto3 +optional fields with no code changes. For example, the JSON and TextFormat +parsers/serializers in C++ and Java did not require any changes to support +proto3 presence. This is the major benefit of synthetic oneofs. + +This design does leave some cruft in descriptors. Synthetic oneofs are a +compatibility measure that we can hopefully clean up in the future. For now +though, it is important to preserve them across different descriptor formats and +APIs. It is never safe to drop synthetic oneofs from a proto schema. Code +generators can (and should) skip synthetic oneofs when generating a user-facing +API or user-facing documentation. But for any schema representation that is +consumed programmatically, it is important to keep the synthetic oneofs around. + +In APIs it can be helpful to offer separate accessors that refer to "real" +oneofs (see [API Changes](#api-changes) below). This is a convenient way to omit +synthetic oneofs in code generators. + +## Updating a Code Generator + +When a user adds an `optional` field to proto3, this is internally rewritten as +a one-field oneof, for backward-compatibility with reflection-based algorithms: + +```protobuf +syntax = "proto3"; + +message Foo { + // Experimental feature, not generally supported yet! + optional int32 foo = 1; + + // Internally rewritten to: + // oneof _foo { + // int32 foo = 1 [proto3_optional=true]; + // } + // + // We call _foo a "synthetic" oneof, since it was not created by the user. +} +``` + +As a result, the main two goals when updating a code generator are: + +1. Give `optional` fields like `foo` normal field presence, as described in + [docs/field_presence](field_presence.md) If your implementation already + supports proto2, a proto3 `optional` field should use exactly the same API + and internal implementation as proto2 `optional`. +2. Avoid generating any oneof-based accessors for the synthetic oneof. Its only + purpose is to make reflection-based algorithms work properly if they are + not aware of proto3 presence. The synthetic oneof should not appear anywhere + in the generated API. + +### Satisfying the Experimental Check + +If you try to run `protoc` on a file with proto3 `optional` fields, you will get +an error because the feature is still experimental: + +``` +$ cat test.proto +syntax = "proto3"; + +message Foo { + // Experimental feature, not generally supported yet! + optional int32 a = 1; +} +$ protoc --cpp_out=. test.proto +test.proto: This file contains proto3 optional fields, but --experimental_allow_proto3_optional was not set. +``` + +There are two options for getting around this error: + +1. Pass `--experimental_allow_proto3_optional` to protoc. +2. Make your filename (or a directory name) contain the string + `test_proto3_optional`. This indicates that the proto file is specifically + for testing proto3 optional support, so the check is suppressed. + +These options are demonstrated below: + +``` +# One option: +$ ./src/protoc test.proto --cpp_out=. --experimental_allow_proto3_optional + +# Another option: +$ cp test.proto test_proto3_optional.proto +$ ./src/protoc test_proto3_optional.proto --cpp_out=. +$ +``` + +The experimental check will be removed in a future release, once we are ready +to make this feature generally available. Ideally this will happen for the 3.13 +release of protobuf, sometime in mid-2020, but there is not a specific date set +for this yet. Some of the timing will depend on feedback we get from the +community, so if you have questions or concerns please get in touch via a +GitHub issue. + +### Signaling That Your Code Generator Supports Proto3 Optional + +If you now try to invoke your own code generator with the test proto, you will +run into a different error: + +``` +$ ./src/protoc test_proto3_optional.proto --my_codegen_out=. +test_proto3_optional.proto: is a proto3 file that contains optional fields, but +code generator --my_codegen_out hasn't been updated to support optional fields in +proto3. Please ask the owner of this code generator to support proto3 optional. +``` + +This check exists to make sure that code generators get a chance to update +before they are used with proto3 `optional` fields. Without this check an old +code generator might emit obsolete generated APIs (like accessors for a +synthetic oneof) and users could start depending on these. That would create +a legacy migration burden once a code generator actually implements the feature. + +To signal that your code generator supports `optional` fields in proto3, you +need to tell `protoc` what features you support. The method for doing this +depends on whether you are using the C++ +`google::protobuf::compiler::CodeGenerator` +framework or not. + +If you are using the CodeGenerator framework: + +```c++ +class MyCodeGenerator : public google::protobuf::compiler::CodeGenerator { + // Add this method. + uint64_t GetSupportedFeatures() const override { + // Indicate that this code generator supports proto3 optional fields. + // (Note: don't release your code generator with this flag set until you + // have actually added and tested your proto3 support!) + return FEATURE_PROTO3_OPTIONAL; + } +} +``` + +If you are generating code using raw `CodeGeneratorRequest` and +`CodeGeneratorResponse` messages from `plugin.proto`, the change will be very +similar: + +```c++ +void GenerateResponse() { + CodeGeneratorResponse response; + response.set_supported_features(CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL); + + // Generate code... +} +``` + +Once you have added this, you should now be able to successfully use your code +generator to generate a file containing proto3 optional fields: + +``` +$ ./src/protoc test_proto3_optional.proto --my_codegen_out=. +``` + +### Updating Your Code Generator + +Now to actually add support for proto3 optional to your code generator. The goal +is to recognize proto3 optional fields as optional, and suppress any output from +synthetic oneofs. + +If your code generator does not currently support proto2, you will need to +design an API and implementation for supporting presence in scalar fields. +Generally this means: + +- allocating a bit inside the generated class to represent whether a given field + is present or not. +- exposing a `has_foo()` method for each field to return the value of this bit. +- make the parser set this bit when a value is parsed from the wire. +- make the serializer test this bit to decide whether to serialize. + +If your code generator already supports proto2, then most of your work is +already done. All you need to do is make sure that proto3 optional fields have +exactly the same API and behave in exactly the same way as proto2 optional +fields. + +From experience updating several of Google's code generators, most of the +updates that are required fall into one of several patterns. Here we will show +the patterns in terms of the C++ CodeGenerator framework. If you are using +`CodeGeneratorRequest` and `CodeGeneratorReply` directly, you can translate the +C++ examples to your own language, referencing the C++ implementation of these +methods where required. + +#### To test whether a field should have presence + +Old: + +```c++ +bool MessageHasPresence(const google::protobuf::Descriptor* message) { + return message->file()->syntax() == + google::protobuf::FileDescriptor::SYNTAX_PROTO2; +} +``` + +New: + +```c++ +// Presence is no longer a property of a message, it's a property of individual +// fields. +bool FieldHasPresence(const google::protobuf::FieldDescriptor* field) { + return field->has_presence(); + // Note, the above will return true for fields in a oneof. + // If you want to filter out oneof fields, write this instead: + // return field->has_presence && !field->real_containing_oneof() +} +``` + +#### To test whether a field is a member of a oneof + +Old: + +```c++ +bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) { + return field->containing_oneof() != nullptr; +} +``` + +New: + +```c++ +bool FieldIsInOneof(const google::protobuf::FielDescriptor* field) { + // real_containing_oneof() returns nullptr for synthetic oneofs. + return field->real_containing_oneof() != nullptr; +} +``` + +#### To iterate over all oneofs + +Old: + +```c++ +bool IterateOverOneofs(const google::protobuf::Descriptor* message) { + for (int i = 0; i < message->oneof_decl_count(); i++) { + const google::protobuf::OneofDescriptor* oneof = message->oneof(i); + // ... + } +} +``` + +New: + +```c++ +bool IterateOverOneofs(const google::protobuf::Descriptor* message) { + // Real oneofs are always first, and real_oneof_decl_count() will return the + // total number of oneofs, excluding synthetic oneofs. + for (int i = 0; i < message->real_oneof_decl_count(); i++) { + const google::protobuf::OneofDescriptor* oneof = message->oneof(i); + // ... + } +} +``` + +## Updating Reflection + +If your implementation offers reflection, there are a few other changes to make: + +### API Changes + +The API for reflecting over fields and oneofs should make the following changes. +These match the changes implemented in C++ reflection. + +1. Add a `FieldDescriptor::has_presence()` method returning `bool` + (adjusted to your language's naming convention). This should return true + for all fields that have explicit presence, as documented in + [docs/field_presence](field_presence.md). In particular, this includes + fields in a oneof, proto2 scalar fields, and proto3 `optional` fields. + This accessor will allow users to query what fields have presence without + thinking about the difference between proto2 and proto3. +2. As a corollary of (1), please do *not* expose an accessor for the + `FieldDescriptorProto.proto3_optional` field. We want to avoid having + users implement any proto2/proto3-specific logic. Users should use the + `has_presence()` function instead. +3. You may also wish to add a `FieldDescriptor::has_optional_keyword()` method + returning `bool`, which indicates whether the `optional` keyword is present. + Message fields will always return `true` for `has_presence()`, so this method + can allow a user to know whether the user wrote `optional` or not. It can + occasionally be useful to have this information, even though it does not + change the presence semantics of the field. +4. If your reflection API may be used for a code generator, you may wish to + implement methods to help users tell the difference between real and + synthetic oneofs. In particular: + - `OneofDescriptor::is_synthetic()`: returns true if this is a synthetic + oneof. + - `FieldDescriptor::real_containing_oneof()`: like `containing_oneof()`, + but returns `nullptr` if the oneof is synthetic. + - `Descriptor::real_oneof_decl_count()`: like `oneof_decl_count()`, but + returns the number of real oneofs only. + +### Implementation Changes + +Proto3 `optional` fields and synthetic oneofs must work correctly when +reflected on. Specifically: + +1. Reflection for synthetic oneofs should work properly. Even though synthetic + oneofs do not really exist in the message, you can still make reflection work + as if they did. In particular, you can make a method like + `Reflection::HasOneof()` or `Reflection::GetOneofFieldDescriptor()` look at + the hasbit to determine if the oneof is present or not. +2. Reflection for proto3 optional fields should work properly. For example, a + method like `Reflection::HasField()` should know to look for the hasbit for a + proto3 `optional` field. It should not be fooled by the synthetic oneof into + thinking that there is a `case` member for the oneof. + +Once you have updated reflection to work properly with proto3 `optional` and +synthetic oneofs, any code that *uses* your reflection interface should work +properly with no changes. This is the benefit of using synthetic oneofs. + +In particular, if you have a reflection-based implementation of protobuf text +format or JSON, it should properly support proto3 optional fields without any +changes to the code. The fields will look like they all belong to a one-field +oneof, and existing proto3 reflection code should know how to test presence for +fields in a oneof. + +So the best way to test your reflection changes is to try round-tripping a +message through text format, JSON, or some other reflection-based parser and +serializer, if you have one. + +### Validating Descriptors + +If your reflection implementation supports loading descriptors at runtime, +you must verify that all synthetic oneofs are ordered after all "real" oneofs. + +Here is the code that implements this validation step in C++, for inspiration: + +```c++ + // Validation that runs for each message. + // Synthetic oneofs must be last. + int first_synthetic = -1; + for (int i = 0; i < message->oneof_decl_count(); i++) { + const OneofDescriptor* oneof = message->oneof_decl(i); + if (oneof->is_synthetic()) { + if (first_synthetic == -1) { + first_synthetic = i; + } + } else { + if (first_synthetic != -1) { + AddError(message->full_name(), proto.oneof_decl(i), + DescriptorPool::ErrorCollector::OTHER, + "Synthetic oneofs must be after all other oneofs"); + } + } + } + + if (first_synthetic == -1) { + message->real_oneof_decl_count_ = message->oneof_decl_count_; + } else { + message->real_oneof_decl_count_ = first_synthetic; + } +``` diff --git a/docs/options.md b/docs/options.md index ad7cd0d56d0b..3aee3921852a 100644 --- a/docs/options.md +++ b/docs/options.md @@ -93,8 +93,8 @@ with info about your project (name and website) so we can add an entry for you. * Website: https://github.com/protobuf-c/protobuf-c * Extensions: 1019 -1. ScalePB - * Website: http://trueaccord.github.io/ScalaPB/ +1. ScalaPB + * Website: https://scalapb.github.io/ * Extensions: 1020 1. protoc-gen-bq-schema @@ -224,3 +224,31 @@ with info about your project (name and website) so we can add an entry for you. 1. Wire since and until * Website: https://square.github.io/wire/ * Extensions: 1076, 1077 + +1. Bazel, Failure Details + * Website: https://github.com/bazelbuild/bazel + * Extensions: 1078 + +1. grpc-graphql-gateway + * Website: https://github.com/ysugimoto/grpc-graphql-gateway + * Extensions: 1079 + +1. Cloudstate + * Website: https://cloudstate.io + * Extensions: 1080-1084 + +1. SummaFT protoc-plugins + * Website: https://summaft.com/ + * Extensions: 1085 + +1. ADLINK EdgeSDK + * Website: https://www.adlinktech.com/en/Edge-SDK-IoT + * Extensions: 1086 + +1. Wire wire_package + * Website: https://square.github.io/wire/ + * Extensions: 1087 + +1. Confluent Schema Registry + * Website: https://github.com/confluentinc/schema-registry + * Extensions: 1088 diff --git a/docs/third_party.md b/docs/third_party.md index 528dc6e220ce..7799e308a7af 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -18,6 +18,7 @@ These are projects we know about implementing Protocol Buffers for other program * C: https://github.com/squidfunk/protobluff * C: https://github.com/eerimoq/pbtools * C++: https://github.com/google/protobuf (Google-official implementation) +* C++: https://EmbeddedProto.com * C/C++: http://spbc.sf.net/ * C#: http://code.google.com/p/protobuf-csharp-port * C#: https://silentorbit.com/protobuf/ @@ -25,8 +26,8 @@ These are projects we know about implementing Protocol Buffers for other program * Clojure: http://github.com/ninjudd/clojure-protobuf * Clojure: https://github.com/clojusc/protobuf * Clojure: https://protojure.github.io -* Common Lisp: http://github.com/ndantam/s-protobuf * Common Lisp: http://github.com/brown/protobuf +* Common Lisp: http://github.com/qitab/cl-protobuf * D: https://github.com/dcarp/protobuf-d * D: https://github.com/msoucy/dproto * D: https://github.com/opticron/ProtocolBuffer @@ -35,6 +36,7 @@ These are projects we know about implementing Protocol Buffers for other program * Delphi: http://fundementals.sourceforge.net/dl.html * Elixir: https://github.com/jeremyong/exprotoc * Elixir: https://github.com/tony612/protobuf-elixir +* Elixir: https://github.com/ahamez/protox * Elm: https://github.com/tiziano88/elm-protobuf * Erlang: https://github.com/tomas-abrahamsson/gpb * Erlang: http://piqi.org/ @@ -60,6 +62,8 @@ These are projects we know about implementing Protocol Buffers for other program * Javascript: https://github.com/dcodeIO/ProtoBuf.js * Javascript: http://code.google.com/p/protobuf-for-node/ * Javascript: http://code.google.com/p/protostuff/ +* Javascript: https://github.com/seishun/node-protoc-plugin (Node.js port of plugin.h) +* Javascript: https://github.com/seishun/node-protoc-gen-javascript (Node.js port of the Google-official implementation) * Julia: https://github.com/tanmaykm/ProtoBuf.jl * Kotlin: https://github.com/marcoferrer/kroto-plus * Kotlin: https://github.com/Kotlin/kotlinx.serialization @@ -80,8 +84,10 @@ These are projects we know about implementing Protocol Buffers for other program * PHP: https://github.com/chobie/php-protocolbuffers * PHP: http://drslump.github.com/Protobuf-PHP * Prolog: http://www.swi-prolog.org/pldoc/package/protobufs.html +* Purescript: https://github.com/xc-jp/purescript-protobuf * Python: https://github.com/google/protobuf (Google-official implementation) * Python: https://github.com/eigenein/protobuf +* Python: https://github.com/danielgtaylor/python-betterproto * R: http://cran.r-project.org/package=RProtoBuf * Ruby: http://code.google.com/p/ruby-protobuf/ * Ruby: http://github.com/mozy/ruby-protocol-buffers @@ -151,7 +157,7 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [Alternate encodings (JSON, XML, HTML) for Java protobufs](http://code.google.com/p/protobuf-java-format/) * [Another JSON encoder/decoder for Java](https://github.com/sijuv/protobuf-codec) * [Editor for serialized protobufs](http://code.google.com/p/protobufeditor/) -* [Intellij IDEA plugin](http://github.com/nnmatveev/idea-plugin-protobuf) +* [IntelliJ IDEA plugin](http://github.com/jvolkman/intellij-protobuf-editor) * [TextMate syntax highlighting](http://github.com/michaeledgar/protobuf-tmbundle) * [Oracle PL SQL plugin](http://code.google.com/p/protocol-buffer-plsql/) * [Eclipse editor for protobuf (from Google)](http://code.google.com/p/protobuf-dt/) @@ -181,3 +187,9 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [Protocol Buffer property-based testing utility and example message generator (Python / Hypothesis)](https://github.com/CurataEng/hypothesis-protobuf) * [Protolock - CLI utility to prevent backward-incompatible changes to .proto files](https://github.com/nilslice/protolock) * [Optional GRPC - GRPC for testable microservices (Python)](https://github.com/mattpaletta/optional-grpc.git) +* [Protobuf Parser - Yet another Go package which parses a Protocol Buffer file (proto2+proto3)](https://github.com/yoheimuta/go-protoparser) +* [Protolint - A tool to enforce Protocol Buffer style and conventions.](https://github.com/yoheimuta/protolint) + * [vscode-protolint: A protobuf linter for visual studio code](https://github.com/plexsystems/vscode-protolint) + * [intellij-protolint: A protobuf linter for JetBrains IDEs](https://github.com/yoheimuta/intellij-protolint) + * [vim-protolint: A protobuf linter for Vim](https://github.com/yoheimuta/vim-protolint) +* [super-linter: Protocol Buffer lint as GitHub Action](https://github.com/github/super-linter) diff --git a/editors/proto.vim b/editors/proto.vim index 7f1aeb730a17..bdc60ce7f8ee 100644 --- a/editors/proto.vim +++ b/editors/proto.vim @@ -69,10 +69,10 @@ syn keyword pbBool true false syn match pbInt /-\?\<\d\+\>/ syn match pbInt /\<0[xX]\x+\>/ syn match pbFloat /\<-\?\d*\(\.\d*\)\?/ -syn region pbComment start="\/\*" end="\*\/" contains=@pbCommentGrp -syn region pbComment start="//" skip="\\$" end="$" keepend contains=@pbCommentGrp -syn region pbString start=/"/ skip=/\\./ end=/"/ -syn region pbString start=/'/ skip=/\\./ end=/'/ +syn region pbComment start="\/\*" end="\*\/" contains=@pbCommentGrp,@Spell +syn region pbComment start="//" skip="\\$" end="$" keepend contains=@pbCommentGrp,@Spell +syn region pbString start=/"/ skip=/\\./ end=/"/ contains=@Spell +syn region pbString start=/'/ skip=/\\./ end=/'/ contains=@Spell if version >= 508 || !exists("did_proto_syn_inits") if version < 508 diff --git a/editors/protobuf-mode.el b/editors/protobuf-mode.el index d3bdcded70af..810277166563 100644 --- a/editors/protobuf-mode.el +++ b/editors/protobuf-mode.el @@ -1,4 +1,4 @@ -;;; protobuf-mode.el --- major mode for editing protocol buffers. +;;; protobuf-mode.el --- major mode for editing protocol buffers. -*- lexical-binding: t; -*- ;; Author: Alexandre Vassalotti ;; Created: 23-Apr-2009 @@ -216,7 +216,11 @@ Key bindings: (c-common-init 'protobuf-mode) (easy-menu-add protobuf-menu) (c-run-mode-hooks 'c-mode-common-hook 'protobuf-mode-hook) - (c-update-modeline)) + (c-update-modeline) + (setq imenu-generic-expression + '(("Message" "^[[:space:]]*message[[:space:]]+\\([[:alnum:]]+\\)" 1) + ("Enum" "^[[:space:]]*enum[[:space:]]+\\([[:alnum:]]+\\)" 1) + ("Service" "^[[:space:]]*service[[:space:]]+\\([[:alnum:]]+\\)" 1)))) (provide 'protobuf-mode) diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 000000000000..229542d23ce9 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,2 @@ +# Ignore the bazel symlinks +/bazel-* diff --git a/examples/README.md b/examples/README.md old mode 100755 new mode 100644 diff --git a/fix_permissions.sh b/fix_permissions.sh new file mode 100755 index 000000000000..f33c25c3067b --- /dev/null +++ b/fix_permissions.sh @@ -0,0 +1,8 @@ +#!/bin/bash +for file in $(find . -type f); do + if [ "$(head -c 2 $file)" == "#!" ]; then + chmod u+x $file + else + chmod a-x $file + fi +done diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh index e533d05b431a..dc03fee019d1 100755 --- a/generate_descriptor_proto.sh +++ b/generate_descriptor_proto.sh @@ -62,7 +62,7 @@ do PROTOC=$BOOTSTRAP_PROTOC BOOTSTRAP_PROTOC="" else - make $@ protoc + make -j$(nproc) $@ protoc if test $? -ne 0; then echo "Failed to build protoc." exit 1 diff --git a/global.json b/global.json index 1c02f0719ad0..16f71a741fa7 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,6 @@ { "sdk": { - "version": "3.0.100" + "version": "3.0.100", + "rollForward": "latestMinor" } } diff --git a/java/README.md b/java/README.md index c4e8e20de598..c8050893e02c 100644 --- a/java/README.md +++ b/java/README.md @@ -45,9 +45,9 @@ protobuf-java-util package: If you are using Gradle, add the following to your `build.gradle` file's dependencies: ``` - compile 'com.google.protobuf:protobuf-java:3.11.0' + implementation 'com.google.protobuf:protobuf-java:3.11.0' ``` -Again, be sure to check that the version number maches (or is newer than) the version number of protoc that you are using. +Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using. ### Use Java Protocol Buffers on Android @@ -68,7 +68,7 @@ how to use them. Most users should follow the instructions above to use protobuf Java runtime. If you are contributing code to protobuf or want to use a protobuf version -that hasn't been officially released yet, you can folllow the instructions +that hasn't been officially released yet, you can follow the instructions below to build protobuf from source code. ### Build from Source - With Maven diff --git a/java/bom/pom.xml b/java/bom/pom.xml index ea15d4819034..209a4b555b2e 100644 --- a/java/bom/pom.xml +++ b/java/bom/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-bom - 3.11.2 + 3.14.0 pom Protocol Buffers [BOM] diff --git a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto index 031433e2a9e1..95c8d4d2e32b 100644 --- a/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto +++ b/java/compatibility_tests/v2.5.0/more_protos/src/proto/google/protobuf/descriptor.proto @@ -74,7 +74,7 @@ message FileDescriptorProto { optional FileOptions options = 8; // This field contains optional information about the original source code. - // You may safely remove this entire field whithout harming runtime + // You may safely remove this entire field without harming runtime // functionality of the descriptors -- the information is needed only by // development tools. optional SourceCodeInfo source_code_info = 9; diff --git a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto index 031433e2a9e1..95c8d4d2e32b 100644 --- a/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto +++ b/java/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto @@ -74,7 +74,7 @@ message FileDescriptorProto { optional FileOptions options = 8; // This field contains optional information about the original source code. - // You may safely remove this entire field whithout harming runtime + // You may safely remove this entire field without harming runtime // functionality of the descriptors -- the information is needed only by // development tools. optional SourceCodeInfo source_code_info = 9; diff --git a/java/core/BUILD b/java/core/BUILD new file mode 100644 index 000000000000..e7778f9a62e0 --- /dev/null +++ b/java/core/BUILD @@ -0,0 +1,127 @@ +load("@rules_java//java:defs.bzl", "java_library") +load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") + +LITE_SRCS = [ + # Keep in sync with `//java/lite:pom.xml`. + "src/main/java/com/google/protobuf/AbstractMessageLite.java", + "src/main/java/com/google/protobuf/AbstractParser.java", + "src/main/java/com/google/protobuf/AbstractProtobufList.java", + "src/main/java/com/google/protobuf/AllocatedBuffer.java", + "src/main/java/com/google/protobuf/Android.java", + "src/main/java/com/google/protobuf/ArrayDecoders.java", + "src/main/java/com/google/protobuf/BinaryReader.java", + "src/main/java/com/google/protobuf/BinaryWriter.java", + "src/main/java/com/google/protobuf/BooleanArrayList.java", + "src/main/java/com/google/protobuf/BufferAllocator.java", + "src/main/java/com/google/protobuf/ByteBufferWriter.java", + "src/main/java/com/google/protobuf/ByteOutput.java", + "src/main/java/com/google/protobuf/ByteString.java", + "src/main/java/com/google/protobuf/CodedInputStream.java", + "src/main/java/com/google/protobuf/CodedInputStreamReader.java", + "src/main/java/com/google/protobuf/CodedOutputStream.java", + "src/main/java/com/google/protobuf/CodedOutputStreamWriter.java", + "src/main/java/com/google/protobuf/DoubleArrayList.java", + "src/main/java/com/google/protobuf/ExperimentalApi.java", + "src/main/java/com/google/protobuf/ExtensionLite.java", + "src/main/java/com/google/protobuf/ExtensionRegistryFactory.java", + "src/main/java/com/google/protobuf/ExtensionRegistryLite.java", + "src/main/java/com/google/protobuf/ExtensionSchema.java", + "src/main/java/com/google/protobuf/ExtensionSchemaLite.java", + "src/main/java/com/google/protobuf/ExtensionSchemas.java", + "src/main/java/com/google/protobuf/FieldInfo.java", + "src/main/java/com/google/protobuf/FieldSet.java", + "src/main/java/com/google/protobuf/FieldType.java", + "src/main/java/com/google/protobuf/FloatArrayList.java", + "src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java", + "src/main/java/com/google/protobuf/GeneratedMessageLite.java", + "src/main/java/com/google/protobuf/IntArrayList.java", + "src/main/java/com/google/protobuf/Internal.java", + "src/main/java/com/google/protobuf/InvalidProtocolBufferException.java", + "src/main/java/com/google/protobuf/IterableByteBufferInputStream.java", + "src/main/java/com/google/protobuf/JavaType.java", + "src/main/java/com/google/protobuf/LazyField.java", + "src/main/java/com/google/protobuf/LazyFieldLite.java", + "src/main/java/com/google/protobuf/LazyStringArrayList.java", + "src/main/java/com/google/protobuf/LazyStringList.java", + "src/main/java/com/google/protobuf/ListFieldSchema.java", + "src/main/java/com/google/protobuf/LongArrayList.java", + "src/main/java/com/google/protobuf/ManifestSchemaFactory.java", + "src/main/java/com/google/protobuf/MapEntryLite.java", + "src/main/java/com/google/protobuf/MapFieldLite.java", + "src/main/java/com/google/protobuf/MapFieldSchema.java", + "src/main/java/com/google/protobuf/MapFieldSchemaLite.java", + "src/main/java/com/google/protobuf/MapFieldSchemas.java", + "src/main/java/com/google/protobuf/MessageInfo.java", + "src/main/java/com/google/protobuf/MessageInfoFactory.java", + "src/main/java/com/google/protobuf/MessageLite.java", + "src/main/java/com/google/protobuf/MessageLiteOrBuilder.java", + "src/main/java/com/google/protobuf/MessageLiteToString.java", + "src/main/java/com/google/protobuf/MessageSchema.java", + "src/main/java/com/google/protobuf/MessageSetSchema.java", + "src/main/java/com/google/protobuf/MutabilityOracle.java", + "src/main/java/com/google/protobuf/NewInstanceSchema.java", + "src/main/java/com/google/protobuf/NewInstanceSchemaLite.java", + "src/main/java/com/google/protobuf/NewInstanceSchemas.java", + "src/main/java/com/google/protobuf/NioByteString.java", + "src/main/java/com/google/protobuf/OneofInfo.java", + "src/main/java/com/google/protobuf/Parser.java", + "src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java", + "src/main/java/com/google/protobuf/ProtoSyntax.java", + "src/main/java/com/google/protobuf/Protobuf.java", + "src/main/java/com/google/protobuf/ProtobufArrayList.java", + "src/main/java/com/google/protobuf/ProtobufLists.java", + "src/main/java/com/google/protobuf/ProtocolStringList.java", + "src/main/java/com/google/protobuf/RawMessageInfo.java", + "src/main/java/com/google/protobuf/Reader.java", + "src/main/java/com/google/protobuf/RopeByteString.java", + "src/main/java/com/google/protobuf/Schema.java", + "src/main/java/com/google/protobuf/SchemaFactory.java", + "src/main/java/com/google/protobuf/SchemaUtil.java", + "src/main/java/com/google/protobuf/SmallSortedMap.java", + "src/main/java/com/google/protobuf/StructuralMessageInfo.java", + "src/main/java/com/google/protobuf/TextFormatEscaper.java", + "src/main/java/com/google/protobuf/UninitializedMessageException.java", + "src/main/java/com/google/protobuf/UnknownFieldSchema.java", + "src/main/java/com/google/protobuf/UnknownFieldSetLite.java", + "src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java", + "src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java", + "src/main/java/com/google/protobuf/UnsafeUtil.java", + "src/main/java/com/google/protobuf/Utf8.java", + "src/main/java/com/google/protobuf/WireFormat.java", + "src/main/java/com/google/protobuf/Writer.java", +] + +# Should be used as `//java/lite`. +java_library( + name = "lite", + srcs = LITE_SRCS, + visibility = [ + "//java/lite:__pkg__", + ], +) + +java_library( + name = "core", + srcs = glob( + [ + "src/main/java/com/google/protobuf/*.java", + ], + exclude = LITE_SRCS, + ) + [ + "//:gen_well_known_protos_java", + ], + visibility = ["//visibility:public"], + exports = [ + "//java/lite", + ], + deps = [ + "//java/lite", + ], +) + +proto_lang_toolchain( + name = "toolchain", + command_line = "--java_out=$(OUT)", + runtime = ":core", + visibility = ["//visibility:public"], +) diff --git a/java/core/generate-test-sources-build.xml b/java/core/generate-test-sources-build.xml index 92c0b1c8ae29..71a88d07b33b 100644 --- a/java/core/generate-test-sources-build.xml +++ b/java/core/generate-test-sources-build.xml @@ -17,6 +17,7 @@ + diff --git a/java/core/pom.xml b/java/core/pom.xml index a57f2aa43ccd..6c0732a358bd 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.11.2 + 3.14.0 protobuf-java diff --git a/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java b/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java index 3220f6407243..e792d7d98119 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java @@ -142,7 +142,12 @@ public E remove(int index) { @Override public boolean remove(Object o) { ensureIsMutable(); - return super.remove(o); + int index = indexOf(o); + if (index == -1) { + return false; + } + remove(index); + return true; } @Override diff --git a/java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java b/java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java old mode 100755 new mode 100644 index 1e33c5a7a347..1217e112e0ce --- a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java +++ b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java @@ -39,7 +39,7 @@ * Helper functions to decode protobuf wire format from a byte array. * *

Note that these functions don't do boundary check on the byte array but instead rely on Java - * VM to check it. That means parsing rountines utilizing these functions must catch + * VM to check it. That means parsing routines utilizing these functions must catch * IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when * crossing protobuf public API boundaries. */ @@ -51,7 +51,7 @@ final class ArrayDecoders { * multiple values and let the function set the return value in this Registers instance instead. * *

TODO(xiaofeng): This could be merged into CodedInputStream or CodedInputStreamReader which - * is already being passed through all the parsing rountines. + * is already being passed through all the parsing routines. */ static final class Registers { public int int1; diff --git a/java/core/src/main/java/com/google/protobuf/BinaryReader.java b/java/core/src/main/java/com/google/protobuf/BinaryReader.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/BinaryWriter.java b/java/core/src/main/java/com/google/protobuf/BinaryWriter.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java index 65dcd53aa4d2..451fce1e8499 100644 --- a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java @@ -140,6 +140,26 @@ public boolean getBoolean(int index) { return array[index]; } + @Override + public int indexOf(Object element) { + if (!(element instanceof Boolean)) { + return -1; + } + boolean unboxedElement = (Boolean) element; + int numElems = size(); + for (int i = 0; i < numElems; i++) { + if (array[i] == unboxedElement) { + return i; + } + } + return -1; + } + + @Override + public boolean contains(Object element) { + return indexOf(element) != -1; + } + @Override public int size() { return size; @@ -247,20 +267,6 @@ public boolean addAll(Collection collection) { return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Boolean remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/BufferAllocator.java b/java/core/src/main/java/com/google/protobuf/BufferAllocator.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index f2c7cc47236a..ff81e0032f81 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -41,6 +41,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; @@ -484,7 +485,7 @@ final boolean shouldDiscardUnknownFields() { * Returns true if the stream has reached the end of the input. This is the case if either the end * of the underlying input source has been reached or if the stream has reached a limit created * using {@link #pushLimit(int)}. This function may get blocked when using StreamDecoder as it - * invokes {@link #StreamDecoder.tryRefillBuffer(int)} in this function which will try to read + * invokes {@link StreamDecoder#tryRefillBuffer(int)} in this function which will try to read * bytes from input. */ public abstract boolean isAtEnd() throws IOException; @@ -2009,14 +2010,14 @@ private ByteBuffer slice(long begin, long end) throws IOException { int prevPos = buffer.position(); int prevLimit = buffer.limit(); try { - buffer.position(bufferPos(begin)); - buffer.limit(bufferPos(end)); + ((Buffer) buffer).position(bufferPos(begin)); + ((Buffer) buffer).limit(bufferPos(end)); return buffer.slice(); } catch (IllegalArgumentException e) { throw InvalidProtocolBufferException.truncatedMessage(); } finally { - buffer.position(prevPos); - buffer.limit(prevLimit); + ((Buffer) buffer).position(prevPos); + ((Buffer) buffer).limit(prevLimit); } } } @@ -3910,14 +3911,14 @@ private ByteBuffer slice(int begin, int end) throws IOException { int prevPos = currentByteBuffer.position(); int prevLimit = currentByteBuffer.limit(); try { - currentByteBuffer.position(begin); - currentByteBuffer.limit(end); + ((Buffer) currentByteBuffer).position(begin); + ((Buffer) currentByteBuffer).limit(end); return currentByteBuffer.slice(); } catch (IllegalArgumentException e) { throw InvalidProtocolBufferException.truncatedMessage(); } finally { - currentByteBuffer.position(prevPos); - currentByteBuffer.limit(prevLimit); + ((Buffer) currentByteBuffer).position(prevPos); + ((Buffer) currentByteBuffer).limit(prevLimit); } } } diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java b/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java b/java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index a20829e56df6..c30b00ddf730 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -702,6 +702,11 @@ public List getOneofs() { return Collections.unmodifiableList(Arrays.asList(oneofs)); } + /** Get a list of this message type's real oneofs. */ + public List getRealOneofs() { + return Collections.unmodifiableList(Arrays.asList(oneofs).subList(0, realOneofCount)); + } + /** Get a list of this message type's extensions. */ public List getExtensions() { return Collections.unmodifiableList(Arrays.asList(extensions)); @@ -759,7 +764,10 @@ public boolean isExtendable() { /** * Finds a field by name. * - * @param name The unqualified name of the field (e.g. "foo"). + * @param name The unqualified name of the field (e.g. "foo"). For protocol buffer messages that + * follow Google's + * guidance on naming this will be a snake case string, such as

song_name
. * @return The field's descriptor, or {@code null} if not found. */ public FieldDescriptor findFieldByName(final String name) { @@ -821,6 +829,7 @@ public EnumDescriptor findEnumTypeByName(final String name) { private final FieldDescriptor[] fields; private final FieldDescriptor[] extensions; private final OneofDescriptor[] oneofs; + private final int realOneofCount; // Used to create a placeholder when the type cannot be found. Descriptor(final String fullname) throws DescriptorValidationException { @@ -846,6 +855,7 @@ public EnumDescriptor findEnumTypeByName(final String name) { this.fields = new FieldDescriptor[0]; this.extensions = new FieldDescriptor[0]; this.oneofs = new OneofDescriptor[0]; + this.realOneofCount = 0; // Create a placeholder FileDescriptor to hold this message. this.file = new FileDescriptor(packageName, this); @@ -899,6 +909,18 @@ private Descriptor( } } + int syntheticOneofCount = 0; + for (OneofDescriptor oneof : this.oneofs) { + if (oneof.isSynthetic()) { + syntheticOneofCount++; + } else { + if (syntheticOneofCount > 0) { + throw new DescriptorValidationException(this, "Synthetic oneofs must come last."); + } + } + } + this.realOneofCount = this.oneofs.length - syntheticOneofCount; + file.pool.addSymbol(this); } @@ -1065,7 +1087,7 @@ public boolean isRepeated() { /** * Does this field have the {@code [packed = true]} option or is this field packable in proto3 - * and not explicitly setted to unpacked? + * and not explicitly set to unpacked? */ @Override public boolean isPacked() { @@ -1125,6 +1147,40 @@ public OneofDescriptor getContainingOneof() { return containingOneof; } + /** Get the field's containing oneof, only if non-synthetic. */ + public OneofDescriptor getRealContainingOneof() { + return containingOneof != null && !containingOneof.isSynthetic() ? containingOneof : null; + } + + /** + * Returns true if this field was syntactically written with "optional" in the .proto file. + * Excludes singular proto3 fields that do not have a label. + */ + public boolean hasOptionalKeyword() { + return isProto3Optional + || (file.getSyntax() == Syntax.PROTO2 && isOptional() && getContainingOneof() == null); + } + + /** + * Returns true if this field tracks presence, ie. does the field distinguish between "unset" + * and "present with default value." + * + *

This includes required, optional, and oneof fields. It excludes maps, repeated fields, and + * singular proto3 fields without "optional". + * + *

For fields where hasPresence() == true, the return value of msg.hasField() is semantically + * meaningful. + */ + boolean hasPresence() { + if (isRepeated()) { + return false; + } + return getType() == Type.MESSAGE + || getType() == Type.GROUP + || getContainingOneof() != null + || file.getSyntax() == Syntax.PROTO2; + } + /** * For extensions defined nested within message types, gets the outer type. Not valid for * non-extension fields. For example, consider this {@code .proto} file: @@ -1203,6 +1259,7 @@ public String toString() { private final String jsonName; private final FileDescriptor file; private final Descriptor extensionScope; + private final boolean isProto3Optional; // Possibly initialized during cross-linking. private Type type; @@ -1327,6 +1384,8 @@ private FieldDescriptor( type = Type.valueOf(proto.getType()); } + isProto3Optional = proto.getProto3Optional(); + if (getNumber() <= 0) { throw new DescriptorValidationException(this, "Field numbers must be positive integers."); } @@ -2627,6 +2686,10 @@ public OneofOptions getOptions() { return proto.getOptions(); } + public boolean isSynthetic() { + return fields.length == 1 && fields[0].isProto3Optional; + } + /** Get a list of this message type's fields. */ public List getFields() { return Collections.unmodifiableList(Arrays.asList(fields)); diff --git a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java index ac14949e6f50..408565343720 100644 --- a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java @@ -140,6 +140,26 @@ public double getDouble(int index) { return array[index]; } + @Override + public int indexOf(Object element) { + if (!(element instanceof Double)) { + return -1; + } + double unboxedElement = (Double) element; + int numElems = size(); + for (int i = 0; i < numElems; i++) { + if (array[i] == unboxedElement) { + return i; + } + } + return -1; + } + + @Override + public boolean contains(Object element) { + return indexOf(element) != -1; + } + @Override public int size() { return size; @@ -247,20 +267,6 @@ public boolean addAll(Collection collection) { return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Double remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java index 63dda6b9f28a..8beebba24d65 100644 --- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java +++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java @@ -328,20 +328,6 @@ private Builder(Descriptor type) { this.fields = FieldSet.newFieldSet(); this.unknownFields = UnknownFieldSet.getDefaultInstance(); this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()]; - // A MapEntry has all of its fields present at all times. - if (type.getOptions().getMapEntry()) { - populateMapEntry(); - } - } - - private void populateMapEntry() { - for (FieldDescriptor field : type.getFields()) { - if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { - fields.setField(field, getDefaultInstance(field.getMessageType())); - } else { - fields.setField(field, field.getDefaultValue()); - } - } } // --------------------------------------------------------------- @@ -354,10 +340,6 @@ public Builder clear() { } else { fields.clear(); } - // A MapEntry has all of its fields present at all times. - if (type.getOptions().getMapEntry()) { - populateMapEntry(); - } unknownFields = UnknownFieldSet.getDefaultInstance(); return this; } @@ -423,6 +405,19 @@ private DynamicMessage buildParsed() throws InvalidProtocolBufferException { @Override public DynamicMessage buildPartial() { + // Set default values for all fields in a MapEntry. + if (type.getOptions().getMapEntry()) { + for (FieldDescriptor field : type.getFields()) { + if (field.isOptional() && !fields.hasField(field)) { + if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + fields.setField(field, getDefaultInstance(field.getMessageType())); + } else { + fields.setField(field, field.getDefaultValue()); + } + } + } + } + fields.makeImmutable(); DynamicMessage result = new DynamicMessage( diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java index 241fcbd93248..0a63fad187e8 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java @@ -46,7 +46,6 @@ final class ExtensionRegistryFactory { @Nullable */ static final Class EXTENSION_REGISTRY_CLASS = reflectExtensionRegistry(); - /* @Nullable */ static Class reflectExtensionRegistry() { try { return Class.forName(FULL_REGISTRY_CLASS_NAME); @@ -77,7 +76,6 @@ static boolean isFullRegistry(ExtensionRegistryLite registry) { && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass()); } - /* @Nullable */ private static final ExtensionRegistryLite invokeSubclassFactory(String methodName) { if (EXTENSION_REGISTRY_CLASS == null) { return null; diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java index 0c4b20ed746b..caa58e1ada67 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java @@ -84,10 +84,8 @@ public class ExtensionRegistryLite { static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension"; private static class ExtensionClassHolder { - /* @Nullable */ static final Class INSTANCE = resolveExtensionClass(); - /* @Nullable */ static Class resolveExtensionClass() { try { return Class.forName(EXTENSION_CLASS_NAME); diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/FieldInfo.java b/java/core/src/main/java/com/google/protobuf/FieldInfo.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java index d52aede95803..1d8592f7527c 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java @@ -119,7 +119,6 @@ boolean isEmpty() { } /** Make this FieldSet immutable from this point forward. */ - @SuppressWarnings("unchecked") public void makeImmutable() { if (isImmutable) { return; @@ -286,11 +285,11 @@ public void setField(final T descriptor, Object value) { final List newList = new ArrayList(); newList.addAll((List) value); for (final Object element : newList) { - verifyType(descriptor.getLiteType(), element); + verifyType(descriptor, element); } value = newList; } else { - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); } if (value instanceof LazyField) { @@ -354,7 +353,7 @@ public void setRepeatedField(final T descriptor, final int index, final Object v throw new IndexOutOfBoundsException(); } - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); ((List) list).set(index, value); } @@ -369,7 +368,7 @@ public void addRepeatedField(final T descriptor, final Object value) { "addRepeatedField() can only be called on repeated fields."); } - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); final Object existingValue = getField(descriptor); List list; @@ -390,8 +389,8 @@ public void addRepeatedField(final T descriptor, final Object value) { * * @throws IllegalArgumentException The value is not of the right type. */ - private void verifyType(final WireFormat.FieldType type, final Object value) { - if (!isValidType(type, value)) { + private void verifyType(final T descriptor, final Object value) { + if (!isValidType(descriptor.getLiteType(), value)) { // TODO(kenton): When chaining calls to setField(), it can be hard to // tell from the stack trace which exact call failed, since the whole // chain is considered one line of code. It would be nice to print @@ -400,10 +399,16 @@ private void verifyType(final WireFormat.FieldType type, final Object value) { // isn't a big deal, though, since it would only really apply when using // reflection and generally people don't chain reflection setters. throw new IllegalArgumentException( - "Wrong object type used with protocol message reflection."); + String.format( + "Wrong object type used with protocol message reflection.\n" + + "Field number: %d, field java type: %s, value type: %s\n", + descriptor.getNumber(), + descriptor.getLiteType().getJavaType(), + value.getClass().getName())); } } + private static boolean isValidType(final WireFormat.FieldType type, final Object value) { checkNotNull(value); switch (type.getJavaType()) { @@ -1081,12 +1086,12 @@ public void setField(final T descriptor, Object value) { final List newList = new ArrayList(); newList.addAll((List) value); for (final Object element : newList) { - verifyType(descriptor.getLiteType(), element); + verifyType(descriptor, element); hasNestedBuilders = hasNestedBuilders || element instanceof MessageLite.Builder; } value = newList; } else { - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); } if (value instanceof LazyField) { @@ -1172,7 +1177,7 @@ public void setRepeatedField(final T descriptor, final int index, final Object v throw new IndexOutOfBoundsException(); } - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); ((List) list).set(index, value); } @@ -1190,7 +1195,7 @@ public void addRepeatedField(final T descriptor, final Object value) { hasNestedBuilders = hasNestedBuilders || value instanceof MessageLite.Builder; - verifyType(descriptor.getLiteType(), value); + verifyType(descriptor, value); final Object existingValue = getField(descriptor); List list; @@ -1211,15 +1216,20 @@ public void addRepeatedField(final T descriptor, final Object value) { * * @throws IllegalArgumentException The value is not of the right type. */ - private static void verifyType(final WireFormat.FieldType type, final Object value) { - if (!FieldSet.isValidType(type, value)) { + private void verifyType(final T descriptor, final Object value) { + if (!FieldSet.isValidType(descriptor.getLiteType(), value)) { // Builder can accept Message.Builder values even though FieldSet will reject. - if (type.getJavaType() == WireFormat.JavaType.MESSAGE + if (descriptor.getLiteType().getJavaType() == WireFormat.JavaType.MESSAGE && value instanceof MessageLite.Builder) { return; } throw new IllegalArgumentException( - "Wrong object type used with protocol message reflection."); + String.format( + "Wrong object type used with protocol message reflection.\n" + + "Field number: %d, field java type: %s, value type: %s\n", + descriptor.getNumber(), + descriptor.getLiteType().getJavaType(), + value.getClass().getName())); } } diff --git a/java/core/src/main/java/com/google/protobuf/FieldType.java b/java/core/src/main/java/com/google/protobuf/FieldType.java old mode 100755 new mode 100644 index 1b8f9e5da255..72327537fd20 --- a/java/core/src/main/java/com/google/protobuf/FieldType.java +++ b/java/core/src/main/java/com/google/protobuf/FieldType.java @@ -204,7 +204,6 @@ private boolean isValidForList(Field field) { * * @return the {@link FieldType} or {@code null} if not found. */ - /* @Nullable */ public static FieldType forId(int id) { if (id < 0 || id >= VALUES.length) { return null; @@ -228,7 +227,6 @@ public static FieldType forId(int id) { * * @return the generic super class/interface, or {@code null} if not found. */ - /* @Nullable */ private static Type getGenericSuperList(Class clazz) { // First look at interfaces. Type[] genericInterfaces = clazz.getGenericInterfaces(); diff --git a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java index 9d2ab71d7c38..e6feba8a354c 100644 --- a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java @@ -139,6 +139,26 @@ public float getFloat(int index) { return array[index]; } + @Override + public int indexOf(Object element) { + if (!(element instanceof Float)) { + return -1; + } + float unboxedElement = (Float) element; + int numElems = size(); + for (int i = 0; i < numElems; i++) { + if (array[i] == unboxedElement) { + return i; + } + } + return -1; + } + + @Override + public boolean contains(Object element) { + return indexOf(element) != -1; + } + @Override public int size() { return size; @@ -246,20 +266,6 @@ public boolean addAll(Collection collection) { return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Float remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java index 1ee785de8e6b..27f52100979f 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -121,7 +121,11 @@ public boolean equals( return true; } - if (!getDefaultInstanceForType().getClass().isInstance(other)) { + if (other == null) { + return false; + } + + if (this.getClass() != other.getClass()) { return false; } @@ -219,7 +223,7 @@ public static enum MethodToInvoke { /** * A method that implements different types of operations described in {@link MethodToInvoke}. - * Theses different kinds of operations are required to implement message-level operations for + * These different kinds of operations are required to implement message-level operations for * builders in the runtime. This method bundles those operations to reduce the generated methods * count. * @@ -230,7 +234,7 @@ public static enum MethodToInvoke { * It doesn't use or modify any memoized value. *
  • {@code GET_MEMOIZED_IS_INITIALIZED} returns the memoized {@code isInitialized} byte * value. - *
  • {@code SET_MEMOIZED_IS_INITIALIZED} sets the memoized {@code isInitilaized} byte value to + *
  • {@code SET_MEMOIZED_IS_INITIALIZED} sets the memoized {@code isInitialized} byte value to * 1 if the first parameter is not null, or to 0 if the first parameter is null. *
  • {@code NEW_BUILDER} returns a {@code BuilderType} instance. * @@ -457,7 +461,7 @@ public BuilderType mergeFrom( throws IOException { copyOnWrite(); try { - // TODO(yilunchong): Try to make input with type CodedInpuStream.ArrayDecoder use + // TODO(yilunchong): Try to make input with type CodedInputStream.ArrayDecoder use // fast path. Protobuf.getInstance().schemaFor(instance).mergeFrom( instance, CodedInputStreamReader.forCodedInput(input), extensionRegistry); diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java index 4a0e28e127cf..86f88a0228f2 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -1987,9 +1987,9 @@ public FieldAccessorTable ensureFieldAccessorsInitialized( int oneofsSize = oneofs.length; for (int i = 0; i < oneofsSize; i++) { - oneofs[i] = new OneofAccessor( - descriptor, camelCaseNames[i + fieldsSize], - messageClass, builderClass); + oneofs[i] = + new OneofAccessor( + descriptor, i, camelCaseNames[i + fieldsSize], messageClass, builderClass); } initialized = true; camelCaseNames = null; @@ -2057,14 +2057,22 @@ Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, /** OneofAccessor provides access to a single oneof. */ private static class OneofAccessor { OneofAccessor( - final Descriptor descriptor, final String camelCaseName, + final Descriptor descriptor, + final int oneofIndex, + final String camelCaseName, final Class messageClass, final Class builderClass) { this.descriptor = descriptor; - caseMethod = - getMethodOrDie(messageClass, "get" + camelCaseName + "Case"); - caseMethodBuilder = - getMethodOrDie(builderClass, "get" + camelCaseName + "Case"); + OneofDescriptor oneofDescriptor = descriptor.getOneofs().get(oneofIndex); + if (oneofDescriptor.isSynthetic()) { + caseMethod = null; + caseMethodBuilder = null; + fieldDescriptor = oneofDescriptor.getFields().get(0); + } else { + caseMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "Case"); + caseMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "Case"); + fieldDescriptor = null; + } clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); } @@ -2072,33 +2080,51 @@ private static class OneofAccessor { private final Method caseMethod; private final Method caseMethodBuilder; private final Method clearMethod; + private final FieldDescriptor fieldDescriptor; public boolean has(final GeneratedMessageV3 message) { - if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) { - return false; + if (fieldDescriptor != null) { + return message.hasField(fieldDescriptor); + } else { + if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) { + return false; + } } return true; } public boolean has(GeneratedMessageV3.Builder builder) { - if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) { - return false; + if (fieldDescriptor != null) { + return builder.hasField(fieldDescriptor); + } else { + if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) { + return false; + } } return true; } public FieldDescriptor get(final GeneratedMessageV3 message) { - int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); - if (fieldNumber > 0) { - return descriptor.findFieldByNumber(fieldNumber); + if (fieldDescriptor != null) { + return message.hasField(fieldDescriptor) ? fieldDescriptor : null; + } else { + int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); + if (fieldNumber > 0) { + return descriptor.findFieldByNumber(fieldNumber); + } } return null; } public FieldDescriptor get(GeneratedMessageV3.Builder builder) { - int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); - if (fieldNumber > 0) { - return descriptor.findFieldByNumber(fieldNumber); + if (fieldDescriptor != null) { + return builder.hasField(fieldDescriptor) ? fieldDescriptor : null; + } else { + int fieldNumber = + ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); + if (fieldNumber > 0) { + return descriptor.findFieldByNumber(fieldNumber); + } } return null; } @@ -2108,10 +2134,6 @@ public void clear(final Builder builder) { } } - private static boolean supportFieldPresence(FileDescriptor file) { - return file.getSyntax() == FileDescriptor.Syntax.PROTO2; - } - // --------------------------------------------------------------- private static class SingularFieldAccessor implements FieldAccessor { @@ -2216,9 +2238,13 @@ public void clear(final GeneratedMessageV3.Builder builder) { final Class messageClass, final Class builderClass, final String containingOneofCamelCaseName) { - isOneofField = descriptor.getContainingOneof() != null; - hasHasMethod = supportFieldPresence(descriptor.getFile()) - || (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE); + isOneofField = + descriptor.getContainingOneof() != null + && !descriptor.getContainingOneof().isSynthetic(); + hasHasMethod = + descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO2 + || descriptor.hasOptionalKeyword() + || (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE); ReflectionInvoker reflectionInvoker = new ReflectionInvoker( descriptor, diff --git a/java/core/src/main/java/com/google/protobuf/IntArrayList.java b/java/core/src/main/java/com/google/protobuf/IntArrayList.java index 98f1f81331c4..9daeebed9923 100644 --- a/java/core/src/main/java/com/google/protobuf/IntArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/IntArrayList.java @@ -139,6 +139,26 @@ public int getInt(int index) { return array[index]; } + @Override + public int indexOf(Object element) { + if (!(element instanceof Integer)) { + return -1; + } + int unboxedElement = (Integer) element; + int numElems = size(); + for (int i = 0; i < numElems; i++) { + if (array[i] == unboxedElement) { + return i; + } + } + return -1; + } + + @Override + public boolean contains(Object element) { + return indexOf(element) != -1; + } + @Override public int size() { return size; @@ -246,20 +266,6 @@ public boolean addAll(Collection collection) { return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Integer remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java index 0826351bcbca..90643b8abb99 100644 --- a/java/core/src/main/java/com/google/protobuf/Internal.java +++ b/java/core/src/main/java/com/google/protobuf/Internal.java @@ -30,7 +30,6 @@ package com.google.protobuf; -import java.io.IOException; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.charset.Charset; diff --git a/java/core/src/main/java/com/google/protobuf/JavaType.java b/java/core/src/main/java/com/google/protobuf/JavaType.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/LongArrayList.java b/java/core/src/main/java/com/google/protobuf/LongArrayList.java index 2dd15b4deb28..bda43a41bb4a 100644 --- a/java/core/src/main/java/com/google/protobuf/LongArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/LongArrayList.java @@ -139,6 +139,26 @@ public long getLong(int index) { return array[index]; } + @Override + public int indexOf(Object element) { + if (!(element instanceof Long)) { + return -1; + } + long unboxedElement = (Long) element; + int numElems = size(); + for (int i = 0; i < numElems; i++) { + if (array[i] == unboxedElement) { + return i; + } + } + return -1; + } + + @Override + public boolean contains(Object element) { + return indexOf(element) != -1; + } + @Override public int size() { return size; @@ -246,20 +266,6 @@ public boolean addAll(Collection collection) { return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Long remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java b/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java index ca2a3c2a97b1..81bf4c2b1840 100644 --- a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java @@ -192,7 +192,7 @@ static Map.Entry parseEntry( } /** - * Parses an entry off of the input into the map. This helper avoids allocaton of a {@link + * Parses an entry off of the input into the map. This helper avoids allocation of a {@link * MapEntryLite} by parsing directly into the provided {@link MapFieldLite}. */ public void parseInto( diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaFull.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaFull.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/MessageInfo.java b/java/core/src/main/java/com/google/protobuf/MessageInfo.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java b/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/MessageSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSchema.java old mode 100755 new mode 100644 index 8f9ce7328ee0..33c8e914b24e --- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java @@ -89,6 +89,7 @@ final class MessageSchema implements Schema { private static final int FIELD_TYPE_MASK = 0x0FF00000; private static final int REQUIRED_MASK = 0x10000000; private static final int ENFORCE_UTF8_MASK = 0x20000000; + private static final int NO_PRESENCE_SENTINEL = -1 & OFFSET_MASK; private static final int[] EMPTY_INT_ARRAY = new int[0]; /** An offset applied to the field type ID for scalar fields that are a member of a oneof. */ @@ -118,6 +119,11 @@ final class MessageSchema implements Schema { * [70 - 75] field presence mask shift (unused for oneof/repeated fields) * [76 - 95] presence field offset / oneof case field offset / cached size field offset * + * + * Note that presence field offset can only use 20 bits - 1. All bits set to 1 is the sentinel + * value for non-presence. This is not validated at runtime, we simply assume message layouts + * will not exceed 1MB (assuming ~10 bytes per field, that implies 100k fields which should hit + * other javac limits first). */ private final int[] buffer; @@ -260,7 +266,7 @@ static MessageSchema newSchemaForRawMessageInfo( } next = result | (next << shift); } - final int flags = next; + final int unusedFlags = next; next = info.charAt(i++); if (next >= 0xD800) { @@ -464,8 +470,7 @@ static MessageSchema newSchemaForRawMessageInfo( || oneofFieldType == 17 /* FieldType.GROUP */) { objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; } else if (oneofFieldType == 12 /* FieldType.ENUM */) { - // proto2 - if ((flags & 0x1) == 0x1) { + if (!isProto3) { objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; } } @@ -508,7 +513,7 @@ static MessageSchema newSchemaForRawMessageInfo( } else if (fieldType == 12 /* FieldType.ENUM */ || fieldType == 30 /* FieldType.ENUM_LIST */ || fieldType == 44 /* FieldType.ENUM_LIST_PACKED */) { - if ((flags & 0x1) == 0x1) { + if (!isProto3) { objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; } } else if (fieldType == 50 /* FieldType.MAP */) { @@ -520,7 +525,8 @@ static MessageSchema newSchemaForRawMessageInfo( } fieldOffset = (int) unsafe.objectFieldOffset(field); - if ((flags & 0x1) == 0x1 && fieldType <= 17 /* FieldType.GROUP */) { + boolean hasHasBit = (fieldTypeWithExtraBits & 0x1000) == 0x1000; + if (hasHasBit && fieldType <= 17 /* FieldType.GROUP */) { next = info.charAt(i++); if (next >= 0xD800) { int result = next & 0x1FFF; @@ -546,7 +552,7 @@ static MessageSchema newSchemaForRawMessageInfo( presenceFieldOffset = (int) unsafe.objectFieldOffset(hasBitsField); presenceMaskShift = hasBitsIndex % 32; } else { - presenceFieldOffset = 0; + presenceFieldOffset = NO_PRESENCE_SENTINEL; presenceMaskShift = 0; } @@ -662,7 +668,7 @@ static MessageSchema newSchemaForMessageInfo( // We found the entry for the next field. Store the entry in the manifest for // this field and increment the field index. - storeFieldData(fi, buffer, bufferIndex, isProto3, objects); + storeFieldData(fi, buffer, bufferIndex, objects); // Convert field number to index if (checkInitializedIndex < checkInitialized.length @@ -719,7 +725,7 @@ static MessageSchema newSchemaForMessageInfo( } private static void storeFieldData( - FieldInfo fi, int[] buffer, int bufferIndex, boolean proto3, Object[] objects) { + FieldInfo fi, int[] buffer, int bufferIndex, Object[] objects) { final int fieldOffset; final int typeId; final int presenceMaskShift; @@ -735,8 +741,13 @@ private static void storeFieldData( FieldType type = fi.getType(); fieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getField()); typeId = type.id(); - if (!proto3 && !type.isList() && !type.isMap()) { - presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getPresenceField()); + if (!type.isList() && !type.isMap()) { + Field presenceField = fi.getPresenceField(); + if (presenceField == null) { + presenceFieldOffset = NO_PRESENCE_SENTINEL; + } else { + presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(presenceField); + } presenceMaskShift = Integer.numberOfTrailingZeros(fi.getPresenceMask()); } else { if (fi.getCachedSizeField() == null) { @@ -1391,8 +1402,10 @@ private void mergeOneofMessage(T message, T other, int pos) { if (!isOneofPresent(other, number, pos)) { return; } - - Object mine = UnsafeUtil.getObject(message, offset); + Object mine = null; + if (isOneofPresent(message, number, pos)) { + mine = UnsafeUtil.getObject(message, offset); + } Object theirs = UnsafeUtil.getObject(other, offset); if (mine != null && theirs != null) { Object merged = Internal.mergeMessage(mine, theirs); @@ -1408,13 +1421,13 @@ private void mergeOneofMessage(T message, T other, int pos) { public int getSerializedSize(T message) { return proto3 ? getSerializedSizeProto3(message) : getSerializedSizeProto2(message); } - + @SuppressWarnings("unchecked") private int getSerializedSizeProto2(T message) { int size = 0; final sun.misc.Unsafe unsafe = UNSAFE; - int currentPresenceFieldOffset = -1; + int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; int currentPresenceField = 0; for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) { final int typeAndOffset = typeAndOffsetAt(i); @@ -2548,7 +2561,7 @@ private void writeFieldsInAscendingOrderProto2(T message, Writer writer) throws nextExtension = extensionIterator.next(); } } - int currentPresenceFieldOffset = -1; + int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; int currentPresenceField = 0; final int bufferLength = buffer.length; final sun.misc.Unsafe unsafe = UNSAFE; @@ -2559,7 +2572,7 @@ private void writeFieldsInAscendingOrderProto2(T message, Writer writer) throws int presenceMaskAndOffset = 0; int presenceMask = 0; - if (!proto3 && fieldType <= 17) { + if (fieldType <= 17) { presenceMaskAndOffset = buffer[pos + 2]; final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; if (presenceFieldOffset != currentPresenceFieldOffset) { @@ -2924,7 +2937,6 @@ private void writeFieldsInAscendingOrderProto3(T message, Writer writer) throws nextExtension = extensionIterator.next(); } } - final int bufferLength = buffer.length; for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) { final int typeAndOffset = typeAndOffsetAt(pos); @@ -4867,7 +4879,7 @@ int parseProto2Message( T message, byte[] data, int position, int limit, int endGroup, Registers registers) throws IOException { final sun.misc.Unsafe unsafe = UNSAFE; - int currentPresenceFieldOffset = -1; + int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; int currentPresenceField = 0; int tag = 0; int oldNumber = -1; @@ -4901,7 +4913,7 @@ int parseProto2Message( // We cache the 32-bit has-bits integer value and only write it back when parsing a field // using a different has-bits integer. if (presenceFieldOffset != currentPresenceFieldOffset) { - if (currentPresenceFieldOffset != -1) { + if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField); } currentPresenceFieldOffset = presenceFieldOffset; @@ -5143,7 +5155,7 @@ int parseProto2Message( tag, data, position, limit, getMutableUnknownFields(message), registers); } } - if (currentPresenceFieldOffset != -1) { + if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField); } UnknownFieldSetLite unknownFields = null; @@ -5175,6 +5187,8 @@ int parseProto2Message( private int parseProto3Message( T message, byte[] data, int position, int limit, Registers registers) throws IOException { final sun.misc.Unsafe unsafe = UNSAFE; + int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; + int currentPresenceField = 0; int tag = 0; int oldNumber = -1; int pos = 0; @@ -5200,11 +5214,30 @@ private int parseProto3Message( final int fieldType = type(typeAndOffset); final long fieldOffset = offset(typeAndOffset); if (fieldType <= 17) { + // Proto3 optional fields have has-bits. + final int presenceMaskAndOffset = buffer[pos + 2]; + final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); + final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; + // We cache the 32-bit has-bits integer value and only write it back when parsing a field + // using a different has-bits integer. + // + // Note that for fields that do not have hasbits, we unconditionally write and discard + // the data. + if (presenceFieldOffset != currentPresenceFieldOffset) { + if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { + unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField); + } + if (presenceFieldOffset != NO_PRESENCE_SENTINEL) { + currentPresenceField = unsafe.getInt(message, (long) presenceFieldOffset); + } + currentPresenceFieldOffset = presenceFieldOffset; + } switch (fieldType) { case 0: // DOUBLE: if (wireType == WireFormat.WIRETYPE_FIXED64) { UnsafeUtil.putDouble(message, fieldOffset, decodeDouble(data, position)); position += 8; + currentPresenceField |= presenceMask; continue; } break; @@ -5212,6 +5245,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_FIXED32) { UnsafeUtil.putFloat(message, fieldOffset, decodeFloat(data, position)); position += 4; + currentPresenceField |= presenceMask; continue; } break; @@ -5220,6 +5254,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_VARINT) { position = decodeVarint64(data, position, registers); unsafe.putLong(message, fieldOffset, registers.long1); + currentPresenceField |= presenceMask; continue; } break; @@ -5228,6 +5263,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_VARINT) { position = decodeVarint32(data, position, registers); unsafe.putInt(message, fieldOffset, registers.int1); + currentPresenceField |= presenceMask; continue; } break; @@ -5236,6 +5272,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_FIXED64) { unsafe.putLong(message, fieldOffset, decodeFixed64(data, position)); position += 8; + currentPresenceField |= presenceMask; continue; } break; @@ -5244,6 +5281,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_FIXED32) { unsafe.putInt(message, fieldOffset, decodeFixed32(data, position)); position += 4; + currentPresenceField |= presenceMask; continue; } break; @@ -5251,6 +5289,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_VARINT) { position = decodeVarint64(data, position, registers); UnsafeUtil.putBoolean(message, fieldOffset, registers.long1 != 0); + currentPresenceField |= presenceMask; continue; } break; @@ -5262,6 +5301,7 @@ private int parseProto3Message( position = decodeStringRequireUtf8(data, position, registers); } unsafe.putObject(message, fieldOffset, registers.object1); + currentPresenceField |= presenceMask; continue; } break; @@ -5277,6 +5317,7 @@ private int parseProto3Message( unsafe.putObject( message, fieldOffset, Internal.mergeMessage(oldValue, registers.object1)); } + currentPresenceField |= presenceMask; continue; } break; @@ -5284,6 +5325,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { position = decodeBytes(data, position, registers); unsafe.putObject(message, fieldOffset, registers.object1); + currentPresenceField |= presenceMask; continue; } break; @@ -5291,6 +5333,7 @@ private int parseProto3Message( if (wireType == WireFormat.WIRETYPE_VARINT) { position = decodeVarint32(data, position, registers); unsafe.putInt(message, fieldOffset, registers.int1); + currentPresenceField |= presenceMask; continue; } break; @@ -5299,6 +5342,7 @@ private int parseProto3Message( position = decodeVarint32(data, position, registers); unsafe.putInt( message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1)); + currentPresenceField |= presenceMask; continue; } break; @@ -5307,6 +5351,7 @@ private int parseProto3Message( position = decodeVarint64(data, position, registers); unsafe.putLong( message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1)); + currentPresenceField |= presenceMask; continue; } break; @@ -5381,6 +5426,9 @@ private int parseProto3Message( position = decodeUnknownField( tag, data, position, limit, getMutableUnknownFields(message), registers); } + if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { + unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField); + } if (position != limit) { throw InvalidProtocolBufferException.parseFailure(); } @@ -5502,28 +5550,26 @@ private final UB filterUnknownEnumMap( @Override public final boolean isInitialized(T message) { - int currentPresenceFieldOffset = -1; + int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; int currentPresenceField = 0; for (int i = 0; i < checkInitializedCount; i++) { final int pos = intArray[i]; final int number = numberAt(pos); - final int typeAndOffset = typeAndOffsetAt(pos); - int presenceMaskAndOffset = 0; - int presenceMask = 0; - if (!proto3) { - presenceMaskAndOffset = buffer[pos + 2]; - final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; - presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); - if (presenceFieldOffset != currentPresenceFieldOffset) { - currentPresenceFieldOffset = presenceFieldOffset; + int presenceMaskAndOffset = buffer[pos + 2]; + final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; + int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); + if (presenceFieldOffset != currentPresenceFieldOffset) { + currentPresenceFieldOffset = presenceFieldOffset; + if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { currentPresenceField = UNSAFE.getInt(message, (long) presenceFieldOffset); } } if (isRequired(typeAndOffset)) { - if (!isFieldPresent(message, pos, currentPresenceField, presenceMask)) { + if (!isFieldPresent( + message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { return false; } // If a required message field is set but has no required fields of it's own, we still @@ -5534,7 +5580,8 @@ public final boolean isInitialized(T message) { switch (type(typeAndOffset)) { case 9: // MESSAGE case 17: // GROUP - if (isFieldPresent(message, pos, currentPresenceField, presenceMask) + if (isFieldPresent( + message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask) && !isInitialized(message, typeAndOffset, getMessageFieldSchema(pos))) { return false; } @@ -5744,8 +5791,9 @@ private boolean arePresentForEquals(T message, T other, int pos) { return isFieldPresent(message, pos) == isFieldPresent(other, pos); } - private boolean isFieldPresent(T message, int pos, int presenceField, int presenceMask) { - if (proto3) { + private boolean isFieldPresent( + T message, int pos, int presenceFieldOffset, int presenceField, int presenceMask) { + if (presenceFieldOffset == NO_PRESENCE_SENTINEL) { return isFieldPresent(message, pos); } else { return (presenceField & presenceMask) != 0; @@ -5753,7 +5801,9 @@ private boolean isFieldPresent(T message, int pos, int presenceField, int presen } private boolean isFieldPresent(T message, int pos) { - if (proto3) { + final int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); + final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; + if (presenceFieldOffset == NO_PRESENCE_SENTINEL) { final int typeAndOffset = typeAndOffsetAt(pos); final long offset = offset(typeAndOffset); switch (type(typeAndOffset)) { @@ -5804,20 +5854,18 @@ private boolean isFieldPresent(T message, int pos) { throw new IllegalArgumentException(); } } else { - int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); return (UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) & presenceMask) != 0; } } private void setFieldPresent(T message, int pos) { - if (proto3) { - // Proto3 doesn't have presence fields + int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); + final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; + if (presenceFieldOffset == NO_PRESENCE_SENTINEL) { return; } - int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); - final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; UnsafeUtil.putInt( message, presenceFieldOffset, diff --git a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaFull.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaFull.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/NioByteString.java b/java/core/src/main/java/com/google/protobuf/NioByteString.java index 64c46be68997..1e594ff878c5 100644 --- a/java/core/src/main/java/com/google/protobuf/NioByteString.java +++ b/java/core/src/main/java/com/google/protobuf/NioByteString.java @@ -37,6 +37,7 @@ import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.OutputStream; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.InvalidMarkException; @@ -109,7 +110,7 @@ public ByteString substring(int beginIndex, int endIndex) { protected void copyToInternal( byte[] target, int sourceOffset, int targetOffset, int numberToCopy) { ByteBuffer slice = buffer.slice(); - slice.position(sourceOffset); + ((Buffer) slice).position(sourceOffset); slice.get(target, targetOffset, numberToCopy); } @@ -285,8 +286,8 @@ private ByteBuffer slice(int beginIndex, int endIndex) { } ByteBuffer slice = buffer.slice(); - slice.position(beginIndex - buffer.position()); - slice.limit(endIndex - buffer.position()); + ((Buffer) slice).position(beginIndex - buffer.position()); + ((Buffer) slice).limit(endIndex - buffer.position()); return slice; } } diff --git a/java/core/src/main/java/com/google/protobuf/OneofInfo.java b/java/core/src/main/java/com/google/protobuf/OneofInfo.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/ProtoSyntax.java b/java/core/src/main/java/com/google/protobuf/ProtoSyntax.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/Protobuf.java b/java/core/src/main/java/com/google/protobuf/Protobuf.java old mode 100755 new mode 100644 index adaa7fa8f232..0affac5f0a40 --- a/java/core/src/main/java/com/google/protobuf/Protobuf.java +++ b/java/core/src/main/java/com/google/protobuf/Protobuf.java @@ -76,11 +76,8 @@ public void makeImmutable(T message) { schemaFor(message).makeImmutable(message); } - /** - * Checks if all required fields are set. TODO(xiaofeng): Make this package private when the tests - * are moved to protobuf package. - */ - public boolean isInitialized(T message) { + /** Checks if all required fields are set. */ + boolean isInitialized(T message) { return schemaFor(message).isInitialized(message); } diff --git a/java/core/src/main/java/com/google/protobuf/ProtobufLists.java b/java/core/src/main/java/com/google/protobuf/ProtobufLists.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java old mode 100755 new mode 100644 index b9a3d2bb55bc..72f56ed88e5d --- a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java @@ -96,7 +96,7 @@ final class RawMessageInfo implements MessageInfo { * If the field is in an oneof: * *
      - *
    • [2]: oenof index + *
    • [2]: oneof index *
    * * For other types, the field entry only has field number and field type. diff --git a/java/core/src/main/java/com/google/protobuf/Reader.java b/java/core/src/main/java/com/google/protobuf/Reader.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java index f3b09fbacca4..f51436c83d23 100644 --- a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java +++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java @@ -346,9 +346,8 @@ public RepeatedFieldBuilder addAllMessages( // If we can inspect the size, we can more efficiently add messages. int size = -1; if (values instanceof Collection) { - @SuppressWarnings("unchecked") - final Collection collection = (Collection) values; - if (collection.size() == 0) { + final Collection collection = (Collection) values; + if (collection.isEmpty()) { return this; } size = collection.size(); @@ -408,8 +407,7 @@ public BType addBuilder(int index, MType message) { /** * Removes the element at the specified position in this list. Shifts any subsequent elements to - * the left (subtracts one from their indices). Returns the element that was removed from the - * list. + * the left (subtracts one from their indices). * * @param index the index at which to remove the message */ diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java index fb1667c4c65b..91bc3e286dd0 100644 --- a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java +++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java @@ -346,9 +346,8 @@ public RepeatedFieldBuilderV3 addAllMessages( // If we can inspect the size, we can more efficiently add messages. int size = -1; if (values instanceof Collection) { - @SuppressWarnings("unchecked") - final Collection collection = (Collection) values; - if (collection.size() == 0) { + final Collection collection = (Collection) values; + if (collection.isEmpty()) { return this; } size = collection.size(); @@ -408,8 +407,7 @@ public BType addBuilder(int index, MType message) { /** * Removes the element at the specified position in this list. Shifts any subsequent elements to - * the left (subtracts one from their indices). Returns the element that was removed from the - * list. + * the left (subtracts one from their indices). * * @param index the index at which to remove the message */ diff --git a/java/core/src/main/java/com/google/protobuf/RopeByteString.java b/java/core/src/main/java/com/google/protobuf/RopeByteString.java index 54d418059509..cc6e0445b0d6 100644 --- a/java/core/src/main/java/com/google/protobuf/RopeByteString.java +++ b/java/core/src/main/java/com/google/protobuf/RopeByteString.java @@ -845,7 +845,10 @@ public int read(byte[] b, int offset, int length) { throw new IndexOutOfBoundsException(); } int bytesRead = readSkipInternal(b, offset, length); - if (bytesRead == 0) { + if (bytesRead == 0 && (length > 0 || availableInternal() == 0)) { + // Modeling ByteArrayInputStream.read(byte[], int, int) behavior noted above: + // It's ok to read 0 bytes on purpose (length == 0) from a stream that isn't at EOF. + // It's not ok to try to read bytes (even 0 bytes) from a stream that is at EOF. return -1; } else { return bytesRead; @@ -905,8 +908,7 @@ public int read() throws IOException { @Override public int available() throws IOException { - int bytesRead = currentPieceOffsetInRope + currentPieceIndex; - return RopeByteString.this.size() - bytesRead; + return availableInternal(); } @Override @@ -955,5 +957,11 @@ private void advanceIfCurrentPieceFullyRead() { } } } + + /** Computes the number of bytes still available to read. */ + private int availableInternal() { + int bytesRead = currentPieceOffsetInRope + currentPieceIndex; + return RopeByteString.this.size() - bytesRead; + } } } diff --git a/java/core/src/main/java/com/google/protobuf/Schema.java b/java/core/src/main/java/com/google/protobuf/Schema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/SchemaFactory.java b/java/core/src/main/java/com/google/protobuf/SchemaFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/SchemaUtil.java b/java/core/src/main/java/com/google/protobuf/SchemaUtil.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java b/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index f3f1011a585f..e781df333d10 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -30,14 +30,18 @@ package com.google.protobuf; +import static java.nio.charset.StandardCharsets.UTF_8; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.MessageReflection.MergeTarget; import java.io.IOException; import java.math.BigInteger; import java.nio.CharBuffer; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; @@ -57,6 +61,7 @@ private TextFormat() {} private static final Logger logger = Logger.getLogger(TextFormat.class.getName()); + /** * Outputs a textual representation of the Protocol Message supplied into the parameter output. * (This representation is the new version of the classic "ProtocolPrinter" output from the @@ -137,7 +142,7 @@ public static String shortDebugString(final UnknownFieldSet fields) { /** * Like {@code print()}, but writes directly to a {@code String} and returns it. * - * @deprecated Use {@link MessageOrBuilder#toString()} + * @deprecated Use {@code message.toString()} */ @Deprecated public static String printToString(final MessageOrBuilder message) { @@ -419,7 +424,17 @@ public void printField(final FieldDescriptor field, final Object value, final Ap private void printField( final FieldDescriptor field, final Object value, final TextGenerator generator) throws IOException { - if (field.isRepeated()) { + // Sort map field entries by key + if (field.isMapField()) { + List adapters = new ArrayList<>(); + for (Object entry : (List) value) { + adapters.add(new MapEntryAdapter(entry, field)); + } + Collections.sort(adapters); + for (MapEntryAdapter adapter : adapters) { + printSingleField(field, adapter.getEntry(), generator); + } + } else if (field.isRepeated()) { // Repeated field. Print each element. for (Object element : (List) value) { printSingleField(field, element, generator); @@ -429,6 +444,78 @@ private void printField( } } + /** + * An adapter class that can take a MapEntry or a MutableMapEntry and returns its key and entry. + * This class is created solely for the purpose of sorting map entries by its key and prevent + * duplicated logic by having a separate comparator for MapEntry and MutableMapEntry. + */ + private static class MapEntryAdapter implements Comparable { + private Object entry; + + @SuppressWarnings({"rawtypes"}) + private MapEntry mapEntry; + + + private final FieldDescriptor.JavaType fieldType; + + public MapEntryAdapter(Object entry, FieldDescriptor fieldDescriptor) { + if (entry instanceof MapEntry) { + this.mapEntry = (MapEntry) entry; + } else { + this.entry = entry; + } + this.fieldType = extractFieldType(fieldDescriptor); + } + + private static FieldDescriptor.JavaType extractFieldType(FieldDescriptor fieldDescriptor) { + return fieldDescriptor.getMessageType().getFields().get(0).getJavaType(); + } + + public Object getKey() { + if (mapEntry != null) { + return mapEntry.getKey(); + } + return null; + } + + public Object getEntry() { + if (mapEntry != null) { + return mapEntry; + } + return entry; + } + + @Override + public int compareTo(MapEntryAdapter b) { + if (getKey() == null || b.getKey() == null) { + logger.info("Invalid key for map field."); + return -1; + } + switch (fieldType) { + case BOOLEAN: + return Boolean.compare((boolean) getKey(), (boolean) b.getKey()); + case LONG: + return Long.compare((long) getKey(), (long) b.getKey()); + case INT: + return Integer.compare((int) getKey(), (int) b.getKey()); + case STRING: + String aString = (String) getKey(); + String bString = (String) b.getKey(); + if (aString == null && bString == null) { + return 0; + } else if (aString == null && bString != null) { + return -1; + } else if (aString != null && bString == null) { + return 1; + } else { + return aString.compareTo(bString); + } + default: + return 0; + } + } + } + /** * Outputs a textual representation of the value of given field value. * @@ -641,9 +728,9 @@ private void printSingleField( // Groups must be serialized with their original capitalization. generator.print(field.getMessageType().getName()); } else { - generator.print(field.getName()); + generator.print(field.getName()); + } } - } if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { generator.print(" {"); @@ -1577,7 +1664,7 @@ public void merge( throws IOException { // Read the entire input to a String then parse that. - // If StreamTokenizer were not quite so crippled, or if there were a kind + // If StreamTokenizer was not so limited, or if there were a kind // of Reader that could read in chunks that match some particular regex, // or if we wanted to write a custom Reader to tokenize our stream, then // we would not have to read to one big String. Alas, none of these is @@ -1708,6 +1795,12 @@ private void mergeField( final Descriptor type = target.getDescriptorForType(); ExtensionRegistry.ExtensionInfo extension = null; + if ("google.protobuf.Any".equals(type.getFullName()) && tokenizer.tryConsume("[")) { + mergeAnyFieldValue(tokenizer, extensionRegistry, target, parseTreeBuilder, unknownFields, + type); + return; + } + if (tokenizer.tryConsume("[")) { // An extension. final StringBuilder name = new StringBuilder(tokenizer.consumeIdentifier()); @@ -1719,16 +1812,16 @@ private void mergeField( extension = target.findExtensionByName(extensionRegistry, name.toString()); if (extension == null) { - String message = - (tokenizer.getPreviousLine() + 1) - + ":" - + (tokenizer.getPreviousColumn() + 1) - + ":\t" - + type.getFullName() - + ".[" - + name - + "]"; - unknownFields.add(new UnknownField(message, UnknownField.Type.EXTENSION)); + String message = + (tokenizer.getPreviousLine() + 1) + + ":" + + (tokenizer.getPreviousColumn() + 1) + + ":\t" + + type.getFullName() + + ".[" + + name + + "]"; + unknownFields.add(new UnknownField(message, UnknownField.Type.EXTENSION)); } else { if (extension.descriptor.getContainingType() != type) { throw tokenizer.parseExceptionPreviousToken( @@ -1928,9 +2021,13 @@ private void consumeFieldValue( // Try to parse human readable format of Any in the form: [type_url]: { ... } if (field.getMessageType().getFullName().equals("google.protobuf.Any") && tokenizer.tryConsume("[")) { - value = - consumeAnyFieldValue( - tokenizer, extensionRegistry, field, parseTreeBuilder, unknownFields); + // Use Proto reflection here since depending on Any would intoduce a cyclic dependency + // (java_proto_library for any_java_proto depends on the protobuf_impl). + Message anyBuilder = DynamicMessage.getDefaultInstance(field.getMessageType()); + MessageReflection.MergeTarget anyField = target.newMergeTargetForField(field, anyBuilder); + mergeAnyFieldValue(tokenizer, extensionRegistry, anyField, parseTreeBuilder, + unknownFields, field.getMessageType()); + value = anyField.finish(); tokenizer.consume(endToken); } else { Message defaultInstance = (extension == null) ? null : extension.defaultInstance; @@ -2052,12 +2149,13 @@ private void consumeFieldValue( } } - private Object consumeAnyFieldValue( + private void mergeAnyFieldValue( final Tokenizer tokenizer, final ExtensionRegistry extensionRegistry, - final FieldDescriptor field, + MergeTarget target, final TextFormatParseInfoTree.Builder parseTreeBuilder, - List unknownFields) + List unknownFields, + Descriptor anyDescriptor) throws ParseException { // Try to parse human readable format of Any in the form: [type_url]: { ... } StringBuilder typeUrlBuilder = new StringBuilder(); @@ -2105,21 +2203,13 @@ private Object consumeAnyFieldValue( mergeField(tokenizer, extensionRegistry, contentTarget, parseTreeBuilder, unknownFields); } - // Serialize the content and put it back into an Any. Note that we can't depend on Any here - // because of a cyclic dependency (java_proto_library for any_java_proto depends on the - // protobuf_impl), so we need to construct the Any using proto reflection. - Descriptor anyDescriptor = field.getMessageType(); - Message.Builder anyBuilder = - DynamicMessage.getDefaultInstance(anyDescriptor).newBuilderForType(); - anyBuilder.setField(anyDescriptor.findFieldByName("type_url"), typeUrlBuilder.toString()); - anyBuilder.setField( + target.setField(anyDescriptor.findFieldByName("type_url"), typeUrlBuilder.toString()); + target.setField( anyDescriptor.findFieldByName("value"), contentBuilder.build().toByteString()); - - return anyBuilder.build(); } /** Skips the next field including the field's name and value. */ - private void skipField(Tokenizer tokenizer) throws ParseException { + private static void skipField(Tokenizer tokenizer) throws ParseException { if (tokenizer.tryConsume("[")) { // Extension name. do { @@ -2151,7 +2241,7 @@ private void skipField(Tokenizer tokenizer) throws ParseException { /** * Skips the whole body of a message including the beginning delimiter and the ending delimiter. */ - private void skipFieldMessage(Tokenizer tokenizer) throws ParseException { + private static void skipFieldMessage(Tokenizer tokenizer) throws ParseException { final String delimiter; if (tokenizer.tryConsume("<")) { delimiter = ">"; @@ -2166,7 +2256,7 @@ private void skipFieldMessage(Tokenizer tokenizer) throws ParseException { } /** Skips a field value. */ - private void skipFieldValue(Tokenizer tokenizer) throws ParseException { + private static void skipFieldValue(Tokenizer tokenizer) throws ParseException { if (tokenizer.tryConsumeString()) { while (tokenizer.tryConsumeString()) {} return; @@ -2288,6 +2378,73 @@ public static ByteString unescapeBytes(final CharSequence charString) result[pos++] = (byte) code; break; + case 'u': + // Unicode escape + ++i; + if (i + 3 < input.size() + && isHex(input.byteAt(i)) + && isHex(input.byteAt(i + 1)) + && isHex(input.byteAt(i + 2)) + && isHex(input.byteAt(i + 3))) { + char ch = + (char) + (digitValue(input.byteAt(i)) << 12 + | digitValue(input.byteAt(i + 1)) << 8 + | digitValue(input.byteAt(i + 2)) << 4 + | digitValue(input.byteAt(i + 3))); + if (Character.isSurrogate(ch)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\u' refers to a surrogate"); + } + byte[] chUtf8 = Character.toString(ch).getBytes(UTF_8); + System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); + pos += chUtf8.length; + i += 3; + } else { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\u' with too few hex chars"); + } + break; + + case 'U': + // Unicode escape + ++i; + if (i + 7 >= input.size()) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U' with too few hex chars"); + } + int codepoint = 0; + for (int offset = i; offset < i + 8; offset++) { + byte b = input.byteAt(offset); + if (!isHex(b)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U' with too few hex chars"); + } + codepoint = (codepoint << 4) | digitValue(b); + } + if (!Character.isValidCodePoint(codepoint)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U" + + input.substring(i, i + 8).toStringUtf8() + + "' is not a valid code point value"); + } + Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(codepoint); + if (unicodeBlock.equals(Character.UnicodeBlock.LOW_SURROGATES) + || unicodeBlock.equals(Character.UnicodeBlock.HIGH_SURROGATES) + || unicodeBlock.equals(Character.UnicodeBlock.HIGH_PRIVATE_USE_SURROGATES)) { + throw new InvalidEscapeSequenceException( + "Invalid escape sequence: '\\U" + + input.substring(i, i + 8).toStringUtf8() + + "' refers to a surrogate code unit"); + } + int[] codepoints = new int[1]; + codepoints[0] = codepoint; + byte[] chUtf8 = new String(codepoints, 0, 1).getBytes(UTF_8); + System.arraycopy(chUtf8, 0, result, pos, chUtf8.length); + pos += chUtf8.length; + i += 7; + break; + default: throw new InvalidEscapeSequenceException( "Invalid escape sequence: '\\" + (char) c + '\''); diff --git a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java old mode 100755 new mode 100644 index 47d798bfe621..422ff1f870fc --- a/java/core/src/main/java/com/google/protobuf/TypeRegistry.java +++ b/java/core/src/main/java/com/google/protobuf/TypeRegistry.java @@ -70,7 +70,6 @@ public Descriptor find(String name) { /** * Find a type by its typeUrl. Returns null if it cannot be found in this {@link TypeRegistry}. */ - /* @Nullable */ public final Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException { return find(getTypeName(typeUrl)); diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java index 2f6315c80d4d..b2cb7be4baef 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java @@ -301,7 +301,7 @@ public int getSerializedSize() { return size; } - private static boolean equals(int[] tags1, int[] tags2, int count) { + private static boolean tagsEquals(int[] tags1, int[] tags2, int count) { for (int i = 0; i < count; ++i) { if (tags1[i] != tags2[i]) { return false; @@ -310,7 +310,7 @@ private static boolean equals(int[] tags1, int[] tags2, int count) { return true; } - private static boolean equals(Object[] objects1, Object[] objects2, int count) { + private static boolean objectsEquals(Object[] objects1, Object[] objects2, int count) { for (int i = 0; i < count; ++i) { if (!objects1[i].equals(objects2[i])) { return false; @@ -335,8 +335,8 @@ public boolean equals(Object obj) { UnknownFieldSetLite other = (UnknownFieldSetLite) obj; if (count != other.count - || !equals(tags, other.tags, count) - || !equals(objects, other.objects, count)) { + || !tagsEquals(tags, other.tags, count) + || !objectsEquals(objects, other.objects, count)) { return false; } diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetSchema.java old mode 100755 new mode 100644 diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java index b435327ab8b8..b9b32af15823 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -41,7 +41,6 @@ /** Utility class for working with unsafe operations. */ final class UnsafeUtil { - private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName()); private static final sun.misc.Unsafe UNSAFE = getUnsafe(); private static final Class MEMORY_CLASS = Android.getMemoryClass(); private static final boolean IS_ANDROID_64 = determineAndroidSupportByAddressSize(long.class); @@ -363,9 +362,13 @@ private static boolean supportsUnsafeArrayOperations() { return true; } catch (Throwable e) { - logger.log( - Level.WARNING, - "platform method missing - proto runtime falling back to safer methods: " + e); + // Because log statements are fairly sparse in this class, this logger is initialized + // non-statically. Static initialization adds undue runtime costs to the first client to + // initialize this class. + Logger.getLogger(UnsafeUtil.class.getName()) + .log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); } return false; } @@ -385,7 +388,7 @@ private static boolean supportsUnsafeByteBufferOperations() { } if (Android.isOnAndroidDevice()) { - return true; + return false; } clazz.getMethod("getByte", long.class); clazz.getMethod("putByte", long.class, byte.class); @@ -397,9 +400,13 @@ private static boolean supportsUnsafeByteBufferOperations() { clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); return true; } catch (Throwable e) { - logger.log( - Level.WARNING, - "platform method missing - proto runtime falling back to safer methods: " + e); + // Because log statements are fairly sparse in this class, this logger is initialized + // non-statically. Static initialization adds undue runtime costs to the first client to + // initialize this class. + Logger.getLogger(UnsafeUtil.class.getName()) + .log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); } return false; } diff --git a/java/core/src/main/java/com/google/protobuf/Writer.java b/java/core/src/main/java/com/google/protobuf/Writer.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto3LiteSchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto3LiteSchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/AbstractProto3SchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractProto3SchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/AbstractSchemaTest.java b/java/core/src/test/java/com/google/protobuf/AbstractSchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java b/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/BinaryProtocolTest.java b/java/core/src/test/java/com/google/protobuf/BinaryProtocolTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java index ae50071398a3..805b7b042f25 100644 --- a/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java @@ -140,6 +140,68 @@ public void testGetBoolean() { } } + public void testIndexOf_nullElement() { + assertEquals(-1, TERTIARY_LIST.indexOf(null)); + } + + public void testIndexOf_incompatibleElementType() { + assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + } + + public void testIndexOf_notInList() { + assertEquals(-1, UNARY_LIST.indexOf(false)); + } + + public void testIndexOf_notInListWithDuplicates() { + BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true); + assertEquals(-1, listWithDupes.indexOf(false)); + } + + public void testIndexOf_inList() { + assertEquals(1, TERTIARY_LIST.indexOf(false)); + } + + public void testIndexOf_inListWithDuplicates_matchAtHead() { + BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true, false); + assertEquals(0, listWithDupes.indexOf(true)); + } + + public void testIndexOf_inListWithDuplicates_matchMidList() { + BooleanArrayList listWithDupes = newImmutableBooleanArrayList(false, true, true, false); + assertEquals(1, listWithDupes.indexOf(true)); + } + + public void testContains_nullElement() { + assertEquals(false, TERTIARY_LIST.contains(null)); + } + + public void testContains_incompatibleElementType() { + assertEquals(false, TERTIARY_LIST.contains(new Object())); + } + + public void testContains_notInList() { + assertEquals(false, UNARY_LIST.contains(false)); + } + + public void testContains_notInListWithDuplicates() { + BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true); + assertEquals(false, listWithDupes.contains(false)); + } + + public void testContains_inList() { + assertEquals(true, TERTIARY_LIST.contains(false)); + } + + public void testContains_inListWithDuplicates_matchAtHead() { + BooleanArrayList listWithDupes = newImmutableBooleanArrayList(true, true, false); + assertEquals(true, listWithDupes.contains(true)); + } + + public void testContains_inListWithDuplicates_matchMidList() { + BooleanArrayList listWithDupes = newImmutableBooleanArrayList(false, true, true, false); + assertEquals(true, listWithDupes.contains(true)); + } + public void testSize() { assertEquals(0, BooleanArrayList.emptyList().size()); assertEquals(1, UNARY_LIST.size()); diff --git a/java/core/src/test/java/com/google/protobuf/CachedFieldSizeTest.java b/java/core/src/test/java/com/google/protobuf/CachedFieldSizeTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/CodedAdapterTest.java b/java/core/src/test/java/com/google/protobuf/CodedAdapterTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java index 3a8254aa69fb..019b5a14444f 100644 --- a/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java @@ -139,6 +139,68 @@ public void testGetDouble() { } } + public void testIndexOf_nullElement() { + assertEquals(-1, TERTIARY_LIST.indexOf(null)); + } + + public void testIndexOf_incompatibleElementType() { + assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + } + + public void testIndexOf_notInList() { + assertEquals(-1, UNARY_LIST.indexOf(2D)); + } + + public void testIndexOf_notInListWithDuplicates() { + DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D); + assertEquals(-1, listWithDupes.indexOf(2D)); + } + + public void testIndexOf_inList() { + assertEquals(1, TERTIARY_LIST.indexOf(2D)); + } + + public void testIndexOf_inListWithDuplicates_matchAtHead() { + DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D, 2D); + assertEquals(0, listWithDupes.indexOf(1D)); + } + + public void testIndexOf_inListWithDuplicates_matchMidList() { + DoubleArrayList listWithDupes = newImmutableDoubleArrayList(2D, 1D, 1D, 2D); + assertEquals(1, listWithDupes.indexOf(1D)); + } + + public void testContains_nullElement() { + assertEquals(false, TERTIARY_LIST.contains(null)); + } + + public void testContains_incompatibleElementType() { + assertEquals(false, TERTIARY_LIST.contains(new Object())); + } + + public void testContains_notInList() { + assertEquals(false, UNARY_LIST.contains(2D)); + } + + public void testContains_notInListWithDuplicates() { + DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D); + assertEquals(false, listWithDupes.contains(2D)); + } + + public void testContains_inList() { + assertEquals(true, TERTIARY_LIST.contains(2D)); + } + + public void testContains_inListWithDuplicates_matchAtHead() { + DoubleArrayList listWithDupes = newImmutableDoubleArrayList(1D, 1D, 2D); + assertEquals(true, listWithDupes.contains(1D)); + } + + public void testContains_inListWithDuplicates_matchMidList() { + DoubleArrayList listWithDupes = newImmutableDoubleArrayList(2D, 1D, 1D, 2D); + assertEquals(true, listWithDupes.contains(1D)); + } + public void testSize() { assertEquals(0, DoubleArrayList.emptyList().size()); assertEquals(1, UNARY_LIST.size()); diff --git a/java/core/src/test/java/com/google/protobuf/ExperimentalMessageFactory.java b/java/core/src/test/java/com/google/protobuf/ExperimentalMessageFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/ExperimentalSerializationUtil.java b/java/core/src/test/java/com/google/protobuf/ExperimentalSerializationUtil.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/ExperimentalTestDataProvider.java b/java/core/src/test/java/com/google/protobuf/ExperimentalTestDataProvider.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java b/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java index c6aed074feb3..70466ba2e7ac 100644 --- a/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java +++ b/java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java @@ -41,6 +41,7 @@ import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; +import org.junit.Ignore; /** * Tests for {@link ExtensionRegistryFactory} and the {@link ExtensionRegistry} instances it @@ -52,7 +53,13 @@ * *

    The test mechanism employed here is based on the pattern in {@code * com.google.common.util.concurrent.AbstractFutureFallbackAtomicHelperTest} + * + *

    This test is temporarily disabled due to what appears to be a subtle change to class loading + * behavior in Java 11. That seems to have broken the way the test uses a custom ClassLoader to + * exercise Lite functionality. */ +@SuppressWarnings("JUnit4ClassUsedInJUnit3") +@Ignore public class ExtensionRegistryFactoryTest extends TestCase { // A classloader which blacklists some non-Lite classes. diff --git a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java index db4ecfedaa04..a1c98c0cef8e 100644 --- a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java +++ b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java @@ -34,9 +34,11 @@ import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.FieldPresenceTestProto.TestAllTypes; import com.google.protobuf.FieldPresenceTestProto.TestOptionalFieldsOnly; import com.google.protobuf.FieldPresenceTestProto.TestRepeatedFieldsOnly; +import com.google.protobuf.testing.proto.TestProto3Optional; import protobuf_unittest.UnittestProto; import junit.framework.TestCase; @@ -100,6 +102,114 @@ public void testHasMethod() { UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofBytes"); } + public void testHasMethodForProto3Optional() throws Exception { + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalInt32()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalInt64()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalUint32()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalUint64()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalSint32()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalSint64()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalFixed32()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalFixed64()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalFloat()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalDouble()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalBool()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalString()); + assertFalse(TestProto3Optional.getDefaultInstance().hasOptionalBytes()); + + TestProto3Optional.Builder builder = TestProto3Optional.newBuilder().setOptionalInt32(0); + assertTrue(builder.hasOptionalInt32()); + assertTrue(builder.build().hasOptionalInt32()); + + TestProto3Optional.Builder otherBuilder = TestProto3Optional.newBuilder().setOptionalInt32(1); + otherBuilder.mergeFrom(builder.build()); + assertTrue(otherBuilder.hasOptionalInt32()); + assertEquals(0, otherBuilder.getOptionalInt32()); + + TestProto3Optional.Builder builder3 = + TestProto3Optional.newBuilder().setOptionalNestedEnumValue(5); + assertTrue(builder3.hasOptionalNestedEnum()); + + TestProto3Optional.Builder builder4 = + TestProto3Optional.newBuilder().setOptionalNestedEnum(TestProto3Optional.NestedEnum.FOO); + assertTrue(builder4.hasOptionalNestedEnum()); + + TestProto3Optional proto = TestProto3Optional.parseFrom(builder.build().toByteArray()); + assertTrue(proto.hasOptionalInt32()); + assertTrue(proto.toBuilder().hasOptionalInt32()); + } + + private static void assertProto3OptionalReflection(String name) throws Exception { + FieldDescriptor fieldDescriptor = TestProto3Optional.getDescriptor().findFieldByName(name); + OneofDescriptor oneofDescriptor = fieldDescriptor.getContainingOneof(); + assertNotNull(fieldDescriptor.getContainingOneof()); + assertTrue(fieldDescriptor.hasOptionalKeyword()); + assertTrue(fieldDescriptor.hasPresence()); + + assertFalse(TestProto3Optional.getDefaultInstance().hasOneof(oneofDescriptor)); + assertNull(TestProto3Optional.getDefaultInstance().getOneofFieldDescriptor(oneofDescriptor)); + + TestProto3Optional.Builder builder = TestProto3Optional.newBuilder(); + builder.setField(fieldDescriptor, fieldDescriptor.getDefaultValue()); + assertTrue(builder.hasField(fieldDescriptor)); + assertEquals(fieldDescriptor.getDefaultValue(), builder.getField(fieldDescriptor)); + assertTrue(builder.build().hasField(fieldDescriptor)); + assertEquals(fieldDescriptor.getDefaultValue(), builder.build().getField(fieldDescriptor)); + assertTrue(builder.hasOneof(oneofDescriptor)); + assertEquals(fieldDescriptor, builder.getOneofFieldDescriptor(oneofDescriptor)); + assertTrue(builder.build().hasOneof(oneofDescriptor)); + assertEquals(fieldDescriptor, builder.build().getOneofFieldDescriptor(oneofDescriptor)); + + TestProto3Optional.Builder otherBuilder = TestProto3Optional.newBuilder(); + otherBuilder.mergeFrom(builder.build()); + assertTrue(otherBuilder.hasField(fieldDescriptor)); + assertEquals(fieldDescriptor.getDefaultValue(), otherBuilder.getField(fieldDescriptor)); + + TestProto3Optional proto = TestProto3Optional.parseFrom(builder.build().toByteArray()); + assertTrue(proto.hasField(fieldDescriptor)); + assertTrue(proto.toBuilder().hasField(fieldDescriptor)); + + DynamicMessage.Builder dynamicBuilder = + DynamicMessage.newBuilder(TestProto3Optional.getDescriptor()); + dynamicBuilder.setField(fieldDescriptor, fieldDescriptor.getDefaultValue()); + assertTrue(dynamicBuilder.hasField(fieldDescriptor)); + assertEquals(fieldDescriptor.getDefaultValue(), dynamicBuilder.getField(fieldDescriptor)); + assertTrue(dynamicBuilder.build().hasField(fieldDescriptor)); + assertEquals( + fieldDescriptor.getDefaultValue(), dynamicBuilder.build().getField(fieldDescriptor)); + assertTrue(dynamicBuilder.hasOneof(oneofDescriptor)); + assertEquals(fieldDescriptor, dynamicBuilder.getOneofFieldDescriptor(oneofDescriptor)); + assertTrue(dynamicBuilder.build().hasOneof(oneofDescriptor)); + assertEquals(fieldDescriptor, dynamicBuilder.build().getOneofFieldDescriptor(oneofDescriptor)); + + DynamicMessage.Builder otherDynamicBuilder = + DynamicMessage.newBuilder(TestProto3Optional.getDescriptor()); + otherDynamicBuilder.mergeFrom(dynamicBuilder.build()); + assertTrue(otherDynamicBuilder.hasField(fieldDescriptor)); + assertEquals(fieldDescriptor.getDefaultValue(), otherDynamicBuilder.getField(fieldDescriptor)); + + DynamicMessage dynamicProto = + DynamicMessage.parseFrom(TestProto3Optional.getDescriptor(), builder.build().toByteArray()); + assertTrue(dynamicProto.hasField(fieldDescriptor)); + assertTrue(dynamicProto.toBuilder().hasField(fieldDescriptor)); + } + + public void testProto3Optional_reflection() throws Exception { + assertProto3OptionalReflection("optional_int32"); + assertProto3OptionalReflection("optional_int64"); + assertProto3OptionalReflection("optional_uint32"); + assertProto3OptionalReflection("optional_uint64"); + assertProto3OptionalReflection("optional_sint32"); + assertProto3OptionalReflection("optional_sint64"); + assertProto3OptionalReflection("optional_fixed32"); + assertProto3OptionalReflection("optional_fixed64"); + assertProto3OptionalReflection("optional_float"); + assertProto3OptionalReflection("optional_double"); + assertProto3OptionalReflection("optional_bool"); + assertProto3OptionalReflection("optional_string"); + assertProto3OptionalReflection("optional_bytes"); + } + public void testOneofEquals() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); TestAllTypes message1 = builder.build(); diff --git a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java index 77a2839b90d7..091ac5bb784e 100644 --- a/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java @@ -139,6 +139,68 @@ public void testGetFloat() { } } + public void testIndexOf_nullElement() { + assertEquals(-1, TERTIARY_LIST.indexOf(null)); + } + + public void testIndexOf_incompatibleElementType() { + assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + } + + public void testIndexOf_notInList() { + assertEquals(-1, UNARY_LIST.indexOf(2F)); + } + + public void testIndexOf_notInListWithDuplicates() { + FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F); + assertEquals(-1, listWithDupes.indexOf(2F)); + } + + public void testIndexOf_inList() { + assertEquals(1, TERTIARY_LIST.indexOf(2F)); + } + + public void testIndexOf_inListWithDuplicates_matchAtHead() { + FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F, 2F); + assertEquals(0, listWithDupes.indexOf(1F)); + } + + public void testIndexOf_inListWithDuplicates_matchMidList() { + FloatArrayList listWithDupes = newImmutableFloatArrayList(2F, 1F, 1F, 2F); + assertEquals(1, listWithDupes.indexOf(1F)); + } + + public void testContains_nullElement() { + assertEquals(false, TERTIARY_LIST.contains(null)); + } + + public void testContains_incompatibleElementType() { + assertEquals(false, TERTIARY_LIST.contains(new Object())); + } + + public void testContains_notInList() { + assertEquals(false, UNARY_LIST.contains(2F)); + } + + public void testContains_notInListWithDuplicates() { + FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F); + assertEquals(false, listWithDupes.contains(2F)); + } + + public void testContains_inList() { + assertEquals(true, TERTIARY_LIST.contains(2F)); + } + + public void testContains_inListWithDuplicates_matchAtHead() { + FloatArrayList listWithDupes = newImmutableFloatArrayList(1F, 1F, 2F); + assertEquals(true, listWithDupes.contains(1F)); + } + + public void testContains_inListWithDuplicates_matchMidList() { + FloatArrayList listWithDupes = newImmutableFloatArrayList(2F, 1F, 1F, 2F); + assertEquals(true, listWithDupes.contains(1F)); + } + public void testSize() { assertEquals(0, FloatArrayList.emptyList().size()); assertEquals(1, UNARY_LIST.size()); diff --git a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java index 51ebc987d03d..2ad94f83de73 100644 --- a/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/IntArrayListTest.java @@ -139,6 +139,68 @@ public void testGetInt() { } } + public void testIndexOf_nullElement() { + assertEquals(-1, TERTIARY_LIST.indexOf(null)); + } + + public void testIndexOf_incompatibleElementType() { + assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + } + + public void testIndexOf_notInList() { + assertEquals(-1, UNARY_LIST.indexOf(2)); + } + + public void testIndexOf_notInListWithDuplicates() { + IntArrayList listWithDupes = newImmutableIntArrayList(1, 1); + assertEquals(-1, listWithDupes.indexOf(2)); + } + + public void testIndexOf_inList() { + assertEquals(1, TERTIARY_LIST.indexOf(2)); + } + + public void testIndexOf_inListWithDuplicates_matchAtHead() { + IntArrayList listWithDupes = newImmutableIntArrayList(1, 1, 2); + assertEquals(0, listWithDupes.indexOf(1)); + } + + public void testIndexOf_inListWithDuplicates_matchMidList() { + IntArrayList listWithDupes = newImmutableIntArrayList(2, 1, 1, 2); + assertEquals(1, listWithDupes.indexOf(1)); + } + + public void testContains_nullElement() { + assertEquals(false, TERTIARY_LIST.contains(null)); + } + + public void testContains_incompatibleElementType() { + assertEquals(false, TERTIARY_LIST.contains(new Object())); + } + + public void testContains_notInList() { + assertEquals(false, UNARY_LIST.contains(2)); + } + + public void testContains_notInListWithDuplicates() { + IntArrayList listWithDupes = newImmutableIntArrayList(1, 1); + assertEquals(false, listWithDupes.contains(2)); + } + + public void testContains_inList() { + assertEquals(true, TERTIARY_LIST.contains(2)); + } + + public void testContains_inListWithDuplicates_matchAtHead() { + IntArrayList listWithDupes = newImmutableIntArrayList(1, 1, 2); + assertEquals(true, listWithDupes.contains(1)); + } + + public void testContains_inListWithDuplicates_matchMidList() { + IntArrayList listWithDupes = newImmutableIntArrayList(2, 1, 1, 2); + assertEquals(true, listWithDupes.contains(1)); + } + public void testSize() { assertEquals(0, IntArrayList.emptyList().size()); assertEquals(1, UNARY_LIST.size()); diff --git a/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java index 9f64b6baba70..4177a47e67f2 100644 --- a/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java @@ -514,6 +514,20 @@ public void testNewInput() throws IOException { assertEquals(classUnderTest + " InputStream must now be exhausted", -1, input.read()); } + public void testNewInput_readZeroBytes() throws IOException { + InputStream input = stringUnderTest.newInput(); + assertEquals( + classUnderTest + " InputStream.read() returns 0 when told to read 0 bytes and not at EOF", + 0, + input.read(new byte[0])); + + input.skip(input.available()); + assertEquals( + classUnderTest + " InputStream.read() returns -1 when told to read 0 bytes at EOF", + -1, + input.read(new byte[0])); + } + public void testNewInput_skip() throws IOException { InputStream input = stringUnderTest.newInput(); int stringSize = stringUnderTest.size(); diff --git a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java index 1935100503d6..d6fbaf9d9506 100644 --- a/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/LongArrayListTest.java @@ -139,6 +139,68 @@ public void testGetLong() { } } + public void testIndexOf_nullElement() { + assertEquals(-1, TERTIARY_LIST.indexOf(null)); + } + + public void testIndexOf_incompatibleElementType() { + assertEquals(-1, TERTIARY_LIST.indexOf(new Object())); + } + + public void testIndexOf_notInList() { + assertEquals(-1, UNARY_LIST.indexOf(2L)); + } + + public void testIndexOf_notInListWithDuplicates() { + LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L); + assertEquals(-1, listWithDupes.indexOf(2L)); + } + + public void testIndexOf_inList() { + assertEquals(1, TERTIARY_LIST.indexOf(2L)); + } + + public void testIndexOf_inListWithDuplicates_matchAtHead() { + LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L, 2L); + assertEquals(0, listWithDupes.indexOf(1L)); + } + + public void testIndexOf_inListWithDuplicates_matchMidList() { + LongArrayList listWithDupes = newImmutableLongArrayList(2L, 1L, 1L, 2L); + assertEquals(1, listWithDupes.indexOf(1L)); + } + + public void testContains_nullElement() { + assertEquals(false, TERTIARY_LIST.contains(null)); + } + + public void testContains_incompatibleElementType() { + assertEquals(false, TERTIARY_LIST.contains(new Object())); + } + + public void testContains_notInList() { + assertEquals(false, UNARY_LIST.contains(2L)); + } + + public void testContains_notInListWithDuplicates() { + LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L); + assertEquals(false, listWithDupes.contains(2L)); + } + + public void testContains_inList() { + assertEquals(true, TERTIARY_LIST.contains(2L)); + } + + public void testContains_inListWithDuplicates_matchAtHead() { + LongArrayList listWithDupes = newImmutableLongArrayList(1L, 1L, 2L); + assertEquals(true, listWithDupes.contains(1L)); + } + + public void testContains_inListWithDuplicates_matchMidList() { + LongArrayList listWithDupes = newImmutableLongArrayList(2L, 1L, 1L, 2L); + assertEquals(true, listWithDupes.contains(1L)); + } + public void testSize() { assertEquals(0, LongArrayList.emptyList().size()); assertEquals(1, UNARY_LIST.size()); diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java index adca1d51b6c9..4de09cd1619a 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java @@ -77,44 +77,44 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValues(TestMap.Builder builder) { @@ -152,49 +152,49 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -206,13 +206,13 @@ public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32Field().isEmpty()); + assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); message = builder.build(); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); } public void testGetMapIsImmutable() { @@ -226,13 +226,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { @@ -254,30 +254,31 @@ private void assertImmutable(Map map, K key, V value) { public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField()); + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumFieldMap()); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); + assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + builder.build().getInt32ToMessageFieldMap()); assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField()); + newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap( @@ -285,7 +286,7 @@ public void testMutableMapLifecycle() { TestMap.MessageValue.getDefaultInstance(), 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + builder.getInt32ToMessageFieldMap()); } public void testGettersAndSetters() throws Exception { @@ -415,7 +416,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -476,14 +477,14 @@ public void testUnknownEnumValues() throws Exception { TestMap message = TestMap.parseFrom(data); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); + assertEquals(1, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); + assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); + assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); } public void testIterationOrder() throws Exception { @@ -493,7 +494,7 @@ public void testIterationOrder() throws Exception { assertEquals( Arrays.asList("1", "2", "3"), - new ArrayList(message.getStringToInt32Field().keySet())); + new ArrayList(message.getStringToInt32FieldMap().keySet())); } private static Map newMap(K key1, V value1) { @@ -513,10 +514,10 @@ public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java index bb706326c4b4..d2565ca15701 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -119,44 +119,44 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMapOrBuilder message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); - - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { @@ -236,49 +236,49 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); - - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); - - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); - - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); - - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); - - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); + + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); + + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); + + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); + + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); + + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -293,13 +293,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { @@ -563,7 +563,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -698,8 +698,8 @@ public void testReflectionApi() throws Exception { builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32Field().size()); - assertEquals(0, message.getInt32ToMessageField().size()); + assertEquals(0, message.getInt32ToInt32FieldMap().size()); + assertEquals(0, message.getInt32ToMessageFieldMap().size()); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -710,10 +710,10 @@ public void testReflectionApi() throws Exception { 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - assertEquals(22, message.getInt32ToInt32Field().get(11).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(33).intValue()); - assertEquals(222, message.getInt32ToMessageField().get(111).getValue()); - assertEquals(444, message.getInt32ToMessageField().get(333).getValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue()); + assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue()); + assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue()); // Test addRepeatedField builder.addRepeatedField( @@ -726,8 +726,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -740,8 +740,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -755,9 +755,9 @@ public void testReflectionApi() throws Exception { builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32Field().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); } // See additional coverage in TextFormatTest.java. @@ -844,16 +844,16 @@ public void testUnknownEnumValues() throws Exception { TestMap message = TestMap.parseFrom(data); // Entries with unknown enum values will be stored into UnknownFieldSet so // there is only one entry in the map. - assertEquals(1, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); + assertEquals(1, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); // UnknownFieldSet should not be empty. assertFalse(message.getUnknownFields().asMap().isEmpty()); // Serializing and parsing should preserve the unknown entry. data = message.toByteString(); TestUnknownEnumValue messageWithUnknownEnums = TestUnknownEnumValue.parseFrom(data); - assertEquals(2, messageWithUnknownEnums.getInt32ToInt32Field().size()); - assertEquals(1, messageWithUnknownEnums.getInt32ToInt32Field().get(1).intValue()); - assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32Field().get(2).intValue()); + assertEquals(2, messageWithUnknownEnums.getInt32ToInt32FieldMap().size()); + assertEquals(1, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(54321, messageWithUnknownEnums.getInt32ToInt32FieldMap().get(2).intValue()); } public void testRequiredMessage() throws Exception { @@ -874,8 +874,8 @@ public void testRecursiveMap() throws Exception { ByteString data = builder.build().toByteString(); TestRecursiveMap message = TestRecursiveMap.parseFrom(data); - assertEquals(2, message.getRecursiveMapField().get(1).getValue()); - assertEquals(4, message.getRecursiveMapField().get(3).getValue()); + assertEquals(2, message.getRecursiveMapFieldMap().get(1).getValue()); + assertEquals(4, message.getRecursiveMapFieldMap().get(3).getValue()); } public void testIterationOrder() throws Exception { @@ -885,7 +885,7 @@ public void testIterationOrder() throws Exception { assertEquals( Arrays.asList("1", "2", "3"), - new ArrayList(message.getStringToInt32Field().keySet())); + new ArrayList(message.getStringToInt32FieldMap().keySet())); } public void testContains() { @@ -1172,9 +1172,9 @@ public void testGetMap() { setMapValuesUsingAccessors(builder); assertMapValuesSet(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } } diff --git a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java old mode 100755 new mode 100644 index d18fd13e0ace..33282add80d0 --- a/java/core/src/test/java/com/google/protobuf/MapLiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapLiteTest.java @@ -84,44 +84,44 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValues(TestMap.Builder builder) { @@ -159,49 +159,49 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -213,12 +213,12 @@ public void testSanityCopyOnWrite() throws InvalidProtocolBufferException { TestMap.Builder builder = TestMap.newBuilder(); TestMap message = builder.build(); builder.putInt32ToInt32Field(1, 2); - assertTrue(message.getInt32ToInt32Field().isEmpty()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertTrue(message.getInt32ToInt32FieldMap().isEmpty()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); message = builder.build(); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2), message.getInt32ToInt32Field()); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), message.getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); } public void testGetMapIsImmutable() { @@ -232,13 +232,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { @@ -266,30 +266,31 @@ public void testMapFieldClear() { public void testMutableMapLifecycle() { TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2); - assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field()); - assertEquals(newMap(1, 2), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2), builder.build().getInt32ToInt32FieldMap()); + assertEquals(newMap(1, 2), builder.getInt32ToInt32FieldMap()); builder.putInt32ToInt32Field(2, 3); - assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field()); + assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32FieldMap()); builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField()); - assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumFieldMap()); + assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumFieldMap()); builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO); assertEquals( - newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField()); + newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), + builder.getInt32ToEnumFieldMap()); builder.putInt32ToStringField(1, "1"); - assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField()); - assertEquals(newMap(1, "1"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1"), builder.build().getInt32ToStringFieldMap()); + assertEquals(newMap(1, "1"), builder.getInt32ToStringFieldMap()); builder.putInt32ToStringField(2, "2"); - assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField()); + assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringFieldMap()); builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap(1, TestMap.MessageValue.getDefaultInstance()), - builder.build().getInt32ToMessageField()); + builder.build().getInt32ToMessageFieldMap()); assertEquals( - newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField()); + newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageFieldMap()); builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance()); assertEquals( newMap( @@ -297,7 +298,7 @@ public void testMutableMapLifecycle() { TestMap.MessageValue.getDefaultInstance(), 2, TestMap.MessageValue.getDefaultInstance()), - builder.getInt32ToMessageField()); + builder.getInt32ToMessageFieldMap()); } public void testGettersAndSetters() throws Exception { @@ -342,12 +343,12 @@ public void testPutAllForUnknownEnumValues() throws Exception { TestMap source = sourceBuilder.build(); TestMap.Builder destinationBuilder = TestMap.newBuilder(); - destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()); + destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()); TestMap destination = destinationBuilder.build(); - assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue()); - assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue()); - assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue()); + assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue()); + assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue()); assertEquals(3, destination.getInt32ToEnumFieldCount()); } @@ -459,7 +460,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -524,24 +525,24 @@ public void testUnknownEnumValues() throws Exception { .putInt32ToEnumFieldValue(2, 1000); // unknown value. TestMap message = builder.build(); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); builder.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value. message = builder.build(); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); @@ -550,7 +551,7 @@ public void testUnknownEnumValues() throws Exception { assertFalse(message.equals(message2)); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField()); + assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); } public void testIterationOrder() throws Exception { @@ -559,18 +560,18 @@ public void testIterationOrder() throws Exception { TestMap message = builder.build(); assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet())); + Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); } public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValues(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java index 9f1ebaed692b..2f55328b5105 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -122,44 +122,44 @@ public void testSetMapValues() { private void copyMapValues(TestMap source, TestMap.Builder destination) { destination - .putAllInt32ToInt32Field(source.getInt32ToInt32Field()) - .putAllInt32ToStringField(source.getInt32ToStringField()) - .putAllInt32ToBytesField(source.getInt32ToBytesField()) - .putAllInt32ToEnumField(source.getInt32ToEnumField()) - .putAllInt32ToMessageField(source.getInt32ToMessageField()) - .putAllStringToInt32Field(source.getStringToInt32Field()); + .putAllInt32ToInt32Field(source.getInt32ToInt32FieldMap()) + .putAllInt32ToStringField(source.getInt32ToStringFieldMap()) + .putAllInt32ToBytesField(source.getInt32ToBytesFieldMap()) + .putAllInt32ToEnumField(source.getInt32ToEnumFieldMap()) + .putAllInt32ToMessageField(source.getInt32ToMessageFieldMap()) + .putAllStringToInt32Field(source.getStringToInt32FieldMap()); } private void assertMapValuesSet(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(11, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(22, message.getInt32ToInt32Field().get(2).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(2).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("11", message.getInt32ToStringField().get(1)); - assertEquals("22", message.getInt32ToStringField().get(2)); - assertEquals("33", message.getInt32ToStringField().get(3)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("11", message.getInt32ToStringFieldMap().get(1)); + assertEquals("22", message.getInt32ToStringFieldMap().get(2)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesFieldMap().get(2)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(11, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(22, message.getInt32ToMessageField().get(2).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(11, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(22, message.getInt32ToMessageFieldMap().get(2).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(11, message.getStringToInt32Field().get("1").intValue()); - assertEquals(22, message.getStringToInt32Field().get("2").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(11, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(22, message.getStringToInt32FieldMap().get("2").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); } private void updateMapValuesUsingMutableMap(TestMap.Builder builder) { @@ -239,49 +239,49 @@ public void testUpdateMapValues() { } private void assertMapValuesUpdated(TestMap message) { - assertEquals(3, message.getInt32ToInt32Field().size()); - assertEquals(111, message.getInt32ToInt32Field().get(1).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(3).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(4).intValue()); + assertEquals(3, message.getInt32ToInt32FieldMap().size()); + assertEquals(111, message.getInt32ToInt32FieldMap().get(1).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(3).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(4).intValue()); - assertEquals(3, message.getInt32ToStringField().size()); - assertEquals("111", message.getInt32ToStringField().get(1)); - assertEquals("33", message.getInt32ToStringField().get(3)); - assertEquals("44", message.getInt32ToStringField().get(4)); + assertEquals(3, message.getInt32ToStringFieldMap().size()); + assertEquals("111", message.getInt32ToStringFieldMap().get(1)); + assertEquals("33", message.getInt32ToStringFieldMap().get(3)); + assertEquals("44", message.getInt32ToStringFieldMap().get(4)); - assertEquals(3, message.getInt32ToBytesField().size()); - assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1)); - assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3)); - assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4)); + assertEquals(3, message.getInt32ToBytesFieldMap().size()); + assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesFieldMap().get(1)); + assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesFieldMap().get(3)); + assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesFieldMap().get(4)); - assertEquals(3, message.getInt32ToEnumField().size()); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3)); - assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4)); + assertEquals(3, message.getInt32ToEnumFieldMap().size()); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumFieldMap().get(3)); + assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumFieldMap().get(4)); - assertEquals(3, message.getInt32ToMessageField().size()); - assertEquals(111, message.getInt32ToMessageField().get(1).getValue()); - assertEquals(33, message.getInt32ToMessageField().get(3).getValue()); - assertEquals(44, message.getInt32ToMessageField().get(4).getValue()); + assertEquals(3, message.getInt32ToMessageFieldMap().size()); + assertEquals(111, message.getInt32ToMessageFieldMap().get(1).getValue()); + assertEquals(33, message.getInt32ToMessageFieldMap().get(3).getValue()); + assertEquals(44, message.getInt32ToMessageFieldMap().get(4).getValue()); - assertEquals(3, message.getStringToInt32Field().size()); - assertEquals(111, message.getStringToInt32Field().get("1").intValue()); - assertEquals(33, message.getStringToInt32Field().get("3").intValue()); - assertEquals(44, message.getStringToInt32Field().get("4").intValue()); + assertEquals(3, message.getStringToInt32FieldMap().size()); + assertEquals(111, message.getStringToInt32FieldMap().get("1").intValue()); + assertEquals(33, message.getStringToInt32FieldMap().get("3").intValue()); + assertEquals(44, message.getStringToInt32FieldMap().get("4").intValue()); } private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) { - assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToStringField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToStringFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount()); - assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size()); + assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldMap().size()); assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount()); - assertEquals(0, testMapOrBuilder.getStringToInt32Field().size()); + assertEquals(0, testMapOrBuilder.getStringToInt32FieldMap().size()); assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount()); } @@ -296,13 +296,13 @@ public void testGetMapIsImmutable() { } private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) { - assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2); - assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2"); - assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2")); - assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO); + assertImmutable(testMapOrBuilder.getInt32ToInt32FieldMap(), 1, 2); + assertImmutable(testMapOrBuilder.getInt32ToStringFieldMap(), 1, "2"); + assertImmutable(testMapOrBuilder.getInt32ToBytesFieldMap(), 1, TestUtil.toBytes("2")); + assertImmutable(testMapOrBuilder.getInt32ToEnumFieldMap(), 1, TestMap.EnumValue.FOO); assertImmutable( - testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance()); - assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2); + testMapOrBuilder.getInt32ToMessageFieldMap(), 1, MessageValue.getDefaultInstance()); + assertImmutable(testMapOrBuilder.getStringToInt32FieldMap(), "1", 2); } private void assertImmutable(Map map, K key, V value) { @@ -468,11 +468,13 @@ public void testPutAllForUnknownEnumValues() throws Exception { .build(); TestMap destination = - TestMap.newBuilder().putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue()).build(); + TestMap.newBuilder() + .putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValueMap()) + .build(); - assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue()); - assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue()); - assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(0, destination.getInt32ToEnumFieldValueMap().get(0).intValue()); + assertEquals(1, destination.getInt32ToEnumFieldValueMap().get(1).intValue()); + assertEquals(1000, destination.getInt32ToEnumFieldValueMap().get(2).intValue()); assertEquals(3, destination.getInt32ToEnumFieldCount()); } @@ -583,7 +585,7 @@ public void testParseError() throws Exception { } catch (InvalidProtocolBufferException expected) { assertTrue(expected.getUnfinishedMessage() instanceof TestMap); map = (TestMap) expected.getUnfinishedMessage(); - assertTrue(map.getInt32ToMessageField().isEmpty()); + assertTrue(map.getInt32ToMessageFieldMap().isEmpty()); } map = @@ -644,14 +646,14 @@ public void testNestedBuilderOnChangeEventPropagation() { TestOnChangeEventPropagation.Builder parent = TestOnChangeEventPropagation.newBuilder(); parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 2); TestOnChangeEventPropagation message = parent.build(); - assertEquals(2, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(2, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make a change using nested builder. parent.getOptionalMessageBuilder().putInt32ToInt32Field(1, 3); // Should be able to observe the change. message = parent.build(); - assertEquals(3, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(3, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make another change using mergeFrom() TestMap other = TestMap.newBuilder().putInt32ToInt32Field(1, 4).build(); @@ -659,14 +661,14 @@ public void testNestedBuilderOnChangeEventPropagation() { // Should be able to observe the change. message = parent.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Make yet another change by clearing the nested builder. parent.getOptionalMessageBuilder().clear(); // Should be able to observe the change. message = parent.build(); - assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); } public void testNestedBuilderOnChangeEventPropagationReflection() { @@ -683,7 +685,7 @@ public void testNestedBuilderOnChangeEventPropagationReflection() { // Should be able to observe the change. TestOnChangeEventPropagation message = parentBuilder.build(); - assertEquals(1, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(1, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); // Change the entry value. entryBuilder.putInt32ToInt32Field(1, 4); @@ -692,7 +694,7 @@ public void testNestedBuilderOnChangeEventPropagationReflection() { // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(4, message.getOptionalMessage().getInt32ToInt32Field().get(1).intValue()); + assertEquals(4, message.getOptionalMessage().getInt32ToInt32FieldMap().get(1).intValue()); // Clear the nested builder. testMapBuilder = parentBuilder.getOptionalMessageBuilder(); @@ -700,7 +702,7 @@ public void testNestedBuilderOnChangeEventPropagationReflection() { // Should be able to observe the change. message = parentBuilder.build(); - assertEquals(0, message.getOptionalMessage().getInt32ToInt32Field().size()); + assertEquals(0, message.getOptionalMessage().getInt32ToInt32FieldMap().size()); } // The following methods are used to test reflection API. @@ -789,8 +791,8 @@ public void testReflectionApi() throws Exception { builder.clearField(f("int32_to_int32_field")); builder.clearField(f("int32_to_message_field")); message = builder.build(); - assertEquals(0, message.getInt32ToInt32Field().size()); - assertEquals(0, message.getInt32ToMessageField().size()); + assertEquals(0, message.getInt32ToInt32FieldMap().size()); + assertEquals(0, message.getInt32ToMessageFieldMap().size()); // Test setField() setMapValues(builder, "int32_to_int32_field", mapForValues(11, 22, 33, 44)); @@ -801,10 +803,10 @@ public void testReflectionApi() throws Exception { 111, MessageValue.newBuilder().setValue(222).build(), 333, MessageValue.newBuilder().setValue(444).build())); message = builder.build(); - assertEquals(22, message.getInt32ToInt32Field().get(11).intValue()); - assertEquals(44, message.getInt32ToInt32Field().get(33).intValue()); - assertEquals(222, message.getInt32ToMessageField().get(111).getValue()); - assertEquals(444, message.getInt32ToMessageField().get(333).getValue()); + assertEquals(22, message.getInt32ToInt32FieldMap().get(11).intValue()); + assertEquals(44, message.getInt32ToInt32FieldMap().get(33).intValue()); + assertEquals(222, message.getInt32ToMessageFieldMap().get(111).getValue()); + assertEquals(444, message.getInt32ToMessageFieldMap().get(333).getValue()); // Test addRepeatedField builder.addRepeatedField( @@ -817,8 +819,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(666).build())); message = builder.build(); - assertEquals(66, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(666, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(66, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(666, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test addRepeatedField (overriding existing values) builder.addRepeatedField( @@ -831,8 +833,8 @@ public void testReflectionApi() throws Exception { 555, MessageValue.newBuilder().setValue(555).build())); message = builder.build(); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); - assertEquals(555, message.getInt32ToMessageField().get(555).getValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); + assertEquals(555, message.getInt32ToMessageFieldMap().get(555).getValue()); // Test setRepeatedField for (int i = 0; i < builder.getRepeatedFieldCount(f("int32_to_int32_field")); i++) { @@ -846,9 +848,9 @@ public void testReflectionApi() throws Exception { builder.setRepeatedField(f("int32_to_int32_field"), i, mapEntryBuilder.build()); } message = builder.build(); - assertEquals(11, message.getInt32ToInt32Field().get(22).intValue()); - assertEquals(33, message.getInt32ToInt32Field().get(44).intValue()); - assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); + assertEquals(11, message.getInt32ToInt32FieldMap().get(22).intValue()); + assertEquals(33, message.getInt32ToInt32FieldMap().get(44).intValue()); + assertEquals(55, message.getInt32ToInt32FieldMap().get(55).intValue()); } // See additional coverage in TextFormatTest.java. @@ -937,21 +939,21 @@ public void testUnknownEnumValues() throws Exception { 2, 1000)); // unknown value. TestMap message = builder.build(); - assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0)); - assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1)); - assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2)); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumFieldMap().get(0)); + assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumFieldMap().get(1)); + assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumFieldMap().get(2)); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); // Unknown enum values should be preserved after: // 1. Serialization and parsing. // 2. toBuild(). // 3. mergeFrom(). message = TestMap.parseFrom(message.toByteString()); - assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, message.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = message.toBuilder(); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); builder = TestMap.newBuilder().mergeFrom(message); - assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue()); + assertEquals(1000, builder.getInt32ToEnumFieldValueMap().get(2).intValue()); // hashCode()/equals() should take unknown enum values into account. builder.putAllInt32ToEnumFieldValue(newMap(2, 1001)); @@ -960,7 +962,7 @@ public void testUnknownEnumValues() throws Exception { assertFalse(message.equals(message2)); // Unknown values will be converted to UNRECOGNIZED so the resulted enum map // should be the same. - assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField()); + assertEquals(message2.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); } public void testUnknownEnumValuesInReflectionApi() throws Exception { @@ -991,7 +993,7 @@ public void testUnknownEnumValuesInReflectionApi() throws Exception { // Verify that enum values have been successfully updated. TestMap message = builder.build(); - for (Map.Entry entry : message.getInt32ToEnumFieldValue().entrySet()) { + for (Map.Entry entry : message.getInt32ToEnumFieldValueMap().entrySet()) { assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue()); } } @@ -1002,18 +1004,18 @@ public void testIterationOrder() throws Exception { TestMap message = builder.build(); assertEquals( - Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet())); + Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32FieldMap().keySet())); } public void testGetMap() { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); TestMap message = builder.build(); - assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap()); - assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap()); - assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap()); - assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap()); - assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap()); + assertEquals(message.getStringToInt32FieldMap(), message.getStringToInt32FieldMap()); + assertEquals(message.getInt32ToBytesFieldMap(), message.getInt32ToBytesFieldMap()); + assertEquals(message.getInt32ToEnumFieldMap(), message.getInt32ToEnumFieldMap()); + assertEquals(message.getInt32ToEnumFieldValueMap(), message.getInt32ToEnumFieldValueMap()); + assertEquals(message.getInt32ToMessageFieldMap(), message.getInt32ToMessageFieldMap()); } public void testContains() { diff --git a/java/core/src/test/java/com/google/protobuf/PackedFieldTest.java b/java/core/src/test/java/com/google/protobuf/PackedFieldTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java b/java/core/src/test/java/com/google/protobuf/ParserLiteTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java b/java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto2LiteSchemaTest.java b/java/core/src/test/java/com/google/protobuf/Proto2LiteSchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto2MessageFactory.java b/java/core/src/test/java/com/google/protobuf/Proto2MessageFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java b/java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto2MessageLiteFactory.java b/java/core/src/test/java/com/google/protobuf/Proto2MessageLiteFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto2SchemaTest.java b/java/core/src/test/java/com/google/protobuf/Proto2SchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java b/java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto3LiteSchemaTest.java b/java/core/src/test/java/com/google/protobuf/Proto3LiteSchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto3MessageFactory.java b/java/core/src/test/java/com/google/protobuf/Proto3MessageFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java b/java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto3MessageLiteFactory.java b/java/core/src/test/java/com/google/protobuf/Proto3MessageLiteFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java b/java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Proto3SchemaTest.java b/java/core/src/test/java/com/google/protobuf/Proto3SchemaTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/TestSchemas.java b/java/core/src/test/java/com/google/protobuf/TestSchemas.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/TestSchemasLite.java b/java/core/src/test/java/com/google/protobuf/TestSchemasLite.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java index 22c0be25226c..d3f0b0eda968 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java @@ -260,8 +260,8 @@ private TestUtil() {} TestRequired.newBuilder().setA(1).setB(2).setC(3).build(); /** Helper to convert a String to ByteString. */ - static ByteString toBytes(String str) { - return ByteString.copyFrom(str.getBytes(Internal.UTF_8)); + public static ByteString toBytes(String str) { + return ByteString.copyFromUtf8(str); } // BEGIN FULL-RUNTIME diff --git a/java/core/src/test/java/com/google/protobuf/TestUtilLite.java b/java/core/src/test/java/com/google/protobuf/TestUtilLite.java index 31565fc40a64..993dd9defb2c 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtilLite.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtilLite.java @@ -142,8 +142,8 @@ public final class TestUtilLite { private TestUtilLite() {} /** Helper to convert a String to ByteString. */ - static ByteString toBytes(String str) { - return ByteString.copyFrom(str.getBytes(Internal.UTF_8)); + public static ByteString toBytes(String str) { + return ByteString.copyFromUtf8(str); } /** diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index dd0e8c847cc8..915dddf39218 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -30,6 +30,7 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED; import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED; @@ -40,6 +41,8 @@ import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy; +import com.google.protobuf.testing.proto.TestProto3Optional; +import com.google.protobuf.testing.proto.TestProto3Optional.NestedEnum; import any_test.AnyTestProto.TestAny; import map_test.MapTestProto.TestMap; import protobuf_unittest.UnittestMset.TestMessageSetExtension1; @@ -319,6 +322,24 @@ public void testPrintExotic() throws Exception { assertEquals(canonicalExoticText, message.toString()); } + public void testRoundtripProto3Optional() throws Exception { + Message message = + TestProto3Optional.newBuilder() + .setOptionalInt32(1) + .setOptionalInt64(2) + .setOptionalNestedEnum(NestedEnum.BAZ) + .build(); + TestProto3Optional.Builder message2 = TestProto3Optional.newBuilder(); + TextFormat.merge(message.toString(), message2); + + assertTrue(message2.hasOptionalInt32()); + assertTrue(message2.hasOptionalInt64()); + assertTrue(message2.hasOptionalNestedEnum()); + assertEquals(1, message2.getOptionalInt32()); + assertEquals(2, message2.getOptionalInt64()); + assertEquals(NestedEnum.BAZ, message2.getOptionalNestedEnum()); + } + public void testPrintMessageSet() throws Exception { TestMessageSet messageSet = TestMessageSet.newBuilder() @@ -846,6 +867,12 @@ public void testEscape() throws Exception { assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\341\\210\\264")); assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4")); assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\xe1\\x88\\xb4")); + assertEquals("\u1234", TextFormat.unescapeText("\\u1234")); + assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\u1234")); + assertEquals(bytes(0xe1, 0x88, 0xb4), TextFormat.unescapeBytes("\\U00001234")); + assertEquals( + new String(new int[] {0x10437}, 0, 1), TextFormat.unescapeText("\\xf0\\x90\\x90\\xb7")); + assertEquals(bytes(0xf0, 0x90, 0x90, 0xb7), TextFormat.unescapeBytes("\\U00010437")); // Handling of strings with unescaped Unicode characters > 255. final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c"; @@ -873,6 +900,87 @@ public void testEscape() throws Exception { } catch (TextFormat.InvalidEscapeSequenceException e) { // success } + + try { + TextFormat.unescapeText("\\u"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\ud800"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\ud800\\u1234"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\udc00"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\ud801\\udc37"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\u' refers to a surrogate"); + } + + try { + TextFormat.unescapeText("\\U1234"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\U1234no more hex"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U' with too few hex chars"); + } + + try { + TextFormat.unescapeText("\\U00110000"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U00110000' is not a valid code point value"); + } + + try { + TextFormat.unescapeText("\\U0000d801\\U00000dc37"); + fail("Should have thrown an exception."); + } catch (TextFormat.InvalidEscapeSequenceException e) { + assertThat(e) + .hasMessageThat() + .isEqualTo("Invalid escape sequence: '\\U0000d801' refers to a surrogate code unit"); + } } public void testParseInteger() throws Exception { @@ -1384,6 +1492,27 @@ public void testMapTextFormat() throws Exception { } } + public void testMapDuplicateKeys() throws Exception { + String input = + "int32_to_int32_field: {\n" + + " key: 1\n" + + " value: 1\n" + + "}\n" + + "int32_to_int32_field: {\n" + + " key: -2147483647\n" + + " value: 5\n" + + "}\n" + + "int32_to_int32_field: {\n" + + " key: 1\n" + + " value: -1\n" + + "}\n"; + TestMap msg = TextFormat.parse(input, TestMap.class); + int i1 = msg.getInt32ToInt32Field().get(1); + TestMap msg2 = TextFormat.parse(msg.toString(), TestMap.class); + int i2 = msg2.getInt32ToInt32Field().get(1); + assertEquals(i1, i2); + } + public void testMapShortForm() throws Exception { String text = "string_to_int32_field [{ key: 'x' value: 10 }, { key: 'y' value: 20 }]\n" @@ -1437,11 +1566,23 @@ public void testMapOverwrite() throws Exception { // With overwrite forbidden, same behavior. // TODO(b/29122459): Expect parse exception here. TestMap.Builder builder = TestMap.newBuilder(); - defaultParser.merge(text, builder); + parserWithOverwriteForbidden.merge(text, builder); TestMap map = builder.build(); assertEquals(2, map.getInt32ToInt32Field().size()); assertEquals(30, map.getInt32ToInt32Field().get(1).intValue()); } + + { + // With overwrite forbidden and a dynamic message, same behavior. + // TODO(b/29122459): Expect parse exception here. + Message.Builder builder = DynamicMessage.newBuilder(TestMap.getDescriptor()); + parserWithOverwriteForbidden.merge(text, builder); + TestMap map = + TestMap.parseFrom( + builder.build().toByteString(), ExtensionRegistryLite.getEmptyRegistry()); + assertEquals(2, map.getInt32ToInt32Field().size()); + assertEquals(30, map.getInt32ToInt32Field().get(1).intValue()); + } } // ======================================================================= @@ -1536,4 +1677,42 @@ private void assertLocation( index, line, column)); } } + + public void testSortMapFields() throws Exception { + TestMap message = + TestMap.newBuilder() + .putStringToInt32Field("cherry", 30) + .putStringToInt32Field("banana", 20) + .putStringToInt32Field("apple", 10) + .putInt32ToStringField(30, "cherry") + .putInt32ToStringField(20, "banana") + .putInt32ToStringField(10, "apple") + .build(); + String text = + "int32_to_string_field {\n" + + " key: 10\n" + + " value: \"apple\"\n" + + "}\n" + + "int32_to_string_field {\n" + + " key: 20\n" + + " value: \"banana\"\n" + + "}\n" + + "int32_to_string_field {\n" + + " key: 30\n" + + " value: \"cherry\"\n" + + "}\n" + + "string_to_int32_field {\n" + + " key: \"apple\"\n" + + " value: 10\n" + + "}\n" + + "string_to_int32_field {\n" + + " key: \"banana\"\n" + + " value: 20\n" + + "}\n" + + "string_to_int32_field {\n" + + " key: \"cherry\"\n" + + " value: 30\n" + + "}\n"; + assertEquals(text, TextFormat.printer().printToString(message)); + } } diff --git a/java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java b/java/core/src/test/java/com/google/protobuf/TypeRegistryTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Utf8Test.java b/java/core/src/test/java/com/google/protobuf/Utf8Test.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/Utf8Utils.java b/java/core/src/test/java/com/google/protobuf/Utf8Utils.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java b/java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java b/java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java b/java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/cached_field_size_test.proto b/java/core/src/test/proto/com/google/protobuf/cached_field_size_test.proto old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto b/java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/packed_field_test.proto b/java/core/src/test/proto/com/google/protobuf/packed_field_test.proto old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/proto2_message.proto b/java/core/src/test/proto/com/google/protobuf/proto2_message.proto old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/proto2_message_lite.proto b/java/core/src/test/proto/com/google/protobuf/proto2_message_lite.proto old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/proto3_message.proto b/java/core/src/test/proto/com/google/protobuf/proto3_message.proto old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/proto3_message_lite.proto b/java/core/src/test/proto/com/google/protobuf/proto3_message_lite.proto old mode 100755 new mode 100644 diff --git a/java/core/src/test/proto/com/google/protobuf/wrappers_test.proto b/java/core/src/test/proto/com/google/protobuf/wrappers_test.proto old mode 100755 new mode 100644 diff --git a/java/lite.md b/java/lite.md index 5cbfbb1d5fd6..f248ff6c3e82 100644 --- a/java/lite.md +++ b/java/lite.md @@ -34,6 +34,22 @@ protobuf Java runtime. If you are using Maven, use the following: ``` +## R8 rule to make production app builds work + +The Lite runtime internally uses reflection to avoid generating hashCode/equals/(de)serialization methods. +R8 by default obfuscates the field names, which makes the reflection fail causing exceptions of the form +`java.lang.RuntimeException: Field {NAME}_ for {CLASS} not found. Known fields are [ {FIELDS} ]` in MessageSchema.java. + +There are open issues for this on the [protobuf Github project](https://github.com/protocolbuffers/protobuf/issues/6463) and [R8](https://issuetracker.google.com/issues/144631039). + +Until the issues is resolved you need to add the following line to your `proguard-rules.pro` file inside your project: + +``` +-keep class * extends com.google.protobuf.GeneratedMessageLite { *; } +``` + +## Older versions + For the older version of Java Lite (v3.0.0), please refer to: https://github.com/protocolbuffers/protobuf/blob/javalite/java/lite.md diff --git a/java/lite/BUILD b/java/lite/BUILD new file mode 100644 index 000000000000..22840ec48c8a --- /dev/null +++ b/java/lite/BUILD @@ -0,0 +1,14 @@ +load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") + +alias( + name = "lite", + actual = "//java/core:lite", + visibility = ["//visibility:public"], +) + +proto_lang_toolchain( + name = "toolchain", + command_line = "--java_out=lite:$(OUT)", + runtime = ":lite", + visibility = ["//visibility:public"], +) diff --git a/java/lite/generate-test-sources-build.xml b/java/lite/generate-test-sources-build.xml index 1c1a18c544b6..62bca93c86f9 100644 --- a/java/lite/generate-test-sources-build.xml +++ b/java/lite/generate-test-sources-build.xml @@ -15,6 +15,7 @@ + diff --git a/java/lite/pom.xml b/java/lite/pom.xml index 81e052104f35..104c5c1676ac 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.11.2 + 3.14.0 protobuf-javalite @@ -52,6 +52,7 @@ google/protobuf/any.proto google/protobuf/api.proto + google/protobuf/duration.proto google/protobuf/empty.proto google/protobuf/field_mask.proto google/protobuf/source_context.proto @@ -89,7 +90,7 @@ ${basedir}/../core/src/main/java/com/google/protobuf - + AbstractMessageLite.java AbstractParser.java AbstractProtobufList.java diff --git a/java/lite/proguard.pgcfg b/java/lite/proguard.pgcfg old mode 100755 new mode 100644 diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java old mode 100755 new mode 100644 index 3e39bc7c8b4e..140df7270fc2 --- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java @@ -42,6 +42,7 @@ import com.google.protobuf.UnittestLite.TestAllTypesLite; import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedEnum; import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage; +import com.google.protobuf.UnittestLite.TestAllTypesLite.NestedMessage2; import com.google.protobuf.UnittestLite.TestAllTypesLite.OneofFieldCase; import com.google.protobuf.UnittestLite.TestAllTypesLite.OptionalGroup; import com.google.protobuf.UnittestLite.TestAllTypesLite.RepeatedGroup; @@ -1354,6 +1355,45 @@ public void testBuilderMergeFromWithUnknownFields() throws Exception { assertEquals(message.getSerializedSize() * 2, result.getSerializedSize()); } + public void testMergeFrom_differentFieldsSetWithinOneField() throws Exception { + TestAllTypesLite result = + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2)) + .mergeFrom( + TestAllTypesLite.newBuilder() + .setOneofNestedMessage2(NestedMessage2.newBuilder().setDd(3)) + .build()) + .build(); + + assertToStringEquals("oneof_nested_message2 {\n dd: 3\n}", result); + } + + public void testMergeFrom_differentFieldsOfSameTypeSetWithinOneField() throws Exception { + TestAllTypesLite result = + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2)) + .mergeFrom( + TestAllTypesLite.newBuilder() + .setOneofLazyNestedMessage(NestedMessage.newBuilder().setCc(3)) + .build()) + .build(); + + assertToStringEquals("oneof_lazy_nested_message {\n cc: 3\n}", result); + } + + public void testMergeFrom_sameFieldSetWithinOneofField() throws Exception { + TestAllTypesLite result = + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setBb(2)) + .mergeFrom( + TestAllTypesLite.newBuilder() + .setOneofNestedMessage(NestedMessage.newBuilder().setCc(4)) + .build()) + .build(); + + assertToStringEquals("oneof_nested_message {\n bb: 2\n cc: 4\n}", result); + } + public void testToStringDefaultInstance() throws Exception { assertToStringEquals("", TestAllTypesLite.getDefaultInstance()); } diff --git a/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java b/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java old mode 100755 new mode 100644 index 4a1d89b93704..a17dda5c1f17 --- a/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java +++ b/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java @@ -174,19 +174,24 @@ private MessageInfo newRawMessageInfoForProto2MessageLite() { "fieldRequiredSint6487_", "fieldRequiredGroup88_", }; - // To update this after a proto change, run protoc on proto2_message_lite.proto and copy over - // the content of the generated buildMessageInfo() method here. + // To update this after a proto change, run blaze build on proto2_message_lite.proto and copy + // over the String info from the proto2_message_lite_proto-lite-src.jar file in the + // blaze-genfiles directory. java.lang.String info = - "\u0001U\u0001\u0002\u0001XU\u0000 \u0015\u0001\u0000\u0000\u0002\u0001\u0001\u0003" - + "\u0002\u0002\u0004\u0003\u0003\u0005\u0004\u0004\u0006\u0005\u0005\u0007\u0006\u0006" - + "\b\u0007\u0007\t\b\b\n\u0409\t\u000b\n\n\f\u000b\u000b\r\f\f\u000e\r\r\u000f\u000e" - + "\u000e\u0010\u000f\u000f\u0011\u0010\u0010\u0012\u0012\u0013\u0013\u0014\u0014\u0015" - + "\u0015\u0016\u0016\u0017\u0017\u0018\u0018\u0019\u0019\u001a\u001a\u001b\u041b\u001c" - + "\u001c\u001d\u001d\u001e\u001e\u001f\u001f !!\"\"##$$%%&&\'\'(())**++,,--..//00" - + "1\u0011\u00113153\u000064\u000075\u000086\u000097\u0000:8\u0000;9\u0000<:\u0000=" - + ";\u0000>\u043c\u0000?=\u0000@>\u0000A@\u0000BA\u0000CB\u0000DC\u0000ED\u0000G\u0500" - + "#H\u0501$I\u0502%J\u0503&K\u0504\'L\u0505(M\u0506)N\u0507*O\u0508+P\u0509,Q\u050a" - + "-R\u050b.S\u050c/T\u050d0U\u050e1V\u050f2W\u05103X\u05114"; + "\u0001U\u0001\u0002\u0001XU\u0000 \u0015\u0001\u1000\u0000\u0002\u1001\u0001\u0003" + + "\u1002\u0002\u0004\u1003\u0003\u0005\u1004\u0004\u0006\u1005\u0005\u0007\u1006\u0006\b\u1007\u0007" + + "\t\u1008\b\n" + + "\u1409\t\u000b\u100a\n" + + "\f\u100b\u000b\r" + + "\u100c\f\u000e\u100d\r" + + "\u000f\u100e\u000e\u0010\u100f\u000f\u0011\u1010\u0010\u0012\u0012\u0013\u0013" + + "\u0014\u0014\u0015\u0015\u0016\u0016\u0017\u0017\u0018\u0018\u0019\u0019\u001a\u001a\u001b\u041b\u001c\u001c\u001d\u001d\u001e\u001e\u001f\u001f" + + " !!\"\"##$$%%&&\'\'" + + "(())**++,,--..//001\u1011\u0011315\u1033\u00006\u1034\u00007\u1035\u00008\u1036\u0000" + + "9\u1037\u0000:\u1038\u0000;\u1039\u0000<\u103a\u0000=\u103b\u0000>\u143c\u0000?\u103d" + + "\u0000@\u103e\u0000A\u1040\u0000B\u1041\u0000C\u1042\u0000D\u1043\u0000E\u1044\u0000" + + "G\u1500#H\u1501$I\u1502%J\u1503&K\u1504\'L\u1505(M\u1506)N\u1507*O\u1508+P\u1509" + + ",Q\u150a-R\u150b.S\u150c/T\u150d0U\u150e1V\u150f2W\u15103X\u15114"; return new RawMessageInfo(Proto2MessageLite.getDefaultInstance(), info, objects); } diff --git a/java/pom.xml b/java/pom.xml index 8d07e0825851..3283268afcb4 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.11.2 + 3.14.0 pom Protocol Buffers [Parent] @@ -75,7 +75,7 @@ junit junit - 4.13 + 4.13.1 test @@ -93,12 +93,12 @@ com.google.guava guava - 28.2-android + 29.0-android com.google.guava guava-testlib - 28.2-android + 29.0-android test diff --git a/java/util/BUILD b/java/util/BUILD new file mode 100644 index 000000000000..71f73bab10dc --- /dev/null +++ b/java/util/BUILD @@ -0,0 +1,16 @@ +load("@rules_java//java:defs.bzl", "java_library") + +java_library( + name = "util", + srcs = glob([ + "src/main/java/com/google/protobuf/util/*.java", + ]), + visibility = ["//visibility:public"], + deps = [ + "//external:error_prone_annotations", + "//external:gson", + "//external:guava", + "//java/core", + "//java/lite", + ], +) diff --git a/java/util/pom.xml b/java/util/pom.xml index 56d648884af6..75457fbc8ea7 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.11.2 + 3.14.0 protobuf-java-util diff --git a/java/util/src/main/java/com/google/protobuf/util/Durations.java b/java/util/src/main/java/com/google/protobuf/util/Durations.java index 1edc8f0af259..747096082176 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Durations.java +++ b/java/util/src/main/java/com/google/protobuf/util/Durations.java @@ -44,6 +44,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.Duration; +import java.io.Serializable; import java.text.ParseException; import java.util.Comparator; @@ -72,23 +73,25 @@ public final class Durations { private Durations() {} - private static final Comparator COMPARATOR = - new Comparator() { - @Override - public int compare(Duration d1, Duration d2) { - checkValid(d1); - checkValid(d2); - int secDiff = Long.compare(d1.getSeconds(), d2.getSeconds()); - return (secDiff != 0) ? secDiff : Integer.compare(d1.getNanos(), d2.getNanos()); - } - }; + private static enum DurationComparator implements Comparator, Serializable { + INSTANCE; + + @Override + public int compare(Duration d1, Duration d2) { + checkValid(d1); + checkValid(d2); + int secDiff = Long.compare(d1.getSeconds(), d2.getSeconds()); + return (secDiff != 0) ? secDiff : Integer.compare(d1.getNanos(), d2.getNanos()); + } + } /** * Returns a {@link Comparator} for {@link Duration}s which sorts in increasing chronological - * order. Nulls and invalid {@link Duration}s are not allowed (see {@link #isValid}). + * order. Nulls and invalid {@link Duration}s are not allowed (see {@link #isValid}). The returned + * comparator is serializable. */ public static Comparator comparator() { - return COMPARATOR; + return DurationComparator.INSTANCE; } /** @@ -99,7 +102,7 @@ public static Comparator comparator() { * and a value greater than {@code 0} if {@code x > y} */ public static int compare(Duration x, Duration y) { - return COMPARATOR.compare(x, y); + return DurationComparator.INSTANCE.compare(x, y); } /** diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java index d07731d248bc..352376e01509 100644 --- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java +++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java @@ -30,6 +30,7 @@ package com.google.protobuf.util; +import com.google.common.base.Splitter; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; @@ -66,7 +67,7 @@ final class FieldMaskTree { private static final String FIELD_PATH_SEPARATOR_REGEX = "\\."; private static final class Node { - final SortedMap children = new TreeMap(); + final SortedMap children = new TreeMap<>(); } private final Node root = new Node(); @@ -97,6 +98,7 @@ public String toString() { * to add is a sub-path of an existing leaf node, nothing will be changed in the tree. */ @CanIgnoreReturnValue + @SuppressWarnings("StringSplitter") FieldMaskTree addFieldPath(String path) { String[] parts = path.split(FIELD_PATH_SEPARATOR_REGEX); if (parts.length == 0) { @@ -134,6 +136,65 @@ FieldMaskTree mergeFromFieldMask(FieldMask mask) { return this; } + /** + * Removes {@code path} from the tree. + * + *

      + * When removing a field path from the tree: + *
    • All sub-paths will be removed. That is, after removing "foo.bar" from the tree, + * "foo.bar.baz" will be removed. + *
    • If all children of a node has been removed, the node itself will be removed as well. + * That is, if "foo" only has one child "bar" and "foo.bar" only has one child "baz", + * removing "foo.bar.barz" would remove both "foo" and "foo.bar". + * If "foo" has both "bar" and "qux" as children, removing "foo.bar" would leave the path + * "foo.qux" intact. + *
    • If the field path to remove is a non-exist sub-path, nothing will be changed. + *
    + */ + @CanIgnoreReturnValue + FieldMaskTree removeFieldPath(String path) { + List parts = Splitter.onPattern(FIELD_PATH_SEPARATOR_REGEX).splitToList(path); + if (parts.isEmpty()) { + return this; + } + removeFieldPath(root, parts, 0); + return this; + } + + /** + * Removes {@code parts} from {@code node} recursively. + * + * @return a boolean value indicating whether current {@code node} should be removed. + */ + @CanIgnoreReturnValue + private static boolean removeFieldPath(Node node, List parts, int index) { + String key = parts.get(index); + + // Base case 1: path not match. + if (!node.children.containsKey(key)) { + return false; + } + // Base case 2: last element in parts. + if (index == parts.size() - 1) { + node.children.remove(key); + return node.children.isEmpty(); + } + // Recursive remove sub-path. + if (removeFieldPath(node.children.get(key), parts, index + 1)) { + node.children.remove(key); + } + return node.children.isEmpty(); + } + + /** Removes all field paths in {@code mask} from this tree. */ + @CanIgnoreReturnValue + FieldMaskTree removeFromFieldMask(FieldMask mask) { + for (String path : mask.getPathsList()) { + removeFieldPath(path); + } + return this; + } + /** * Converts this tree to a FieldMask. */ @@ -141,15 +202,13 @@ FieldMask toFieldMask() { if (root.children.isEmpty()) { return FieldMask.getDefaultInstance(); } - List paths = new ArrayList(); + List paths = new ArrayList<>(); getFieldPaths(root, "", paths); return FieldMask.newBuilder().addAllPaths(paths).build(); } - /** - * Gathers all field paths in a sub-tree. - */ - private void getFieldPaths(Node node, String path, List paths) { + /** Gathers all field paths in a sub-tree. */ + private static void getFieldPaths(Node node, String path, List paths) { if (node.children.isEmpty()) { paths.add(path); return; @@ -186,7 +245,7 @@ void intersectFieldPath(String path, FieldMaskTree output) { } // We found a matching node for the path. All leaf children of this matching // node is in the intersection. - List paths = new ArrayList(); + List paths = new ArrayList<>(); getFieldPaths(node, path, paths); for (String value : paths) { output.addFieldPath(value); @@ -206,10 +265,8 @@ void merge(Message source, Message.Builder destination, FieldMaskUtil.MergeOptio merge(root, "", source, destination, options); } - /** - * Merges all fields specified by a sub-tree from {@code source} to {@code destination}. - */ - private void merge( + /** Merges all fields specified by a sub-tree from {@code source} to {@code destination}. */ + private static void merge( Node node, String path, Message source, diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java index 92458226ab59..c32d10a2639c 100644 --- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java +++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java @@ -34,6 +34,7 @@ import com.google.common.base.CaseFormat; import com.google.common.base.Joiner; +import com.google.common.base.Optional; import com.google.common.base.Splitter; import com.google.common.primitives.Ints; import com.google.errorprone.annotations.CanIgnoreReturnValue; @@ -49,7 +50,7 @@ /** * Utility helper functions to work with {@link com.google.protobuf.FieldMask}. */ -public class FieldMaskUtil { +public final class FieldMaskUtil { private static final String FIELD_PATH_SEPARATOR = ","; private static final String FIELD_PATH_SEPARATOR_REGEX = ","; private static final String FIELD_SEPARATOR_REGEX = "\\."; @@ -83,7 +84,7 @@ public static String toString(FieldMask fieldMask) { */ public static FieldMask fromString(String value) { // TODO(xiaofeng): Consider using com.google.common.base.Splitter here instead. - return fromStringList(null, Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX))); + return fromStringList(Arrays.asList(value.split(FIELD_PATH_SEPARATOR_REGEX))); } /** @@ -103,14 +104,36 @@ public static FieldMask fromString(Class type, String value) */ // TODO(xiaofeng): Consider renaming fromStrings() public static FieldMask fromStringList(Class type, Iterable paths) { + return fromStringList(Internal.getDefaultInstance(type).getDescriptorForType(), paths); + } + + /** + * Constructs a FieldMask for a list of field paths in a certain type. + * + * @throws IllegalArgumentException if any of the field path is not valid. + */ + public static FieldMask fromStringList(Descriptor descriptor, Iterable paths) { + return fromStringList(Optional.of(descriptor), paths); + } + + /** + * Constructs a FieldMask for a list of field paths in a certain type. Does not validate the given + * paths. + */ + public static FieldMask fromStringList(Iterable paths) { + return fromStringList(Optional.absent(), paths); + } + + private static FieldMask fromStringList(Optional descriptor, Iterable paths) { FieldMask.Builder builder = FieldMask.newBuilder(); for (String path : paths) { if (path.isEmpty()) { // Ignore empty field paths. continue; } - if (type != null && !isValid(type, path)) { - throw new IllegalArgumentException(path + " is not a valid path for " + type); + if (descriptor.isPresent() && !isValid(descriptor.get(), path)) { + throw new IllegalArgumentException( + path + " is not a valid path for " + descriptor.get().getFullName()); } builder.addPaths(path); } @@ -253,6 +276,22 @@ public static FieldMask union( return maskTree.toFieldMask(); } + /** + * Subtracts {@code secondMask} and {@code otherMasks} from {@code firstMask}. + * + *

    This method disregards proto structure. That is, if {@code firstMask} is "foo" and {@code + * secondMask} is "foo.bar", the response will always be "foo" without considering the internal + * proto structure of message "foo". + */ + public static FieldMask subtract( + FieldMask firstMask, FieldMask secondMask, FieldMask... otherMasks) { + FieldMaskTree maskTree = new FieldMaskTree(firstMask).removeFromFieldMask(secondMask); + for (FieldMask mask : otherMasks) { + maskTree.removeFromFieldMask(mask); + } + return maskTree.toFieldMask(); + } + /** * Calculates the intersection of two FieldMasks. */ diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index d9bcf8970ac7..4f2fe3fcfa4b 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -233,7 +233,7 @@ public Printer printingEnumsAsInts() { registry, oldRegistry, alwaysOutputDefaultValueFields, - Collections.emptySet(), + includingDefaultValueFields, preservingProtoFieldNames, omittingInsignificantWhitespace, true, @@ -328,14 +328,13 @@ public Printer omittingInsignificantWhitespace() { /** * Create a new {@link Printer} that will sort the map keys in the JSON output. * - * Use of this modifier is discouraged, the generated JSON messages are equivalent - * with and without this option set, but there are some corner caseuse cases that - * demand a stable output, while order of map keys is otherwise arbitrary. + *

    Use of this modifier is discouraged, the generated JSON messages are equivalent with and + * without this option set, but there are some corner use cases that demand a stable output, + * while order of map keys is otherwise arbitrary. * - * The generated order is not well-defined and should not be depended on, but - * it's stable. + *

    The generated order is not well-defined and should not be depended on, but it's stable. * - * This new Printer clones all other configurations from the current {@link Printer}. + *

    This new Printer clones all other configurations from the current {@link Printer}. */ public Printer sortingMapKeys() { return new Printer( @@ -526,7 +525,6 @@ public Descriptor find(String name) { return types.get(name); } - /* @Nullable */ Descriptor getDescriptorForTypeUrl(String typeUrl) throws InvalidProtocolBufferException { return find(getTypeName(typeUrl)); } diff --git a/java/util/src/main/java/com/google/protobuf/util/Structs.java b/java/util/src/main/java/com/google/protobuf/util/Structs.java old mode 100755 new mode 100644 diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java index 0c19ad5eb505..fe9b9a50b838 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java +++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java @@ -39,6 +39,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.protobuf.Duration; import com.google.protobuf.Timestamp; +import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Comparator; @@ -92,7 +93,7 @@ private static SimpleDateFormat createTimestampFormat() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); // We use Proleptic Gregorian Calendar (i.e., Gregorian calendar extends - // backwards to year one) for timestamp formating. + // backwards to year one) for timestamp formatting. calendar.setGregorianChange(new Date(Long.MIN_VALUE)); sdf.setCalendar(calendar); return sdf; @@ -100,24 +101,25 @@ private static SimpleDateFormat createTimestampFormat() { private Timestamps() {} - private static final Comparator COMPARATOR = - new Comparator() { - @Override - public int compare(Timestamp t1, Timestamp t2) { - checkValid(t1); - checkValid(t2); - int secDiff = Long.compare(t1.getSeconds(), t2.getSeconds()); - return (secDiff != 0) ? secDiff : Integer.compare(t1.getNanos(), t2.getNanos()); - } - }; + private static enum TimestampComparator implements Comparator, Serializable { + INSTANCE; + + @Override + public int compare(Timestamp t1, Timestamp t2) { + checkValid(t1); + checkValid(t2); + int secDiff = Long.compare(t1.getSeconds(), t2.getSeconds()); + return (secDiff != 0) ? secDiff : Integer.compare(t1.getNanos(), t2.getNanos()); + } + } /** * Returns a {@link Comparator} for {@link Timestamp Timestamps} which sorts in increasing * chronological order. Nulls and invalid {@link Timestamp Timestamps} are not allowed (see - * {@link #isValid}). + * {@link #isValid}). The returned comparator is serializable. */ public static Comparator comparator() { - return COMPARATOR; + return TimestampComparator.INSTANCE; } /** @@ -128,7 +130,7 @@ public static Comparator comparator() { * and a value greater than {@code 0} if {@code x > y} */ public static int compare(Timestamp x, Timestamp y) { - return COMPARATOR.compare(x, y); + return TimestampComparator.INSTANCE.compare(x, y); } /** diff --git a/java/util/src/main/java/com/google/protobuf/util/Values.java b/java/util/src/main/java/com/google/protobuf/util/Values.java old mode 100755 new mode 100644 index b3ade2ddfb7e..f03d70e0dcd3 --- a/java/util/src/main/java/com/google/protobuf/util/Values.java +++ b/java/util/src/main/java/com/google/protobuf/util/Values.java @@ -71,8 +71,8 @@ public static Value of(ListValue value) { } /** - * Returns a Value with ListValue set to the appending the result of calling {@link #of(Object)} - * on each element in the iterable. + * Returns a Value with ListValue set to the appending the result of calling {@link #of} on each + * element in the iterable. */ public static Value of(Iterable values) { Value.Builder valueBuilder = Value.newBuilder(); diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java index baae2244f9aa..c8297226f77a 100644 --- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java @@ -30,6 +30,8 @@ package com.google.protobuf.util; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.DynamicMessage; import com.google.protobuf.Message; import com.google.protobuf.UninitializedMessageException; @@ -43,9 +45,9 @@ public class FieldMaskTreeTest extends TestCase { public void testAddFieldPath() throws Exception { FieldMaskTree tree = new FieldMaskTree(); - assertEquals("", tree.toString()); + assertThat(tree.toString()).isEmpty(); tree.addFieldPath(""); - assertEquals("", tree.toString()); + assertThat(tree.toString()).isEmpty(); // New branch. tree.addFieldPath("foo"); assertEquals("foo", tree.toString()); @@ -73,15 +75,57 @@ public void testMergeFromFieldMask() throws Exception { assertEquals("bar,foo", tree.toString()); } + public void testRemoveFieldPath() throws Exception { + String initialTreeString = "bar.baz,bar.quz.bar,foo"; + FieldMaskTree tree; + + // Empty path. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + tree.removeFieldPath(""); + assertEquals(initialTreeString, tree.toString()); + + // Non-exist sub-path of an existing leaf. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + tree.removeFieldPath("foo.bar"); + assertEquals(initialTreeString, tree.toString()); + + // Non-exist path. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + tree.removeFieldPath("bar.foo"); + assertEquals(initialTreeString, tree.toString()); + + // Match an existing leaf node -> remove leaf node. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + tree.removeFieldPath("foo"); + assertEquals("bar.baz,bar.quz.bar", tree.toString()); + + // Match sub-path of an existing leaf node -> recursive removal. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + tree.removeFieldPath("bar.quz.bar"); + assertEquals("bar.baz,foo", tree.toString()); + + // Match a non-leaf node -> remove all children. + tree = new FieldMaskTree(FieldMaskUtil.fromString(initialTreeString)); + tree.removeFieldPath("bar"); + assertEquals("foo", tree.toString()); + } + + public void testRemoveFromFieldMask() throws Exception { + FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz")); + assertEquals("bar.baz,bar.quz,foo", tree.toString()); + tree.removeFromFieldMask(FieldMaskUtil.fromString("foo.bar,bar")); + assertEquals("foo", tree.toString()); + } + public void testIntersectFieldPath() throws Exception { FieldMaskTree tree = new FieldMaskTree(FieldMaskUtil.fromString("foo,bar.baz,bar.quz")); FieldMaskTree result = new FieldMaskTree(); // Empty path. tree.intersectFieldPath("", result); - assertEquals("", result.toString()); + assertThat(result.toString()).isEmpty(); // Non-exist path. tree.intersectFieldPath("quz", result); - assertEquals("", result.toString()); + assertThat(result.toString()).isEmpty(); // Sub-path of an existing leaf. tree.intersectFieldPath("foo.bar", result); assertEquals("foo.bar", result.toString()); diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java index 1a998570532b..28e43a7bf77b 100644 --- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java @@ -30,10 +30,12 @@ package com.google.protobuf.util; +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; import com.google.protobuf.FieldMask; import protobuf_unittest.UnittestProto.NestedTestAllTypes; import protobuf_unittest.UnittestProto.TestAllTypes; - import junit.framework.TestCase; /** Unit tests for {@link FieldMaskUtil}. */ @@ -172,6 +174,38 @@ public void testFromJsonString() throws Exception { assertEquals("bar_baz", mask.getPaths(1)); } + public void testFromStringList() throws Exception { + FieldMask mask = + FieldMaskUtil.fromStringList( + NestedTestAllTypes.class, ImmutableList.of("payload.repeated_nested_message", "child")); + assertThat(mask) + .isEqualTo( + FieldMask.newBuilder() + .addPaths("payload.repeated_nested_message") + .addPaths("child") + .build()); + + mask = + FieldMaskUtil.fromStringList( + NestedTestAllTypes.getDescriptor(), + ImmutableList.of("payload.repeated_nested_message", "child")); + assertThat(mask) + .isEqualTo( + FieldMask.newBuilder() + .addPaths("payload.repeated_nested_message") + .addPaths("child") + .build()); + + mask = + FieldMaskUtil.fromStringList(ImmutableList.of("payload.repeated_nested_message", "child")); + assertThat(mask) + .isEqualTo( + FieldMask.newBuilder() + .addPaths("payload.repeated_nested_message") + .addPaths("child") + .build()); + } + public void testUnion() throws Exception { // Only test a simple case here and expect // {@link FieldMaskTreeTest#testAddFieldPath} to cover all scenarios. @@ -190,6 +224,24 @@ public void testUnion_usingVarArgs() throws Exception { assertEquals("bar,foo", FieldMaskUtil.toString(result)); } + public void testSubstract() throws Exception { + // Only test a simple case here and expect + // {@link FieldMaskTreeTest#testRemoveFieldPath} to cover all scenarios. + FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz"); + FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar"); + FieldMask result = FieldMaskUtil.subtract(mask1, mask2); + assertEquals("foo", FieldMaskUtil.toString(result)); + } + + public void testSubstract_usingVarArgs() throws Exception { + FieldMask mask1 = FieldMaskUtil.fromString("foo,bar.baz,bar.quz.bar"); + FieldMask mask2 = FieldMaskUtil.fromString("foo.bar,bar.baz.quz"); + FieldMask mask3 = FieldMaskUtil.fromString("bar.quz"); + FieldMask mask4 = FieldMaskUtil.fromString("foo,bar.baz"); + FieldMask result = FieldMaskUtil.subtract(mask1, mask2, mask3, mask4); + assertThat(FieldMaskUtil.toString(result)).isEmpty(); + } + public void testIntersection() throws Exception { // Only test a simple case here and expect // {@link FieldMaskTreeTest#testIntersectFieldPath} to cover all scenarios. diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index a06483192fb0..46d3cc4c352c 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -30,6 +30,7 @@ package com.google.protobuf.util; +import com.google.common.collect.ImmutableSet; import com.google.protobuf.Any; import com.google.protobuf.BoolValue; import com.google.protobuf.ByteString; @@ -721,8 +722,8 @@ public void testParserAcceptNonQuotedObjectKey() throws Exception { mergeFromJson( "{\n" + " int32ToInt32Map: {1: 2},\n" + " stringToInt32Map: {hello: 3}\n" + "}", builder); TestMap message = builder.build(); - assertEquals(2, message.getInt32ToInt32Map().get(1).intValue()); - assertEquals(3, message.getStringToInt32Map().get("hello").intValue()); + assertEquals(2, message.getInt32ToInt32MapMap().get(1).intValue()); + assertEquals(3, message.getStringToInt32MapMap().get("hello").intValue()); } public void testWrappers() throws Exception { @@ -1784,4 +1785,16 @@ public void testSortedMapKeys() throws Exception { TestMap emptyMap = TestMap.getDefaultInstance(); assertEquals("{\n}", toSortedJsonString(emptyMap)); } + + public void testPrintingEnumsAsIntsChainedAfterIncludingDefaultValueFields() throws Exception { + TestAllTypes message = TestAllTypes.newBuilder().setOptionalBool(false).build(); + + assertEquals( + "{\n" + " \"optionalBool\": false\n" + "}", + JsonFormat.printer() + .includingDefaultValueFields( + ImmutableSet.of(message.getDescriptorForType().findFieldByName("optional_bool"))) + .printingEnumsAsInts() + .print(message)); + } } diff --git a/java/util/src/test/java/com/google/protobuf/util/StructsTest.java b/java/util/src/test/java/com/google/protobuf/util/StructsTest.java old mode 100755 new mode 100644 diff --git a/java/util/src/test/java/com/google/protobuf/util/ValuesTest.java b/java/util/src/test/java/com/google/protobuf/util/ValuesTest.java old mode 100755 new mode 100644 diff --git a/js/binary/constants.js b/js/binary/constants.js index f8b13a8b9e37..d2e62e5b0f6c 100644 --- a/js/binary/constants.js +++ b/js/binary/constants.js @@ -31,6 +31,7 @@ /** * @fileoverview This file contains constants and typedefs used by * jspb.BinaryReader and BinaryWriter. + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/binary/decoder.js b/js/binary/decoder.js index 257c283f09a7..fb40ec99e3f0 100644 --- a/js/binary/decoder.js +++ b/js/binary/decoder.js @@ -40,6 +40,7 @@ * intact, you _must_ read them using one of the Hash64 methods, which return * an 8-character string. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/binary/reader.js b/js/binary/reader.js index 2af1a4ac393a..31bbfda43885 100644 --- a/js/binary/reader.js +++ b/js/binary/reader.js @@ -41,6 +41,7 @@ * using the typed jspb code generator, but if you bypass that you'll need * to keep things in sync by hand. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ @@ -206,6 +207,15 @@ jspb.BinaryReader.prototype.getWireType = function() { }; +/** + * @return {boolean} Whether the current wire type is a delimited field. Used to + * conditionally parse packed repeated fields. + */ +jspb.BinaryReader.prototype.isDelimited = function() { + return this.nextWireType_ == jspb.BinaryConstants.WireType.DELIMITED; +}; + + /** * @return {boolean} Whether the current wire type is an end-group tag. Used as * an exit condition in decoder loops in generated code. diff --git a/js/binary/utils.js b/js/binary/utils.js index 0d55a4ad366e..6cd15e36445d 100644 --- a/js/binary/utils.js +++ b/js/binary/utils.js @@ -32,6 +32,7 @@ * @fileoverview This file contains helper code used by jspb.BinaryReader * and BinaryWriter. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ @@ -258,7 +259,7 @@ jspb.utils.splitFloat64 = function(value) { // Compute the least significant exponent needed to represent the magnitude of // the value by repeadly dividing/multiplying by 2 until the magnitude // crosses 2. While tempting to use log math to find the exponent, at the - // bounadaries of precision, the result can be off by one. + // boundaries of precision, the result can be off by one. var maxDoubleExponent = 1023; var minDoubleExponent = -1022; var x = value; diff --git a/js/binary/writer.js b/js/binary/writer.js index ab9a81505602..1e2beee3e94e 100644 --- a/js/binary/writer.js +++ b/js/binary/writer.js @@ -52,6 +52,7 @@ * Major caveat 3 - This class uses typed arrays and must not be used on older * browsers that do not support them. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/experimental/benchmarks/code_size/kernel/all_types.js b/js/experimental/benchmarks/code_size/kernel/all_types.js index 218a4b9de4f3..17cc7a6eff7e 100644 --- a/js/experimental/benchmarks/code_size/kernel/all_types.js +++ b/js/experimental/benchmarks/code_size/kernel/all_types.js @@ -6,7 +6,7 @@ goog.module('protobuf.benchmark.KernelCodeSizeBenchmarkAllTypes'); const ByteString = goog.require('protobuf.ByteString'); const Int64 = goog.require('protobuf.Int64'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); @@ -17,7 +17,7 @@ ensureCommonBaseLine(); * @return {string} */ function accessAllTypes() { - const message = new TestMessage(LazyAccessor.createEmpty()); + const message = new TestMessage(Kernel.createEmpty()); message.addPackedBoolElement(1, true); message.addPackedBoolIterable(1, [true]); diff --git a/js/experimental/benchmarks/code_size/kernel/popular_types.js b/js/experimental/benchmarks/code_size/kernel/popular_types.js index fb026225262d..90e1792f6767 100644 --- a/js/experimental/benchmarks/code_size/kernel/popular_types.js +++ b/js/experimental/benchmarks/code_size/kernel/popular_types.js @@ -20,7 +20,7 @@ goog.module('protobuf.benchmark.KernelCodeSizeBenchmarkPopularTypes'); const Int64 = goog.require('protobuf.Int64'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase'); @@ -31,7 +31,7 @@ ensureCommonBaseLine(); * @return {string} */ function accessAllTypes() { - const message = new TestMessage(LazyAccessor.createEmpty()); + const message = new TestMessage(Kernel.createEmpty()); message.addRepeatedMessageElement(1, message, TestMessage.instanceCreator); message.addRepeatedMessageIterable(1, [message], TestMessage.instanceCreator); diff --git a/js/experimental/runtime/internal/checks.js b/js/experimental/runtime/internal/checks.js index 369c6af6ef55..3d1af548f598 100644 --- a/js/experimental/runtime/internal/checks.js +++ b/js/experimental/runtime/internal/checks.js @@ -2,7 +2,7 @@ * @fileoverview Proto internal runtime checks. * * Checks are grouped into different severity, see: - * http://g3doc/javascript/protobuf/README.md#configurable-check-support-in-protocol-buffers + * http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers * * Checks are also grouped into different sections: * - CHECK_BOUNDS: @@ -23,7 +23,7 @@ const WireType = goog.require('protobuf.binary.WireType'); // // See -// http://g3doc/javascript/protobuf/README.md#configurable-check-support-in-protocol-buffers +// http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers // /** @define{string} */ const CHECK_LEVEL_DEFINE = goog.define('protobuf.defines.CHECK_LEVEL', ''); diff --git a/js/experimental/runtime/kernel/binary_storage.js b/js/experimental/runtime/kernel/binary_storage.js new file mode 100644 index 000000000000..4cbde30a6946 --- /dev/null +++ b/js/experimental/runtime/kernel/binary_storage.js @@ -0,0 +1,130 @@ +goog.module('protobuf.runtime.BinaryStorage'); + +const Storage = goog.require('protobuf.runtime.Storage'); +const {checkDefAndNotNull} = goog.require('protobuf.internal.checks'); + +/** + * Class storing all the fields of a binary protobuf message. + * + * @package + * @template FieldType + * @implements {Storage} + */ +class BinaryStorage { + /** + * @param {number=} pivot + */ + constructor(pivot = Storage.DEFAULT_PIVOT) { + /** + * Fields having a field number no greater than the pivot value are stored + * into an array for fast access. A field with field number X is stored into + * the array position X - 1. + * + * @private @const {!Array} + */ + this.array_ = new Array(pivot); + + /** + * Fields having a field number higher than the pivot value are stored into + * the map. We create the map only when it's needed, since even an empty map + * takes up a significant amount of memory. + * + * @private {?Map} + */ + this.map_ = null; + } + + /** + * Fields having a field number no greater than the pivot value are stored + * into an array for fast access. A field with field number X is stored into + * the array position X - 1. + * @return {number} + * @override + */ + getPivot() { + return this.array_.length; + } + + /** + * Sets a field in the specified field number. + * + * @param {number} fieldNumber + * @param {!FieldType} field + * @override + */ + set(fieldNumber, field) { + if (fieldNumber <= this.getPivot()) { + this.array_[fieldNumber - 1] = field; + } else { + if (this.map_) { + this.map_.set(fieldNumber, field); + } else { + this.map_ = new Map([[fieldNumber, field]]); + } + } + } + + /** + * Returns a field at the specified field number. + * + * @param {number} fieldNumber + * @return {!FieldType|undefined} + * @override + */ + get(fieldNumber) { + if (fieldNumber <= this.getPivot()) { + return this.array_[fieldNumber - 1]; + } else { + return this.map_ ? this.map_.get(fieldNumber) : undefined; + } + } + + /** + * Deletes a field from the specified field number. + * + * @param {number} fieldNumber + * @override + */ + delete(fieldNumber) { + if (fieldNumber <= this.getPivot()) { + delete this.array_[fieldNumber - 1]; + } else { + if (this.map_) { + this.map_.delete(fieldNumber); + } + } + } + + /** + * Executes the provided function once for each field. + * + * @param {function(!FieldType, number): void} callback + * @override + */ + forEach(callback) { + this.array_.forEach((field, fieldNumber) => { + if (field) { + callback(checkDefAndNotNull(field), fieldNumber + 1); + } + }); + if (this.map_) { + this.map_.forEach(callback); + } + } + + /** + * Creates a shallow copy of the storage. + * + * @return {!BinaryStorage} + * @override + */ + shallowCopy() { + const copy = new BinaryStorage(this.getPivot()); + this.forEach( + (field, fieldNumber) => + void copy.set(fieldNumber, field.shallowCopy())); + return copy; + } +} + +exports = BinaryStorage; diff --git a/js/experimental/runtime/kernel/storage_test.js b/js/experimental/runtime/kernel/binary_storage_test.js similarity index 85% rename from js/experimental/runtime/kernel/storage_test.js rename to js/experimental/runtime/kernel/binary_storage_test.js index e4958d3c8945..2686f04e47c2 100644 --- a/js/experimental/runtime/kernel/storage_test.js +++ b/js/experimental/runtime/kernel/binary_storage_test.js @@ -1,11 +1,11 @@ /** * @fileoverview Tests for storage.js. */ -goog.module('protobuf.binary.StorageTest'); +goog.module('protobuf.runtime.BinaryStorageTest'); goog.setTestOnly(); -const Storage = goog.require('protobuf.binary.Storage'); +const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); const {Field} = goog.require('protobuf.binary.field'); /** @@ -25,7 +25,7 @@ const /** !Field */ field4 = /** * Returns the number of fields stored. * - * @param {!Storage} storage + * @param {!BinaryStorage} storage * @return {number} */ function getStorageSize(storage) { @@ -34,9 +34,9 @@ function getStorageSize(storage) { return size; } -describe('Storage', () => { +describe('BinaryStorage', () => { it('sets and gets a field not greater than the pivot', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(1, field1); storage.set(DEFAULT_PIVOT, field2); @@ -47,7 +47,7 @@ describe('Storage', () => { }); it('sets and gets a field greater than the pivot', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(DEFAULT_PIVOT + 1, field1); storage.set(100000, field2); @@ -57,7 +57,7 @@ describe('Storage', () => { }); it('sets and gets a field when pivot is zero', () => { - const storage = new Storage(0); + const storage = new BinaryStorage(0); storage.set(0, field1); storage.set(100000, field2); @@ -68,7 +68,7 @@ describe('Storage', () => { }); it('sets and gets a field when pivot is undefined', () => { - const storage = new Storage(); + const storage = new BinaryStorage(); storage.set(0, field1); storage.set(DEFAULT_PIVOT, field2); @@ -81,7 +81,7 @@ describe('Storage', () => { }); it('returns undefined for nonexistent fields', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); expect(storage.get(1)).toBeUndefined(); expect(storage.get(DEFAULT_PIVOT)).toBeUndefined(); @@ -91,7 +91,7 @@ describe('Storage', () => { it('returns undefined for nonexistent fields after map initialization', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(100001, field1); expect(storage.get(1)).toBeUndefined(); @@ -101,7 +101,7 @@ describe('Storage', () => { }); it('deletes a field in delete() when values are only in array', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(1, field1); storage.delete(1); @@ -111,7 +111,7 @@ describe('Storage', () => { it('deletes a field in delete() when values are both in array and map', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(DEFAULT_PIVOT, field2); storage.set(DEFAULT_PIVOT + 1, field3); @@ -123,7 +123,7 @@ describe('Storage', () => { }); it('deletes a field in delete() when values are only in map', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(100000, field4); storage.delete(100000); @@ -132,7 +132,7 @@ describe('Storage', () => { }); it('loops over all the elements in forEach()', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(1, field1); storage.set(DEFAULT_PIVOT, field2); storage.set(DEFAULT_PIVOT + 1, field3); @@ -150,7 +150,7 @@ describe('Storage', () => { }); it('creates a shallow copy of the storage in shallowCopy()', () => { - const storage = new Storage(DEFAULT_PIVOT); + const storage = new BinaryStorage(DEFAULT_PIVOT); storage.set(1, field1); storage.set(100000, field2); diff --git a/js/experimental/runtime/kernel/buffer_decoder.js b/js/experimental/runtime/kernel/buffer_decoder.js index 614659a1e6fe..b0c45354266f 100644 --- a/js/experimental/runtime/kernel/buffer_decoder.js +++ b/js/experimental/runtime/kernel/buffer_decoder.js @@ -6,7 +6,7 @@ goog.module('protobuf.binary.BufferDecoder'); const ByteString = goog.require('protobuf.ByteString'); const functions = goog.require('goog.functions'); -const {POLYFILL_TEXT_ENCODING, checkCriticalElementIndex, checkCriticalPositionIndex, checkState} = goog.require('protobuf.internal.checks'); +const {POLYFILL_TEXT_ENCODING, checkCriticalPositionIndex, checkCriticalState, checkState} = goog.require('protobuf.internal.checks'); const {byteStringFromUint8ArrayUnsafe} = goog.require('protobuf.byteStringInternal'); const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays'); const {decode} = goog.require('protobuf.binary.textencoding'); @@ -72,7 +72,9 @@ class BufferDecoder { /** @private @const {number} */ this.startIndex_ = startIndex; /** @private @const {number} */ - this.endIndex_ = this.startIndex_ + length; + this.endIndex_ = startIndex + length; + /** @private {number} */ + this.cursor_ = startIndex; } /** @@ -99,12 +101,38 @@ class BufferDecoder { return this.endIndex_ - this.startIndex_; } + /** + * Returns the start position of the next data, i.e. end position of the last + * read data + 1. + * @return {number} + */ + cursor() { + return this.cursor_; + } + + /** + * Sets the cursor to the specified position. + * @param {number} position + */ + setCursor(position) { + this.cursor_ = position; + } + + /** + * Returns if there is more data to read after the current cursor position. + * @return {boolean} + */ + hasNext() { + return this.cursor_ < this.endIndex_; + } + /** * Returns a float32 from a given index * @param {number} index * @return {number} */ getFloat32(index) { + this.cursor_ = index + 4; return this.dataView_.getFloat32(index, true); } @@ -114,6 +142,7 @@ class BufferDecoder { * @return {number} */ getFloat64(index) { + this.cursor_ = index + 8; return this.dataView_.getFloat64(index, true); } @@ -123,45 +152,40 @@ class BufferDecoder { * @return {number} */ getInt32(index) { + this.cursor_ = index + 4; return this.dataView_.getInt32(index, true); } - /** - * @param {number} index - * @return {number} - */ - getUint8(index) { - return this.dataView_.getUint8(index); - } - /** * Returns a uint32 from a given index * @param {number} index * @return {number} */ getUint32(index) { + this.cursor_ = index + 4; return this.dataView_.getUint32(index, true); } /** - * Returns two JS numbers each representing 32 bits of a 64 bit number. + * Returns two JS numbers each representing 32 bits of a 64 bit number. Also + * sets the cursor to the start of the next block of data. * @param {number} index - * @return {{lowBits: number, highBits: number, dataStart: number}} + * @return {{lowBits: number, highBits: number}} */ getVarint(index) { - let start = index; + this.cursor_ = index; let lowBits = 0; let highBits = 0; for (let shift = 0; shift < 28; shift += 7) { - const b = this.dataView_.getUint8(start++); + const b = this.dataView_.getUint8(this.cursor_++); lowBits |= (b & 0x7F) << shift; if ((b & 0x80) === 0) { - return {lowBits, highBits, dataStart: start}; + return {lowBits, highBits}; } } - const middleByte = this.dataView_.getUint8(start++); + const middleByte = this.dataView_.getUint8(this.cursor_++); // last four bits of the first 32 bit number lowBits |= (middleByte & 0x0F) << 28; @@ -170,36 +194,99 @@ class BufferDecoder { highBits = (middleByte & 0x70) >> 4; if ((middleByte & 0x80) === 0) { - return {lowBits, highBits, dataStart: start}; + return {lowBits, highBits}; } for (let shift = 3; shift <= 31; shift += 7) { - const b = this.dataView_.getUint8(start++); + const b = this.dataView_.getUint8(this.cursor_++); highBits |= (b & 0x7F) << shift; if ((b & 0x80) === 0) { - return {lowBits, highBits, dataStart: start}; + return {lowBits, highBits}; } } - checkState(false, 'Data is longer than 10 bytes'); - return {lowBits, highBits, dataStart: start}; + checkCriticalState(false, 'Data is longer than 10 bytes'); + + return {lowBits, highBits}; + } + + /** + * Returns an unsigned int32 number at the current cursor position. The upper + * bits are discarded if the varint is longer than 32 bits. Also sets the + * cursor to the start of the next block of data. + * @return {number} + */ + getUnsignedVarint32() { + let b = this.dataView_.getUint8(this.cursor_++); + let result = b & 0x7F; + if ((b & 0x80) === 0) { + return result; + } + + b = this.dataView_.getUint8(this.cursor_++); + result |= (b & 0x7F) << 7; + if ((b & 0x80) === 0) { + return result; + } + + b = this.dataView_.getUint8(this.cursor_++); + result |= (b & 0x7F) << 14; + if ((b & 0x80) === 0) { + return result; + } + + b = this.dataView_.getUint8(this.cursor_++); + result |= (b & 0x7F) << 21; + if ((b & 0x80) === 0) { + return result; + } + + // Extract only last 4 bits + b = this.dataView_.getUint8(this.cursor_++); + result |= (b & 0x0F) << 28; + + for (let readBytes = 5; ((b & 0x80) !== 0) && readBytes < 10; readBytes++) { + b = this.dataView_.getUint8(this.cursor_++); + } + + checkCriticalState((b & 0x80) === 0, 'Data is longer than 10 bytes'); + + // Result can be have 32 bits, convert it to unsigned + return result >>> 0; + } + + /** + * Returns an unsigned int32 number at the specified index. The upper bits are + * discarded if the varint is longer than 32 bits. Also sets the cursor to the + * start of the next block of data. + * @param {number} index + * @return {number} + */ + getUnsignedVarint32At(index) { + this.cursor_ = index; + return this.getUnsignedVarint32(); + } + + /** + * Seeks forward by the given amount. + * @param {number} skipAmount + * @package + */ + skip(skipAmount) { + this.cursor_ += skipAmount; + checkCriticalPositionIndex(this.cursor_, this.endIndex_); } /** - * Skips over a varint at a given index and returns the next position. - * @param {number} index Start of the data. - * @return {number} Position of the first byte after the varint. + * Skips over a varint from the current cursor position. * @package */ - skipVarint(index) { - let cursor = index; - checkCriticalElementIndex(cursor, this.endIndex()); - while (this.dataView_.getUint8(cursor++) & 0x80) { - checkCriticalElementIndex(cursor, this.endIndex()); + skipVarint() { + const startIndex = this.cursor_; + while (this.dataView_.getUint8(this.cursor_++) & 0x80) { } - checkCriticalPositionIndex(cursor, index + 10); - return cursor; + checkCriticalPositionIndex(this.cursor_, startIndex + 10); } /** diff --git a/js/experimental/runtime/kernel/buffer_decoder_test.js b/js/experimental/runtime/kernel/buffer_decoder_test.js index aed045a8e5f7..17f28966b8e4 100644 --- a/js/experimental/runtime/kernel/buffer_decoder_test.js +++ b/js/experimental/runtime/kernel/buffer_decoder_test.js @@ -5,7 +5,7 @@ goog.module('protobuf.binary.varintsTest'); const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const {CHECK_CRITICAL_BOUNDS, CHECK_STATE} = goog.require('protobuf.internal.checks'); +const {CHECK_CRITICAL_STATE, CHECK_STATE} = goog.require('protobuf.internal.checks'); goog.setTestOnly(); @@ -17,32 +17,54 @@ function createArrayBuffer(...bytes) { return new Uint8Array(bytes).buffer; } +describe('setCursor does', () => { + it('set the cursor at the position specified', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1)); + expect(bufferDecoder.cursor()).toBe(0); + bufferDecoder.setCursor(1); + expect(bufferDecoder.cursor()).toBe(1); + }); +}); + +describe('skip does', () => { + it('advance the cursor', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1, 0x2)); + bufferDecoder.setCursor(1); + bufferDecoder.skip(1); + expect(bufferDecoder.cursor()).toBe(2); + }); +}); + describe('Skip varint does', () => { it('skip a varint', () => { const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); - expect(bufferDecoder.skipVarint(0)).toBe(1); + bufferDecoder.skipVarint(); + expect(bufferDecoder.cursor()).toBe(1); }); it('fail when varint is larger than 10 bytes', () => { const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); - if (CHECK_CRITICAL_BOUNDS) { - expect(() => bufferDecoder.skipVarint(0)).toThrow(); + if (CHECK_CRITICAL_STATE) { + expect(() => bufferDecoder.skipVarint()).toThrow(); } else { // Note in unchecked mode we produce invalid output for invalid inputs. // This test just documents our behavior in those cases. // These values might change at any point and are not considered // what the implementation should be doing here. - expect(bufferDecoder.skipVarint(0)).toBe(11); + bufferDecoder.skipVarint(); + expect(bufferDecoder.cursor()).toBe(11); } }); it('fail when varint is beyond end of underlying array', () => { const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x80)); - expect(() => bufferDecoder.skipVarint(0)).toThrow(); + expect(() => bufferDecoder.skipVarint()).toThrow(); }); }); @@ -50,28 +72,144 @@ describe('readVarint64 does', () => { it('read zero', () => { const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)); - const {dataStart, lowBits, highBits} = bufferDecoder.getVarint(0); - expect(dataStart).toBe(1); + const {lowBits, highBits} = bufferDecoder.getVarint(0); expect(lowBits).toBe(0); expect(highBits).toBe(0); + expect(bufferDecoder.cursor()).toBe(1); }); it('read one', () => { const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); - const {dataStart, lowBits, highBits} = bufferDecoder.getVarint(0); - expect(dataStart).toBe(1); + const {lowBits, highBits} = bufferDecoder.getVarint(0); expect(lowBits).toBe(1); expect(highBits).toBe(0); + expect(bufferDecoder.cursor()).toBe(1); }); it('read max value', () => { const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); - const {dataStart, lowBits, highBits} = bufferDecoder.getVarint(0); - expect(dataStart).toBe(10); + const {lowBits, highBits} = bufferDecoder.getVarint(0); expect(lowBits).toBe(-1); expect(highBits).toBe(-1); + expect(bufferDecoder.cursor()).toBe(10); + }); +}); + +describe('readUnsignedVarint32 does', () => { + it('read zero', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)); + const result = bufferDecoder.getUnsignedVarint32(); + expect(result).toBe(0); + expect(bufferDecoder.cursor()).toBe(1); + }); + + it('read one', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)); + const result = bufferDecoder.getUnsignedVarint32(); + expect(result).toBe(1); + expect(bufferDecoder.cursor()).toBe(1); + }); + + it('read max int32', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF, 0x0F)); + const result = bufferDecoder.getUnsignedVarint32(); + expect(result).toBe(4294967295); + expect(bufferDecoder.cursor()).toBe(5); + }); + + it('read max value', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); + const result = bufferDecoder.getUnsignedVarint32(); + expect(result).toBe(4294967295); + expect(bufferDecoder.cursor()).toBe(10); + }); + + it('fail if data is longer than 10 bytes', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer( + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01)); + if (CHECK_CRITICAL_STATE) { + expect(() => bufferDecoder.getUnsignedVarint32()).toThrow(); + } else { + // Note in unchecked mode we produce invalid output for invalid inputs. + // This test just documents our behavior in those cases. + // These values might change at any point and are not considered + // what the implementation should be doing here. + const result = bufferDecoder.getUnsignedVarint32(); + expect(result).toBe(4294967295); + expect(bufferDecoder.cursor()).toBe(10); + } + }); +}); + +describe('readUnsignedVarint32At does', () => { + it('reads from a specific index', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x1, 0x2)); + const result = bufferDecoder.getUnsignedVarint32At(1); + expect(result).toBe(2); + expect(bufferDecoder.cursor()).toBe(2); + }); +}); + +describe('getFloat32 does', () => { + it('read one', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0x00, 0x00, 0x80, 0x3F)); + const result = bufferDecoder.getFloat32(0); + expect(result).toBe(1); + expect(bufferDecoder.cursor()).toBe(4); + }); +}); + +describe('getFloat64 does', () => { + it('read one', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)); + const result = bufferDecoder.getFloat64(0); + expect(result).toBe(1); + expect(bufferDecoder.cursor()).toBe(8); + }); +}); + +describe('getInt32 does', () => { + it('read one', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0x01, 0x00, 0x00, 0x00)); + const result = bufferDecoder.getInt32(0); + expect(result).toBe(1); + expect(bufferDecoder.cursor()).toBe(4); + }); + + it('read minus one', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF)); + const result = bufferDecoder.getInt32(0); + expect(result).toBe(-1); + expect(bufferDecoder.cursor()).toBe(4); + }); +}); + +describe('getUint32 does', () => { + it('read one', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x00, 0x00, 0x0)); + const result = bufferDecoder.getUint32(0); + expect(result).toBe(1); + expect(bufferDecoder.cursor()).toBe(4); + }); + + it('read max uint32', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF)); + const result = bufferDecoder.getUint32(0); + expect(result).toBe(4294967295); + expect(bufferDecoder.cursor()).toBe(4); }); }); diff --git a/js/experimental/runtime/kernel/conformance/conformance_request.js b/js/experimental/runtime/kernel/conformance/conformance_request.js index c9f70affd25d..2d4f1067f893 100644 --- a/js/experimental/runtime/kernel/conformance/conformance_request.js +++ b/js/experimental/runtime/kernel/conformance/conformance_request.js @@ -3,7 +3,7 @@ */ goog.module('proto.conformance.ConformanceRequest'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); const WireFormat = goog.require('proto.conformance.WireFormat'); /** @@ -19,8 +19,8 @@ class ConformanceRequest { * @private */ constructor(bytes) { - /** @private @const {!LazyAccessor} */ - this.accessor_ = LazyAccessor.fromArrayBuffer(bytes); + /** @private @const {!Kernel} */ + this.accessor_ = Kernel.fromArrayBuffer(bytes); } /** diff --git a/js/experimental/runtime/kernel/conformance/conformance_response.js b/js/experimental/runtime/kernel/conformance/conformance_response.js index 3711f84acedb..482f31bb8efe 100644 --- a/js/experimental/runtime/kernel/conformance/conformance_response.js +++ b/js/experimental/runtime/kernel/conformance/conformance_response.js @@ -4,7 +4,7 @@ goog.module('proto.conformance.ConformanceResponse'); const ByteString = goog.require('protobuf.ByteString'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); /** * Handwritten code of conformance.ConformanceResponse. @@ -19,8 +19,8 @@ class ConformanceResponse { * @private */ constructor(bytes) { - /** @private @const {!LazyAccessor} */ - this.accessor_ = LazyAccessor.fromArrayBuffer(bytes); + /** @private @const {!Kernel} */ + this.accessor_ = Kernel.fromArrayBuffer(bytes); } /** diff --git a/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js b/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js index 34336ee884b8..3be1beea0fc6 100644 --- a/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js +++ b/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js @@ -4,7 +4,7 @@ goog.module('proto.conformance.TestAllTypesProto2'); const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); /** * Handwritten code of conformance.TestAllTypesProto2. @@ -14,18 +14,18 @@ const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); */ class TestAllTypesProto2 { /** - * @param {!LazyAccessor=} accessor + * @param {!Kernel=} accessor * @private */ - constructor(accessor = LazyAccessor.createEmpty()) { - /** @private @const {!LazyAccessor} */ + constructor(accessor = Kernel.createEmpty()) { + /** @private @const {!Kernel} */ this.accessor_ = accessor; } /** * @override * @package - * @return {!LazyAccessor} + * @return {!Kernel} */ internalGetKernel() { return this.accessor_; @@ -34,7 +34,7 @@ class TestAllTypesProto2 { /** * Create a request instance with the given bytes data. * If we directly use the accessor created by the binary decoding, the - * LazyAccessor instance will only copy the same data over for encoding. By + * Kernel instance will only copy the same data over for encoding. By * explicitly fetching data from the previous accessor and setting all fields * into a new accessor, we will actually test encoding/decoding for the binary * format. @@ -43,7 +43,7 @@ class TestAllTypesProto2 { */ static deserialize(bytes) { const msg = new TestAllTypesProto2(); - const requestAccessor = LazyAccessor.fromArrayBuffer(bytes); + const requestAccessor = Kernel.fromArrayBuffer(bytes); if (requestAccessor.hasFieldNumber(1)) { const value = requestAccessor.getInt32WithDefault(1); diff --git a/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js b/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js index 645026b433f7..c68d370f1920 100644 --- a/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js +++ b/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js @@ -4,7 +4,7 @@ goog.module('proto.conformance.TestAllTypesProto3'); const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); /** * Handwritten code of conformance.TestAllTypesProto3. @@ -14,18 +14,18 @@ const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); */ class TestAllTypesProto3 { /** - * @param {!LazyAccessor=} accessor + * @param {!Kernel=} accessor * @private */ - constructor(accessor = LazyAccessor.createEmpty()) { - /** @private @const {!LazyAccessor} */ + constructor(accessor = Kernel.createEmpty()) { + /** @private @const {!Kernel} */ this.accessor_ = accessor; } /** * @override * @package - * @return {!LazyAccessor} + * @return {!Kernel} */ internalGetKernel() { return this.accessor_; @@ -34,7 +34,7 @@ class TestAllTypesProto3 { /** * Create a request instance with the given bytes data. * If we directly use the accessor created by the binary decoding, the - * LazyAccessor instance will only copy the same data over for encoding. By + * Kernel instance will only copy the same data over for encoding. By * explicitly fetching data from the previous accessor and setting all fields * into a new accessor, we will actually test encoding/decoding for the binary * format. @@ -43,7 +43,7 @@ class TestAllTypesProto3 { */ static deserialize(bytes) { const msg = new TestAllTypesProto3(); - const requestAccessor = LazyAccessor.fromArrayBuffer(bytes); + const requestAccessor = Kernel.fromArrayBuffer(bytes); if (requestAccessor.hasFieldNumber(1)) { const value = requestAccessor.getInt32WithDefault(1); diff --git a/js/experimental/runtime/kernel/indexer.js b/js/experimental/runtime/kernel/indexer.js index c247c2faa6c9..205a34e44de0 100644 --- a/js/experimental/runtime/kernel/indexer.js +++ b/js/experimental/runtime/kernel/indexer.js @@ -4,15 +4,16 @@ */ goog.module('protobuf.binary.indexer'); +const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Storage = goog.require('protobuf.binary.Storage'); const WireType = goog.require('protobuf.binary.WireType'); const {Field} = goog.require('protobuf.binary.field'); -const {checkCriticalPositionIndex, checkCriticalState} = goog.require('protobuf.internal.checks'); +const {checkCriticalState} = goog.require('protobuf.internal.checks'); +const {skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag'); /** * Appends a new entry in the index array for the given field number. - * @param {!Storage} storage + * @param {!BinaryStorage} storage * @param {number} fieldNumber * @param {!WireType} wireType * @param {number} startIndex @@ -26,167 +27,29 @@ function addIndexEntry(storage, fieldNumber, wireType, startIndex) { } } -/** - * Returns wire type stored in a tag. - * Protos store the wire type as the first 3 bit of a tag. - * @param {number} tag - * @return {!WireType} - */ -function tagToWireType(tag) { - return /** @type {!WireType} */ (tag & 0x07); -} - -/** - * Returns the field number stored in a tag. - * Protos store the field number in the upper 29 bits of a 32 bit number. - * @param {number} tag - * @return {number} - */ -function tagToFieldNumber(tag) { - return tag >>> 3; -} - -/** - * An Indexer that indexes a given binary protobuf by fieldnumber. - */ -class Indexer { - /** - * @param {!BufferDecoder} bufferDecoder - * @private - */ - constructor(bufferDecoder) { - /** @private @const {!BufferDecoder} */ - this.bufferDecoder_ = bufferDecoder; - /** @private {number} */ - this.cursor_ = bufferDecoder.startIndex(); - } - - /** - * @param {number|undefined} pivot - * @return {!Storage} - */ - index(pivot) { - const storage = new Storage(pivot); - while (this.hasNextByte_()) { - const tag = this.readVarInt32_(); - const wireType = tagToWireType(tag); - const fieldNumber = tagToFieldNumber(tag); - checkCriticalState( - fieldNumber > 0, `Invalid field number ${fieldNumber}`); - - addIndexEntry(storage, fieldNumber, wireType, this.cursor_); - - checkCriticalState( - !this.skipField_(wireType, fieldNumber), - 'Found unmatched stop group.'); - } - return storage; - } - - /** - * Skips over fields until the next field of the message. - * @param {!WireType} wireType - * @param {number} fieldNumber - * @return {boolean} Whether the field we skipped over was a stop group. - * @private - */ - skipField_(wireType, fieldNumber) { - switch (wireType) { - case WireType.VARINT: - this.cursor_ = this.bufferDecoder_.skipVarint(this.cursor_); - return false; - case WireType.FIXED64: - this.skip_(8); - return false; - case WireType.DELIMITED: - const length = this.readVarInt32_(); - this.skip_(length); - return false; - case WireType.START_GROUP: - checkCriticalState(this.skipGroup_(fieldNumber), 'No end group found.'); - return false; - case WireType.END_GROUP: - // Signal that we found a stop group to the caller - return true; - case WireType.FIXED32: - this.skip_(4); - return false; - default: - throw new Error(`Invalid wire type: ${wireType}`); - } - } - - /** - * Seeks forward by the given amount. - * @param {number} skipAmount - * @private - */ - skip_(skipAmount) { - this.cursor_ += skipAmount; - checkCriticalPositionIndex(this.cursor_, this.bufferDecoder_.endIndex()); - } - - /** - * Skips over fields until it finds the end of a given group. - * @param {number} groupFieldNumber - * @return {boolean} Returns true if an end was found. - * @private - */ - skipGroup_(groupFieldNumber) { - // On a start group we need to keep skipping fields until we find a - // corresponding stop group - // Note: Since we are calling skipField from here nested groups will be - // handled by recursion of this method and thus we will not see a nested - // STOP GROUP here unless there is something wrong with the input data. - while (this.hasNextByte_()) { - const tag = this.readVarInt32_(); - const wireType = tagToWireType(tag); - const fieldNumber = tagToFieldNumber(tag); - - if (this.skipField_(wireType, fieldNumber)) { - checkCriticalState( - groupFieldNumber === fieldNumber, - `Expected stop group for fieldnumber ${ - groupFieldNumber} not found.`); - return true; - } - } - return false; - } - - /** - * Returns a JS number for a 32 bit var int. - * @return {number} - * @private - */ - readVarInt32_() { - const {lowBits, dataStart} = this.bufferDecoder_.getVarint(this.cursor_); - this.cursor_ = dataStart; - return lowBits; - } - - /** - * Returns true if there are more bytes to read in the array. - * @return {boolean} - * @private - */ - hasNextByte_() { - return this.cursor_ < this.bufferDecoder_.endIndex(); - } -} - /** * Creates an index of field locations in a given binary protobuf. * @param {!BufferDecoder} bufferDecoder * @param {number|undefined} pivot - * @return {!Storage} + * @return {!BinaryStorage} * @package */ function buildIndex(bufferDecoder, pivot) { - return new Indexer(bufferDecoder).index(pivot); + bufferDecoder.setCursor(bufferDecoder.startIndex()); + + const storage = new BinaryStorage(pivot); + while (bufferDecoder.hasNext()) { + const tag = bufferDecoder.getUnsignedVarint32(); + const wireType = tagToWireType(tag); + const fieldNumber = tagToFieldNumber(tag); + checkCriticalState(fieldNumber > 0, `Invalid field number ${fieldNumber}`); + addIndexEntry(storage, fieldNumber, wireType, bufferDecoder.cursor()); + skipField(bufferDecoder, wireType, fieldNumber); + } + return storage; } - exports = { buildIndex, + tagToWireType, }; diff --git a/js/experimental/runtime/kernel/indexer_test.js b/js/experimental/runtime/kernel/indexer_test.js index 1c95a07b5272..ffb8807994b5 100644 --- a/js/experimental/runtime/kernel/indexer_test.js +++ b/js/experimental/runtime/kernel/indexer_test.js @@ -10,8 +10,8 @@ goog.setTestOnly(); // in this file have to know which checking level is enabled to make correct // assertions. // Test are run in all checking levels. +const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); -const Storage = goog.require('protobuf.binary.Storage'); const WireType = goog.require('protobuf.binary.WireType'); const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); const {Field, IndexEntry} = goog.require('protobuf.binary.field'); @@ -21,7 +21,7 @@ const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper' /** * Returns the number of fields stored. * - * @param {!Storage} storage + * @param {!BinaryStorage} storage * @return {number} */ function getStorageSize(storage) { @@ -37,7 +37,7 @@ const PIVOT = 1; /** * Asserts a single IndexEntry at a given field number. - * @param {!Storage} storage + * @param {!BinaryStorage} storage * @param {number} fieldNumber * @param {...!IndexEntry} expectedEntries */ @@ -72,12 +72,12 @@ describe('Indexer does', () => { it('fail for invalid wire type (6)', () => { expect(() => buildIndex(createBufferDecoder(0x0E, 0x01), PIVOT)) - .toThrowError('Invalid wire type: 6'); + .toThrowError('Unexpected wire type: 6'); }); it('fail for invalid wire type (7)', () => { expect(() => buildIndex(createBufferDecoder(0x0F, 0x01), PIVOT)) - .toThrowError('Invalid wire type: 7'); + .toThrowError('Unexpected wire type: 7'); }); it('index varint', () => { @@ -269,33 +269,8 @@ describe('Indexer does', () => { it('fail on unmatched stop group', () => { const data = createBufferDecoder(0x0C, 0x01); - if (CHECK_CRITICAL_STATE) { - expect(() => buildIndex(data, PIVOT)) - .toThrowError('Found unmatched stop group.'); - } else { - // Note in unchecked mode we produce invalid output for invalid inputs. - // This test just documents our behavior in those cases. - // These values might change at any point and are not considered - // what the implementation should be doing here. - const storage = buildIndex(data, PIVOT); - - expect(getStorageSize(storage)).toBe(1); - const entryArray = storage.get(1).getIndexArray(); - expect(entryArray).not.toBeUndefined(); - expect(entryArray.length).toBe(1); - const entry = entryArray[0]; - - expect(Field.getWireType(entry)).toBe(WireType.END_GROUP); - expect(Field.getStartIndex(entry)).toBe(1); - - const entryArray2 = storage.get(0).getIndexArray(); - expect(entryArray2).not.toBeUndefined(); - expect(entryArray2.length).toBe(1); - const entry2 = entryArray2[0]; - - expect(Field.getWireType(entry2)).toBe(WireType.FIXED64); - expect(Field.getStartIndex(entry2)).toBe(2); - } + expect(() => buildIndex(data, PIVOT)) + .toThrowError('Unexpected wire type: 4'); }); it('fail for groups without matching stop group', () => { diff --git a/js/experimental/runtime/kernel/internal_message.js b/js/experimental/runtime/kernel/internal_message.js index 2e85ebd5e39d..1ba9ed983b7f 100644 --- a/js/experimental/runtime/kernel/internal_message.js +++ b/js/experimental/runtime/kernel/internal_message.js @@ -4,7 +4,7 @@ */ goog.module('protobuf.binary.InternalMessage'); -const LazyAccessor = goog.requireType('protobuf.binary.LazyAccessor'); +const Kernel = goog.requireType('protobuf.runtime.Kernel'); /** * Interface that needs to be implemented by messages implemented with the @@ -16,7 +16,7 @@ const LazyAccessor = goog.requireType('protobuf.binary.LazyAccessor'); class InternalMessage { /** * @package - * @return {!LazyAccessor} + * @return {!Kernel} */ internalGetKernel() {} } diff --git a/js/experimental/runtime/kernel/lazy_accessor.js b/js/experimental/runtime/kernel/kernel.js similarity index 87% rename from js/experimental/runtime/kernel/lazy_accessor.js rename to js/experimental/runtime/kernel/kernel.js index cebf0c0bd27c..bb2608398ae0 100644 --- a/js/experimental/runtime/kernel/lazy_accessor.js +++ b/js/experimental/runtime/kernel/kernel.js @@ -1,30 +1,32 @@ /** - * @fileoverview LazyAccessor is a class to provide type-checked accessing + * @fileoverview Kernel is a class to provide type-checked accessing * (read/write bool/int32/string/...) on binary data. * - * When creating the LazyAccessor with the binary data, there is no deep + * When creating the Kernel with the binary data, there is no deep * decoding done (which requires full type information). The deep decoding is * deferred until the first time accessing (when accessors can provide * full type information). * * Because accessors can be statically analyzed and stripped, unlike eager * binary decoding (which requires the full type information of all defined - * fields), LazyAccessor will only need the full type information of used + * fields), Kernel will only need the full type information of used * fields. */ -goog.module('protobuf.binary.LazyAccessor'); +goog.module('protobuf.runtime.Kernel'); +const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage'); const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); const ByteString = goog.require('protobuf.ByteString'); const Int64 = goog.require('protobuf.Int64'); const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const Storage = goog.require('protobuf.binary.Storage'); +const Storage = goog.require('protobuf.runtime.Storage'); const WireType = goog.require('protobuf.binary.WireType'); const Writer = goog.require('protobuf.binary.Writer'); const reader = goog.require('protobuf.binary.reader'); const {CHECK_TYPE, checkCriticalElementIndex, checkCriticalState, checkCriticalType, checkCriticalTypeBool, checkCriticalTypeBoolArray, checkCriticalTypeByteString, checkCriticalTypeByteStringArray, checkCriticalTypeDouble, checkCriticalTypeDoubleArray, checkCriticalTypeFloat, checkCriticalTypeFloatIterable, checkCriticalTypeMessageArray, checkCriticalTypeSignedInt32, checkCriticalTypeSignedInt32Array, checkCriticalTypeSignedInt64, checkCriticalTypeSignedInt64Array, checkCriticalTypeString, checkCriticalTypeStringArray, checkCriticalTypeUnsignedInt32, checkCriticalTypeUnsignedInt32Array, checkDefAndNotNull, checkElementIndex, checkFieldNumber, checkFunctionExists, checkState, checkTypeDouble, checkTypeFloat, checkTypeSignedInt32, checkTypeSignedInt64, checkTypeUnsignedInt32} = goog.require('protobuf.internal.checks'); const {Field, IndexEntry} = goog.require('protobuf.binary.field'); const {buildIndex} = goog.require('protobuf.binary.indexer'); +const {createTag, get32BitVarintLength, getTagLength} = goog.require('protobuf.binary.tag'); /** @@ -53,12 +55,12 @@ function checkIsInternalMessage(obj) { /** * Checks if the instanceCreator returns an instance that implements the * InternalMessage interface. - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @template T */ function checkInstanceCreator(instanceCreator) { if (CHECK_TYPE) { - const emptyMessage = instanceCreator(LazyAccessor.createEmpty()); + const emptyMessage = instanceCreator(Kernel.createEmpty()); checkFunctionExists(emptyMessage.internalGetKernel); } } @@ -138,6 +140,28 @@ function readRepeatedNonPrimitive(indexArray, bufferDecoder, singularReadFunc) { return result; } +/** + * Converts all entries of the index array to the template type using the given + * read function and return an Array containing those converted values. This is + * used to implement parsing repeated non-primitive fields. + * @param {!Array} indexArray + * @param {!BufferDecoder} bufferDecoder + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {!Array} + * @template T + */ +function readRepeatedGroup( + indexArray, bufferDecoder, fieldNumber, instanceCreator, pivot) { + const result = new Array(indexArray.length); + for (let i = 0; i < indexArray.length; i++) { + result[i] = doReadGroup( + bufferDecoder, indexArray[i], fieldNumber, instanceCreator, pivot); + } + return result; +} + /** * Creates a new bytes array to contain all data of a submessage. * When there are multiple entries, merge them together. @@ -156,7 +180,7 @@ function mergeMessageArrays(indexArray, bufferDecoder) { * @param {!Array} indexArray * @param {!BufferDecoder} bufferDecoder * @param {number=} pivot - * @return {!LazyAccessor} + * @return {!Kernel} */ function readAccessor(indexArray, bufferDecoder, pivot = undefined) { checkState(indexArray.length > 0); @@ -173,7 +197,7 @@ function readAccessor(indexArray, bufferDecoder, pivot = undefined) { }); accessorBuffer = mergeMessageArrays(indexArray, bufferDecoder); } - return LazyAccessor.fromBufferDecoder_(accessorBuffer, pivot); + return Kernel.fromBufferDecoder_(accessorBuffer, pivot); } /** @@ -181,7 +205,7 @@ function readAccessor(indexArray, bufferDecoder, pivot = undefined) { * This is used to implement parsing singular message fields. * @param {!Array} indexArray * @param {!BufferDecoder} bufferDecoder - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number=} pivot * @return {T} * @template T @@ -192,6 +216,51 @@ function readMessage(indexArray, bufferDecoder, instanceCreator, pivot) { return instanceCreator(accessor); } +/** + * Merges all index entries of the index array using the given read function. + * This is used to implement parsing singular group fields. + * @param {!Array} indexArray + * @param {!BufferDecoder} bufferDecoder + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {T} + * @template T + */ +function readGroup( + indexArray, bufferDecoder, fieldNumber, instanceCreator, pivot) { + checkInstanceCreator(instanceCreator); + checkState(indexArray.length > 0); + return doReadGroup( + bufferDecoder, indexArray[indexArray.length - 1], fieldNumber, + instanceCreator, pivot); +} + +/** + * Merges all index entries of the index array using the given read function. + * This is used to implement parsing singular message fields. + * @param {!BufferDecoder} bufferDecoder + * @param {!IndexEntry} indexEntry + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {T} + * @template T + */ +function doReadGroup( + bufferDecoder, indexEntry, fieldNumber, instanceCreator, pivot) { + validateWireType(indexEntry, WireType.START_GROUP); + const fieldStartIndex = Field.getStartIndex(indexEntry); + const tag = createTag(WireType.START_GROUP, fieldNumber); + const groupTagLength = get32BitVarintLength(tag); + const groupLength = getTagLength( + bufferDecoder, fieldStartIndex, WireType.START_GROUP, fieldNumber); + const accessorBuffer = bufferDecoder.subBufferDecoder( + fieldStartIndex, groupLength - groupTagLength); + const kernel = Kernel.fromBufferDecoder_(accessorBuffer, pivot); + return instanceCreator(kernel); +} + /** * @param {!Writer} writer * @param {number} fieldNumber @@ -202,6 +271,18 @@ function writeMessage(writer, fieldNumber, value) { fieldNumber, checkDefAndNotNull(value).internalGetKernel().serialize()); } +/** + * @param {!Writer} writer + * @param {number} fieldNumber + * @param {?InternalMessage} value + */ +function writeGroup(writer, fieldNumber, value) { + const kernel = checkDefAndNotNull(value).internalGetKernel(); + writer.writeStartGroup(fieldNumber); + kernel.serializeToWriter(writer); + writer.writeEndGroup(fieldNumber); +} + /** * Writes the array of Messages into the writer for the given field number. * @param {!Writer} writer @@ -214,6 +295,18 @@ function writeRepeatedMessage(writer, fieldNumber, values) { } } +/** + * Writes the array of Messages into the writer for the given field number. + * @param {!Writer} writer + * @param {number} fieldNumber + * @param {!Array} values + */ +function writeRepeatedGroup(writer, fieldNumber, values) { + for (const value of values) { + writeGroup(writer, fieldNumber, value); + } +} + /** * Array.from has a weird type definition in google3/javascript/externs/es6.js * and wants the mapping function accept strings. @@ -247,10 +340,10 @@ class ArrayIterable { * at the first access. * @final */ -class LazyAccessor { +class Kernel { /** - * Create a LazyAccessor for the given binary bytes. - * The bytes array is kept by the LazyAccessor. DON'T MODIFY IT. + * Create a Kernel for the given binary bytes. + * The bytes array is kept by the Kernel. DON'T MODIFY IT. * @param {!ArrayBuffer} arrayBuffer Binary bytes. * @param {number=} pivot Fields with a field number no greater than the pivot * value will be stored in an array for fast access. Other fields will be @@ -259,15 +352,15 @@ class LazyAccessor { * value to the max field number of the message unless the field numbers * are too sparse. If the value is not set, a default value specified in * storage.js will be used. - * @return {!LazyAccessor} + * @return {!Kernel} */ static fromArrayBuffer(arrayBuffer, pivot = undefined) { const bufferDecoder = BufferDecoder.fromArrayBuffer(arrayBuffer); - return LazyAccessor.fromBufferDecoder_(bufferDecoder, pivot); + return Kernel.fromBufferDecoder_(bufferDecoder, pivot); } /** - * Creates an empty LazyAccessor. + * Creates an empty Kernel. * @param {number=} pivot Fields with a field number no greater than the pivot * value will be stored in an array for fast access. Other fields will be * stored in a map. A higher pivot value can improve runtime performance @@ -275,22 +368,22 @@ class LazyAccessor { * value to the max field number of the message unless the field numbers * are too sparse. If the value is not set, a default value specified in * storage.js will be used. - * @return {!LazyAccessor} + * @return {!Kernel} */ static createEmpty(pivot = undefined) { - return new LazyAccessor(/* bufferDecoder= */ null, new Storage(pivot)); + return new Kernel(/* bufferDecoder= */ null, new BinaryStorage(pivot)); } /** - * Create a LazyAccessor for the given binary bytes. - * The bytes array is kept by the LazyAccessor. DON'T MODIFY IT. + * Create a Kernel for the given binary bytes. + * The bytes array is kept by the Kernel. DON'T MODIFY IT. * @param {!BufferDecoder} bufferDecoder Binary bytes. * @param {number|undefined} pivot - * @return {!LazyAccessor} + * @return {!Kernel} * @private */ static fromBufferDecoder_(bufferDecoder, pivot) { - return new LazyAccessor(bufferDecoder, buildIndex(bufferDecoder, pivot)); + return new Kernel(bufferDecoder, buildIndex(bufferDecoder, pivot)); } /** @@ -310,10 +403,10 @@ class LazyAccessor { /** * Creates a shallow copy of the accessor. - * @return {!LazyAccessor} + * @return {!Kernel} */ shallowCopy() { - return new LazyAccessor(this.bufferDecoder_, this.fields_.shallowCopy()); + return new Kernel(this.bufferDecoder_, this.fields_.shallowCopy()); } /** @@ -405,7 +498,8 @@ class LazyAccessor { writer.writeTag(fieldNumber, Field.getWireType(indexEntry)); writer.writeBufferDecoder( checkDefAndNotNull(this.bufferDecoder_), - Field.getStartIndex(indexEntry), Field.getWireType(indexEntry)); + Field.getStartIndex(indexEntry), Field.getWireType(indexEntry), + fieldNumber); } } }); @@ -676,7 +770,7 @@ class LazyAccessor { * getMessageOrNull after getMessage will not register the encoder. * * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number=} pivot * @return {?T} * @template T @@ -689,6 +783,28 @@ class LazyAccessor { writeMessage); } + /** + * Returns data as a mutable proto Message for the given field number. + * If no value has been set, return null. + * If hasFieldNumber(fieldNumber) == false before calling, it remains false. + * + * This method should not be used along with getMessage, since calling + * getMessageOrNull after getMessage will not register the encoder. + * + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {?T} + * @template T + */ + getGroupOrNull(fieldNumber, instanceCreator, pivot = undefined) { + return this.getFieldWithDefault_( + fieldNumber, null, + (indexArray, bytes) => + readGroup(indexArray, bytes, fieldNumber, instanceCreator, pivot), + writeGroup); + } + /** * Returns data as a mutable proto Message for the given field number. * If no value has been set previously, creates and attaches an instance. @@ -698,7 +814,7 @@ class LazyAccessor { * getMessageAttach after getMessage will not register the encoder. * * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number=} pivot * @return {T} * @template T @@ -707,12 +823,36 @@ class LazyAccessor { checkInstanceCreator(instanceCreator); let instance = this.getMessageOrNull(fieldNumber, instanceCreator, pivot); if (!instance) { - instance = instanceCreator(LazyAccessor.createEmpty()); + instance = instanceCreator(Kernel.createEmpty()); this.setField_(fieldNumber, instance, writeMessage); } return instance; } + /** + * Returns data as a mutable proto Message for the given field number. + * If no value has been set previously, creates and attaches an instance. + * Postcondition: hasFieldNumber(fieldNumber) == true. + * + * This method should not be used along with getMessage, since calling + * getMessageAttach after getMessage will not register the encoder. + * + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {T} + * @template T + */ + getGroupAttach(fieldNumber, instanceCreator, pivot = undefined) { + checkInstanceCreator(instanceCreator); + let instance = this.getGroupOrNull(fieldNumber, instanceCreator, pivot); + if (!instance) { + instance = instanceCreator(Kernel.createEmpty()); + this.setField_(fieldNumber, instance, writeGroup); + } + return instance; + } + /** * Returns data as a proto Message for the given field number. * If no value has been set, return a default instance. @@ -726,7 +866,7 @@ class LazyAccessor { * getMessageAttach, since these methods register the encoder. * * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number=} pivot * @return {T} * @template T @@ -740,8 +880,37 @@ class LazyAccessor { // Returns an empty message as the default value if the field doesn't exist. // We don't pass the default value to getFieldWithDefault_ to reduce object // allocation. - return message === null ? instanceCreator(LazyAccessor.createEmpty()) : - message; + return message === null ? instanceCreator(Kernel.createEmpty()) : message; + } + + /** + * Returns data as a proto Message for the given field number. + * If no value has been set, return a default instance. + * This default instance is guaranteed to be the same instance, unless this + * field is cleared. + * Does not register the encoder, so changes made to the returned + * sub-message will not be included when serializing the parent message. + * Use getMessageAttach() if the resulting sub-message should be mutable. + * + * This method should not be used along with getMessageOrNull or + * getMessageAttach, since these methods register the encoder. + * + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {T} + * @template T + */ + getGroup(fieldNumber, instanceCreator, pivot = undefined) { + checkInstanceCreator(instanceCreator); + const message = this.getFieldWithDefault_( + fieldNumber, null, + (indexArray, bytes) => + readGroup(indexArray, bytes, fieldNumber, instanceCreator, pivot)); + // Returns an empty message as the default value if the field doesn't exist. + // We don't pass the default value to getFieldWithDefault_ to reduce object + // allocation. + return message === null ? instanceCreator(Kernel.createEmpty()) : message; } /** @@ -749,7 +918,7 @@ class LazyAccessor { * it hasn't been set. * @param {number} fieldNumber * @param {number=} pivot - * @return {?LazyAccessor} + * @return {?Kernel} */ getMessageAccessorOrNull(fieldNumber, pivot = undefined) { checkFieldNumber(fieldNumber); @@ -808,8 +977,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedBoolIterable(fieldNumber) { - const array = this.getRepeatedBoolArray_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedBoolArray_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedBoolArray_(fieldNumber)); } /** @@ -857,8 +1028,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedDoubleIterable(fieldNumber) { - const array = this.getRepeatedDoubleArray_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedDoubleArray_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedDoubleArray_(fieldNumber)); } /** @@ -906,8 +1079,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedFixed32Iterable(fieldNumber) { - const array = this.getRepeatedFixed32Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedFixed32Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedFixed32Array_(fieldNumber)); } /** @@ -986,8 +1161,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedFloatIterable(fieldNumber) { - const array = this.getRepeatedFloatArray_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedFloatArray_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedFloatArray_(fieldNumber)); } /** @@ -1035,8 +1212,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedInt32Iterable(fieldNumber) { - const array = this.getRepeatedInt32Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedInt32Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedInt32Array_(fieldNumber)); } /** @@ -1084,8 +1263,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedInt64Iterable(fieldNumber) { - const array = this.getRepeatedInt64Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedInt64Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedInt64Array_(fieldNumber)); } /** @@ -1133,8 +1314,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedSfixed32Iterable(fieldNumber) { - const array = this.getRepeatedSfixed32Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedSfixed32Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedSfixed32Array_(fieldNumber)); } /** @@ -1182,8 +1365,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedSfixed64Iterable(fieldNumber) { - const array = this.getRepeatedSfixed64Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedSfixed64Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedSfixed64Array_(fieldNumber)); } /** @@ -1231,8 +1416,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedSint32Iterable(fieldNumber) { - const array = this.getRepeatedSint32Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedSint32Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedSint32Array_(fieldNumber)); } /** @@ -1280,8 +1467,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedSint64Iterable(fieldNumber) { - const array = this.getRepeatedSint64Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedSint64Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedSint64Array_(fieldNumber)); } /** @@ -1329,8 +1518,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedUint32Iterable(fieldNumber) { - const array = this.getRepeatedUint32Array_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedUint32Array_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedUint32Array_(fieldNumber)); } /** @@ -1408,8 +1599,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedBytesIterable(fieldNumber) { - const array = this.getRepeatedBytesArray_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedBytesArray_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedBytesArray_(fieldNumber)); } /** @@ -1456,8 +1649,10 @@ class LazyAccessor { * @return {!Iterable} */ getRepeatedStringIterable(fieldNumber) { - const array = this.getRepeatedStringArray_(fieldNumber); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedStringArray_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable(this.getRepeatedStringArray_(fieldNumber)); } /** @@ -1475,31 +1670,48 @@ class LazyAccessor { * Returns an Array instance containing boolean values for the given field * number. * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number|undefined} pivot * @return {!Array} * @template T * @private */ getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot) { + // This method can be shortened using getFieldWithDefault and + // getRepeatedNonPrimitive methods. But that will require creating and + // passing a reader closure every time getRepeatedMessageArray_ is called, + // which is expensive. checkInstanceCreator(instanceCreator); - const bytesInstanceCreator = (bufferDecoder) => - instanceCreator(LazyAccessor.fromBufferDecoder_(bufferDecoder, pivot)); - const readMessageFunc = (bufferDecoder, start) => - bytesInstanceCreator(reader.readDelimited(bufferDecoder, start)); - - const readRepeatedMessageFunc = (indexArray, bufferDecoder) => - readRepeatedNonPrimitive(indexArray, bufferDecoder, readMessageFunc); - const encoder = (writer, fieldNumber, values) => - writeRepeatedMessage(writer, fieldNumber, values); - return this.getFieldWithDefault_( - fieldNumber, /* defaultValue= */[], readRepeatedMessageFunc, encoder); + checkFieldNumber(fieldNumber); + + const field = this.fields_.get(fieldNumber); + if (field === undefined) { + return []; + } + + if (field.hasDecodedValue()) { + return field.getDecodedValue(); + } + + const indexArray = checkDefAndNotNull(field.getIndexArray()); + const result = new Array(indexArray.length); + for (let i = 0; i < indexArray.length; i++) { + validateWireType(indexArray[i], WireType.DELIMITED); + const subMessageBuffer = reader.readDelimited( + checkDefAndNotNull(this.bufferDecoder_), + Field.getStartIndex(indexArray[i])); + result[i] = + instanceCreator(Kernel.fromBufferDecoder_(subMessageBuffer, pivot)); + } + field.setCache(result, writeRepeatedMessage); + + return result; } /** * Returns the element at index for the given field number as a message. * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number} index * @param {number=} pivot * @return {T} @@ -1517,15 +1729,17 @@ class LazyAccessor { * Returns an Iterable instance containing message values for the given field * number. * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number=} pivot * @return {!Iterable} * @template T */ getRepeatedMessageIterable(fieldNumber, instanceCreator, pivot = undefined) { - const array = - this.getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot); - return new ArrayIterable(array); + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedMessageArray_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable( + this.getRepeatedMessageArray_(fieldNumber, instanceCreator, pivot)); } /** @@ -1533,7 +1747,7 @@ class LazyAccessor { * field number. * @param {number} fieldNumber * @param {number=} pivot - * @return {!Iterable} + * @return {!Iterable} */ getRepeatedMessageAccessorIterable(fieldNumber, pivot = undefined) { checkFieldNumber(fieldNumber); @@ -1548,9 +1762,8 @@ class LazyAccessor { value => checkIsInternalMessage(value).internalGetKernel())); } - const readMessageFunc = (bufferDecoder, start) => - LazyAccessor.fromBufferDecoder_( - reader.readDelimited(bufferDecoder, start), pivot); + const readMessageFunc = (bufferDecoder, start) => Kernel.fromBufferDecoder_( + reader.readDelimited(bufferDecoder, start), pivot); const array = readRepeatedNonPrimitive( checkDefAndNotNull(field.getIndexArray()), checkDefAndNotNull(this.bufferDecoder_), readMessageFunc); @@ -1560,7 +1773,7 @@ class LazyAccessor { /** * Returns the size of the repeated field. * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @return {number} * @param {number=} pivot * @template T @@ -1570,6 +1783,71 @@ class LazyAccessor { .length; } + /** + * Returns an Array instance containing boolean values for the given field + * number. + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number|undefined} pivot + * @return {!Array} + * @template T + * @private + */ + getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot) { + return this.getFieldWithDefault_( + fieldNumber, [], + (indexArray, bufferDecoder) => readRepeatedGroup( + indexArray, bufferDecoder, fieldNumber, instanceCreator, pivot), + writeRepeatedGroup); + } + + /** + * Returns the element at index for the given field number as a group. + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number} index + * @param {number=} pivot + * @return {T} + * @template T + */ + getRepeatedGroupElement( + fieldNumber, instanceCreator, index, pivot = undefined) { + const array = + this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot); + checkCriticalElementIndex(index, array.length); + return array[index]; + } + + /** + * Returns an Iterable instance containing group values for the given field + * number. + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {!Iterable} + * @template T + */ + getRepeatedGroupIterable(fieldNumber, instanceCreator, pivot = undefined) { + // Don't split this statement unless needed. JS compiler thinks + // getRepeatedMessageArray_ might have side effects and doesn't inline the + // call in the compiled code. See cl/293894484 for details. + return new ArrayIterable( + this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot)); + } + + /** + * Returns the size of the repeated field. + * @param {number} fieldNumber + * @param {function(!Kernel):T} instanceCreator + * @return {number} + * @param {number=} pivot + * @template T + */ + getRepeatedGroupSize(fieldNumber, instanceCreator, pivot = undefined) { + return this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot) + .length; + } + /*************************************************************************** * OPTIONAL SETTER METHODS ***************************************************************************/ @@ -1757,9 +2035,23 @@ class LazyAccessor { this.setInt64(fieldNumber, value); } + /** + * Sets a proto Group to the field with the given field number. + * Instead of working with the Kernel inside of the message directly, we + * need the message instance to keep its reference equality for subsequent + * gettings. + * @param {number} fieldNumber + * @param {!InternalMessage} value + */ + setGroup(fieldNumber, value) { + checkCriticalType( + value !== null, 'Given value is not a message instance: null'); + this.setField_(fieldNumber, value, writeGroup); + } + /** * Sets a proto Message to the field with the given field number. - * Instead of working with the LazyAccessor inside of the message directly, we + * Instead of working with the Kernel inside of the message directly, we * need the message instance to keep its reference equality for subsequent * gettings. * @param {number} fieldNumber @@ -3712,7 +4004,7 @@ class LazyAccessor { * Adds all message values into the field for the given field number. * @param {number} fieldNumber * @param {!Iterable} values - * @param {function(!LazyAccessor):!InternalMessage} instanceCreator + * @param {function(!Kernel):!InternalMessage} instanceCreator * @param {number=} pivot */ addRepeatedMessageIterable( @@ -3734,7 +4026,7 @@ class LazyAccessor { * the given index. * @param {number} fieldNumber * @param {!InternalMessage} value - * @param {function(!LazyAccessor):!InternalMessage} instanceCreator + * @param {function(!Kernel):!InternalMessage} instanceCreator * @param {number} index * @param {number=} pivot * @throws {!Error} if index is out of range when check mode is critical @@ -3754,7 +4046,7 @@ class LazyAccessor { * Adds a single message value into the field for the given field number. * @param {number} fieldNumber * @param {!InternalMessage} value - * @param {function(!LazyAccessor):!InternalMessage} instanceCreator + * @param {function(!Kernel):!InternalMessage} instanceCreator * @param {number=} pivot */ addRepeatedMessageElement( @@ -3762,6 +4054,69 @@ class LazyAccessor { this.addRepeatedMessageIterable( fieldNumber, [value], instanceCreator, pivot); } + + // Groups + /** + * Sets all message values into the field for the given field number. + * @param {number} fieldNumber + * @param {!Iterable} values + */ + setRepeatedGroupIterable(fieldNumber, values) { + const /** !Array */ array = Array.from(values); + checkCriticalTypeMessageArray(array); + this.setField_(fieldNumber, array, writeRepeatedGroup); + } + + /** + * Adds all message values into the field for the given field number. + * @param {number} fieldNumber + * @param {!Iterable} values + * @param {function(!Kernel):!InternalMessage} instanceCreator + * @param {number=} pivot + */ + addRepeatedGroupIterable( + fieldNumber, values, instanceCreator, pivot = undefined) { + const array = [ + ...this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot), + ...values, + ]; + checkCriticalTypeMessageArray(array); + // Needs to set it back with the new array. + this.setField_(fieldNumber, array, writeRepeatedGroup); + } + + /** + * Sets a single message value into the field for the given field number at + * the given index. + * @param {number} fieldNumber + * @param {!InternalMessage} value + * @param {function(!Kernel):!InternalMessage} instanceCreator + * @param {number} index + * @param {number=} pivot + * @throws {!Error} if index is out of range when check mode is critical + */ + setRepeatedGroupElement( + fieldNumber, value, instanceCreator, index, pivot = undefined) { + checkInstanceCreator(instanceCreator); + checkCriticalType( + value !== null, 'Given value is not a message instance: null'); + const array = + this.getRepeatedGroupArray_(fieldNumber, instanceCreator, pivot); + checkCriticalElementIndex(index, array.length); + array[index] = value; + } + + /** + * Adds a single message value into the field for the given field number. + * @param {number} fieldNumber + * @param {!InternalMessage} value + * @param {function(!Kernel):!InternalMessage} instanceCreator + * @param {number=} pivot + */ + addRepeatedGroupElement( + fieldNumber, value, instanceCreator, pivot = undefined) { + this.addRepeatedGroupIterable(fieldNumber, [value], instanceCreator, pivot); + } } -exports = LazyAccessor; +exports = Kernel; diff --git a/js/experimental/runtime/kernel/lazy_accessor_compatibility_test.js b/js/experimental/runtime/kernel/kernel_compatibility_test.js similarity index 77% rename from js/experimental/runtime/kernel/lazy_accessor_compatibility_test.js rename to js/experimental/runtime/kernel/kernel_compatibility_test.js index d3eab20b9728..155008f7b1e5 100644 --- a/js/experimental/runtime/kernel/lazy_accessor_compatibility_test.js +++ b/js/experimental/runtime/kernel/kernel_compatibility_test.js @@ -1,5 +1,5 @@ /** - * @fileoverview Tests to make sure LazyAccessor can read data in a backward + * @fileoverview Tests to make sure Kernel can read data in a backward * compatible way even when protobuf schema changes according to the rules * defined in * https://developers.google.com/protocol-buffers/docs/proto#updating and @@ -10,13 +10,13 @@ * by binary_json_conformance_suite. Ultimately all of the tests in this file * should be moved to binary_json_conformance_suite. */ -goog.module('protobuf.binary.LazyAccessorCompatibilityTest'); +goog.module('protobuf.runtime.KernelCompatibilityTest'); goog.setTestOnly(); const ByteString = goog.require('protobuf.ByteString'); const Int64 = goog.require('protobuf.Int64'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); @@ -39,26 +39,26 @@ function getCharacterCodes(str) { describe('optional -> repeated compatibility', () => { it('is maintained for scalars', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setInt32(1, 1); const serializedData = oldAccessor.serialize(); expect(serializedData).toEqual(createArrayBuffer(0x8, 0x1)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getRepeatedInt32Size(1)).toEqual(1); expect(newAccessor.getRepeatedInt32Element(1, 0)).toEqual(1); }); it('is maintained for messages', () => { - const message = new TestMessage(LazyAccessor.createEmpty()); + const message = new TestMessage(Kernel.createEmpty()); message.setInt32(1, 1); - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setMessage(1, message); const serializedData = oldAccessor.serialize(); expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getRepeatedMessageSize(1, TestMessage.instanceCreator)) .toEqual(1); expect( @@ -68,43 +68,43 @@ describe('optional -> repeated compatibility', () => { }); it('is maintained for bytes', () => { - const message = new TestMessage(LazyAccessor.createEmpty()); + const message = new TestMessage(Kernel.createEmpty()); message.setInt32(1, 1); - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setBytes( 1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); const serializedData = oldAccessor.serialize(); expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getRepeatedBytesSize(1)).toEqual(1); expect(newAccessor.getRepeatedBoolElement(1, 0)) .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); }); it('is maintained for strings', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setString(1, 'hello'); const serializedData = oldAccessor.serialize(); expect(serializedData) .toEqual(createArrayBuffer(0xA, 0x5, 0x68, 0x65, 0x6C, 0x6C, 0x6F)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getRepeatedStringSize(1)).toEqual(1); expect(newAccessor.getRepeatedStringElement(1, 0)).toEqual('hello'); }); }); -describe('LazyAccessor repeated -> optional compatibility', () => { +describe('Kernel repeated -> optional compatibility', () => { it('is maintained for unpacked scalars', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.addUnpackedInt32Element(1, 0); oldAccessor.addUnpackedInt32Element(1, 1); const serializedData = oldAccessor.serialize(); expect(serializedData).toEqual(createArrayBuffer(0x8, 0x0, 0x8, 0x1)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getInt32WithDefault(1)).toEqual(1); expect(newAccessor.serialize()).toEqual(serializedData); }); @@ -112,26 +112,26 @@ describe('LazyAccessor repeated -> optional compatibility', () => { // repeated -> optional transformation is not supported for packed fields yet: // go/proto-schema-repeated it('is not maintained for packed scalars', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.addPackedInt32Element(1, 0); oldAccessor.addPackedInt32Element(1, 1); const serializedData = oldAccessor.serialize(); expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x0, 0x1)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); if (CHECK_CRITICAL_STATE) { expect(() => newAccessor.getInt32WithDefault(1)).toThrow(); } }); it('is maintained for messages', () => { - const message1 = new TestMessage(LazyAccessor.createEmpty()); + const message1 = new TestMessage(Kernel.createEmpty()); message1.setInt32(1, 1); - const message2 = new TestMessage(LazyAccessor.createEmpty()); + const message2 = new TestMessage(Kernel.createEmpty()); message2.setInt32(1, 2); message2.setInt32(2, 3); - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.addRepeatedMessageElement( 1, message1, TestMessage.instanceCreator); oldAccessor.addRepeatedMessageElement( @@ -141,7 +141,7 @@ describe('LazyAccessor repeated -> optional compatibility', () => { .toEqual(createArrayBuffer( 0xA, 0x2, 0x8, 0x1, 0xA, 0x4, 0x8, 0x2, 0x10, 0x3)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); // Values from message1 and message2 have been merged const newMessage = newAccessor.getMessage(1, TestMessage.instanceCreator); expect(newMessage.getRepeatedInt32Size(1)).toEqual(2); @@ -153,7 +153,7 @@ describe('LazyAccessor repeated -> optional compatibility', () => { }); it('is maintained for bytes', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.addRepeatedBytesElement( 1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB))); oldAccessor.addRepeatedBytesElement( @@ -162,14 +162,14 @@ describe('LazyAccessor repeated -> optional compatibility', () => { expect(serializedData) .toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB, 0xA, 0x2, 0xC, 0xD)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getBytesWithDefault(1)) .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xC, 0xD))); expect(newAccessor.serialize()).toEqual(serializedData); }); it('is maintained for strings', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.addRepeatedStringElement(1, 'hello'); oldAccessor.addRepeatedStringElement(1, 'world'); const serializedData = oldAccessor.serialize(); @@ -178,7 +178,7 @@ describe('LazyAccessor repeated -> optional compatibility', () => { 0xA, 0x5, ...getCharacterCodes('hello'), 0xA, 0x5, ...getCharacterCodes('world'))); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getStringWithDefault(1)).toEqual('world'); expect(newAccessor.serialize()).toEqual(serializedData); }); @@ -186,64 +186,64 @@ describe('LazyAccessor repeated -> optional compatibility', () => { describe('Type change', () => { it('is supported for fixed32 -> sfixed32', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setFixed32(1, 4294967295); const serializedData = oldAccessor.serialize(); expect(serializedData) .toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getSfixed32WithDefault(1)).toEqual(-1); expect(newAccessor.serialize()).toEqual(serializedData); }); it('is supported for sfixed32 -> fixed32', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setSfixed32(1, -1); const serializedData = oldAccessor.serialize(); expect(serializedData) .toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getFixed32WithDefault(1)).toEqual(4294967295); expect(newAccessor.serialize()).toEqual(serializedData); }); it('is supported for fixed64 -> sfixed64', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setFixed64(1, Int64.fromHexString('0xFFFFFFFFFFFFFFFF')); const serializedData = oldAccessor.serialize(); expect(serializedData) .toEqual(createArrayBuffer( 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(-1)); expect(newAccessor.serialize()).toEqual(serializedData); }); it('is supported for sfixed64 -> fixed64', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setSfixed64(1, Int64.fromInt(-1)); const serializedData = oldAccessor.serialize(); expect(serializedData) .toEqual(createArrayBuffer( 0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getFixed64WithDefault(1)) .toEqual(Int64.fromHexString('0xFFFFFFFFFFFFFFFF')); expect(newAccessor.serialize()).toEqual(serializedData); }); it('is supported for bytes -> message', () => { - const oldAccessor = LazyAccessor.createEmpty(); + const oldAccessor = Kernel.createEmpty(); oldAccessor.setBytes( 1, ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1))); const serializedData = oldAccessor.serialize(); expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); const message = newAccessor.getMessage(1, TestMessage.instanceCreator); expect(message.getInt32WithDefault(1)).toEqual(1); expect(message.serialize()).toEqual(createArrayBuffer(0x8, 0x1)); @@ -251,14 +251,14 @@ describe('Type change', () => { }); it('is supported for message -> bytes', () => { - const oldAccessor = LazyAccessor.createEmpty(); - const message = new TestMessage(LazyAccessor.createEmpty()); + const oldAccessor = Kernel.createEmpty(); + const message = new TestMessage(Kernel.createEmpty()); message.setInt32(1, 1); oldAccessor.setMessage(1, message); const serializedData = oldAccessor.serialize(); expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1)); - const newAccessor = LazyAccessor.fromArrayBuffer(serializedData); + const newAccessor = Kernel.fromArrayBuffer(serializedData); expect(newAccessor.getBytesWithDefault(1)) .toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1))); expect(newAccessor.serialize()).toEqual(serializedData); diff --git a/js/experimental/runtime/kernel/lazy_accessor_repeated_test.js b/js/experimental/runtime/kernel/kernel_repeated_test.js similarity index 83% rename from js/experimental/runtime/kernel/lazy_accessor_repeated_test.js rename to js/experimental/runtime/kernel/kernel_repeated_test.js index 77c4c5925ab6..6a798b6c09f0 100644 --- a/js/experimental/runtime/kernel/lazy_accessor_repeated_test.js +++ b/js/experimental/runtime/kernel/kernel_repeated_test.js @@ -1,14 +1,14 @@ /** - * @fileoverview Tests for repeated methods in lazy_accessor.js. + * @fileoverview Tests for repeated methods in kernel.js. */ -goog.module('protobuf.binary.LazyAccessorTest'); +goog.module('protobuf.runtime.KernelTest'); goog.setTestOnly(); const ByteString = goog.require('protobuf.ByteString'); const Int64 = goog.require('protobuf.Int64'); const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); // Note to the reader: // Since the lazy accessor behavior changes with the checking level some of the @@ -68,33 +68,33 @@ function expectEqualToMessageArray(iterable, expected) { } } -describe('LazyAccessor for repeated boolean does', () => { +describe('Kernel for repeated boolean does', () => { it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expectEqualToArray(accessor.getRepeatedBoolIterable(1), []); }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedBoolIterable(1); const list2 = accessor.getRepeatedBoolIterable(1); expect(list1).not.toBe(list2); }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expect(accessor.getRepeatedBoolSize(1)).toEqual(0); }); it('return unpacked values from the input', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); }); it('ensure not the same instance returned for unpacked values', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const list1 = accessor.getRepeatedBoolIterable(1); const list2 = accessor.getRepeatedBoolIterable(1); expect(list1).not.toBe(list2); @@ -102,12 +102,12 @@ describe('LazyAccessor for repeated boolean does', () => { it('return unpacked multibytes values from the input', () => { const bytes = createArrayBuffer(0x08, 0x80, 0x01, 0x08, 0x80, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); }); it('return for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedBoolElement(1, true); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); accessor.addUnpackedBoolElement(1, false); @@ -115,7 +115,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('return for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedBoolIterable(1, [true]); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); accessor.addUnpackedBoolIterable(1, [false]); @@ -124,13 +124,13 @@ describe('LazyAccessor for repeated boolean does', () => { it('return for setting single unpacked value', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); accessor.setUnpackedBoolElement(1, 0, true); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, true]); }); it('return for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedBoolIterable(1, [true]); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); accessor.setUnpackedBoolIterable(1, [false]); @@ -138,7 +138,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); accessor.addUnpackedBoolElement(1, true); accessor.addUnpackedBoolElement(1, false); @@ -146,7 +146,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); accessor.addUnpackedBoolIterable(1, [true, false]); expect(accessor.serialize()).toEqual(bytes); @@ -154,14 +154,14 @@ describe('LazyAccessor for repeated boolean does', () => { it('encode for setting single unpacked value', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x00, 0x01)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x00, 0x01)); const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x01); accessor.setUnpackedBoolElement(1, 0, true); expect(accessor.serialize()).toEqual(bytes); }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); accessor.setUnpackedBoolIterable(1, [true, false]); expect(accessor.serialize()).toEqual(bytes); @@ -169,13 +169,13 @@ describe('LazyAccessor for repeated boolean does', () => { it('return packed values from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); }); it('ensure not the same instance returned for packed values', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const list1 = accessor.getRepeatedBoolIterable(1); const list2 = accessor.getRepeatedBoolIterable(1); expect(list1).not.toBe(list2); @@ -183,12 +183,12 @@ describe('LazyAccessor for repeated boolean does', () => { it('return packed multibytes values from the input', () => { const bytes = createArrayBuffer(0x0A, 0x04, 0x80, 0x01, 0x80, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, false]); }); it('return for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedBoolElement(1, true); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); accessor.addPackedBoolElement(1, false); @@ -196,7 +196,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('return for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedBoolIterable(1, [true]); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); accessor.addPackedBoolIterable(1, [false]); @@ -205,13 +205,13 @@ describe('LazyAccessor for repeated boolean does', () => { it('return for setting single packed value', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); accessor.setPackedBoolElement(1, 0, true); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true, true]); }); it('return for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedBoolIterable(1, [true]); expectEqualToArray(accessor.getRepeatedBoolIterable(1), [true]); accessor.setPackedBoolIterable(1, [false]); @@ -219,7 +219,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); accessor.addPackedBoolElement(1, true); accessor.addPackedBoolElement(1, false); @@ -227,7 +227,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); accessor.addPackedBoolIterable(1, [true, false]); expect(accessor.serialize()).toEqual(bytes); @@ -235,14 +235,14 @@ describe('LazyAccessor for repeated boolean does', () => { it('encode for setting single packed value', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00, 0x08, 0x01)); const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x01); accessor.setPackedBoolElement(1, 0, true); expect(accessor.serialize()).toEqual(bytes); }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes = createArrayBuffer(0x0A, 0x02, 0x01, 0x00); accessor.setPackedBoolIterable(1, [true, false]); expect(accessor.serialize()).toEqual(bytes); @@ -251,14 +251,14 @@ describe('LazyAccessor for repeated boolean does', () => { it('return combined values from the input', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x0A, 0x02, 0x01, 0x00, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expectEqualToArray( accessor.getRepeatedBoolIterable(1), [true, true, false, false]); }); it('return the repeated field element from the input', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getRepeatedBoolElement( /* fieldNumber= */ 1, /* index= */ 0)) .toEqual(true); @@ -269,12 +269,12 @@ describe('LazyAccessor for repeated boolean does', () => { it('return the size from the input', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getRepeatedBoolSize(1)).toEqual(2); }); it('fail when getting unpacked bool value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { @@ -290,7 +290,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when adding unpacked bool values with number value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedBoolIterable(1, [fakeBoolean])) @@ -306,7 +306,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when adding single unpacked bool value with number value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedBoolElement(1, fakeBoolean)) @@ -322,7 +322,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when setting unpacked bool values with number value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedBoolIterable(1, [fakeBoolean])) @@ -338,8 +338,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when setting single unpacked bool value with number value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedBoolElement(1, 0, fakeBoolean)) @@ -355,7 +354,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when adding packed bool values with number value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedBoolIterable(1, [fakeBoolean])) @@ -371,7 +370,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when adding single packed bool value with number value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedBoolElement(1, fakeBoolean)) @@ -387,7 +386,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when setting packed bool values with number value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedBoolIterable(1, [fakeBoolean])) @@ -403,8 +402,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when setting single packed bool value with number value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedBoolElement(1, 0, fakeBoolean)) @@ -420,8 +418,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedBoolElement(1, 1, true)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -436,8 +433,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedBoolElement(1, 1, true)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -452,7 +448,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedBoolElement( @@ -470,7 +466,7 @@ describe('LazyAccessor for repeated boolean does', () => { }); }); -describe('LazyAccessor for repeated double does', () => { +describe('Kernel for repeated double does', () => { const value1 = 1; const value2 = 0; @@ -557,7 +553,7 @@ describe('LazyAccessor for repeated double does', () => { ); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedDoubleIterable(1); @@ -565,7 +561,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedDoubleIterable(1); const list2 = accessor.getRepeatedDoubleIterable(1); @@ -574,7 +570,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedDoubleSize(1); @@ -582,7 +578,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedDoubleIterable(1); @@ -590,7 +586,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedDoubleIterable(1); const list2 = accessor.getRepeatedDoubleIterable(1); @@ -599,7 +595,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedDoubleElement(1, value1); const list1 = accessor.getRepeatedDoubleIterable(1); @@ -611,7 +607,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedDoubleIterable(1, [value1]); const list1 = accessor.getRepeatedDoubleIterable(1); @@ -623,7 +619,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedDoubleElement(1, 1, value1); const list = accessor.getRepeatedDoubleIterable(1); @@ -632,7 +628,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedDoubleIterable(1, [value1]); const list = accessor.getRepeatedDoubleIterable(1); @@ -641,7 +637,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedDoubleElement(1, value1); accessor.addUnpackedDoubleElement(1, value2); @@ -651,7 +647,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedDoubleIterable(1, [value1]); accessor.addUnpackedDoubleIterable(1, [value2]); @@ -661,7 +657,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedDoubleElement(1, 0, value2); accessor.setUnpackedDoubleElement(1, 1, value1); @@ -671,7 +667,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedDoubleIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -680,7 +676,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedDoubleIterable(1); @@ -688,7 +684,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedDoubleIterable(1); const list2 = accessor.getRepeatedDoubleIterable(1); @@ -697,7 +693,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedDoubleElement(1, value1); const list1 = accessor.getRepeatedDoubleIterable(1); @@ -709,7 +705,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedDoubleIterable(1, [value1]); const list1 = accessor.getRepeatedDoubleIterable(1); @@ -721,7 +717,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedDoubleElement(1, 1, value1); const list = accessor.getRepeatedDoubleIterable(1); @@ -730,7 +726,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedDoubleIterable(1, [value1]); const list1 = accessor.getRepeatedDoubleIterable(1); @@ -742,7 +738,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedDoubleElement(1, value1); accessor.addPackedDoubleElement(1, value2); @@ -752,7 +748,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedDoubleIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -761,7 +757,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedDoubleElement(1, 0, value2); accessor.setPackedDoubleElement(1, 1, value1); @@ -772,7 +768,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedDoubleIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -781,7 +777,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, @@ -826,7 +822,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedDoubleElement( /* fieldNumber= */ 1, /* index= */ 0); @@ -838,7 +834,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedDoubleSize(1); @@ -846,7 +842,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when getting unpacked double value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { @@ -863,7 +859,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when adding unpacked double values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedDoubleIterable(1, [fakeDouble])) @@ -879,7 +875,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when adding single unpacked double value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedDoubleElement(1, fakeDouble)) @@ -895,7 +891,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when setting unpacked double values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedDoubleIterable(1, [fakeDouble])) @@ -911,7 +907,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when setting single unpacked double value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -928,7 +924,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when adding packed double values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedDoubleIterable(1, [fakeDouble])) @@ -944,7 +940,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when adding single packed double value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedDoubleElement(1, fakeDouble)) @@ -960,7 +956,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when setting packed double values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedDoubleIterable(1, [fakeDouble])) @@ -976,7 +972,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when setting single packed double value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); const fakeDouble = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -993,7 +989,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedDoubleElement(1, 1, 1)) @@ -1009,7 +1005,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedDoubleElement(1, 1, 1)) @@ -1025,7 +1021,7 @@ describe('LazyAccessor for repeated double does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedDoubleElement( @@ -1043,7 +1039,7 @@ describe('LazyAccessor for repeated double does', () => { }); }); -describe('LazyAccessor for repeated fixed32 does', () => { +describe('Kernel for repeated fixed32 does', () => { const value1 = 1; const value2 = 0; @@ -1058,7 +1054,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { 0x0A, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedFixed32Iterable(1); @@ -1066,7 +1062,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedFixed32Iterable(1); const list2 = accessor.getRepeatedFixed32Iterable(1); @@ -1075,7 +1071,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedFixed32Size(1); @@ -1083,7 +1079,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedFixed32Iterable(1); @@ -1091,7 +1087,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedFixed32Iterable(1); const list2 = accessor.getRepeatedFixed32Iterable(1); @@ -1100,7 +1096,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed32Element(1, value1); const list1 = accessor.getRepeatedFixed32Iterable(1); @@ -1112,7 +1108,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed32Iterable(1, [value1]); const list1 = accessor.getRepeatedFixed32Iterable(1); @@ -1124,7 +1120,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedFixed32Element(1, 1, value1); const list = accessor.getRepeatedFixed32Iterable(1); @@ -1133,7 +1129,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedFixed32Iterable(1, [value1]); const list = accessor.getRepeatedFixed32Iterable(1); @@ -1142,7 +1138,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed32Element(1, value1); accessor.addUnpackedFixed32Element(1, value2); @@ -1152,7 +1148,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed32Iterable(1, [value1]); accessor.addUnpackedFixed32Iterable(1, [value2]); @@ -1162,7 +1158,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedFixed32Element(1, 0, value2); accessor.setUnpackedFixed32Element(1, 1, value1); @@ -1172,7 +1168,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedFixed32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -1181,7 +1177,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedFixed32Iterable(1); @@ -1189,7 +1185,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedFixed32Iterable(1); const list2 = accessor.getRepeatedFixed32Iterable(1); @@ -1198,7 +1194,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed32Element(1, value1); const list1 = accessor.getRepeatedFixed32Iterable(1); @@ -1210,7 +1206,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed32Iterable(1, [value1]); const list1 = accessor.getRepeatedFixed32Iterable(1); @@ -1222,7 +1218,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedFixed32Element(1, 1, value1); const list = accessor.getRepeatedFixed32Iterable(1); @@ -1231,7 +1227,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedFixed32Iterable(1, [value1]); const list1 = accessor.getRepeatedFixed32Iterable(1); @@ -1243,7 +1239,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed32Element(1, value1); accessor.addPackedFixed32Element(1, value2); @@ -1253,7 +1249,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -1262,7 +1258,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedFixed32Element(1, 0, value2); accessor.setPackedFixed32Element(1, 1, value1); @@ -1273,7 +1269,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedFixed32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -1282,7 +1278,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x01, 0x00, @@ -1311,7 +1307,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedFixed32Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -1323,7 +1319,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedFixed32Size(1); @@ -1331,8 +1327,8 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when getting unpacked fixed32 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedFixed32Iterable(1); @@ -1349,7 +1345,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when adding unpacked fixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedFixed32Iterable(1, [fakeFixed32])) @@ -1365,7 +1361,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when adding single unpacked fixed32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedFixed32Element(1, fakeFixed32)) @@ -1381,7 +1377,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when setting unpacked fixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFixed32Iterable(1, [fakeFixed32])) @@ -1397,8 +1393,8 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when setting single unpacked fixed32 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFixed32Element(1, 0, fakeFixed32)) @@ -1416,7 +1412,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when adding packed fixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedFixed32Iterable(1, [fakeFixed32])) @@ -1432,7 +1428,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when adding single packed fixed32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedFixed32Element(1, fakeFixed32)) @@ -1448,7 +1444,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when setting packed fixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFixed32Iterable(1, [fakeFixed32])) @@ -1464,8 +1460,8 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when setting single packed fixed32 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); const fakeFixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFixed32Element(1, 0, fakeFixed32)) @@ -1481,7 +1477,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer( + const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0A, 0x04, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFixed32Element(1, 1, 1)) @@ -1499,8 +1495,8 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFixed32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -1517,7 +1513,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedFixed32Element( @@ -1535,7 +1531,7 @@ describe('LazyAccessor for repeated fixed32 does', () => { }); }); -describe('LazyAccessor for repeated fixed64 does', () => { +describe('Kernel for repeated fixed64 does', () => { const value1 = Int64.fromInt(1); const value2 = Int64.fromInt(0); @@ -1622,7 +1618,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { ); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedFixed64Iterable(1); @@ -1630,7 +1626,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedFixed64Iterable(1); const list2 = accessor.getRepeatedFixed64Iterable(1); @@ -1639,7 +1635,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedFixed64Size(1); @@ -1647,7 +1643,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedFixed64Iterable(1); @@ -1655,7 +1651,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedFixed64Iterable(1); const list2 = accessor.getRepeatedFixed64Iterable(1); @@ -1664,7 +1660,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed64Element(1, value1); const list1 = accessor.getRepeatedFixed64Iterable(1); @@ -1676,7 +1672,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed64Iterable(1, [value1]); const list1 = accessor.getRepeatedFixed64Iterable(1); @@ -1688,7 +1684,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedFixed64Element(1, 1, value1); const list = accessor.getRepeatedFixed64Iterable(1); @@ -1697,7 +1693,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedFixed64Iterable(1, [value1]); const list = accessor.getRepeatedFixed64Iterable(1); @@ -1706,7 +1702,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed64Element(1, value1); accessor.addUnpackedFixed64Element(1, value2); @@ -1716,7 +1712,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFixed64Iterable(1, [value1]); accessor.addUnpackedFixed64Iterable(1, [value2]); @@ -1726,7 +1722,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedFixed64Element(1, 0, value2); accessor.setUnpackedFixed64Element(1, 1, value1); @@ -1736,7 +1732,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedFixed64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -1745,7 +1741,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedFixed64Iterable(1); @@ -1753,7 +1749,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedFixed64Iterable(1); const list2 = accessor.getRepeatedFixed64Iterable(1); @@ -1762,7 +1758,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed64Element(1, value1); const list1 = accessor.getRepeatedFixed64Iterable(1); @@ -1774,7 +1770,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed64Iterable(1, [value1]); const list1 = accessor.getRepeatedFixed64Iterable(1); @@ -1786,7 +1782,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedFixed64Element(1, 1, value1); const list = accessor.getRepeatedFixed64Iterable(1); @@ -1795,7 +1791,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedFixed64Iterable(1, [value1]); const list1 = accessor.getRepeatedFixed64Iterable(1); @@ -1807,7 +1803,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed64Element(1, value1); accessor.addPackedFixed64Element(1, value2); @@ -1817,7 +1813,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFixed64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -1826,7 +1822,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedFixed64Element(1, 0, value2); accessor.setPackedFixed64Element(1, 1, value1); @@ -1837,7 +1833,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedFixed64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -1846,7 +1842,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 0x0A, 0x10, // tag 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 @@ -1860,7 +1856,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedFixed64Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -1872,7 +1868,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedFixed64Size(1); @@ -1880,7 +1876,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when getting unpacked fixed64 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { @@ -1898,7 +1894,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when adding unpacked fixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedFixed64Iterable(1, [fakeFixed64])) @@ -1914,7 +1910,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when adding single unpacked fixed64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedFixed64Element(1, fakeFixed64)) @@ -1930,7 +1926,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when setting unpacked fixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFixed64Iterable(1, [fakeFixed64])) @@ -1946,7 +1942,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when setting single unpacked fixed64 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -1963,7 +1959,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when adding packed fixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedFixed64Iterable(1, [fakeFixed64])) @@ -1979,7 +1975,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when adding single packed fixed64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedFixed64Element(1, fakeFixed64)) @@ -1995,7 +1991,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when setting packed fixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFixed64Iterable(1, [fakeFixed64])) @@ -2011,7 +2007,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when setting single packed fixed64 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); const fakeFixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -2028,7 +2024,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFixed64Element(1, 1, Int64.fromInt(1))) @@ -2046,7 +2042,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFixed64Element(1, 1, Int64.fromInt(1))) @@ -2064,7 +2060,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedFixed64Element( @@ -2082,7 +2078,7 @@ describe('LazyAccessor for repeated fixed64 does', () => { }); }); -describe('LazyAccessor for repeated float does', () => { +describe('Kernel for repeated float does', () => { const value1 = 1.6; const value1Float = Math.fround(1.6); const value2 = 0; @@ -2098,7 +2094,7 @@ describe('LazyAccessor for repeated float does', () => { 0x0A, 0x08, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xCC, 0xCC, 0x3F); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedFloatIterable(1); @@ -2106,7 +2102,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedFloatIterable(1); const list2 = accessor.getRepeatedFloatIterable(1); @@ -2115,7 +2111,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedFloatSize(1); @@ -2123,7 +2119,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedFloatIterable(1); @@ -2131,7 +2127,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedFloatIterable(1); const list2 = accessor.getRepeatedFloatIterable(1); @@ -2140,7 +2136,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFloatElement(1, value1); const list1 = accessor.getRepeatedFloatIterable(1); @@ -2152,7 +2148,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFloatIterable(1, [value1]); const list1 = accessor.getRepeatedFloatIterable(1); @@ -2164,7 +2160,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedFloatElement(1, 1, value1); const list = accessor.getRepeatedFloatIterable(1); @@ -2173,7 +2169,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedFloatIterable(1, [value1]); const list = accessor.getRepeatedFloatIterable(1); @@ -2182,7 +2178,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFloatElement(1, value1); accessor.addUnpackedFloatElement(1, value2); @@ -2192,7 +2188,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedFloatIterable(1, [value1]); accessor.addUnpackedFloatIterable(1, [value2]); @@ -2202,7 +2198,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedFloatElement(1, 0, value2); accessor.setUnpackedFloatElement(1, 1, value1); @@ -2212,7 +2208,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedFloatIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -2221,7 +2217,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedFloatIterable(1); @@ -2229,7 +2225,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedFloatIterable(1); const list2 = accessor.getRepeatedFloatIterable(1); @@ -2238,7 +2234,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFloatElement(1, value1); const list1 = accessor.getRepeatedFloatIterable(1); @@ -2250,7 +2246,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFloatIterable(1, [value1]); const list1 = accessor.getRepeatedFloatIterable(1); @@ -2262,7 +2258,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedFloatElement(1, 1, value1); const list = accessor.getRepeatedFloatIterable(1); @@ -2271,7 +2267,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedFloatIterable(1, [value1]); const list1 = accessor.getRepeatedFloatIterable(1); @@ -2283,7 +2279,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFloatElement(1, value1); accessor.addPackedFloatElement(1, value2); @@ -2293,7 +2289,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedFloatIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -2302,7 +2298,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedFloatElement(1, 0, value2); accessor.setPackedFloatElement(1, 1, value1); @@ -2313,7 +2309,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedFloatIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -2322,7 +2318,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0xCD, 0xCC, @@ -2351,7 +2347,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedFloatElement( /* fieldNumber= */ 1, /* index= */ 0); @@ -2363,7 +2359,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedFloatSize(1); @@ -2371,8 +2367,8 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when getting unpacked float value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedFloatIterable(1); @@ -2389,7 +2385,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when adding unpacked float values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedFloatIterable(1, [fakeFloat])) @@ -2405,7 +2401,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when adding single unpacked float value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedFloatElement(1, fakeFloat)) @@ -2421,7 +2417,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when setting unpacked float values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFloatIterable(1, [fakeFloat])) @@ -2437,8 +2433,8 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when setting single unpacked float value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFloatElement(1, 0, fakeFloat)) @@ -2454,7 +2450,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when adding packed float values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedFloatIterable(1, [fakeFloat])) @@ -2470,7 +2466,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when adding single packed float value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedFloatElement(1, fakeFloat)) @@ -2486,7 +2482,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when setting packed float values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFloatIterable(1, [fakeFloat])) @@ -2502,8 +2498,8 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when setting single packed float value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); const fakeFloat = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFloatElement(1, 0, fakeFloat)) @@ -2519,8 +2515,8 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedFloatElement(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -2537,8 +2533,8 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedFloatElement(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -2555,7 +2551,7 @@ describe('LazyAccessor for repeated float does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedFloatElement( @@ -2573,7 +2569,7 @@ describe('LazyAccessor for repeated float does', () => { }); }); -describe('LazyAccessor for repeated int32 does', () => { +describe('Kernel for repeated int32 does', () => { const value1 = 1; const value2 = 0; @@ -2584,7 +2580,7 @@ describe('LazyAccessor for repeated int32 does', () => { const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedInt32Iterable(1); @@ -2592,7 +2588,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedInt32Iterable(1); const list2 = accessor.getRepeatedInt32Iterable(1); @@ -2601,7 +2597,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedInt32Size(1); @@ -2609,7 +2605,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedInt32Iterable(1); @@ -2617,7 +2613,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedInt32Iterable(1); const list2 = accessor.getRepeatedInt32Iterable(1); @@ -2626,7 +2622,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt32Element(1, value1); const list1 = accessor.getRepeatedInt32Iterable(1); @@ -2638,7 +2634,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt32Iterable(1, [value1]); const list1 = accessor.getRepeatedInt32Iterable(1); @@ -2650,7 +2646,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedInt32Element(1, 1, value1); const list = accessor.getRepeatedInt32Iterable(1); @@ -2659,7 +2655,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedInt32Iterable(1, [value1]); const list = accessor.getRepeatedInt32Iterable(1); @@ -2668,7 +2664,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt32Element(1, value1); accessor.addUnpackedInt32Element(1, value2); @@ -2678,7 +2674,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt32Iterable(1, [value1]); accessor.addUnpackedInt32Iterable(1, [value2]); @@ -2688,7 +2684,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedInt32Element(1, 0, value2); accessor.setUnpackedInt32Element(1, 1, value1); @@ -2698,7 +2694,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedInt32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -2707,7 +2703,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedInt32Iterable(1); @@ -2715,7 +2711,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedInt32Iterable(1); const list2 = accessor.getRepeatedInt32Iterable(1); @@ -2724,7 +2720,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt32Element(1, value1); const list1 = accessor.getRepeatedInt32Iterable(1); @@ -2736,7 +2732,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt32Iterable(1, [value1]); const list1 = accessor.getRepeatedInt32Iterable(1); @@ -2748,7 +2744,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedInt32Element(1, 1, value1); const list = accessor.getRepeatedInt32Iterable(1); @@ -2757,7 +2753,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedInt32Iterable(1, [value1]); const list1 = accessor.getRepeatedInt32Iterable(1); @@ -2769,7 +2765,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt32Element(1, value1); accessor.addPackedInt32Element(1, value2); @@ -2779,7 +2775,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -2788,7 +2784,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedInt32Element(1, 0, value2); accessor.setPackedInt32Element(1, 1, value1); @@ -2799,7 +2795,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedInt32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -2808,7 +2804,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x01, // unpacked value1 0x0A, @@ -2825,7 +2821,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedInt32Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -2837,7 +2833,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedInt32Size(1); @@ -2845,8 +2841,8 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when getting unpacked int32 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedInt32Iterable(1); @@ -2863,7 +2859,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when adding unpacked int32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedInt32Iterable(1, [fakeInt32])) @@ -2879,7 +2875,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when adding single unpacked int32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedInt32Element(1, fakeInt32)) @@ -2895,7 +2891,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when setting unpacked int32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedInt32Iterable(1, [fakeInt32])) @@ -2911,8 +2907,8 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when setting single unpacked int32 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedInt32Element(1, 0, fakeInt32)) @@ -2930,7 +2926,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when adding packed int32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedInt32Iterable(1, [fakeInt32])) @@ -2946,7 +2942,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when adding single packed int32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedInt32Element(1, fakeInt32)) @@ -2962,7 +2958,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when setting packed int32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedInt32Iterable(1, [fakeInt32])) @@ -2978,8 +2974,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when setting single packed int32 value with null value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeInt32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedInt32Element(1, 0, fakeInt32)) @@ -2996,7 +2991,7 @@ describe('LazyAccessor for repeated int32 does', () => { it('fail when setting single unpacked with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedInt32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -3013,8 +3008,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedInt32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -3031,7 +3025,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedInt32Element( @@ -3049,7 +3043,7 @@ describe('LazyAccessor for repeated int32 does', () => { }); }); -describe('LazyAccessor for repeated int64 does', () => { +describe('Kernel for repeated int64 does', () => { const value1 = Int64.fromInt(1); const value2 = Int64.fromInt(0); @@ -3060,7 +3054,7 @@ describe('LazyAccessor for repeated int64 does', () => { const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedInt64Iterable(1); @@ -3068,7 +3062,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedInt64Iterable(1); const list2 = accessor.getRepeatedInt64Iterable(1); @@ -3077,7 +3071,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedInt64Size(1); @@ -3085,7 +3079,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedInt64Iterable(1); @@ -3093,7 +3087,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedInt64Iterable(1); const list2 = accessor.getRepeatedInt64Iterable(1); @@ -3102,7 +3096,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt64Element(1, value1); const list1 = accessor.getRepeatedInt64Iterable(1); @@ -3114,7 +3108,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt64Iterable(1, [value1]); const list1 = accessor.getRepeatedInt64Iterable(1); @@ -3126,7 +3120,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedInt64Element(1, 1, value1); const list = accessor.getRepeatedInt64Iterable(1); @@ -3135,7 +3129,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedInt64Iterable(1, [value1]); const list = accessor.getRepeatedInt64Iterable(1); @@ -3144,7 +3138,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt64Element(1, value1); accessor.addUnpackedInt64Element(1, value2); @@ -3154,7 +3148,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedInt64Iterable(1, [value1]); accessor.addUnpackedInt64Iterable(1, [value2]); @@ -3164,7 +3158,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedInt64Element(1, 0, value2); accessor.setUnpackedInt64Element(1, 1, value1); @@ -3174,7 +3168,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedInt64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -3183,7 +3177,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedInt64Iterable(1); @@ -3191,7 +3185,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedInt64Iterable(1); const list2 = accessor.getRepeatedInt64Iterable(1); @@ -3200,7 +3194,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt64Element(1, value1); const list1 = accessor.getRepeatedInt64Iterable(1); @@ -3212,7 +3206,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt64Iterable(1, [value1]); const list1 = accessor.getRepeatedInt64Iterable(1); @@ -3224,7 +3218,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedInt64Element(1, 1, value1); const list = accessor.getRepeatedInt64Iterable(1); @@ -3233,7 +3227,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedInt64Iterable(1, [value1]); const list1 = accessor.getRepeatedInt64Iterable(1); @@ -3245,7 +3239,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt64Element(1, value1); accessor.addPackedInt64Element(1, value2); @@ -3255,7 +3249,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedInt64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -3264,7 +3258,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedInt64Element(1, 0, value2); accessor.setPackedInt64Element(1, 1, value1); @@ -3275,7 +3269,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedInt64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -3284,7 +3278,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x01, // unpacked value1 0x0A, @@ -3301,7 +3295,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedInt64Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -3313,7 +3307,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedInt64Size(1); @@ -3321,8 +3315,8 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when getting unpacked int64 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedInt64Iterable(1); @@ -3339,7 +3333,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when adding unpacked int64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedInt64Iterable(1, [fakeInt64])) @@ -3355,7 +3349,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when adding single unpacked int64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedInt64Element(1, fakeInt64)) @@ -3371,7 +3365,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when setting unpacked int64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedInt64Iterable(1, [fakeInt64])) @@ -3387,8 +3381,8 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when setting single unpacked int64 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedInt64Element(1, 0, fakeInt64)) @@ -3404,7 +3398,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when adding packed int64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedInt64Iterable(1, [fakeInt64])) @@ -3420,7 +3414,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when adding single packed int64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedInt64Element(1, fakeInt64)) @@ -3436,7 +3430,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when setting packed int64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedInt64Iterable(1, [fakeInt64])) @@ -3452,8 +3446,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when setting single packed int64 value with null value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeInt64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedInt64Element(1, 0, fakeInt64)) @@ -3470,7 +3463,7 @@ describe('LazyAccessor for repeated int64 does', () => { it('fail when setting single unpacked with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedInt64Element(1, 1, Int64.fromInt(1))) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -3487,8 +3480,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedInt64Element(1, 1, Int64.fromInt(1))) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -3505,7 +3497,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedInt64Element( @@ -3523,7 +3515,7 @@ describe('LazyAccessor for repeated int64 does', () => { }); }); -describe('LazyAccessor for repeated sfixed32 does', () => { +describe('Kernel for repeated sfixed32 does', () => { const value1 = 1; const value2 = 0; @@ -3538,7 +3530,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { 0x0A, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedSfixed32Iterable(1); @@ -3546,7 +3538,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedSfixed32Iterable(1); const list2 = accessor.getRepeatedSfixed32Iterable(1); @@ -3555,7 +3547,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedSfixed32Size(1); @@ -3563,7 +3555,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedSfixed32Iterable(1); @@ -3571,7 +3563,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedSfixed32Iterable(1); const list2 = accessor.getRepeatedSfixed32Iterable(1); @@ -3580,7 +3572,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed32Element(1, value1); const list1 = accessor.getRepeatedSfixed32Iterable(1); @@ -3592,7 +3584,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed32Iterable(1, [value1]); const list1 = accessor.getRepeatedSfixed32Iterable(1); @@ -3604,7 +3596,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedSfixed32Element(1, 1, value1); const list = accessor.getRepeatedSfixed32Iterable(1); @@ -3613,7 +3605,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSfixed32Iterable(1, [value1]); const list = accessor.getRepeatedSfixed32Iterable(1); @@ -3622,7 +3614,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed32Element(1, value1); accessor.addUnpackedSfixed32Element(1, value2); @@ -3632,7 +3624,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed32Iterable(1, [value1]); accessor.addUnpackedSfixed32Iterable(1, [value2]); @@ -3642,7 +3634,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedSfixed32Element(1, 0, value2); accessor.setUnpackedSfixed32Element(1, 1, value1); @@ -3652,7 +3644,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSfixed32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -3661,7 +3653,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedSfixed32Iterable(1); @@ -3669,7 +3661,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedSfixed32Iterable(1); const list2 = accessor.getRepeatedSfixed32Iterable(1); @@ -3678,7 +3670,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed32Element(1, value1); const list1 = accessor.getRepeatedSfixed32Iterable(1); @@ -3690,7 +3682,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed32Iterable(1, [value1]); const list1 = accessor.getRepeatedSfixed32Iterable(1); @@ -3702,7 +3694,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSfixed32Element(1, 1, value1); const list = accessor.getRepeatedSfixed32Iterable(1); @@ -3711,7 +3703,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSfixed32Iterable(1, [value1]); const list1 = accessor.getRepeatedSfixed32Iterable(1); @@ -3723,7 +3715,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed32Element(1, value1); accessor.addPackedSfixed32Element(1, value2); @@ -3733,7 +3725,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -3742,7 +3734,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSfixed32Element(1, 0, value2); accessor.setPackedSfixed32Element(1, 1, value1); @@ -3753,7 +3745,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSfixed32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -3762,7 +3754,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x01, 0x00, @@ -3791,7 +3783,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedSfixed32Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -3803,7 +3795,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedSfixed32Size(1); @@ -3811,8 +3803,8 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when getting unpacked sfixed32 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedSfixed32Iterable(1); @@ -3829,7 +3821,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when adding unpacked sfixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSfixed32Iterable(1, [fakeSfixed32])) @@ -3845,7 +3837,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when adding single unpacked sfixed32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSfixed32Element(1, fakeSfixed32)) @@ -3861,7 +3853,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when setting unpacked sfixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSfixed32Iterable(1, [fakeSfixed32])) @@ -3877,8 +3869,8 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when setting single unpacked sfixed32 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSfixed32Element(1, 0, fakeSfixed32)) @@ -3894,7 +3886,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when adding packed sfixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSfixed32Iterable(1, [fakeSfixed32])) @@ -3910,7 +3902,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when adding single packed sfixed32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSfixed32Element(1, fakeSfixed32)) @@ -3926,7 +3918,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when setting packed sfixed32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSfixed32Iterable(1, [fakeSfixed32])) @@ -3942,8 +3934,8 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when setting single packed sfixed32 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); const fakeSfixed32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSfixed32Element(1, 0, fakeSfixed32)) @@ -3959,8 +3951,8 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSfixed32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -3977,8 +3969,8 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSfixed32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -3995,7 +3987,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedSfixed32Element( @@ -4013,7 +4005,7 @@ describe('LazyAccessor for repeated sfixed32 does', () => { }); }); -describe('LazyAccessor for repeated sfixed64 does', () => { +describe('Kernel for repeated sfixed64 does', () => { const value1 = Int64.fromInt(1); const value2 = Int64.fromInt(0); @@ -4100,7 +4092,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { ); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedSfixed64Iterable(1); @@ -4108,7 +4100,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedSfixed64Iterable(1); const list2 = accessor.getRepeatedSfixed64Iterable(1); @@ -4117,7 +4109,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedSfixed64Size(1); @@ -4125,7 +4117,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedSfixed64Iterable(1); @@ -4133,7 +4125,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedSfixed64Iterable(1); const list2 = accessor.getRepeatedSfixed64Iterable(1); @@ -4142,7 +4134,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed64Element(1, value1); const list1 = accessor.getRepeatedSfixed64Iterable(1); @@ -4154,7 +4146,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed64Iterable(1, [value1]); const list1 = accessor.getRepeatedSfixed64Iterable(1); @@ -4166,7 +4158,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedSfixed64Element(1, 1, value1); const list = accessor.getRepeatedSfixed64Iterable(1); @@ -4175,7 +4167,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSfixed64Iterable(1, [value1]); const list = accessor.getRepeatedSfixed64Iterable(1); @@ -4184,7 +4176,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed64Element(1, value1); accessor.addUnpackedSfixed64Element(1, value2); @@ -4194,7 +4186,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSfixed64Iterable(1, [value1]); accessor.addUnpackedSfixed64Iterable(1, [value2]); @@ -4204,7 +4196,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedSfixed64Element(1, 0, value2); accessor.setUnpackedSfixed64Element(1, 1, value1); @@ -4214,7 +4206,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSfixed64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -4223,7 +4215,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedSfixed64Iterable(1); @@ -4231,7 +4223,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedSfixed64Iterable(1); const list2 = accessor.getRepeatedSfixed64Iterable(1); @@ -4240,7 +4232,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed64Element(1, value1); const list1 = accessor.getRepeatedSfixed64Iterable(1); @@ -4252,7 +4244,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed64Iterable(1, [value1]); const list1 = accessor.getRepeatedSfixed64Iterable(1); @@ -4264,7 +4256,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSfixed64Element(1, 1, value1); const list = accessor.getRepeatedSfixed64Iterable(1); @@ -4273,7 +4265,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSfixed64Iterable(1, [value1]); const list1 = accessor.getRepeatedSfixed64Iterable(1); @@ -4285,7 +4277,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed64Element(1, value1); accessor.addPackedSfixed64Element(1, value2); @@ -4295,7 +4287,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSfixed64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -4304,7 +4296,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSfixed64Element(1, 0, value2); accessor.setPackedSfixed64Element(1, 1, value1); @@ -4315,7 +4307,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSfixed64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -4324,7 +4316,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 0x0A, 0x10, // tag 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value1 @@ -4338,7 +4330,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedSfixed64Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -4350,7 +4342,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedSfixed64Size(1); @@ -4358,7 +4350,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when getting unpacked sfixed64 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { @@ -4376,7 +4368,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when adding unpacked sfixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSfixed64Iterable(1, [fakeSfixed64])) @@ -4392,7 +4384,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when adding single unpacked sfixed64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSfixed64Element(1, fakeSfixed64)) @@ -4408,7 +4400,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when setting unpacked sfixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSfixed64Iterable(1, [fakeSfixed64])) @@ -4424,7 +4416,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when setting single unpacked sfixed64 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -4441,7 +4433,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when adding packed sfixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSfixed64Iterable(1, [fakeSfixed64])) @@ -4457,7 +4449,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when adding single packed sfixed64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSfixed64Element(1, fakeSfixed64)) @@ -4473,7 +4465,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when setting packed sfixed64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSfixed64Iterable(1, [fakeSfixed64])) @@ -4489,7 +4481,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when setting single packed sfixed64 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); const fakeSfixed64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -4506,7 +4498,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when setting single unpacked with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSfixed64Element(1, 1, Int64.fromInt(1))) @@ -4524,7 +4516,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSfixed64Element(1, 1, Int64.fromInt(1))) @@ -4542,7 +4534,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedSfixed64Element( @@ -4560,7 +4552,7 @@ describe('LazyAccessor for repeated sfixed64 does', () => { }); }); -describe('LazyAccessor for repeated sint32 does', () => { +describe('Kernel for repeated sint32 does', () => { const value1 = -1; const value2 = 0; @@ -4571,7 +4563,7 @@ describe('LazyAccessor for repeated sint32 does', () => { const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedSint32Iterable(1); @@ -4579,7 +4571,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedSint32Iterable(1); const list2 = accessor.getRepeatedSint32Iterable(1); @@ -4588,7 +4580,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedSint32Size(1); @@ -4596,7 +4588,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedSint32Iterable(1); @@ -4604,7 +4596,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedSint32Iterable(1); const list2 = accessor.getRepeatedSint32Iterable(1); @@ -4613,7 +4605,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint32Element(1, value1); const list1 = accessor.getRepeatedSint32Iterable(1); @@ -4625,7 +4617,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint32Iterable(1, [value1]); const list1 = accessor.getRepeatedSint32Iterable(1); @@ -4637,7 +4629,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedSint32Element(1, 1, value1); const list = accessor.getRepeatedSint32Iterable(1); @@ -4646,7 +4638,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSint32Iterable(1, [value1]); const list = accessor.getRepeatedSint32Iterable(1); @@ -4655,7 +4647,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint32Element(1, value1); accessor.addUnpackedSint32Element(1, value2); @@ -4665,7 +4657,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint32Iterable(1, [value1]); accessor.addUnpackedSint32Iterable(1, [value2]); @@ -4675,7 +4667,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedSint32Element(1, 0, value2); accessor.setUnpackedSint32Element(1, 1, value1); @@ -4685,7 +4677,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSint32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -4694,7 +4686,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedSint32Iterable(1); @@ -4702,7 +4694,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedSint32Iterable(1); const list2 = accessor.getRepeatedSint32Iterable(1); @@ -4711,7 +4703,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint32Element(1, value1); const list1 = accessor.getRepeatedSint32Iterable(1); @@ -4723,7 +4715,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint32Iterable(1, [value1]); const list1 = accessor.getRepeatedSint32Iterable(1); @@ -4735,7 +4727,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSint32Element(1, 1, value1); const list = accessor.getRepeatedSint32Iterable(1); @@ -4744,7 +4736,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSint32Iterable(1, [value1]); const list1 = accessor.getRepeatedSint32Iterable(1); @@ -4756,7 +4748,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint32Element(1, value1); accessor.addPackedSint32Element(1, value2); @@ -4766,7 +4758,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -4775,7 +4767,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSint32Element(1, 0, value2); accessor.setPackedSint32Element(1, 1, value1); @@ -4786,7 +4778,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSint32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -4795,7 +4787,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x01, // unpacked value1 0x0A, @@ -4812,7 +4804,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedSint32Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -4824,7 +4816,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedSint32Size(1); @@ -4832,8 +4824,8 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when getting unpacked sint32 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedSint32Iterable(1); @@ -4850,7 +4842,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when adding unpacked sint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSint32Iterable(1, [fakeSint32])) @@ -4866,7 +4858,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when adding single unpacked sint32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSint32Element(1, fakeSint32)) @@ -4882,7 +4874,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when setting unpacked sint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSint32Iterable(1, [fakeSint32])) @@ -4898,8 +4890,8 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when setting single unpacked sint32 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSint32Element(1, 0, fakeSint32)) @@ -4917,7 +4909,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when adding packed sint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSint32Iterable(1, [fakeSint32])) @@ -4933,7 +4925,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when adding single packed sint32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSint32Element(1, fakeSint32)) @@ -4949,7 +4941,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when setting packed sint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSint32Iterable(1, [fakeSint32])) @@ -4965,8 +4957,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when setting single packed sint32 value with null value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeSint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSint32Element(1, 0, fakeSint32)) @@ -4983,7 +4974,7 @@ describe('LazyAccessor for repeated sint32 does', () => { it('fail when setting single unpacked with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSint32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -5000,8 +4991,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSint32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -5018,7 +5008,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedSint32Element( @@ -5036,7 +5026,7 @@ describe('LazyAccessor for repeated sint32 does', () => { }); }); -describe('LazyAccessor for repeated sint64 does', () => { +describe('Kernel for repeated sint64 does', () => { const value1 = Int64.fromInt(-1); const value2 = Int64.fromInt(0); @@ -5047,7 +5037,7 @@ describe('LazyAccessor for repeated sint64 does', () => { const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedSint64Iterable(1); @@ -5055,7 +5045,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedSint64Iterable(1); const list2 = accessor.getRepeatedSint64Iterable(1); @@ -5064,7 +5054,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedSint64Size(1); @@ -5072,7 +5062,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedSint64Iterable(1); @@ -5080,7 +5070,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedSint64Iterable(1); const list2 = accessor.getRepeatedSint64Iterable(1); @@ -5089,7 +5079,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint64Element(1, value1); const list1 = accessor.getRepeatedSint64Iterable(1); @@ -5101,7 +5091,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint64Iterable(1, [value1]); const list1 = accessor.getRepeatedSint64Iterable(1); @@ -5113,7 +5103,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedSint64Element(1, 1, value1); const list = accessor.getRepeatedSint64Iterable(1); @@ -5122,7 +5112,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSint64Iterable(1, [value1]); const list = accessor.getRepeatedSint64Iterable(1); @@ -5131,7 +5121,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint64Element(1, value1); accessor.addUnpackedSint64Element(1, value2); @@ -5141,7 +5131,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedSint64Iterable(1, [value1]); accessor.addUnpackedSint64Iterable(1, [value2]); @@ -5151,7 +5141,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedSint64Element(1, 0, value2); accessor.setUnpackedSint64Element(1, 1, value1); @@ -5161,7 +5151,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedSint64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -5170,7 +5160,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedSint64Iterable(1); @@ -5178,7 +5168,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedSint64Iterable(1); const list2 = accessor.getRepeatedSint64Iterable(1); @@ -5187,7 +5177,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint64Element(1, value1); const list1 = accessor.getRepeatedSint64Iterable(1); @@ -5199,7 +5189,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint64Iterable(1, [value1]); const list1 = accessor.getRepeatedSint64Iterable(1); @@ -5211,7 +5201,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSint64Element(1, 1, value1); const list = accessor.getRepeatedSint64Iterable(1); @@ -5220,7 +5210,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSint64Iterable(1, [value1]); const list1 = accessor.getRepeatedSint64Iterable(1); @@ -5232,7 +5222,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint64Element(1, value1); accessor.addPackedSint64Element(1, value2); @@ -5242,7 +5232,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedSint64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -5251,7 +5241,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedSint64Element(1, 0, value2); accessor.setPackedSint64Element(1, 1, value1); @@ -5262,7 +5252,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedSint64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -5271,7 +5261,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x01, // unpacked value1 0x0A, @@ -5288,7 +5278,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedSint64Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -5300,7 +5290,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedSint64Size(1); @@ -5308,8 +5298,8 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when getting unpacked sint64 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedSint64Iterable(1); @@ -5326,7 +5316,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when adding unpacked sint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSint64Iterable(1, [fakeSint64])) @@ -5342,7 +5332,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when adding single unpacked sint64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedSint64Element(1, fakeSint64)) @@ -5358,7 +5348,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when setting unpacked sint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSint64Iterable(1, [fakeSint64])) @@ -5374,8 +5364,8 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when setting single unpacked sint64 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSint64Element(1, 0, fakeSint64)) @@ -5391,7 +5381,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when adding packed sint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSint64Iterable(1, [fakeSint64])) @@ -5407,7 +5397,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when adding single packed sint64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedSint64Element(1, fakeSint64)) @@ -5423,7 +5413,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when setting packed sint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSint64Iterable(1, [fakeSint64])) @@ -5439,8 +5429,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when setting single packed sint64 value with null value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeSint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSint64Element(1, 0, fakeSint64)) @@ -5457,7 +5446,7 @@ describe('LazyAccessor for repeated sint64 does', () => { it('fail when setting single unpacked with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedSint64Element(1, 1, Int64.fromInt(1))) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -5474,8 +5463,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedSint64Element(1, 1, Int64.fromInt(1))) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -5492,7 +5480,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedSint64Element( @@ -5510,7 +5498,7 @@ describe('LazyAccessor for repeated sint64 does', () => { }); }); -describe('LazyAccessor for repeated uint32 does', () => { +describe('Kernel for repeated uint32 does', () => { const value1 = 1; const value2 = 0; @@ -5521,7 +5509,7 @@ describe('LazyAccessor for repeated uint32 does', () => { const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedUint32Iterable(1); @@ -5529,7 +5517,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedUint32Iterable(1); const list2 = accessor.getRepeatedUint32Iterable(1); @@ -5538,7 +5526,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedUint32Size(1); @@ -5546,7 +5534,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedUint32Iterable(1); @@ -5554,7 +5542,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedUint32Iterable(1); const list2 = accessor.getRepeatedUint32Iterable(1); @@ -5563,7 +5551,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint32Element(1, value1); const list1 = accessor.getRepeatedUint32Iterable(1); @@ -5575,7 +5563,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint32Iterable(1, [value1]); const list1 = accessor.getRepeatedUint32Iterable(1); @@ -5587,7 +5575,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedUint32Element(1, 1, value1); const list = accessor.getRepeatedUint32Iterable(1); @@ -5596,7 +5584,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedUint32Iterable(1, [value1]); const list = accessor.getRepeatedUint32Iterable(1); @@ -5605,7 +5593,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint32Element(1, value1); accessor.addUnpackedUint32Element(1, value2); @@ -5615,7 +5603,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint32Iterable(1, [value1]); accessor.addUnpackedUint32Iterable(1, [value2]); @@ -5625,7 +5613,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedUint32Element(1, 0, value2); accessor.setUnpackedUint32Element(1, 1, value1); @@ -5635,7 +5623,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedUint32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -5644,7 +5632,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedUint32Iterable(1); @@ -5652,7 +5640,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedUint32Iterable(1); const list2 = accessor.getRepeatedUint32Iterable(1); @@ -5661,7 +5649,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint32Element(1, value1); const list1 = accessor.getRepeatedUint32Iterable(1); @@ -5673,7 +5661,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint32Iterable(1, [value1]); const list1 = accessor.getRepeatedUint32Iterable(1); @@ -5685,7 +5673,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedUint32Element(1, 1, value1); const list = accessor.getRepeatedUint32Iterable(1); @@ -5694,7 +5682,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedUint32Iterable(1, [value1]); const list1 = accessor.getRepeatedUint32Iterable(1); @@ -5706,7 +5694,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint32Element(1, value1); accessor.addPackedUint32Element(1, value2); @@ -5716,7 +5704,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -5725,7 +5713,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedUint32Element(1, 0, value2); accessor.setPackedUint32Element(1, 1, value1); @@ -5736,7 +5724,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedUint32Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -5745,7 +5733,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x01, // unpacked value1 0x0A, @@ -5762,7 +5750,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedUint32Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -5774,7 +5762,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedUint32Size(1); @@ -5782,8 +5770,8 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when getting unpacked uint32 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedUint32Iterable(1); @@ -5800,7 +5788,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when adding unpacked uint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedUint32Iterable(1, [fakeUint32])) @@ -5816,7 +5804,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when adding single unpacked uint32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedUint32Element(1, fakeUint32)) @@ -5832,7 +5820,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when setting unpacked uint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedUint32Iterable(1, [fakeUint32])) @@ -5848,8 +5836,8 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when setting single unpacked uint32 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedUint32Element(1, 0, fakeUint32)) @@ -5867,7 +5855,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when adding packed uint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedUint32Iterable(1, [fakeUint32])) @@ -5883,7 +5871,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when adding single packed uint32 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedUint32Element(1, fakeUint32)) @@ -5899,7 +5887,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when setting packed uint32 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedUint32Iterable(1, [fakeUint32])) @@ -5915,8 +5903,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when setting single packed uint32 value with null value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeUint32 = /** @type {number} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedUint32Element(1, 0, fakeUint32)) @@ -5933,7 +5920,7 @@ describe('LazyAccessor for repeated uint32 does', () => { it('fail when setting single unpacked with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedUint32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -5950,8 +5937,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedUint32Element(1, 1, 1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -5968,7 +5954,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedUint32Element( @@ -5986,7 +5972,7 @@ describe('LazyAccessor for repeated uint32 does', () => { }); }); -describe('LazyAccessor for repeated uint64 does', () => { +describe('Kernel for repeated uint64 does', () => { const value1 = Int64.fromInt(1); const value2 = Int64.fromInt(0); @@ -5997,7 +5983,7 @@ describe('LazyAccessor for repeated uint64 does', () => { const packedValue2Value1 = createArrayBuffer(0x0A, 0x02, 0x00, 0x01); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedUint64Iterable(1); @@ -6005,7 +5991,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedUint64Iterable(1); const list2 = accessor.getRepeatedUint64Iterable(1); @@ -6014,7 +6000,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedUint64Size(1); @@ -6022,7 +6008,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('return unpacked values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list = accessor.getRepeatedUint64Iterable(1); @@ -6030,7 +6016,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('ensure not the same instance returned for unpacked values', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const list1 = accessor.getRepeatedUint64Iterable(1); const list2 = accessor.getRepeatedUint64Iterable(1); @@ -6039,7 +6025,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('add single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint64Element(1, value1); const list1 = accessor.getRepeatedUint64Iterable(1); @@ -6051,7 +6037,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('add unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint64Iterable(1, [value1]); const list1 = accessor.getRepeatedUint64Iterable(1); @@ -6063,7 +6049,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('set a single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); accessor.setUnpackedUint64Element(1, 1, value1); const list = accessor.getRepeatedUint64Iterable(1); @@ -6072,7 +6058,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('set unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedUint64Iterable(1, [value1]); const list = accessor.getRepeatedUint64Iterable(1); @@ -6081,7 +6067,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for adding single unpacked value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint64Element(1, value1); accessor.addUnpackedUint64Element(1, value2); @@ -6091,7 +6077,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for adding unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedUint64Iterable(1, [value1]); accessor.addUnpackedUint64Iterable(1, [value2]); @@ -6101,7 +6087,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for setting single unpacked value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setUnpackedUint64Element(1, 0, value2); accessor.setUnpackedUint64Element(1, 1, value1); @@ -6111,7 +6097,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for setting unpacked values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUnpackedUint64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -6120,7 +6106,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('return packed values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list = accessor.getRepeatedUint64Iterable(1); @@ -6128,7 +6114,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('ensure not the same instance returned for packed values', () => { - const accessor = LazyAccessor.fromArrayBuffer(packedValue1Value2); + const accessor = Kernel.fromArrayBuffer(packedValue1Value2); const list1 = accessor.getRepeatedUint64Iterable(1); const list2 = accessor.getRepeatedUint64Iterable(1); @@ -6137,7 +6123,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('add single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint64Element(1, value1); const list1 = accessor.getRepeatedUint64Iterable(1); @@ -6149,7 +6135,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('add packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint64Iterable(1, [value1]); const list1 = accessor.getRepeatedUint64Iterable(1); @@ -6161,7 +6147,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('set a single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedUint64Element(1, 1, value1); const list = accessor.getRepeatedUint64Iterable(1); @@ -6170,7 +6156,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('set packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedUint64Iterable(1, [value1]); const list1 = accessor.getRepeatedUint64Iterable(1); @@ -6182,7 +6168,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for adding single packed value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint64Element(1, value1); accessor.addPackedUint64Element(1, value2); @@ -6192,7 +6178,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for adding packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addPackedUint64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -6201,7 +6187,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for setting single packed value', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); accessor.setPackedUint64Element(1, 0, value2); accessor.setPackedUint64Element(1, 1, value1); @@ -6212,7 +6198,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('encode for setting packed values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedUint64Iterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -6221,7 +6207,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('return combined values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x01, // unpacked value1 0x0A, @@ -6238,7 +6224,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const result1 = accessor.getRepeatedUint64Element( /* fieldNumber= */ 1, /* index= */ 0); @@ -6250,7 +6236,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(unpackedValue1Value2); + const accessor = Kernel.fromArrayBuffer(unpackedValue1Value2); const size = accessor.getRepeatedUint64Size(1); @@ -6258,8 +6244,8 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when getting unpacked uint64 value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedUint64Iterable(1); @@ -6276,7 +6262,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when adding unpacked uint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedUint64Iterable(1, [fakeUint64])) @@ -6292,7 +6278,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when adding single unpacked uint64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addUnpackedUint64Element(1, fakeUint64)) @@ -6308,7 +6294,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when setting unpacked uint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedUint64Iterable(1, [fakeUint64])) @@ -6324,8 +6310,8 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when setting single unpacked uint64 value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x80, 0x80, 0x80, 0x00)); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedUint64Element(1, 0, fakeUint64)) @@ -6341,7 +6327,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when adding packed uint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedUint64Iterable(1, [fakeUint64])) @@ -6357,7 +6343,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when adding single packed uint64 value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addPackedUint64Element(1, fakeUint64)) @@ -6373,7 +6359,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when setting packed uint64 values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedUint64Iterable(1, [fakeUint64])) @@ -6389,8 +6375,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when setting single packed uint64 value with null value', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); const fakeUint64 = /** @type {!Int64} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedUint64Element(1, 0, fakeUint64)) @@ -6407,7 +6392,7 @@ describe('LazyAccessor for repeated uint64 does', () => { it('fail when setting single unpacked with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setUnpackedUint64Element(1, 1, Int64.fromInt(1))) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -6424,8 +6409,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when setting single packed with out-of-bound index', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setPackedUint64Element(1, 1, Int64.fromInt(1))) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -6442,7 +6426,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedUint64Element( @@ -6460,7 +6444,7 @@ describe('LazyAccessor for repeated uint64 does', () => { }); }); -describe('LazyAccessor for repeated bytes does', () => { +describe('Kernel for repeated bytes does', () => { const value1 = ByteString.fromArrayBuffer((createArrayBuffer(0x61))); const value2 = ByteString.fromArrayBuffer((createArrayBuffer(0x62))); @@ -6482,7 +6466,7 @@ describe('LazyAccessor for repeated bytes does', () => { ); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedBytesIterable(1); @@ -6490,7 +6474,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedBytesIterable(1); const list2 = accessor.getRepeatedBytesIterable(1); @@ -6499,7 +6483,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedBytesSize(1); @@ -6507,7 +6491,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('return values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const list = accessor.getRepeatedBytesIterable(1); @@ -6515,7 +6499,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('ensure not the same instance returned for values', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const list1 = accessor.getRepeatedBytesIterable(1); const list2 = accessor.getRepeatedBytesIterable(1); @@ -6524,7 +6508,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('add single value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedBytesElement(1, value1); const list1 = accessor.getRepeatedBytesIterable(1); @@ -6536,7 +6520,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('add values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedBytesIterable(1, [value1]); const list1 = accessor.getRepeatedBytesIterable(1); @@ -6548,7 +6532,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('set a single value', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); accessor.setRepeatedBytesElement(1, 1, value1); const list = accessor.getRepeatedBytesIterable(1); @@ -6557,7 +6541,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('set values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setRepeatedBytesIterable(1, [value1]); const list = accessor.getRepeatedBytesIterable(1); @@ -6566,7 +6550,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('encode for adding single value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedBytesElement(1, value1); accessor.addRepeatedBytesElement(1, value2); @@ -6576,7 +6560,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('encode for adding values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedBytesIterable(1, [value1]); accessor.addRepeatedBytesIterable(1, [value2]); @@ -6586,7 +6570,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('encode for setting single value', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); accessor.setRepeatedBytesElement(1, 0, value2); accessor.setRepeatedBytesElement(1, 1, value1); @@ -6596,7 +6580,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('encode for setting values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setRepeatedBytesIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -6605,7 +6589,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const result1 = accessor.getRepeatedBytesElement( /* fieldNumber= */ 1, /* index= */ 0); @@ -6617,7 +6601,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const size = accessor.getRepeatedBytesSize(1); @@ -6625,7 +6609,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('fail when getting bytes value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { @@ -6643,7 +6627,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('fail when adding bytes values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addRepeatedBytesIterable(1, [fakeBytes])) @@ -6659,7 +6643,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('fail when adding single bytes value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addRepeatedBytesElement(1, fakeBytes)) @@ -6675,7 +6659,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('fail when setting bytes values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setRepeatedBytesIterable(1, [fakeBytes])) @@ -6691,7 +6675,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('fail when setting single bytes value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); const fakeBytes = /** @type {!ByteString} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -6709,7 +6693,7 @@ describe('LazyAccessor for repeated bytes does', () => { it('fail when setting single with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setRepeatedBytesElement(1, 1, value1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -6726,7 +6710,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedBytesElement( @@ -6744,7 +6728,7 @@ describe('LazyAccessor for repeated bytes does', () => { }); }); -describe('LazyAccessor for repeated string does', () => { +describe('Kernel for repeated string does', () => { const value1 = 'a'; const value2 = 'b'; @@ -6766,7 +6750,7 @@ describe('LazyAccessor for repeated string does', () => { ); it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list = accessor.getRepeatedStringIterable(1); @@ -6774,7 +6758,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedStringIterable(1); const list2 = accessor.getRepeatedStringIterable(1); @@ -6783,7 +6767,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const size = accessor.getRepeatedStringSize(1); @@ -6791,7 +6775,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('return values from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const list = accessor.getRepeatedStringIterable(1); @@ -6799,7 +6783,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('ensure not the same instance returned for values', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const list1 = accessor.getRepeatedStringIterable(1); const list2 = accessor.getRepeatedStringIterable(1); @@ -6808,7 +6792,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('add single value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedStringElement(1, value1); const list1 = accessor.getRepeatedStringIterable(1); @@ -6820,7 +6804,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('add values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedStringIterable(1, [value1]); const list1 = accessor.getRepeatedStringIterable(1); @@ -6832,7 +6816,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('set a single value', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); accessor.setRepeatedStringElement(1, 1, value1); const list = accessor.getRepeatedStringIterable(1); @@ -6841,7 +6825,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('set values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setRepeatedStringIterable(1, [value1]); const list = accessor.getRepeatedStringIterable(1); @@ -6850,7 +6834,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('encode for adding single value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedStringElement(1, value1); accessor.addRepeatedStringElement(1, value2); @@ -6860,7 +6844,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('encode for adding values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addRepeatedStringIterable(1, [value1]); accessor.addRepeatedStringIterable(1, [value2]); @@ -6870,7 +6854,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('encode for setting single value', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); accessor.setRepeatedStringElement(1, 0, value2); accessor.setRepeatedStringElement(1, 1, value1); @@ -6880,7 +6864,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('encode for setting values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setRepeatedStringIterable(1, [value1, value2]); const serialized = accessor.serialize(); @@ -6889,7 +6873,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('return the repeated field element from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const result1 = accessor.getRepeatedStringElement( /* fieldNumber= */ 1, /* index= */ 0); @@ -6901,7 +6885,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('return the size from the input', () => { - const accessor = LazyAccessor.fromArrayBuffer(repeatedValue1Value2); + const accessor = Kernel.fromArrayBuffer(repeatedValue1Value2); const size = accessor.getRepeatedStringSize(1); @@ -6909,7 +6893,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('fail when getting string value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { @@ -6927,7 +6911,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('fail when adding string values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeString = /** @type {string} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addRepeatedStringIterable(1, [fakeString])) @@ -6943,7 +6927,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('fail when adding single string value with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeString = /** @type {string} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.addRepeatedStringElement(1, fakeString)) @@ -6959,7 +6943,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('fail when setting string values with null value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeString = /** @type {string} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setRepeatedStringIterable(1, [fakeString])) @@ -6975,7 +6959,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('fail when setting single string value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); const fakeString = /** @type {string} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { @@ -6993,7 +6977,7 @@ describe('LazyAccessor for repeated string does', () => { it('fail when setting single with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setRepeatedStringElement(1, 1, value1)) .toThrowError('Index out of bounds: index: 1 size: 1'); @@ -7010,7 +6994,7 @@ describe('LazyAccessor for repeated string does', () => { }); it('fail when getting element with out-of-range index', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); if (CHECK_CRITICAL_STATE) { expect(() => { accessor.getRepeatedStringElement( @@ -7028,21 +7012,21 @@ describe('LazyAccessor for repeated string does', () => { }); }); -describe('LazyAccessor for repeated message does', () => { +describe('Kernel for repeated message does', () => { it('return empty array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expectEqualToArray( accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator), []); }); it('return empty accessor array for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expectEqualToArray(accessor.getRepeatedMessageAccessorIterable(1), []); }); it('ensure not the same instance returned for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const list1 = accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); const list2 = @@ -7051,7 +7035,7 @@ describe('LazyAccessor for repeated message does', () => { }); it('return size for the empty input', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expect(accessor.getRepeatedMessageSize(1, TestMessage.instanceCreator)) .toEqual(0); }); @@ -7059,12 +7043,12 @@ describe('LazyAccessor for repeated message does', () => { it('return values from the input', () => { const bytes1 = createArrayBuffer(0x08, 0x01); const bytes2 = createArrayBuffer(0x08, 0x00); - const msg1 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes1)); - const msg2 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes2)); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expectEqualToMessageArray( accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator), [msg1, msg2]); @@ -7073,7 +7057,7 @@ describe('LazyAccessor for repeated message does', () => { it('ensure not the same array instance returned', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const list1 = accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); const list2 = @@ -7084,7 +7068,7 @@ describe('LazyAccessor for repeated message does', () => { it('ensure the same array element returned for get iterable', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const list1 = accessor.getRepeatedMessageIterable(1, TestMessage.instanceCreator); const list2 = accessor.getRepeatedMessageIterable( @@ -7099,7 +7083,7 @@ describe('LazyAccessor for repeated message does', () => { it('return accessors from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const [accessor1, accessor2] = [...accessor.getRepeatedMessageAccessorIterable(1)]; expect(accessor1.getInt32WithDefault(1)).toEqual(1); @@ -7109,7 +7093,7 @@ describe('LazyAccessor for repeated message does', () => { it('return accessors from the input when pivot is set', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const [accessor1, accessor2] = [...accessor.getRepeatedMessageAccessorIterable(1, /* pivot= */ 0)]; expect(accessor1.getInt32WithDefault(1)).toEqual(1); @@ -7119,7 +7103,7 @@ describe('LazyAccessor for repeated message does', () => { it('return the repeated field element from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const msg1 = accessor.getRepeatedMessageElement( /* fieldNumber= */ 1, TestMessage.instanceCreator, /* index= */ 0); @@ -7136,7 +7120,7 @@ describe('LazyAccessor for repeated message does', () => { it('ensure the same array element returned', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const msg1 = accessor.getRepeatedMessageElement( /* fieldNumber= */ 1, TestMessage.instanceCreator, /* index= */ 0); @@ -7149,7 +7133,7 @@ describe('LazyAccessor for repeated message does', () => { it('return the size from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getRepeatedMessageSize(1, TestMessage.instanceCreator)) .toEqual(2); }); @@ -7157,16 +7141,16 @@ describe('LazyAccessor for repeated message does', () => { it('encode repeated message from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.serialize()).toEqual(bytes); }); it('add a single value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes1)); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes2)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); accessor.addRepeatedMessageElement(1, msg1, TestMessage.instanceCreator); accessor.addRepeatedMessageElement(1, msg2, TestMessage.instanceCreator); @@ -7177,11 +7161,11 @@ describe('LazyAccessor for repeated message does', () => { }); it('add values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes1)); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes2)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); accessor.addRepeatedMessageIterable(1, [msg1], TestMessage.instanceCreator); accessor.addRepeatedMessageIterable(1, [msg2], TestMessage.instanceCreator); @@ -7193,9 +7177,9 @@ describe('LazyAccessor for repeated message does', () => { it('set a single value', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(LazyAccessor.fromArrayBuffer(subbytes)); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); accessor.setRepeatedMessageElement( /* fieldNumber= */ 1, submsg, TestMessage.instanceCreator, @@ -7209,7 +7193,7 @@ describe('LazyAccessor for repeated message does', () => { it('write submessage changes made via getRepeatedMessagElement', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x05); const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const submsg = accessor.getRepeatedMessageElement( /* fieldNumber= */ 1, TestMessage.instanceCreator, /* index= */ 0); @@ -7220,9 +7204,9 @@ describe('LazyAccessor for repeated message does', () => { }); it('set values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(LazyAccessor.fromArrayBuffer(subbytes)); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); accessor.setRepeatedMessageIterable(1, [submsg]); const result = @@ -7232,11 +7216,11 @@ describe('LazyAccessor for repeated message does', () => { }); it('encode for adding single value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes1)); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes2)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); @@ -7248,11 +7232,11 @@ describe('LazyAccessor for repeated message does', () => { }); it('encode for adding values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes1)); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes2)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x08, 0x00); @@ -7265,9 +7249,9 @@ describe('LazyAccessor for repeated message does', () => { it('encode for setting single value', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(LazyAccessor.fromArrayBuffer(subbytes)); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); accessor.setRepeatedMessageElement( @@ -7279,9 +7263,9 @@ describe('LazyAccessor for repeated message does', () => { }); it('encode for setting values', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const subbytes = createArrayBuffer(0x08, 0x01); - const submsg = new TestMessage(LazyAccessor.fromArrayBuffer(subbytes)); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); const expected = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); accessor.setRepeatedMessageIterable(1, [submsg]); @@ -7291,11 +7275,11 @@ describe('LazyAccessor for repeated message does', () => { }); it('get accessors from set values.', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const bytes1 = createArrayBuffer(0x08, 0x01); - const msg1 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes1)); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); const bytes2 = createArrayBuffer(0x08, 0x00); - const msg2 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes2)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); accessor.addRepeatedMessageIterable( 1, [msg1, msg2], TestMessage.instanceCreator); @@ -7313,7 +7297,7 @@ describe('LazyAccessor for repeated message does', () => { }); it('fail when getting message value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_STATE) { expect(() => { @@ -7331,7 +7315,7 @@ describe('LazyAccessor for repeated message does', () => { }); it('fail when adding message values with wrong type value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect( @@ -7352,7 +7336,7 @@ describe('LazyAccessor for repeated message does', () => { }); it('fail when adding single message value with wrong type value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect( @@ -7373,7 +7357,7 @@ describe('LazyAccessor for repeated message does', () => { }); it('fail when setting message values with wrong type value', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect(() => accessor.setRepeatedMessageIterable(1, [fakeValue])) @@ -7392,7 +7376,7 @@ describe('LazyAccessor for repeated message does', () => { it('fail when setting single value with wrong type value', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x00)); const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_STATE) { expect( @@ -7416,11 +7400,11 @@ describe('LazyAccessor for repeated message does', () => { it('fail when setting single value with out-of-bound index', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x00)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x00)); const msg1 = accessor.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0); const bytes2 = createArrayBuffer(0x08, 0x01); - const msg2 = new TestMessage(LazyAccessor.fromArrayBuffer(bytes2)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); if (CHECK_CRITICAL_STATE) { expect( () => accessor.setRepeatedMessageElement( @@ -7441,3 +7425,383 @@ describe('LazyAccessor for repeated message does', () => { } }); }); + +describe('Kernel for repeated groups does', () => { + it('return empty array for the empty input', () => { + const accessor = Kernel.createEmpty(); + expectEqualToArray( + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator), []); + }); + + it('ensure not the same instance returned for the empty input', () => { + const accessor = Kernel.createEmpty(); + const list1 = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + const list2 = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + expect(list1).not.toBe(list2); + }); + + it('return size for the empty input', () => { + const accessor = Kernel.createEmpty(); + expect(accessor.getRepeatedGroupSize(1, TestMessage.instanceCreator)) + .toEqual(0); + }); + + it('return values from the input', () => { + const bytes1 = createArrayBuffer(0x08, 0x01); + const bytes2 = createArrayBuffer(0x08, 0x02); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); + + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + expectEqualToMessageArray( + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator), + [msg1, msg2]); + }); + + it('ensure not the same array instance returned', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const list1 = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + const list2 = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + expect(list1).not.toBe(list2); + }); + + it('ensure the same array element returned for get iterable', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const list1 = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + const list2 = accessor.getRepeatedGroupIterable( + 1, TestMessage.instanceCreator, /* pivot= */ 0); + const array1 = Array.from(list1); + const array2 = Array.from(list2); + for (let i = 0; i < array1.length; i++) { + expect(array1[i]).toBe(array2[i]); + } + }); + + it('return accessors from the input', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const [accessor1, accessor2] = + [...accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator)]; + expect(accessor1.getInt32WithDefault(1)).toEqual(1); + expect(accessor2.getInt32WithDefault(1)).toEqual(2); + }); + + it('return accessors from the input when pivot is set', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const [accessor1, accessor2] = [...accessor.getRepeatedGroupIterable( + 1, TestMessage.instanceCreator, /* pivot= */ 0)]; + expect(accessor1.getInt32WithDefault(1)).toEqual(1); + expect(accessor2.getInt32WithDefault(1)).toEqual(2); + }); + + it('return the repeated field element from the input', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const msg1 = accessor.getRepeatedGroupElement( + /* fieldNumber= */ 1, TestMessage.instanceCreator, + /* index= */ 0); + const msg2 = accessor.getRepeatedGroupElement( + /* fieldNumber= */ 1, TestMessage.instanceCreator, + /* index= */ 1, /* pivot= */ 0); + expect(msg1.getInt32WithDefault( + /* fieldNumber= */ 1, /* default= */ 0)) + .toEqual(1); + expect(msg2.getInt32WithDefault( + /* fieldNumber= */ 1, /* default= */ 0)) + .toEqual(2); + }); + + it('ensure the same array element returned', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const msg1 = accessor.getRepeatedGroupElement( + /* fieldNumber= */ 1, TestMessage.instanceCreator, + /* index= */ 0); + const msg2 = accessor.getRepeatedGroupElement( + /* fieldNumber= */ 1, TestMessage.instanceCreator, + /* index= */ 0); + expect(msg1).toBe(msg2); + }); + + it('return the size from the input', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + expect(accessor.getRepeatedGroupSize(1, TestMessage.instanceCreator)) + .toEqual(2); + }); + + it('encode repeated message from the input', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + expect(accessor.serialize()).toEqual(bytes); + }); + + it('add a single value', () => { + const accessor = Kernel.createEmpty(); + const bytes1 = createArrayBuffer(0x08, 0x01); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); + const bytes2 = createArrayBuffer(0x08, 0x02); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); + + accessor.addRepeatedGroupElement(1, msg1, TestMessage.instanceCreator); + accessor.addRepeatedGroupElement(1, msg2, TestMessage.instanceCreator); + const result = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + + expect(Array.from(result)).toEqual([msg1, msg2]); + }); + + it('add values', () => { + const accessor = Kernel.createEmpty(); + const bytes1 = createArrayBuffer(0x08, 0x01); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); + const bytes2 = createArrayBuffer(0x08, 0x02); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); + + accessor.addRepeatedGroupIterable(1, [msg1], TestMessage.instanceCreator); + accessor.addRepeatedGroupIterable(1, [msg2], TestMessage.instanceCreator); + const result = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + + expect(Array.from(result)).toEqual([msg1, msg2]); + }); + + it('set a single value', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const subbytes = createArrayBuffer(0x08, 0x01); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); + + accessor.setRepeatedGroupElement( + /* fieldNumber= */ 1, submsg, TestMessage.instanceCreator, + /* index= */ 0); + const result = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + + expect(Array.from(result)).toEqual([submsg]); + }); + + it('write submessage changes made via getRepeatedGroupElement', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x05, 0x0C); + const expected = createArrayBuffer(0x0B, 0x08, 0x00, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const submsg = accessor.getRepeatedGroupElement( + /* fieldNumber= */ 1, TestMessage.instanceCreator, + /* index= */ 0); + expect(submsg.getInt32WithDefault(1, 0)).toEqual(5); + submsg.setInt32(1, 0); + + expect(accessor.serialize()).toEqual(expected); + }); + + it('set values', () => { + const accessor = Kernel.createEmpty(); + const subbytes = createArrayBuffer(0x08, 0x01); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); + + accessor.setRepeatedGroupIterable(1, [submsg]); + const result = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + + expect(Array.from(result)).toEqual([submsg]); + }); + + it('encode for adding single value', () => { + const accessor = Kernel.createEmpty(); + const bytes1 = createArrayBuffer(0x08, 0x01); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); + const bytes2 = createArrayBuffer(0x08, 0x00); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); + const expected = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x00, 0x0C); + + accessor.addRepeatedGroupElement(1, msg1, TestMessage.instanceCreator); + accessor.addRepeatedGroupElement(1, msg2, TestMessage.instanceCreator); + const result = accessor.serialize(); + + expect(result).toEqual(expected); + }); + + it('encode for adding values', () => { + const accessor = Kernel.createEmpty(); + const bytes1 = createArrayBuffer(0x08, 0x01); + const msg1 = new TestMessage(Kernel.fromArrayBuffer(bytes1)); + const bytes2 = createArrayBuffer(0x08, 0x00); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); + const expected = + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C, 0x0B, 0x08, 0x00, 0x0C); + + accessor.addRepeatedGroupIterable( + 1, [msg1, msg2], TestMessage.instanceCreator); + const result = accessor.serialize(); + + expect(result).toEqual(expected); + }); + + it('encode for setting single value', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x00, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const subbytes = createArrayBuffer(0x08, 0x01); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); + const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + + accessor.setRepeatedGroupElement( + /* fieldNumber= */ 1, submsg, TestMessage.instanceCreator, + /* index= */ 0); + const result = accessor.serialize(); + + expect(result).toEqual(expected); + }); + + it('encode for setting values', () => { + const accessor = Kernel.createEmpty(); + const subbytes = createArrayBuffer(0x08, 0x01); + const submsg = new TestMessage(Kernel.fromArrayBuffer(subbytes)); + const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + + accessor.setRepeatedGroupIterable(1, [submsg]); + const result = accessor.serialize(); + + expect(result).toEqual(expected); + }); + + it('fail when getting groups value with other wire types', () => { + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( + 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); + + if (CHECK_CRITICAL_STATE) { + expect(() => { + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + }).toThrow(); + } + }); + + it('fail when adding group values with wrong type value', () => { + const accessor = Kernel.createEmpty(); + const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); + if (CHECK_CRITICAL_STATE) { + expect( + () => accessor.addRepeatedGroupIterable( + 1, [fakeValue], TestMessage.instanceCreator)) + .toThrowError('Given value is not a message instance: null'); + } else { + // Note in unchecked mode we produce invalid output for invalid inputs. + // This test just documents our behavior in those cases. + // These values might change at any point and are not considered + // what the implementation should be doing here. + accessor.addRepeatedGroupIterable( + 1, [fakeValue], TestMessage.instanceCreator); + const list = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + expect(Array.from(list)).toEqual([null]); + } + }); + + it('fail when adding single group value with wrong type value', () => { + const accessor = Kernel.createEmpty(); + const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); + if (CHECK_CRITICAL_STATE) { + expect( + () => accessor.addRepeatedGroupElement( + 1, fakeValue, TestMessage.instanceCreator)) + .toThrowError('Given value is not a message instance: null'); + } else { + // Note in unchecked mode we produce invalid output for invalid inputs. + // This test just documents our behavior in those cases. + // These values might change at any point and are not considered + // what the implementation should be doing here. + accessor.addRepeatedGroupElement( + 1, fakeValue, TestMessage.instanceCreator); + const list = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + expect(Array.from(list)).toEqual([null]); + } + }); + + it('fail when setting message values with wrong type value', () => { + const accessor = Kernel.createEmpty(); + const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); + if (CHECK_CRITICAL_STATE) { + expect(() => accessor.setRepeatedGroupIterable(1, [fakeValue])) + .toThrowError('Given value is not a message instance: null'); + } else { + // Note in unchecked mode we produce invalid output for invalid inputs. + // This test just documents our behavior in those cases. + // These values might change at any point and are not considered + // what the implementation should be doing here. + accessor.setRepeatedGroupIterable(1, [fakeValue]); + const list = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + expect(Array.from(list)).toEqual([null]); + } + }); + + it('fail when setting single value with wrong type value', () => { + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0B, 0x08, 0x00, 0x0C)); + const fakeValue = /** @type {!TestMessage} */ (/** @type {*} */ (null)); + if (CHECK_CRITICAL_STATE) { + expect( + () => accessor.setRepeatedGroupElement( + /* fieldNumber= */ 1, fakeValue, TestMessage.instanceCreator, + /* index= */ 0)) + .toThrowError('Given value is not a message instance: null'); + } else { + // Note in unchecked mode we produce invalid output for invalid inputs. + // This test just documents our behavior in those cases. + // These values might change at any point and are not considered + // what the implementation should be doing here. + accessor.setRepeatedGroupElement( + /* fieldNumber= */ 1, fakeValue, TestMessage.instanceCreator, + /* index= */ 0); + const list = + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator); + expect(Array.from(list).length).toEqual(1); + } + }); + + it('fail when setting single value with out-of-bound index', () => { + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0B, 0x08, 0x00, 0x0C)); + const msg1 = + accessor.getRepeatedGroupElement(1, TestMessage.instanceCreator, 0); + const bytes2 = createArrayBuffer(0x08, 0x01); + const msg2 = new TestMessage(Kernel.fromArrayBuffer(bytes2)); + if (CHECK_CRITICAL_STATE) { + expect( + () => accessor.setRepeatedGroupElement( + /* fieldNumber= */ 1, msg2, TestMessage.instanceCreator, + /* index= */ 1)) + .toThrowError('Index out of bounds: index: 1 size: 1'); + } else { + // Note in unchecked mode we produce invalid output for invalid inputs. + // This test just documents our behavior in those cases. + // These values might change at any point and are not considered + // what the implementation should be doing here. + accessor.setRepeatedGroupElement( + /* fieldNumber= */ 1, msg2, TestMessage.instanceCreator, + /* index= */ 1); + expectEqualToArray( + accessor.getRepeatedGroupIterable(1, TestMessage.instanceCreator), + [msg1, msg2]); + } + }); +}); diff --git a/js/experimental/runtime/kernel/lazy_accessor_test.js b/js/experimental/runtime/kernel/kernel_test.js similarity index 66% rename from js/experimental/runtime/kernel/lazy_accessor_test.js rename to js/experimental/runtime/kernel/kernel_test.js index ad4576dfce1d..eba7c4a55a2d 100644 --- a/js/experimental/runtime/kernel/lazy_accessor_test.js +++ b/js/experimental/runtime/kernel/kernel_test.js @@ -1,14 +1,14 @@ /** - * @fileoverview Tests for lazy_accessor.js. + * @fileoverview Tests for kernel.js. */ -goog.module('protobuf.binary.LazyAccessorTest'); +goog.module('protobuf.runtime.KernelTest'); goog.setTestOnly(); const ByteString = goog.require('protobuf.ByteString'); const Int64 = goog.require('protobuf.Int64'); const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); // Note to the reader: // Since the lazy accessor behavior changes with the checking level some of the @@ -24,58 +24,67 @@ function createArrayBuffer(...bytes) { return new Uint8Array(bytes).buffer; } -describe('LazyAccessor', () => { +describe('Kernel', () => { it('encodes none for the empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); expect(accessor.serialize()).toEqual(new ArrayBuffer(0)); }); + it('encodes and decodes max field number', () => { + const accessor = Kernel.fromArrayBuffer( + createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x01)); + expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toBe(true); + accessor.setBool(MAX_FIELD_NUMBER, false); + expect(accessor.serialize()) + .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0x00)); + }); + it('uses the default pivot point', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); expect(accessor.getPivot()).toBe(24); }); it('makes the pivot point configurable', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0), 50); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0), 50); expect(accessor.getPivot()).toBe(50); }); }); -describe('LazyAccessor hasFieldNumber', () => { +describe('Kernel hasFieldNumber', () => { it('returns false for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); expect(accessor.hasFieldNumber(1)).toBe(false); }); it('returns true for non-empty input', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.hasFieldNumber(1)).toBe(true); }); it('returns false for empty array', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedBoolIterable(1, []); expect(accessor.hasFieldNumber(1)).toBe(false); }); it('returns true for non-empty array', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setPackedBoolIterable(1, [true]); expect(accessor.hasFieldNumber(1)).toBe(true); }); it('updates value after write', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); expect(accessor.hasFieldNumber(1)).toBe(false); accessor.setBool(1, false); expect(accessor.hasFieldNumber(1)).toBe(true); }); }); -describe('LazyAccessor clear field does', () => { +describe('Kernel clear field does', () => { it('clear the field set', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setBool(1, true); accessor.clearField(1); @@ -86,7 +95,7 @@ describe('LazyAccessor clear field does', () => { it('clear the field decoded', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.clearField(1); expect(accessor.hasFieldNumber(1)).toEqual(false); @@ -96,7 +105,7 @@ describe('LazyAccessor clear field does', () => { it('clear the field read', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getBoolWithDefault(1)).toEqual(true); accessor.clearField(1); @@ -106,7 +115,7 @@ describe('LazyAccessor clear field does', () => { }); it('clear set and copied fields without affecting the old', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setBool(1, true); const clonedAccessor = accessor.shallowCopy(); @@ -121,7 +130,7 @@ describe('LazyAccessor clear field does', () => { it('clear decoded and copied fields without affecting the old', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const clonedAccessor = accessor.shallowCopy(); clonedAccessor.clearField(1); @@ -135,7 +144,7 @@ describe('LazyAccessor clear field does', () => { it('clear read and copied fields without affecting the old', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getBoolWithDefault(1)).toEqual(true); const clonedAccessor = accessor.shallowCopy(); @@ -147,21 +156,35 @@ describe('LazyAccessor clear field does', () => { expect(clonedAccessor.serialize()).toEqual(new ArrayBuffer(0)); expect(clonedAccessor.getBoolWithDefault(1)).toEqual(false); }); + + it('clear the max field number', () => { + const accessor = Kernel.createEmpty(); + accessor.setBool(MAX_FIELD_NUMBER, true); + + accessor.clearField(MAX_FIELD_NUMBER); + + expect(accessor.hasFieldNumber(MAX_FIELD_NUMBER)).toEqual(false); + expect(accessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(false); + }); }); -describe('LazyAccessor shallow copy does', () => { +describe('Kernel shallow copy does', () => { it('work for singular fields', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setBool(1, true); + accessor.setBool(MAX_FIELD_NUMBER, true); const clonedAccessor = accessor.shallowCopy(); expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); + expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); accessor.setBool(1, false); + accessor.setBool(MAX_FIELD_NUMBER, false); expect(clonedAccessor.getBoolWithDefault(1)).toEqual(true); + expect(clonedAccessor.getBoolWithDefault(MAX_FIELD_NUMBER)).toEqual(true); }); it('work for repeated fields', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedBoolIterable(2, [true, true]); @@ -175,7 +198,7 @@ describe('LazyAccessor shallow copy does', () => { }); it('work for repeated fields', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.addUnpackedBoolIterable(2, [true, true]); @@ -190,7 +213,7 @@ describe('LazyAccessor shallow copy does', () => { it('return the correct bytes after serialization', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x10, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes, /* pivot= */ 1); + const accessor = Kernel.fromArrayBuffer(bytes, /* pivot= */ 1); const clonedAccessor = accessor.shallowCopy(); accessor.setBool(1, false); @@ -200,9 +223,9 @@ describe('LazyAccessor shallow copy does', () => { }); }); -describe('LazyAccessor for singular boolean does', () => { +describe('Kernel for singular boolean does', () => { it('return false for the empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); expect(accessor.getBoolWithDefault( /* fieldNumber= */ 1)) .toBe(false); @@ -210,7 +233,7 @@ describe('LazyAccessor for singular boolean does', () => { it('return the value from the input', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getBoolWithDefault( /* fieldNumber= */ 1)) .toBe(true); @@ -218,13 +241,13 @@ describe('LazyAccessor for singular boolean does', () => { it('encode the value from the input', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.serialize()).toEqual(bytes); }); it('encode the value from the input after read', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.getBoolWithDefault( /* fieldNumber= */ 1); expect(accessor.serialize()).toEqual(bytes); @@ -232,7 +255,7 @@ describe('LazyAccessor for singular boolean does', () => { it('return the value from multiple inputs', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getBoolWithDefault( /* fieldNumber= */ 1)) .toBe(false); @@ -240,20 +263,20 @@ describe('LazyAccessor for singular boolean does', () => { it('encode the value from multiple inputs', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.serialize()).toEqual(bytes); }); it('encode the value from multiple inputs after read', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.getBoolWithDefault(/* fieldNumber= */ 1); expect(accessor.serialize()).toEqual(bytes); }); it('return the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setBool(1, true); expect(accessor.getBoolWithDefault( /* fieldNumber= */ 1)) @@ -262,7 +285,7 @@ describe('LazyAccessor for singular boolean does', () => { it('encode the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01, 0x08, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x08, 0x01); accessor.setBool(1, true); expect(accessor.serialize()).toEqual(newBytes); @@ -270,7 +293,7 @@ describe('LazyAccessor for singular boolean does', () => { it('return the bool value from cache', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getBoolWithDefault( /* fieldNumber= */ 1)) .toBe(true); @@ -282,7 +305,7 @@ describe('LazyAccessor for singular boolean does', () => { }); it('fail when getting bool value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { @@ -300,7 +323,7 @@ describe('LazyAccessor for singular boolean does', () => { }); it('fail when setting bool value with out-of-range field number', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); if (CHECK_TYPE) { expect(() => accessor.setBool(MAX_FIELD_NUMBER + 1, false)) .toThrowError('Field number is out of range: 536870912'); @@ -315,7 +338,7 @@ describe('LazyAccessor for singular boolean does', () => { }); it('fail when setting bool value with number value', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); const fakeBoolean = /** @type {boolean} */ (/** @type {*} */ (2)); if (CHECK_CRITICAL_TYPE) { expect(() => accessor.setBool(1, fakeBoolean)) @@ -333,30 +356,30 @@ describe('LazyAccessor for singular boolean does', () => { }); }); -describe('LazyAccessor for singular message does', () => { +describe('Kernel for singular message does', () => { it('return message from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); expect(msg.getBoolWithDefault(1, false)).toBe(true); }); it('return message from the input when pivot is set', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes, /* pivot= */ 0); + const accessor = Kernel.fromArrayBuffer(bytes, /* pivot= */ 0); const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); expect(msg.getBoolWithDefault(1, false)).toBe(true); }); it('encode message from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.serialize()).toEqual(bytes); }); it('encode message from the input after read', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.getMessageOrNull(1, TestMessage.instanceCreator); expect(accessor.serialize()).toEqual(bytes); }); @@ -364,7 +387,7 @@ describe('LazyAccessor for singular message does', () => { it('return message from multiple inputs', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const msg = accessor.getMessageOrNull(1, TestMessage.instanceCreator); expect(msg.getBoolWithDefault(1, false)).toBe(true); expect(msg.getBoolWithDefault(2, false)).toBe(true); @@ -373,7 +396,7 @@ describe('LazyAccessor for singular message does', () => { it('encode message from multiple inputs', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.serialize()).toEqual(bytes); }); @@ -381,28 +404,28 @@ describe('LazyAccessor for singular message does', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01, 0x0A, 0x02, 0x10, 0x01); const expected = createArrayBuffer(0x0A, 0x04, 0x08, 0x01, 0x10, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.getMessageOrNull(1, TestMessage.instanceCreator); expect(accessor.serialize()).toEqual(expected); }); it('return null for generic accessor', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const accessor1 = accessor.getMessageAccessorOrNull(7); expect(accessor1).toBe(null); }); it('return null for generic accessor when pivot is set', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const accessor1 = accessor.getMessageAccessorOrNull(7, /* pivot= */ 0); expect(accessor1).toBe(null); }); it('return generic accessor from the input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const accessor1 = accessor.getMessageAccessorOrNull(1); expect(accessor1.getBoolWithDefault(1, false)).toBe(true); // Second call returns a new instance, isn't cached. @@ -413,7 +436,7 @@ describe('LazyAccessor for singular message does', () => { it('return generic accessor from the cached input', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const wrappedMessage = accessor.getMessageOrNull(1, TestMessage.instanceCreator); @@ -433,8 +456,8 @@ describe('LazyAccessor for singular message does', () => { it('return message from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); + const subaccessor = Kernel.fromArrayBuffer(bytes); const submsg1 = new TestMessage(subaccessor); accessor.setMessage(1, submsg1); const submsg2 = accessor.getMessage(1, TestMessage.instanceCreator); @@ -442,10 +465,10 @@ describe('LazyAccessor for singular message does', () => { }); it('encode message from setter', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); + const subaccessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); const subsubaccessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); const subsubmsg = new TestMessage(subsubaccessor); subaccessor.setMessage(1, subsubmsg); const submsg = new TestMessage(subaccessor); @@ -455,12 +478,12 @@ describe('LazyAccessor for singular message does', () => { }); it('encode message with multiple submessage from setter', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); - const subaccessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); + const subaccessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); const subsubaccessor1 = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); const subsubaccessor2 = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); const subsubmsg1 = new TestMessage(subsubaccessor1); const subsubmsg2 = new TestMessage(subsubaccessor2); @@ -477,7 +500,7 @@ describe('LazyAccessor for singular message does', () => { }); it('leave hasFieldNumber unchanged after getMessageOrNull', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expect(accessor.hasFieldNumber(1)).toBe(false); expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) .toBe(null); @@ -486,7 +509,7 @@ describe('LazyAccessor for singular message does', () => { it('serialize changes to submessages made with getMessageOrNull', () => { const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); const mutableSubMessage = accessor.getMessageOrNull(1, TestMessage.instanceCreator); mutableSubMessage.setInt32(1, 10); @@ -496,7 +519,7 @@ describe('LazyAccessor for singular message does', () => { it('serialize additions to submessages made with getMessageOrNull', () => { const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); const mutableSubMessage = accessor.getMessageOrNull(1, TestMessage.instanceCreator); mutableSubMessage.setInt32(2, 3); @@ -507,7 +530,7 @@ describe('LazyAccessor for singular message does', () => { it('fail with getMessageOrNull if immutable message exist in cache', () => { const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); if (CHECK_TYPE) { @@ -526,7 +549,7 @@ describe('LazyAccessor for singular message does', () => { }); it('change hasFieldNumber after getMessageAttach', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expect(accessor.hasFieldNumber(1)).toBe(false); expect(accessor.getMessageAttach(1, TestMessage.instanceCreator)) .not.toBe(null); @@ -534,7 +557,7 @@ describe('LazyAccessor for singular message does', () => { }); it('change hasFieldNumber after getMessageAttach when pivot is set', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); expect(accessor.hasFieldNumber(1)).toBe(false); expect(accessor.getMessageAttach( 1, TestMessage.instanceCreator, /* pivot= */ 1)) @@ -543,7 +566,7 @@ describe('LazyAccessor for singular message does', () => { }); it('serialize submessages made with getMessageAttach', () => { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); const mutableSubMessage = accessor.getMessageAttach(1, TestMessage.instanceCreator); mutableSubMessage.setInt32(1, 10); @@ -553,7 +576,7 @@ describe('LazyAccessor for singular message does', () => { it('serialize additions to submessages using getMessageAttach', () => { const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); const mutableSubMessage = accessor.getMessageAttach(1, TestMessage.instanceCreator); mutableSubMessage.setInt32(2, 3); @@ -564,7 +587,7 @@ describe('LazyAccessor for singular message does', () => { it('fail with getMessageAttach if immutable message exist in cache', () => { const intTwoBytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x02); - const accessor = LazyAccessor.fromArrayBuffer(intTwoBytes); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); const readOnly = accessor.getMessage(1, TestMessage.instanceCreator); if (CHECK_TYPE) { @@ -584,7 +607,7 @@ describe('LazyAccessor for singular message does', () => { it('read default message return empty message with getMessage', () => { const bytes = new ArrayBuffer(0); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getMessage(1, TestMessage.instanceCreator)).toBeTruthy(); expect(accessor.getMessage(1, TestMessage.instanceCreator).serialize()) .toEqual(bytes); @@ -592,14 +615,14 @@ describe('LazyAccessor for singular message does', () => { it('read default message return null with getMessageOrNull', () => { const bytes = new ArrayBuffer(0); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getMessageOrNull(1, TestMessage.instanceCreator)) .toBe(null); }); it('read message preserve reference equality', () => { const bytes = createArrayBuffer(0x0A, 0x02, 0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const msg1 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); const msg2 = accessor.getMessageOrNull(1, TestMessage.instanceCreator); const msg3 = accessor.getMessageAttach(1, TestMessage.instanceCreator); @@ -608,36 +631,35 @@ describe('LazyAccessor for singular message does', () => { }); it('fail when getting message with other wire types', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) .toThrow(); }); it('fail when submessage has incomplete data', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); expect(() => accessor.getMessageOrNull(1, TestMessage.instanceCreator)) .toThrow(); }); it('fail when mutable submessage has incomplete data', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x08)); expect(() => accessor.getMessageAttach(1, TestMessage.instanceCreator)) .toThrow(); }); it('fail when getting message with null instance constructor', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); - const nullMessage = /** @type {function(!LazyAccessor):!TestMessage} */ + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); + const nullMessage = /** @type {function(!Kernel):!TestMessage} */ (/** @type {*} */ (null)); expect(() => accessor.getMessageOrNull(1, nullMessage)).toThrow(); }); it('fail when setting message value with null value', () => { - const accessor = LazyAccessor.fromArrayBuffer(new ArrayBuffer(0)); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); const fakeMessage = /** @type {!TestMessage} */ (/** @type {*} */ (null)); if (CHECK_CRITICAL_TYPE) { expect(() => accessor.setMessage(1, fakeMessage)) @@ -659,32 +681,32 @@ describe('Bytes access', () => { const simpleByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getBytesWithDefault(1)).toEqual(ByteString.EMPTY); }); it('returns the default from parameter', () => { const defaultByteString = ByteString.fromArrayBuffer(createArrayBuffer(1)); const returnValue = ByteString.fromArrayBuffer(createArrayBuffer(1)); - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getBytesWithDefault(1, defaultByteString)) .toEqual(returnValue); }); it('decodes value from wire', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x01)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x01)); expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0A, 0x01, 0x00, 0x0A, 0x01, 0x01)); expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01)); if (CHECK_CRITICAL_TYPE) { expect(() => { @@ -704,26 +726,24 @@ describe('Bytes access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { expect( - () => LazyAccessor.createEmpty().getBytesWithDefault( - -1, simpleByteString)) + () => Kernel.createEmpty().getBytesWithDefault(-1, simpleByteString)) .toThrowError('Field number is out of range: -1'); } else { - expect( - LazyAccessor.createEmpty().getBytesWithDefault(-1, simpleByteString)) + expect(Kernel.createEmpty().getBytesWithDefault(-1, simpleByteString)) .toEqual(simpleByteString); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x0A, 0x01, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setBytes(1, simpleByteString); expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x0A, 0x01, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x0A, 0x01, 0x01); accessor.setBytes(1, simpleByteString); expect(accessor.serialize()).toEqual(newBytes); @@ -731,7 +751,7 @@ describe('Bytes access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x0A, 0x01, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getBytesWithDefault(1)).toEqual(simpleByteString); // Make sure the value is cached. bytes[2] = 0x00; @@ -740,10 +760,10 @@ describe('Bytes access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setBytes(-1, simpleByteString)) + expect(() => Kernel.createEmpty().setBytes(-1, simpleByteString)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setBytes(-1, simpleByteString); expect(accessor.getBytesWithDefault(-1)).toEqual(simpleByteString); } @@ -752,11 +772,11 @@ describe('Bytes access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setBytes( + () => Kernel.createEmpty().setBytes( 1, /** @type {!ByteString} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setBytes( 1, /** @type {!ByteString} */ (/** @type {*} */ (null))); expect(accessor.getBytesWithDefault(1)).toEqual(null); @@ -766,30 +786,30 @@ describe('Bytes access', () => { describe('Fixed32 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getFixed32WithDefault(1)).toEqual(0); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getFixed32WithDefault(1, 2)).toEqual(2); }); it('decodes value from wire', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); expect(accessor.getFixed32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); expect(accessor.getFixed32WithDefault(1)).toEqual(2); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getFixed32WithDefault(1); @@ -805,24 +825,23 @@ describe('Fixed32 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getFixed32WithDefault(-1, 1)) + expect(() => Kernel.createEmpty().getFixed32WithDefault(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getFixed32WithDefault(-1, 1)) - .toEqual(1); + expect(Kernel.createEmpty().getFixed32WithDefault(-1, 1)).toEqual(1); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setFixed32(1, 2); expect(accessor.getFixed32WithDefault(1)).toEqual(2); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); accessor.setFixed32(1, 0); expect(accessor.serialize()).toEqual(newBytes); @@ -830,7 +849,7 @@ describe('Fixed32 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getFixed32WithDefault(1)).toBe(1); // Make sure the value is cached. bytes[2] = 0x00; @@ -839,10 +858,10 @@ describe('Fixed32 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setFixed32(-1, 1)) + expect(() => Kernel.createEmpty().setFixed32(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setFixed32(-1, 1); expect(accessor.getFixed32WithDefault(-1)).toEqual(1); } @@ -851,37 +870,47 @@ describe('Fixed32 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setFixed32( + () => Kernel.createEmpty().setFixed32( 1, /** @type {number} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setFixed32(1, /** @type {number} */ (/** @type {*} */ (null))); expect(accessor.getFixed32WithDefault(1)).toEqual(null); } }); + + it('throws in setter for negative value', () => { + if (CHECK_CRITICAL_TYPE) { + expect(() => Kernel.createEmpty().setFixed32(1, -1)).toThrow(); + } else { + const accessor = Kernel.createEmpty(); + accessor.setFixed32(1, -1); + expect(accessor.getFixed32WithDefault(1)).toEqual(-1); + } + }); }); describe('Fixed64 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(0)); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getFixed64WithDefault(1, Int64.fromInt(2))) .toEqual(Int64.fromInt(2)); }); it('decodes value from wire', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); @@ -889,7 +918,7 @@ describe('Fixed64 access', () => { if (CHECK_CRITICAL_STATE) { it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( + const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); expect(() => { accessor.getFixed64WithDefault(1); @@ -900,12 +929,11 @@ describe('Fixed64 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { expect( - () => LazyAccessor.createEmpty().getFixed64WithDefault( - -1, Int64.fromInt(1))) + () => + Kernel.createEmpty().getFixed64WithDefault(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getFixed64WithDefault( - -1, Int64.fromInt(1))) + expect(Kernel.createEmpty().getFixed64WithDefault(-1, Int64.fromInt(1))) .toEqual(Int64.fromInt(1)); } }); @@ -913,7 +941,7 @@ describe('Fixed64 access', () => { it('returns the value from setter', () => { const bytes = createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setFixed64(1, Int64.fromInt(2)); expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(2)); }); @@ -921,7 +949,7 @@ describe('Fixed64 access', () => { it('encode the value from setter', () => { const bytes = createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); accessor.setFixed64(1, Int64.fromInt(0)); @@ -931,7 +959,7 @@ describe('Fixed64 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getFixed64WithDefault(1)).toEqual(Int64.fromInt(1)); // Make sure the value is cached. bytes[2] = 0x00; @@ -940,10 +968,10 @@ describe('Fixed64 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setFixed64(-1, Int64.fromInt(1))) + expect(() => Kernel.createEmpty().setFixed64(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setFixed64(-1, Int64.fromInt(1)); expect(accessor.getFixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); } @@ -952,11 +980,11 @@ describe('Fixed64 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setSfixed64( + () => Kernel.createEmpty().setSfixed64( 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setFixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); expect(accessor.getFixed64WithDefault(1)).toEqual(null); } @@ -965,30 +993,30 @@ describe('Fixed64 access', () => { describe('Float access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getFloatWithDefault(1)).toEqual(0); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getFloatWithDefault(1, 2)).toEqual(2); }); it('decodes value from wire', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F)); expect(accessor.getFloatWithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x00, 0x00, 0x80, 0x3F, 0x0D, 0x00, 0x00, 0x80, 0xBF)); expect(accessor.getFloatWithDefault(1)).toEqual(-1); }); if (CHECK_CRITICAL_STATE) { it('fails when getting float value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F)); expect(() => { accessor.getFloatWithDefault(1); @@ -999,23 +1027,23 @@ describe('Float access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getFloatWithDefault(-1, 1)) + expect(() => Kernel.createEmpty().getFloatWithDefault(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getFloatWithDefault(-1, 1)).toEqual(1); + expect(Kernel.createEmpty().getFloatWithDefault(-1, 1)).toEqual(1); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setFloat(1, 1.6); expect(accessor.getFloatWithDefault(1)).toEqual(Math.fround(1.6)); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); accessor.setFloat(1, 0); expect(accessor.serialize()).toEqual(newBytes); @@ -1023,7 +1051,7 @@ describe('Float access', () => { it('returns float value from cache', () => { const bytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x80, 0x3F); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getFloatWithDefault(1)).toBe(1); // Make sure the value is cached. bytes[2] = 0x00; @@ -1032,10 +1060,10 @@ describe('Float access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setFloat(-1, 1)) + expect(() => Kernel.createEmpty().setFloat(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setFloat(-1, 1); expect(accessor.getFloatWithDefault(-1)).toEqual(1); } @@ -1044,11 +1072,11 @@ describe('Float access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setFloat( + () => Kernel.createEmpty().setFloat( 1, /** @type {number} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setFloat(1, /** @type {number} */ (/** @type {*} */ (null))); expect(accessor.getFloatWithDefault(1)).toEqual(0); } @@ -1056,10 +1084,10 @@ describe('Float access', () => { it('throws in setter for value outside of float32 precision', () => { if (CHECK_CRITICAL_TYPE) { - expect(() => LazyAccessor.createEmpty().setFloat(1, Number.MAX_VALUE)) + expect(() => Kernel.createEmpty().setFloat(1, Number.MAX_VALUE)) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setFloat(1, Number.MAX_VALUE); expect(accessor.getFloatWithDefault(1)).toEqual(Infinity); } @@ -1068,30 +1096,29 @@ describe('Float access', () => { describe('Int32 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getInt32WithDefault(1)).toEqual(0); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getInt32WithDefault(1, 2)).toEqual(2); }); it('decodes value from wire', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); expect(accessor.getInt32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getInt32WithDefault(1)).toEqual(2); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getInt32WithDefault(1); @@ -1107,23 +1134,23 @@ describe('Int32 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getInt32WithDefault(-1, 1)) + expect(() => Kernel.createEmpty().getInt32WithDefault(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getInt32WithDefault(-1, 1)).toEqual(1); + expect(Kernel.createEmpty().getInt32WithDefault(-1, 1)).toEqual(1); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setInt32(1, 2); expect(accessor.getInt32WithDefault(1)).toEqual(2); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x08, 0x00); accessor.setInt32(1, 0); expect(accessor.serialize()).toEqual(newBytes); @@ -1131,7 +1158,7 @@ describe('Int32 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getInt32WithDefault(1)).toBe(1); // Make sure the value is cached. bytes[2] = 0x00; @@ -1140,10 +1167,10 @@ describe('Int32 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setInt32(-1, 1)) + expect(() => Kernel.createEmpty().setInt32(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setInt32(-1, 1); expect(accessor.getInt32WithDefault(-1)).toEqual(1); } @@ -1152,11 +1179,11 @@ describe('Int32 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setInt32( + () => Kernel.createEmpty().setInt32( 1, /** @type {number} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setInt32(1, /** @type {number} */ (/** @type {*} */ (null))); expect(accessor.getInt32WithDefault(1)).toEqual(null); } @@ -1165,31 +1192,30 @@ describe('Int32 access', () => { describe('Int64 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(0)); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getInt64WithDefault(1, Int64.fromInt(2))) .toEqual(Int64.fromInt(2)); }); it('decodes value from wire', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getInt64WithDefault(1); @@ -1206,26 +1232,24 @@ describe('Int64 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { expect( - () => LazyAccessor.createEmpty().getInt64WithDefault( - -1, Int64.fromInt(1))) + () => Kernel.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - expect( - LazyAccessor.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) + expect(Kernel.createEmpty().getInt64WithDefault(-1, Int64.fromInt(1))) .toEqual(Int64.fromInt(1)); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setInt64(1, Int64.fromInt(2)); expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(2)); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x08, 0x00); accessor.setInt64(1, Int64.fromInt(0)); expect(accessor.serialize()).toEqual(newBytes); @@ -1233,7 +1257,7 @@ describe('Int64 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getInt64WithDefault(1)).toEqual(Int64.fromInt(1)); // Make sure the value is cached. bytes[2] = 0x00; @@ -1242,10 +1266,10 @@ describe('Int64 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setInt64(-1, Int64.fromInt(1))) + expect(() => Kernel.createEmpty().setInt64(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setInt64(-1, Int64.fromInt(1)); expect(accessor.getInt64WithDefault(-1)).toEqual(Int64.fromInt(1)); } @@ -1254,11 +1278,11 @@ describe('Int64 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setInt64( + () => Kernel.createEmpty().setInt64( 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setInt64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); expect(accessor.getInt64WithDefault(1)).toEqual(null); } @@ -1267,30 +1291,30 @@ describe('Int64 access', () => { describe('Sfixed32 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSfixed32WithDefault(1)).toEqual(0); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSfixed32WithDefault(1, 2)).toEqual(2); }); it('decodes value from wire', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00)); expect(accessor.getSfixed32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x0D, 0x01, 0x00, 0x80, 0x00, 0x0D, 0x02, 0x00, 0x00, 0x00)); expect(accessor.getSfixed32WithDefault(1)).toEqual(2); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x80, 0x80, 0x80, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getSfixed32WithDefault(1); @@ -1306,24 +1330,23 @@ describe('Sfixed32 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getSfixed32WithDefault(-1, 1)) + expect(() => Kernel.createEmpty().getSfixed32WithDefault(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getSfixed32WithDefault(-1, 1)) - .toEqual(1); + expect(Kernel.createEmpty().getSfixed32WithDefault(-1, 1)).toEqual(1); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setSfixed32(1, 2); expect(accessor.getSfixed32WithDefault(1)).toEqual(2); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00); accessor.setSfixed32(1, 0); expect(accessor.serialize()).toEqual(newBytes); @@ -1331,7 +1354,7 @@ describe('Sfixed32 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x0D, 0x01, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getSfixed32WithDefault(1)).toBe(1); // Make sure the value is cached. bytes[2] = 0x00; @@ -1340,10 +1363,10 @@ describe('Sfixed32 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setSfixed32(-1, 1)) + expect(() => Kernel.createEmpty().setSfixed32(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setSfixed32(-1, 1); expect(accessor.getSfixed32WithDefault(-1)).toEqual(1); } @@ -1352,11 +1375,11 @@ describe('Sfixed32 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setSfixed32( + () => Kernel.createEmpty().setSfixed32( 1, /** @type {number} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setSfixed32(1, /** @type {number} */ (/** @type {*} */ (null))); expect(accessor.getSfixed32WithDefault(1)).toEqual(null); } @@ -1365,24 +1388,24 @@ describe('Sfixed32 access', () => { describe('Sfixed64 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(0)); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSfixed64WithDefault(1, Int64.fromInt(2))) .toEqual(Int64.fromInt(2)); }); it('decodes value from wire', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); @@ -1390,7 +1413,7 @@ describe('Sfixed64 access', () => { if (CHECK_CRITICAL_STATE) { it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( + const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); expect(() => { accessor.getSfixed64WithDefault(1); @@ -1401,12 +1424,11 @@ describe('Sfixed64 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { expect( - () => LazyAccessor.createEmpty().getSfixed64WithDefault( - -1, Int64.fromInt(1))) + () => + Kernel.createEmpty().getSfixed64WithDefault(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getSfixed64WithDefault( - -1, Int64.fromInt(1))) + expect(Kernel.createEmpty().getSfixed64WithDefault(-1, Int64.fromInt(1))) .toEqual(Int64.fromInt(1)); } }); @@ -1414,7 +1436,7 @@ describe('Sfixed64 access', () => { it('returns the value from setter', () => { const bytes = createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setSfixed64(1, Int64.fromInt(2)); expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(2)); }); @@ -1422,7 +1444,7 @@ describe('Sfixed64 access', () => { it('encode the value from setter', () => { const bytes = createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); accessor.setSfixed64(1, Int64.fromInt(0)); @@ -1432,7 +1454,7 @@ describe('Sfixed64 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(1)); // Make sure the value is cached. bytes[2] = 0x00; @@ -1441,10 +1463,10 @@ describe('Sfixed64 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setSfixed64(-1, Int64.fromInt(1))) + expect(() => Kernel.createEmpty().setSfixed64(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setSfixed64(-1, Int64.fromInt(1)); expect(accessor.getSfixed64WithDefault(-1)).toEqual(Int64.fromInt(1)); } @@ -1453,11 +1475,11 @@ describe('Sfixed64 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setSfixed64( + () => Kernel.createEmpty().setSfixed64( 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setSfixed64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); expect(accessor.getSfixed64WithDefault(1)).toEqual(null); } @@ -1466,30 +1488,29 @@ describe('Sfixed64 access', () => { describe('Sint32 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSint32WithDefault(1)).toEqual(0); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSint32WithDefault(1, 2)).toEqual(2); }); it('decodes value from wire', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); expect(accessor.getSint32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x03, 0x08, 0x02)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x03, 0x08, 0x02)); expect(accessor.getSint32WithDefault(1)).toEqual(1); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getSint32WithDefault(1); @@ -1505,23 +1526,23 @@ describe('Sint32 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getSint32WithDefault(-1, 1)) + expect(() => Kernel.createEmpty().getSint32WithDefault(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getSint32WithDefault(-1, 1)).toEqual(1); + expect(Kernel.createEmpty().getSint32WithDefault(-1, 1)).toEqual(1); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setSint32(1, 2); expect(accessor.getSint32WithDefault(1)).toEqual(2); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x08, 0x00); accessor.setSint32(1, 0); expect(accessor.serialize()).toEqual(newBytes); @@ -1529,7 +1550,7 @@ describe('Sint32 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x08, 0x02); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getSint32WithDefault(1)).toBe(1); // Make sure the value is cached. bytes[2] = 0x00; @@ -1538,10 +1559,10 @@ describe('Sint32 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setSint32(-1, 1)) + expect(() => Kernel.createEmpty().setSint32(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setSint32(-1, 1); expect(accessor.getSint32WithDefault(-1)).toEqual(1); } @@ -1550,11 +1571,11 @@ describe('Sint32 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setSint32( + () => Kernel.createEmpty().setSint32( 1, /** @type {number} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setSint32(1, /** @type {number} */ (/** @type {*} */ (null))); expect(accessor.getSint32WithDefault(1)).toEqual(null); } @@ -1563,31 +1584,30 @@ describe('Sint32 access', () => { describe('SInt64 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(0)); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getSint64WithDefault(1, Int64.fromInt(2))) .toEqual(Int64.fromInt(2)); }); it('decodes value from wire', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02)); expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getSint64WithDefault(1); @@ -1604,26 +1624,24 @@ describe('SInt64 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { expect( - () => LazyAccessor.createEmpty().getSint64WithDefault( - -1, Int64.fromInt(1))) + () => Kernel.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - expect( - LazyAccessor.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) + expect(Kernel.createEmpty().getSint64WithDefault(-1, Int64.fromInt(1))) .toEqual(Int64.fromInt(1)); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setSint64(1, Int64.fromInt(2)); expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(2)); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x08, 0x00); accessor.setSint64(1, Int64.fromInt(0)); expect(accessor.serialize()).toEqual(newBytes); @@ -1631,7 +1649,7 @@ describe('SInt64 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x08, 0x02); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getSint64WithDefault(1)).toEqual(Int64.fromInt(1)); // Make sure the value is cached. bytes[1] = 0x00; @@ -1640,10 +1658,10 @@ describe('SInt64 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setSint64(-1, Int64.fromInt(1))) + expect(() => Kernel.createEmpty().setSint64(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setInt64(-1, Int64.fromInt(1)); expect(accessor.getSint64WithDefault(-1)).toEqual(Int64.fromInt(1)); } @@ -1652,11 +1670,11 @@ describe('SInt64 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setSint64( + () => Kernel.createEmpty().setSint64( 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setSint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); expect(accessor.getSint64WithDefault(1)).toEqual(null); } @@ -1665,31 +1683,31 @@ describe('SInt64 access', () => { describe('String access', () => { it('returns empty string for the empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getStringWithDefault(1)).toEqual(''); }); it('returns the default for the empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getStringWithDefault(1, 'bar')).toEqual('bar'); }); it('decodes value from wire', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x01, 0x61)); expect(accessor.getStringWithDefault(1)).toEqual('a'); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0A, 0x01, 0x60, 0x0A, 0x01, 0x61)); expect(accessor.getStringWithDefault(1)).toEqual('a'); }); if (CHECK_CRITICAL_STATE) { it('fails when getting string value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x08, 0x02, 0x08, 0x08)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x02, 0x08, 0x08)); expect(() => { accessor.getStringWithDefault(1); }).toThrow(); @@ -1699,24 +1717,23 @@ describe('String access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getStringWithDefault(-1, 'a')) + expect(() => Kernel.createEmpty().getStringWithDefault(-1, 'a')) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getStringWithDefault(-1, 'a')) - .toEqual('a'); + expect(Kernel.createEmpty().getStringWithDefault(-1, 'a')).toEqual('a'); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x0A, 0x01, 0x61); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setString(1, 'b'); expect(accessor.getStringWithDefault(1)).toEqual('b'); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x0A, 0x01, 0x61); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x0A, 0x01, 0x62); accessor.setString(1, 'b'); expect(accessor.serialize()).toEqual(newBytes); @@ -1724,7 +1741,7 @@ describe('String access', () => { it('returns string value from cache', () => { const bytes = createArrayBuffer(0x0A, 0x01, 0x61); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getStringWithDefault(1)).toBe('a'); // Make sure the value is cached. bytes[2] = 0x00; @@ -1733,10 +1750,10 @@ describe('String access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_TYPE) { - expect(() => LazyAccessor.createEmpty().setString(-1, 'a')) + expect(() => Kernel.createEmpty().setString(-1, 'a')) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setString(-1, 'a'); expect(accessor.getStringWithDefault(-1)).toEqual('a'); } @@ -1745,11 +1762,11 @@ describe('String access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setString( + () => Kernel.createEmpty().setString( 1, /** @type {string} */ (/** @type {*} */ (null)))) .toThrowError('Must be string, but got: null'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setString(1, /** @type {string} */ (/** @type {*} */ (null))); expect(accessor.getStringWithDefault(1)).toEqual(null); } @@ -1758,30 +1775,29 @@ describe('String access', () => { describe('Uint32 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getUint32WithDefault(1)).toEqual(0); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getUint32WithDefault(1, 2)).toEqual(2); }); it('decodes value from wire', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); expect(accessor.getUint32WithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getUint32WithDefault(1)).toEqual(2); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getUint32WithDefault(1); @@ -1797,23 +1813,23 @@ describe('Uint32 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getUint32WithDefault(-1, 1)) + expect(() => Kernel.createEmpty().getUint32WithDefault(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getUint32WithDefault(-1, 1)).toEqual(1); + expect(Kernel.createEmpty().getUint32WithDefault(-1, 1)).toEqual(1); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setUint32(1, 2); expect(accessor.getUint32WithDefault(1)).toEqual(2); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x08, 0x00); accessor.setUint32(1, 0); expect(accessor.serialize()).toEqual(newBytes); @@ -1821,7 +1837,7 @@ describe('Uint32 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getUint32WithDefault(1)).toBe(1); // Make sure the value is cached. bytes[2] = 0x00; @@ -1830,10 +1846,10 @@ describe('Uint32 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setInt32(-1, 1)) + expect(() => Kernel.createEmpty().setInt32(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUint32(-1, 1); expect(accessor.getUint32WithDefault(-1)).toEqual(1); } @@ -1842,44 +1858,53 @@ describe('Uint32 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setUint32( + () => Kernel.createEmpty().setUint32( 1, /** @type {number} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUint32(1, /** @type {number} */ (/** @type {*} */ (null))); expect(accessor.getUint32WithDefault(1)).toEqual(null); } }); + + it('throws in setter for negative value', () => { + if (CHECK_CRITICAL_TYPE) { + expect(() => Kernel.createEmpty().setUint32(1, -1)).toThrow(); + } else { + const accessor = Kernel.createEmpty(); + accessor.setUint32(1, -1); + expect(accessor.getUint32WithDefault(1)).toEqual(-1); + } + }); }); describe('Uint64 access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(0)); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getUint64WithDefault(1, Int64.fromInt(2))) .toEqual(Int64.fromInt(2)); }); it('decodes value from wire', () => { - const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); }); - it('decodes value from wire with multple values being present', () => { + it('decodes value from wire with multiple values being present', () => { const accessor = - LazyAccessor.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); + Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01, 0x08, 0x02)); expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); }); it('fails when getting value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( - createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0D, 0x00, 0x00, 0x00, 0x00)); if (CHECK_CRITICAL_TYPE) { expect(() => { accessor.getUint64WithDefault(1); @@ -1896,26 +1921,24 @@ describe('Uint64 access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { expect( - () => LazyAccessor.createEmpty().getUint64WithDefault( - -1, Int64.fromInt(1))) + () => Kernel.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - expect( - LazyAccessor.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) + expect(Kernel.createEmpty().getUint64WithDefault(-1, Int64.fromInt(1))) .toEqual(Int64.fromInt(1)); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setUint64(1, Int64.fromInt(2)); expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(2)); }); it('encode the value from setter', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x08, 0x00); accessor.setUint64(1, Int64.fromInt(0)); expect(accessor.serialize()).toEqual(newBytes); @@ -1923,7 +1946,7 @@ describe('Uint64 access', () => { it('returns value from cache', () => { const bytes = createArrayBuffer(0x08, 0x01); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getUint64WithDefault(1)).toEqual(Int64.fromInt(1)); // Make sure the value is cached. bytes[2] = 0x00; @@ -1932,10 +1955,10 @@ describe('Uint64 access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setUint64(-1, Int64.fromInt(1))) + expect(() => Kernel.createEmpty().setUint64(-1, Int64.fromInt(1))) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUint64(-1, Int64.fromInt(1)); expect(accessor.getUint64WithDefault(-1)).toEqual(Int64.fromInt(1)); } @@ -1944,11 +1967,11 @@ describe('Uint64 access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setUint64( + () => Kernel.createEmpty().setUint64( 1, /** @type {!Int64} */ (/** @type {*} */ (null)))) .toThrow(); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setUint64(1, /** @type {!Int64} */ (/** @type {*} */ (null))); expect(accessor.getUint64WithDefault(1)).toEqual(null); } @@ -1957,24 +1980,24 @@ describe('Uint64 access', () => { describe('Double access', () => { it('returns default value for empty input', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getDoubleWithDefault(1)).toEqual(0); }); it('returns the default from parameter', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer()); + const accessor = Kernel.fromArrayBuffer(createArrayBuffer()); expect(accessor.getDoubleWithDefault(1, 2)).toEqual(2); }); it('decodes value from wire', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)); expect(accessor.getDoubleWithDefault(1)).toEqual(1); }); - it('decodes value from wire with multple values being present', () => { - const accessor = LazyAccessor.fromArrayBuffer(createArrayBuffer( + it('decodes value from wire with multiple values being present', () => { + const accessor = Kernel.fromArrayBuffer(createArrayBuffer( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF)); expect(accessor.getDoubleWithDefault(1)).toEqual(-1); @@ -1982,7 +2005,7 @@ describe('Double access', () => { if (CHECK_CRITICAL_STATE) { it('fails when getting double value with other wire types', () => { - const accessor = LazyAccessor.fromArrayBuffer( + const accessor = Kernel.fromArrayBuffer( createArrayBuffer(0x0D, 0x00, 0x00, 0xF0, 0x3F)); expect(() => { accessor.getDoubleWithDefault(1); @@ -1993,17 +2016,17 @@ describe('Double access', () => { it('throws in getter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().getDoubleWithDefault(-1, 1)) + expect(() => Kernel.createEmpty().getDoubleWithDefault(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - expect(LazyAccessor.createEmpty().getDoubleWithDefault(-1, 1)).toEqual(1); + expect(Kernel.createEmpty().getDoubleWithDefault(-1, 1)).toEqual(1); } }); it('returns the value from setter', () => { const bytes = createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); accessor.setDouble(1, 2); expect(accessor.getDoubleWithDefault(1)).toEqual(2); }); @@ -2011,7 +2034,7 @@ describe('Double access', () => { it('encode the value from setter', () => { const bytes = createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); const newBytes = createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); accessor.setDouble(1, 0); @@ -2021,7 +2044,7 @@ describe('Double access', () => { it('returns string value from cache', () => { const bytes = createArrayBuffer(0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F); - const accessor = LazyAccessor.fromArrayBuffer(bytes); + const accessor = Kernel.fromArrayBuffer(bytes); expect(accessor.getDoubleWithDefault(1)).toBe(1); // Make sure the value is cached. bytes[2] = 0x00; @@ -2030,10 +2053,10 @@ describe('Double access', () => { it('throws in setter for invalid fieldNumber', () => { if (CHECK_BOUNDS) { - expect(() => LazyAccessor.createEmpty().setDouble(-1, 1)) + expect(() => Kernel.createEmpty().setDouble(-1, 1)) .toThrowError('Field number is out of range: -1'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setDouble(-1, 1); expect(accessor.getDoubleWithDefault(-1)).toEqual(1); } @@ -2042,13 +2065,265 @@ describe('Double access', () => { it('throws in setter for invalid value', () => { if (CHECK_CRITICAL_TYPE) { expect( - () => LazyAccessor.createEmpty().setDouble( + () => Kernel.createEmpty().setDouble( 1, /** @type {number} */ (/** @type {*} */ (null)))) .toThrowError('Must be a number, but got: null'); } else { - const accessor = LazyAccessor.createEmpty(); + const accessor = Kernel.createEmpty(); accessor.setDouble(1, /** @type {number} */ (/** @type {*} */ (null))); expect(accessor.getDoubleWithDefault(1)).toEqual(null); } }); }); + +describe('Kernel for singular group does', () => { + it('return group from the input', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator); + expect(msg.getBoolWithDefault(1, false)).toBe(true); + }); + + it('return group from the input when pivot is set', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator, 0); + expect(msg.getBoolWithDefault(1, false)).toBe(true); + }); + + it('encode group from the input', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + expect(accessor.serialize()).toEqual(bytes); + }); + + it('encode group from the input after read', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + accessor.getGroupOrNull(1, TestMessage.instanceCreator); + expect(accessor.serialize()).toEqual(bytes); + }); + + it('return last group from multiple inputs', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const msg = accessor.getGroupOrNull(1, TestMessage.instanceCreator); + expect(msg.getBoolWithDefault(1, false)).toBe(true); + }); + + it('removes duplicated group when serializing', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + accessor.getGroupOrNull(1, TestMessage.instanceCreator); + expect(accessor.serialize()) + .toEqual(createArrayBuffer(0x0B, 0x08, 0x01, 0x0C)); + }); + + it('encode group from multiple inputs', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + expect(accessor.serialize()).toEqual(bytes); + }); + + it('encode group after read', () => { + const bytes = + createArrayBuffer(0x0B, 0x08, 0x00, 0x0C, 0x0B, 0x08, 0x01, 0x0C); + const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + accessor.getGroupOrNull(1, TestMessage.instanceCreator); + expect(accessor.serialize()).toEqual(expected); + }); + + it('return group from setter', () => { + const bytes = createArrayBuffer(0x08, 0x01); + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); + const subaccessor = Kernel.fromArrayBuffer(bytes); + const submsg1 = new TestMessage(subaccessor); + accessor.setGroup(1, submsg1); + const submsg2 = accessor.getGroup(1, TestMessage.instanceCreator); + expect(submsg1).toBe(submsg2); + }); + + it('encode group from setter', () => { + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); + const subaccessor = Kernel.fromArrayBuffer(createArrayBuffer(0x08, 0x01)); + const submsg = new TestMessage(subaccessor); + accessor.setGroup(1, submsg); + const expected = createArrayBuffer(0x0B, 0x08, 0x01, 0x0C); + expect(accessor.serialize()).toEqual(expected); + }); + + it('leave hasFieldNumber unchanged after getGroupOrNull', () => { + const accessor = Kernel.createEmpty(); + expect(accessor.hasFieldNumber(1)).toBe(false); + expect(accessor.getGroupOrNull(1, TestMessage.instanceCreator)).toBe(null); + expect(accessor.hasFieldNumber(1)).toBe(false); + }); + + it('serialize changes to subgroups made with getGroupsOrNull', () => { + const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); + const mutableSubMessage = + accessor.getGroupOrNull(1, TestMessage.instanceCreator); + mutableSubMessage.setInt32(1, 10); + const intTenBytes = createArrayBuffer(0x0B, 0x08, 0x0A, 0x0C); + expect(accessor.serialize()).toEqual(intTenBytes); + }); + + it('serialize additions to subgroups made with getGroupOrNull', () => { + const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); + const mutableSubMessage = + accessor.getGroupOrNull(1, TestMessage.instanceCreator); + mutableSubMessage.setInt32(2, 3); + // Sub group contains the original field, plus the new one. + expect(accessor.serialize()) + .toEqual(createArrayBuffer(0x0B, 0x08, 0x02, 0x10, 0x03, 0x0C)); + }); + + it('fail with getGroupOrNull if immutable group exist in cache', () => { + const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); + + const readOnly = accessor.getGroup(1, TestMessage.instanceCreator); + if (CHECK_TYPE) { + expect(() => accessor.getGroupOrNull(1, TestMessage.instanceCreator)) + .toThrow(); + } else { + const mutableSubGropu = + accessor.getGroupOrNull(1, TestMessage.instanceCreator); + // The instance returned by getGroupOrNull is the exact same instance. + expect(mutableSubGropu).toBe(readOnly); + + // Serializing the subgroup does not write the changes + mutableSubGropu.setInt32(1, 0); + expect(accessor.serialize()).toEqual(intTwoBytes); + } + }); + + it('change hasFieldNumber after getGroupAttach', () => { + const accessor = Kernel.createEmpty(); + expect(accessor.hasFieldNumber(1)).toBe(false); + expect(accessor.getGroupAttach(1, TestMessage.instanceCreator)) + .not.toBe(null); + expect(accessor.hasFieldNumber(1)).toBe(true); + }); + + it('change hasFieldNumber after getGroupAttach when pivot is set', () => { + const accessor = Kernel.createEmpty(); + expect(accessor.hasFieldNumber(1)).toBe(false); + expect( + accessor.getGroupAttach(1, TestMessage.instanceCreator, /* pivot= */ 1)) + .not.toBe(null); + expect(accessor.hasFieldNumber(1)).toBe(true); + }); + + it('serialize subgroups made with getGroupAttach', () => { + const accessor = Kernel.createEmpty(); + const mutableSubGroup = + accessor.getGroupAttach(1, TestMessage.instanceCreator); + mutableSubGroup.setInt32(1, 10); + const intTenBytes = createArrayBuffer(0x0B, 0x08, 0x0A, 0x0C); + expect(accessor.serialize()).toEqual(intTenBytes); + }); + + it('serialize additions to subgroups using getMessageAttach', () => { + const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); + const mutableSubGroup = + accessor.getGroupAttach(1, TestMessage.instanceCreator); + mutableSubGroup.setInt32(2, 3); + // Sub message contains the original field, plus the new one. + expect(accessor.serialize()) + .toEqual(createArrayBuffer(0x0B, 0x08, 0x02, 0x10, 0x03, 0x0C)); + }); + + it('fail with getGroupAttach if immutable message exist in cache', () => { + const intTwoBytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(intTwoBytes); + + const readOnly = accessor.getGroup(1, TestMessage.instanceCreator); + if (CHECK_TYPE) { + expect(() => accessor.getGroupAttach(1, TestMessage.instanceCreator)) + .toThrow(); + } else { + const mutableSubGroup = + accessor.getGroupAttach(1, TestMessage.instanceCreator); + // The instance returned by getMessageOrNull is the exact same instance. + expect(mutableSubGroup).toBe(readOnly); + + // Serializing the submessage does not write the changes + mutableSubGroup.setInt32(1, 0); + expect(accessor.serialize()).toEqual(intTwoBytes); + } + }); + + it('read default group return empty group with getGroup', () => { + const bytes = new ArrayBuffer(0); + const accessor = Kernel.fromArrayBuffer(bytes); + expect(accessor.getGroup(1, TestMessage.instanceCreator)).toBeTruthy(); + expect(accessor.getGroup(1, TestMessage.instanceCreator).serialize()) + .toEqual(bytes); + }); + + it('read default group return null with getGroupOrNull', () => { + const bytes = new ArrayBuffer(0); + const accessor = Kernel.fromArrayBuffer(bytes); + expect(accessor.getGroupOrNull(1, TestMessage.instanceCreator)).toBe(null); + }); + + it('read group preserve reference equality', () => { + const bytes = createArrayBuffer(0x0B, 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const msg1 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); + const msg2 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); + const msg3 = accessor.getGroupAttach(1, TestMessage.instanceCreator); + expect(msg1).toBe(msg2); + expect(msg1).toBe(msg3); + }); + + it('fail when getting group with null instance constructor', () => { + const accessor = + Kernel.fromArrayBuffer(createArrayBuffer(0x0A, 0x02, 0x08, 0x01)); + const nullMessage = /** @type {function(!Kernel):!TestMessage} */ + (/** @type {*} */ (null)); + expect(() => accessor.getGroupOrNull(1, nullMessage)).toThrow(); + }); + + it('fail when setting group value with null value', () => { + const accessor = Kernel.fromArrayBuffer(new ArrayBuffer(0)); + const fakeMessage = /** @type {!TestMessage} */ (/** @type {*} */ (null)); + if (CHECK_CRITICAL_TYPE) { + expect(() => accessor.setGroup(1, fakeMessage)) + .toThrowError('Given value is not a message instance: null'); + } else { + // Note in unchecked mode we produce invalid output for invalid inputs. + // This test just documents our behavior in those cases. + // These values might change at any point and are not considered + // what the implementation should be doing here. + accessor.setMessage(1, fakeMessage); + expect(accessor.getGroupOrNull( + /* fieldNumber= */ 1, TestMessage.instanceCreator)) + .toBeNull(); + } + }); + + it('reads group in a longer buffer', () => { + const bytes = createArrayBuffer( + 0x12, 0x20, // 32 length delimited + 0x00, // random values for padding start + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, // random values for padding end + 0x0B, // Group tag + 0x08, 0x02, 0x0C); + const accessor = Kernel.fromArrayBuffer(bytes); + const msg1 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); + const msg2 = accessor.getGroupOrNull(1, TestMessage.instanceCreator); + expect(msg1).toBe(msg2); + }); +}); diff --git a/js/experimental/runtime/kernel/message_set.js b/js/experimental/runtime/kernel/message_set.js new file mode 100644 index 000000000000..d66bace7b5fd --- /dev/null +++ b/js/experimental/runtime/kernel/message_set.js @@ -0,0 +1,285 @@ +/* +########################################################## +# # +# __ __ _____ _ _ _____ _ _ _____ # +# \ \ / /\ | __ \| \ | |_ _| \ | |/ ____| # +# \ \ /\ / / \ | |__) | \| | | | | \| | | __ # +# \ \/ \/ / /\ \ | _ /| . ` | | | | . ` | | |_ | # +# \ /\ / ____ \| | \ \| |\ |_| |_| |\ | |__| | # +# \/ \/_/ \_\_| \_\_| \_|_____|_| \_|\_____| # +# # +# # +########################################################## +# Do not use this class in your code. This class purely # +# exists to make proto code generation easier. # +########################################################## +*/ +goog.module('protobuf.runtime.MessageSet'); + +const InternalMessage = goog.require('protobuf.binary.InternalMessage'); +const Kernel = goog.require('protobuf.runtime.Kernel'); + +// These are the tags for the old MessageSet format, which was defined as: +// message MessageSet { +// repeated group Item = 1 { +// required uint32 type_id = 2; +// optional bytes message = 3; +// } +// } +/** @const {number} */ +const MSET_GROUP_FIELD_NUMBER = 1; +/** @const {number} */ +const MSET_TYPE_ID_FIELD_NUMBER = 2; +/** @const {number} */ +const MSET_MESSAGE_FIELD_NUMBER = 3; + +/** + * @param {!Kernel} kernel + * @return {!Map} + */ +function createItemMap(kernel) { + const itemMap = new Map(); + let totalCount = 0; + for (const item of kernel.getRepeatedGroupIterable( + MSET_GROUP_FIELD_NUMBER, Item.fromKernel)) { + itemMap.set(item.getTypeId(), item); + totalCount++; + } + + // Normalize the entries. + if (totalCount > itemMap.size) { + writeItemMap(kernel, itemMap); + } + return itemMap; +} + +/** + * @param {!Kernel} kernel + * @param {!Map} itemMap + */ +function writeItemMap(kernel, itemMap) { + kernel.setRepeatedGroupIterable(MSET_GROUP_FIELD_NUMBER, itemMap.values()); +} + +/** + * @implements {InternalMessage} + * @final + */ +class MessageSet { + /** + * @param {!Kernel} kernel + * @return {!MessageSet} + */ + static fromKernel(kernel) { + const itemMap = createItemMap(kernel); + return new MessageSet(kernel, itemMap); + } + + /** + * @return {!MessageSet} + */ + static createEmpty() { + return MessageSet.fromKernel(Kernel.createEmpty()); + } + + /** + * @param {!Kernel} kernel + * @param {!Map} itemMap + * @private + */ + constructor(kernel, itemMap) { + /** @const {!Kernel} @private */ + this.kernel_ = kernel; + /** @const {!Map} @private */ + this.itemMap_ = itemMap; + } + + + + // code helpers for code gen + + /** + * @param {number} typeId + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {?T} + * @template T + */ + getMessageOrNull(typeId, instanceCreator, pivot) { + const item = this.itemMap_.get(typeId); + return item ? item.getMessageOrNull(instanceCreator, pivot) : null; + } + + /** + * @param {number} typeId + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {T} + * @template T + */ + getMessageAttach(typeId, instanceCreator, pivot) { + let item = this.itemMap_.get(typeId); + if (item) { + return item.getMessageAttach(instanceCreator, pivot); + } + const message = instanceCreator(Kernel.createEmpty()); + this.setMessage(typeId, message); + return message; + } + + /** + * @param {number} typeId + * @param {number=} pivot + * @return {?Kernel} + */ + getMessageAccessorOrNull(typeId, pivot) { + const item = this.itemMap_.get(typeId); + return item ? item.getMessageAccessorOrNull(pivot) : null; + } + + + /** + * @param {number} typeId + */ + clearMessage(typeId) { + if (this.itemMap_.delete(typeId)) { + writeItemMap(this.kernel_, this.itemMap_); + } + } + + /** + * @param {number} typeId + * @return {boolean} + */ + hasMessage(typeId) { + return this.itemMap_.has(typeId); + } + + /** + * @param {number} typeId + * @param {!InternalMessage} value + */ + setMessage(typeId, value) { + const item = this.itemMap_.get(typeId); + if (item) { + item.setMessage(value); + } else { + this.itemMap_.set(typeId, Item.create(typeId, value)); + writeItemMap(this.kernel_, this.itemMap_); + } + } + + /** + * @return {!Kernel} + * @override + */ + internalGetKernel() { + return this.kernel_; + } +} + +/** + * @implements {InternalMessage} + * @final + */ +class Item { + /** + * @param {number} typeId + * @param {!InternalMessage} message + * @return {!Item} + */ + static create(typeId, message) { + const messageSet = Item.fromKernel(Kernel.createEmpty()); + messageSet.setTypeId_(typeId); + messageSet.setMessage(message); + return messageSet; + } + + + /** + * @param {!Kernel} kernel + * @return {!Item} + */ + static fromKernel(kernel) { + return new Item(kernel); + } + + /** + * @param {!Kernel} kernel + * @private + */ + constructor(kernel) { + /** @const {!Kernel} @private */ + this.kernel_ = kernel; + } + + /** + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {T} + * @template T + */ + getMessage(instanceCreator, pivot) { + return this.kernel_.getMessage( + MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot); + } + + /** + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {?T} + * @template T + */ + getMessageOrNull(instanceCreator, pivot) { + return this.kernel_.getMessageOrNull( + MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot); + } + + /** + * @param {function(!Kernel):T} instanceCreator + * @param {number=} pivot + * @return {T} + * @template T + */ + getMessageAttach(instanceCreator, pivot) { + return this.kernel_.getMessageAttach( + MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot); + } + + /** + * @param {number=} pivot + * @return {?Kernel} + */ + getMessageAccessorOrNull(pivot) { + return this.kernel_.getMessageAccessorOrNull( + MSET_MESSAGE_FIELD_NUMBER, pivot); + } + + /** @param {!InternalMessage} value */ + setMessage(value) { + this.kernel_.setMessage(MSET_MESSAGE_FIELD_NUMBER, value); + } + + /** @return {number} */ + getTypeId() { + return this.kernel_.getUint32WithDefault(MSET_TYPE_ID_FIELD_NUMBER); + } + + /** + * @param {number} value + * @private + */ + setTypeId_(value) { + this.kernel_.setUint32(MSET_TYPE_ID_FIELD_NUMBER, value); + } + + /** + * @return {!Kernel} + * @override + */ + internalGetKernel() { + return this.kernel_; + } +} + +exports = MessageSet; diff --git a/js/experimental/runtime/kernel/message_set_test.js b/js/experimental/runtime/kernel/message_set_test.js new file mode 100644 index 000000000000..35e593501536 --- /dev/null +++ b/js/experimental/runtime/kernel/message_set_test.js @@ -0,0 +1,262 @@ +/** + * @fileoverview Tests for message_set.js. + */ +goog.module('protobuf.runtime.MessageSetTest'); + +goog.setTestOnly(); + +const Kernel = goog.require('protobuf.runtime.Kernel'); +const MessageSet = goog.require('protobuf.runtime.MessageSet'); +const TestMessage = goog.require('protobuf.testing.binary.TestMessage'); + +/** + * @param {...number} bytes + * @return {!ArrayBuffer} + */ +function createArrayBuffer(...bytes) { + return new Uint8Array(bytes).buffer; +} + +describe('MessageSet does', () => { + it('returns no messages for empty set', () => { + const messageSet = MessageSet.createEmpty(); + expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator)) + .toBeNull(); + }); + + it('returns no kernel for empty set', () => { + const messageSet = MessageSet.createEmpty(); + expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull(); + }); + + it('returns message that has been set', () => { + const messageSet = MessageSet.createEmpty(); + const message = TestMessage.createEmpty(); + messageSet.setMessage(12345, message); + expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator)) + .toBe(message); + }); + + it('returns null for cleared message', () => { + const messageSet = MessageSet.createEmpty(); + const message = TestMessage.createEmpty(); + messageSet.setMessage(12345, message); + messageSet.clearMessage(12345); + expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull(); + }); + + it('returns false for not present message', () => { + const messageSet = MessageSet.createEmpty(); + expect(messageSet.hasMessage(12345)).toBe(false); + }); + + it('returns true for present message', () => { + const messageSet = MessageSet.createEmpty(); + const message = TestMessage.createEmpty(); + messageSet.setMessage(12345, message); + expect(messageSet.hasMessage(12345)).toBe(true); + }); + + it('returns false for cleared message', () => { + const messageSet = MessageSet.createEmpty(); + const message = TestMessage.createEmpty(); + messageSet.setMessage(12345, message); + messageSet.clearMessage(12345); + expect(messageSet.hasMessage(12345)).toBe(false); + }); + + it('returns false for cleared message without it being present', () => { + const messageSet = MessageSet.createEmpty(); + messageSet.clearMessage(12345); + expect(messageSet.hasMessage(12345)).toBe(false); + }); + + const createMessageSet = () => { + const messageSet = MessageSet.createEmpty(); + const message = TestMessage.createEmpty(); + message.setInt32(1, 2); + messageSet.setMessage(12345, message); + + + const parsedKernel = + Kernel.fromArrayBuffer(messageSet.internalGetKernel().serialize()); + return MessageSet.fromKernel(parsedKernel); + }; + + it('pass through pivot for getMessageOrNull', () => { + const messageSet = createMessageSet(); + const message = + messageSet.getMessageOrNull(12345, TestMessage.instanceCreator, 2); + expect(message.internalGetKernel().getPivot()).toBe(2); + }); + + it('pass through pivot for getMessageAttach', () => { + const messageSet = createMessageSet(); + const message = + messageSet.getMessageAttach(12345, TestMessage.instanceCreator, 2); + expect(message.internalGetKernel().getPivot()).toBe(2); + }); + + it('pass through pivot for getMessageAccessorOrNull', () => { + const messageSet = createMessageSet(); + const kernel = messageSet.getMessageAccessorOrNull(12345, 2); + expect(kernel.getPivot()).toBe(2); + }); + + it('pick the last value in the stream', () => { + const arrayBuffer = createArrayBuffer( + 0x52, // Tag (field:10, length delimited) + 0x14, // Length of 20 bytes + 0x0B, // Start group fieldnumber 1 + 0x10, // Tag (field 2, varint) + 0xB9, // 12345 + 0x60, // 12345 + 0x1A, // Tag (field 3, length delimited) + 0x03, // length 3 + 0xA0, // Tag (fieldnumber 20, varint) + 0x01, // Tag (fieldnumber 20, varint) + 0x1E, // 30 + 0x0C, // Stop Group field number 1 + // second group + 0x0B, // Start group fieldnumber 1 + 0x10, // Tag (field 2, varint) + 0xB9, // 12345 + 0x60, // 12345 + 0x1A, // Tag (field 3, length delimited) + 0x03, // length 3 + 0xA0, // Tag (fieldnumber 20, varint) + 0x01, // Tag (fieldnumber 20, varint) + 0x01, // 1 + 0x0C // Stop Group field number 1 + ); + + const outerMessage = Kernel.fromArrayBuffer(arrayBuffer); + + const messageSet = outerMessage.getMessage(10, MessageSet.fromKernel); + + const message = + messageSet.getMessageOrNull(12345, TestMessage.instanceCreator); + expect(message.getInt32WithDefault(20)).toBe(1); + }); + + it('removes duplicates when read', () => { + const arrayBuffer = createArrayBuffer( + 0x52, // Tag (field:10, length delimited) + 0x14, // Length of 20 bytes + 0x0B, // Start group fieldnumber 1 + 0x10, // Tag (field 2, varint) + 0xB9, // 12345 + 0x60, // 12345 + 0x1A, // Tag (field 3, length delimited) + 0x03, // length 3 + 0xA0, // Tag (fieldnumber 20, varint) + 0x01, // Tag (fieldnumber 20, varint) + 0x1E, // 30 + 0x0C, // Stop Group field number 1 + // second group + 0x0B, // Start group fieldnumber 1 + 0x10, // Tag (field 2, varint) + 0xB9, // 12345 + 0x60, // 12345 + 0x1A, // Tag (field 3, length delimited) + 0x03, // length 3 + 0xA0, // Tag (fieldnumber 20, varint) + 0x01, // Tag (fieldnumber 20, varint) + 0x01, // 1 + 0x0C // Stop Group field number 1 + ); + + + const outerMessage = Kernel.fromArrayBuffer(arrayBuffer); + outerMessage.getMessageAttach(10, MessageSet.fromKernel); + + expect(outerMessage.serialize()) + .toEqual(createArrayBuffer( + 0x52, // Tag (field:10, length delimited) + 0x0A, // Length of 10 bytes + 0x0B, // Start group fieldnumber 1 + 0x10, // Tag (field 2, varint) + 0xB9, // 12345 + 0x60, // 12345 + 0x1A, // Tag (field 3, length delimited) + 0x03, // length 3 + 0xA0, // Tag (fieldnumber 20, varint) + 0x01, // Tag (fieldnumber 20, varint) + 0x01, // 1 + 0x0C // Stop Group field number 1 + )); + }); + + it('allow for large typeIds', () => { + const messageSet = MessageSet.createEmpty(); + const message = TestMessage.createEmpty(); + messageSet.setMessage(0xFFFFFFFE >>> 0, message); + expect(messageSet.hasMessage(0xFFFFFFFE >>> 0)).toBe(true); + }); +}); + +describe('Optional MessageSet does', () => { + // message Bar { + // optional MessageSet mset = 10; + //} + // + // message Foo { + // extend proto2.bridge.MessageSet { + // optional Foo message_set_extension = 12345; + // } + // optional int32 f20 = 20; + //} + + it('encode as a field', () => { + const fooMessage = Kernel.createEmpty(); + fooMessage.setInt32(20, 30); + + const messageSet = MessageSet.createEmpty(); + messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage)); + + const barMessage = Kernel.createEmpty(); + barMessage.setMessage(10, messageSet); + + expect(barMessage.serialize()) + .toEqual(createArrayBuffer( + 0x52, // Tag (field:10, length delimited) + 0x0A, // Length of 10 bytes + 0x0B, // Start group fieldnumber 1 + 0x10, // Tag (field 2, varint) + 0xB9, // 12345 + 0x60, // 12345 + 0x1A, // Tag (field 3, length delimited) + 0x03, // length 3 + 0xA0, // Tag (fieldnumber 20, varint) + 0x01, // Tag (fieldnumber 20, varint) + 0x1E, // 30 + 0x0C // Stop Group field number 1 + )); + }); + + it('deserializes', () => { + const fooMessage = Kernel.createEmpty(); + fooMessage.setInt32(20, 30); + + const messageSet = MessageSet.createEmpty(); + messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage)); + + + const barMessage = Kernel.createEmpty(); + barMessage.setMessage(10, messageSet); + + const arrayBuffer = barMessage.serialize(); + + const barMessageParsed = Kernel.fromArrayBuffer(arrayBuffer); + expect(barMessageParsed.hasFieldNumber(10)).toBe(true); + + const messageSetParsed = + barMessageParsed.getMessage(10, MessageSet.fromKernel); + + const fooMessageParsed = + messageSetParsed.getMessageOrNull(12345, TestMessage.instanceCreator) + .internalGetKernel(); + + expect(fooMessageParsed.getInt32WithDefault(20)).toBe(30); + }); +}); diff --git a/js/experimental/runtime/kernel/reader.js b/js/experimental/runtime/kernel/reader.js index fec79cfad533..2b80e15bffa6 100644 --- a/js/experimental/runtime/kernel/reader.js +++ b/js/experimental/runtime/kernel/reader.js @@ -6,24 +6,13 @@ goog.module('protobuf.binary.reader'); const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); const ByteString = goog.require('protobuf.ByteString'); const Int64 = goog.require('protobuf.Int64'); +const {checkState} = goog.require('protobuf.internal.checks'); /****************************************************************************** * OPTIONAL FUNCTIONS ******************************************************************************/ -/** - * Reads a boolean from the binary bytes. - * Also returns the first position after the boolean. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} index Start of the data. - * @return {{value: boolean, nextCursor: number}} - */ -function readBoolValue(bufferDecoder, index) { - const {lowBits, highBits, dataStart} = bufferDecoder.getVarint(index); - return {value: lowBits !== 0 || highBits !== 0, nextCursor: dataStart}; -} - /** * Reads a boolean value from the binary bytes. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. @@ -32,11 +21,12 @@ function readBoolValue(bufferDecoder, index) { * @package */ function readBool(bufferDecoder, start) { - return readBoolValue(bufferDecoder, start).value; + const {lowBits, highBits} = bufferDecoder.getVarint(start); + return lowBits !== 0 || highBits !== 0; } /** - * Reads a double value from the binary bytes. + * Reads a ByteString value from the binary bytes. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. * @param {number} start Start of the data. * @return {!ByteString} @@ -46,21 +36,6 @@ function readBytes(bufferDecoder, start) { return readDelimited(bufferDecoder, start).asByteString(); } -/** - * Reads a int32 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} index Start of the data. - * @return {{value: number, nextCursor: number}} - * @package - */ -function readInt32Value(bufferDecoder, index) { - const {lowBits, dataStart} = bufferDecoder.getVarint(index); - // Negative 32 bit integers are encoded with 64 bit values. - // Clients are expected to truncate back to 32 bits. - // This is why we are dropping the upper bytes here. - return {value: lowBits | 0, nextCursor: dataStart}; -} - /** * Reads a int32 value from the binary bytes encoded as varint. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. @@ -69,19 +44,10 @@ function readInt32Value(bufferDecoder, index) { * @package */ function readInt32(bufferDecoder, start) { - return readInt32Value(bufferDecoder, start).value; -} - -/** - * Reads a int32 value from the binary bytes encoded as varint. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} index Start of the data. - * @return {{ value: !Int64, nextCursor: number}} - * @package - */ -function readInt64Value(bufferDecoder, index) { - const {lowBits, highBits, dataStart} = bufferDecoder.getVarint(index); - return {value: Int64.fromBits(lowBits, highBits), nextCursor: dataStart}; + // Negative 32 bit integers are encoded with 64 bit values. + // Clients are expected to truncate back to 32 bits. + // This is why we are dropping the upper bytes here. + return bufferDecoder.getUnsignedVarint32At(start) | 0; } /** @@ -92,7 +58,8 @@ function readInt64Value(bufferDecoder, index) { * @package */ function readInt64(bufferDecoder, start) { - return readInt64Value(bufferDecoder, start).value; + const {lowBits, highBits} = bufferDecoder.getVarint(start); + return Int64.fromBits(lowBits, highBits); } /** @@ -130,19 +97,6 @@ function readSfixed64(bufferDecoder, start) { return Int64.fromBits(lowBits, highBits); } -/** - * Reads a sint32 value from the binary bytes encoded as varint. - * Also returns the first position after the boolean. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} index Start of the data. - * @return {{value: number, nextCursor: number}} - */ -function readSint32Value(bufferDecoder, index) { - const {lowBits, dataStart} = bufferDecoder.getVarint(index); - // Truncate upper bits and convert from zig zag to signd int - return {value: (lowBits >>> 1) ^ -(lowBits & 0x01), nextCursor: dataStart}; -} - /** * Reads a sint32 value from the binary bytes encoded as varint. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. @@ -151,26 +105,9 @@ function readSint32Value(bufferDecoder, index) { * @package */ function readSint32(bufferDecoder, start) { - return readSint32Value(bufferDecoder, start).value; -} - -/** - * Reads a sint64 value from the binary bytes encoded as varint. - * Also returns the first position after the value. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} index Start of the data. - * @return {{value: !Int64, nextCursor: number}} - * @package - */ -function readSint64Value(bufferDecoder, index) { - const {lowBits, highBits, dataStart} = bufferDecoder.getVarint(index); - const sign = -(lowBits & 0x01); - const decodedLowerBits = ((lowBits >>> 1) | (highBits & 0x01) << 31) ^ sign; - const decodedUpperBits = (highBits >>> 1) ^ sign; - return { - value: Int64.fromBits(decodedLowerBits, decodedUpperBits), - nextCursor: dataStart - }; + const bits = bufferDecoder.getUnsignedVarint32At(start); + // Truncate upper bits and convert from zig zag to signd int + return (bits >>> 1) ^ -(bits & 0x01); } /** @@ -181,7 +118,11 @@ function readSint64Value(bufferDecoder, index) { * @package */ function readSint64(bufferDecoder, start) { - return readSint64Value(bufferDecoder, start).value; + const {lowBits, highBits} = bufferDecoder.getVarint(start); + const sign = -(lowBits & 0x01); + const decodedLowerBits = ((lowBits >>> 1) | (highBits & 0x01) << 31) ^ sign; + const decodedUpperBits = (highBits >>> 1) ^ sign; + return Int64.fromBits(decodedLowerBits, decodedUpperBits); } /** @@ -192,9 +133,8 @@ function readSint64(bufferDecoder, start) { * @package */ function readDelimited(bufferDecoder, start) { - const {lowBits, dataStart} = bufferDecoder.getVarint(start); - const unsignedLength = lowBits >>> 0; - return bufferDecoder.subBufferDecoder(dataStart, unsignedLength); + const unsignedLength = bufferDecoder.getUnsignedVarint32At(start); + return bufferDecoder.subBufferDecoder(bufferDecoder.cursor(), unsignedLength); } /** @@ -208,18 +148,6 @@ function readString(bufferDecoder, start) { return readDelimited(bufferDecoder, start).asString(); } -/** - * Reads a uint32 value from the binary bytes encoded as varint. - * Also returns the first position after the value. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} index Start of the data. - * @return {{value: number, nextCursor: number}} - */ -function readUint32Value(bufferDecoder, index) { - const {lowBits, dataStart} = bufferDecoder.getVarint(index); - return {value: lowBits >>> 0, nextCursor: dataStart}; -} - /** * Reads a uint32 value from the binary bytes encoded as varint. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. @@ -228,7 +156,7 @@ function readUint32Value(bufferDecoder, index) { * @package */ function readUint32(bufferDecoder, start) { - return readUint32Value(bufferDecoder, start).value; + return bufferDecoder.getUnsignedVarint32At(start); } /** @@ -266,7 +194,7 @@ function readSfixed32(bufferDecoder, start) { * @package */ function readPackedBool(bufferDecoder, start) { - return readPackedVariableLength(bufferDecoder, start, readBoolValue); + return readPacked(bufferDecoder, start, readBool); } /** @@ -278,7 +206,7 @@ function readPackedBool(bufferDecoder, start) { * @package */ function readPackedDouble(bufferDecoder, start) { - return readPackedFixed(bufferDecoder, start, 8, readDouble); + return readPacked(bufferDecoder, start, readDouble); } /** @@ -290,7 +218,7 @@ function readPackedDouble(bufferDecoder, start) { * @package */ function readPackedFixed32(bufferDecoder, start) { - return readPackedFixed(bufferDecoder, start, 4, readFixed32); + return readPacked(bufferDecoder, start, readFixed32); } /** @@ -302,7 +230,7 @@ function readPackedFixed32(bufferDecoder, start) { * @package */ function readPackedFloat(bufferDecoder, start) { - return readPackedFixed(bufferDecoder, start, 4, readFloat); + return readPacked(bufferDecoder, start, readFloat); } /** @@ -314,7 +242,7 @@ function readPackedFloat(bufferDecoder, start) { * @package */ function readPackedInt32(bufferDecoder, start) { - return readPackedVariableLength(bufferDecoder, start, readInt32Value); + return readPacked(bufferDecoder, start, readInt32); } /** @@ -326,7 +254,7 @@ function readPackedInt32(bufferDecoder, start) { * @package */ function readPackedInt64(bufferDecoder, start) { - return readPackedVariableLength(bufferDecoder, start, readInt64Value); + return readPacked(bufferDecoder, start, readInt64); } /** @@ -338,7 +266,7 @@ function readPackedInt64(bufferDecoder, start) { * @package */ function readPackedSfixed32(bufferDecoder, start) { - return readPackedFixed(bufferDecoder, start, 4, readSfixed32); + return readPacked(bufferDecoder, start, readSfixed32); } /** @@ -350,7 +278,7 @@ function readPackedSfixed32(bufferDecoder, start) { * @package */ function readPackedSfixed64(bufferDecoder, start) { - return readPackedFixed(bufferDecoder, start, 8, readSfixed64); + return readPacked(bufferDecoder, start, readSfixed64); } /** @@ -362,7 +290,7 @@ function readPackedSfixed64(bufferDecoder, start) { * @package */ function readPackedSint32(bufferDecoder, start) { - return readPackedVariableLength(bufferDecoder, start, readSint32Value); + return readPacked(bufferDecoder, start, readSint32); } /** @@ -374,7 +302,7 @@ function readPackedSint32(bufferDecoder, start) { * @package */ function readPackedSint64(bufferDecoder, start) { - return readPackedVariableLength(bufferDecoder, start, readSint64Value); + return readPacked(bufferDecoder, start, readSint64); } /** @@ -386,51 +314,25 @@ function readPackedSint64(bufferDecoder, start) { * @package */ function readPackedUint32(bufferDecoder, start) { - return readPackedVariableLength(bufferDecoder, start, readUint32Value); -} - -/** - * Read packed variable length values. - * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. - * @param {number} start Start of the data. - * @param {function(!BufferDecoder, number):{value:T, nextCursor: number}} - * valueFunction - * @return {!Array} - * @package - * @template T - */ -function readPackedVariableLength(bufferDecoder, start, valueFunction) { - const /** !Array */ result = []; - const {lowBits, dataStart} = bufferDecoder.getVarint(start); - let cursor = dataStart; - const unsignedLength = lowBits >>> 0; - while (cursor < dataStart + unsignedLength) { - const {value, nextCursor} = valueFunction(bufferDecoder, cursor); - cursor = nextCursor; - result.push(value); - } - return result; + return readPacked(bufferDecoder, start, readUint32); } /** - * Read a packed fixed values. + * Read packed values. * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. * @param {number} start Start of the data. - * @param {number} size End of the data. * @param {function(!BufferDecoder, number):T} valueFunction * @return {!Array} * @package * @template T */ -function readPackedFixed(bufferDecoder, start, size, valueFunction) { - const {lowBits, dataStart} = bufferDecoder.getVarint(start); - const unsignedLength = lowBits >>> 0; - const noOfEntries = unsignedLength / size; - const /** !Array */ result = new Array(noOfEntries); - let cursor = dataStart; - for (let i = 0; i < noOfEntries; i++) { - result[i] = valueFunction(bufferDecoder, cursor); - cursor += size; +function readPacked(bufferDecoder, start, valueFunction) { + const /** !Array */ result = []; + const unsignedLength = bufferDecoder.getUnsignedVarint32At(start); + const dataStart = bufferDecoder.cursor(); + while (bufferDecoder.cursor() < dataStart + unsignedLength) { + checkState(bufferDecoder.cursor() > 0); + result.push(valueFunction(bufferDecoder, bufferDecoder.cursor())); } return result; } diff --git a/js/experimental/runtime/kernel/reader_test.js b/js/experimental/runtime/kernel/reader_test.js index a0cbcae67fda..100c7937a224 100644 --- a/js/experimental/runtime/kernel/reader_test.js +++ b/js/experimental/runtime/kernel/reader_test.js @@ -12,7 +12,7 @@ goog.setTestOnly(); const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); const ByteString = goog.require('protobuf.ByteString'); const reader = goog.require('protobuf.binary.reader'); -const {CHECK_STATE} = goog.require('protobuf.internal.checks'); +const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper'); const {encode} = goog.require('protobuf.binary.textencoding'); const {getBoolPairs} = goog.require('protobuf.binary.boolTestPairs'); @@ -45,7 +45,7 @@ const {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs'); describe('Read bool does', () => { for (const pair of getBoolPairs()) { it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_STATE) { + if (pair.error && CHECK_CRITICAL_STATE) { expect(() => reader.readBool(pair.bufferDecoder, 0)).toThrow(); } else { const d = reader.readBool( @@ -120,7 +120,7 @@ describe('readInt32 does', () => { for (const pair of getInt32Pairs()) { it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_STATE) { + if (pair.error && CHECK_CRITICAL_STATE) { expect(() => reader.readInt32(pair.bufferDecoder, 0)).toThrow(); } else { const d = reader.readInt32(pair.bufferDecoder, 0); @@ -166,7 +166,7 @@ describe('readSint32 does', () => { for (const pair of getSint32Pairs()) { it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_STATE) { + if (pair.error && CHECK_CRITICAL_STATE) { expect(() => reader.readSint32(pair.bufferDecoder, 0)).toThrow(); } else { const d = reader.readSint32(pair.bufferDecoder, 0); @@ -184,7 +184,7 @@ describe('readInt64 does', () => { for (const pair of getInt64Pairs()) { it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_STATE) { + if (pair.error && CHECK_CRITICAL_STATE) { expect(() => reader.readInt64(pair.bufferDecoder, 0)).toThrow(); } else { const d = reader.readInt64(pair.bufferDecoder, 0); @@ -202,7 +202,7 @@ describe('readSint64 does', () => { for (const pair of getSint64Pairs()) { it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_STATE) { + if (pair.error && CHECK_CRITICAL_STATE) { expect(() => reader.readSint64(pair.bufferDecoder, 0)).toThrow(); } else { const d = reader.readSint64(pair.bufferDecoder, 0); @@ -219,14 +219,16 @@ describe('readUint32 does', () => { }); for (const pair of getUint32Pairs()) { - it(`decode ${pair.name}`, () => { - if (pair.error && CHECK_STATE) { - expect(() => reader.readUint32(pair.bufferDecoder, 0)).toThrow(); - } else { - const d = reader.readUint32(pair.bufferDecoder, 0); - expect(d).toEqual(pair.intValue); - } - }); + if (!pair.skip_reader) { + it(`decode ${pair.name}`, () => { + if (pair.error && CHECK_CRITICAL_STATE) { + expect(() => reader.readUint32(pair.bufferDecoder, 0)).toThrow(); + } else { + const d = reader.readUint32(pair.bufferDecoder, 0); + expect(d).toEqual(pair.intValue); + } + }); + } } }); diff --git a/js/experimental/runtime/kernel/storage.js b/js/experimental/runtime/kernel/storage.js index 56dc85fbbcf0..a3e1e4f004d4 100644 --- a/js/experimental/runtime/kernel/storage.js +++ b/js/experimental/runtime/kernel/storage.js @@ -1,57 +1,19 @@ -goog.module('protobuf.binary.Storage'); - -const {checkDefAndNotNull} = goog.require('protobuf.internal.checks'); - -/** - * 85% of the proto fields have a field number <= 24: - * https://plx.corp.google.com/scripts2/script_5d._f02af6_0000_23b1_a15f_001a1139dd02 - * - * @type {number} - */ -// LINT.IfChange -const DEFAULT_PIVOT = 24; -// LINT.ThenChange(//depot/google3/third_party/protobuf/javascript/runtime/kernel/storage_test.js, -// //depot/google3/net/proto2/contrib/js_proto/internal/kernel_message_generator.cc) +goog.module('protobuf.runtime.Storage'); /** - * Class storing all the fields of a protobuf message. + * Interface for getting and storing fields of a protobuf message. * + * @interface * @package * @template FieldType */ class Storage { /** - * @param {number=} pivot - */ - constructor(pivot = DEFAULT_PIVOT) { - /** - * Fields having a field number no greater than the pivot value are stored - * into an array for fast access. A field with field number X is stored into - * the array position X - 1. - * - * @private @const {!Array} - */ - this.array_ = new Array(pivot); - - /** - * Fields having a field number higher than the pivot value are stored into - * the map. We create the map only when it's needed, since even an empty map - * takes up a significant amount of memory. - * - * @private {?Map} - */ - this.map_ = null; - } - - /** - * Fields having a field number no greater than the pivot value are stored - * into an array for fast access. A field with field number X is stored into - * the array position X - 1. + * Returns the pivot value. + * * @return {number} */ - getPivot() { - return this.array_.length; - } + getPivot() {} /** * Sets a field in the specified field number. @@ -59,17 +21,7 @@ class Storage { * @param {number} fieldNumber * @param {!FieldType} field */ - set(fieldNumber, field) { - if (fieldNumber <= this.getPivot()) { - this.array_[fieldNumber - 1] = field; - } else { - if (this.map_) { - this.map_.set(fieldNumber, field); - } else { - this.map_ = new Map([[fieldNumber, field]]); - } - } - } + set(fieldNumber, field) {} /** * Returns a field at the specified field number. @@ -77,57 +29,39 @@ class Storage { * @param {number} fieldNumber * @return {!FieldType|undefined} */ - get(fieldNumber) { - if (fieldNumber <= this.getPivot()) { - return this.array_[fieldNumber - 1]; - } else { - return this.map_ ? this.map_.get(fieldNumber) : undefined; - } - } + get(fieldNumber) {} /** * Deletes a field from the specified field number. * * @param {number} fieldNumber */ - delete(fieldNumber) { - if (fieldNumber <= this.getPivot()) { - delete this.array_[fieldNumber - 1]; - } else { - if (this.map_) { - this.map_.delete(fieldNumber); - } - } - } + delete(fieldNumber) {} /** - * Executes the provided function once for each array element. + * Executes the provided function once for each field. * * @param {function(!FieldType, number): void} callback */ - forEach(callback) { - this.array_.forEach((field, fieldNumber) => { - if (field) { - callback(checkDefAndNotNull(field), fieldNumber + 1); - } - }); - if (this.map_) { - this.map_.forEach(callback); - } - } + forEach(callback) {} /** * Creates a shallow copy of the storage. * * @return {!Storage} */ - shallowCopy() { - const copy = new Storage(this.getPivot()); - this.forEach( - (field, fieldNumber) => - void copy.set(fieldNumber, field.shallowCopy())); - return copy; - } + shallowCopy() {} } +/** + * 85% of the proto fields have a field number <= 24: + * https://plx.corp.google.com/scripts2/script_5d._f02af6_0000_23b1_a15f_001a1139dd02 + * + * @type {number} + */ +// LINT.IfChange +Storage.DEFAULT_PIVOT = 24; +// LINT.ThenChange(//depot/google3/third_party/protobuf/javascript/runtime/kernel/binary_storage_test.js, +// //depot/google3/net/proto2/contrib/js_proto/internal/kernel_message_generator.cc) + exports = Storage; diff --git a/js/experimental/runtime/kernel/tag.js b/js/experimental/runtime/kernel/tag.js new file mode 100644 index 000000000000..b288df3b8e89 --- /dev/null +++ b/js/experimental/runtime/kernel/tag.js @@ -0,0 +1,144 @@ +goog.module('protobuf.binary.tag'); + +const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); +const WireType = goog.require('protobuf.binary.WireType'); +const {checkCriticalElementIndex, checkCriticalState} = goog.require('protobuf.internal.checks'); + +/** + * Returns wire type stored in a tag. + * Protos store the wire type as the first 3 bit of a tag. + * @param {number} tag + * @return {!WireType} + */ +function tagToWireType(tag) { + return /** @type {!WireType} */ (tag & 0x07); +} + +/** + * Returns the field number stored in a tag. + * Protos store the field number in the upper 29 bits of a 32 bit number. + * @param {number} tag + * @return {number} + */ +function tagToFieldNumber(tag) { + return tag >>> 3; +} + +/** + * Combines wireType and fieldNumber into a tag. + * @param {!WireType} wireType + * @param {number} fieldNumber + * @return {number} + */ +function createTag(wireType, fieldNumber) { + return (fieldNumber << 3 | wireType) >>> 0; +} + +/** + * Returns the length, in bytes, of the field in the tag stream, less the tag + * itself. + * Note: This moves the cursor in the bufferDecoder. + * @param {!BufferDecoder} bufferDecoder + * @param {number} start + * @param {!WireType} wireType + * @param {number} fieldNumber + * @return {number} + * @private + */ +function getTagLength(bufferDecoder, start, wireType, fieldNumber) { + bufferDecoder.setCursor(start); + skipField(bufferDecoder, wireType, fieldNumber); + return bufferDecoder.cursor() - start; +} + +/** + * @param {number} value + * @return {number} + */ +function get32BitVarintLength(value) { + if (value < 0) { + return 5; + } + let size = 1; + while (value >= 128) { + size++; + value >>>= 7; + } + return size; +} + +/** + * Skips over a field. + * Note: If the field is a start group the entire group will be skipped, placing + * the cursor onto the next field. + * @param {!BufferDecoder} bufferDecoder + * @param {!WireType} wireType + * @param {number} fieldNumber + */ +function skipField(bufferDecoder, wireType, fieldNumber) { + switch (wireType) { + case WireType.VARINT: + checkCriticalElementIndex( + bufferDecoder.cursor(), bufferDecoder.endIndex()); + bufferDecoder.skipVarint(); + return; + case WireType.FIXED64: + bufferDecoder.skip(8); + return; + case WireType.DELIMITED: + checkCriticalElementIndex( + bufferDecoder.cursor(), bufferDecoder.endIndex()); + const length = bufferDecoder.getUnsignedVarint32(); + bufferDecoder.skip(length); + return; + case WireType.START_GROUP: + const foundGroup = skipGroup_(bufferDecoder, fieldNumber); + checkCriticalState(foundGroup, 'No end group found.'); + return; + case WireType.FIXED32: + bufferDecoder.skip(4); + return; + default: + throw new Error(`Unexpected wire type: ${wireType}`); + } +} + +/** + * Skips over fields until it finds the end of a given group consuming the stop + * group tag. + * @param {!BufferDecoder} bufferDecoder + * @param {number} groupFieldNumber + * @return {boolean} Whether the end group tag was found. + * @private + */ +function skipGroup_(bufferDecoder, groupFieldNumber) { + // On a start group we need to keep skipping fields until we find a + // corresponding stop group + // Note: Since we are calling skipField from here nested groups will be + // handled by recursion of this method and thus we will not see a nested + // STOP GROUP here unless there is something wrong with the input data. + while (bufferDecoder.hasNext()) { + const tag = bufferDecoder.getUnsignedVarint32(); + const wireType = tagToWireType(tag); + const fieldNumber = tagToFieldNumber(tag); + + if (wireType === WireType.END_GROUP) { + checkCriticalState( + groupFieldNumber === fieldNumber, + `Expected stop group for fieldnumber ${groupFieldNumber} not found.`); + return true; + } else { + skipField(bufferDecoder, wireType, fieldNumber); + } + } + return false; +} + +exports = { + createTag, + get32BitVarintLength, + getTagLength, + skipField, + tagToWireType, + tagToFieldNumber, +}; diff --git a/js/experimental/runtime/kernel/tag_test.js b/js/experimental/runtime/kernel/tag_test.js new file mode 100644 index 000000000000..35137bb24705 --- /dev/null +++ b/js/experimental/runtime/kernel/tag_test.js @@ -0,0 +1,221 @@ +/** + * @fileoverview Tests for tag.js. + */ +goog.module('protobuf.binary.TagTests'); + +const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); +const WireType = goog.require('protobuf.binary.WireType'); +const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks'); +const {createTag, get32BitVarintLength, skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag'); + + +goog.setTestOnly(); + +/** + * @param {...number} bytes + * @return {!ArrayBuffer} + */ +function createArrayBuffer(...bytes) { + return new Uint8Array(bytes).buffer; +} + +describe('skipField', () => { + it('skips varints', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); + skipField(bufferDecoder, WireType.VARINT, 1); + expect(bufferDecoder.cursor()).toBe(2); + }); + + it('throws for out of bounds varints', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); + bufferDecoder.setCursor(2); + if (CHECK_CRITICAL_STATE) { + expect(() => skipField(bufferDecoder, WireType.VARINT, 1)).toThrowError(); + } + }); + + it('skips fixed64', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); + skipField(bufferDecoder, WireType.FIXED64, 1); + expect(bufferDecoder.cursor()).toBe(8); + }); + + it('throws for fixed64 if length is too short', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); + if (CHECK_CRITICAL_STATE) { + expect(() => skipField(bufferDecoder, WireType.FIXED64, 1)) + .toThrowError(); + } + }); + + it('skips fixed32', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0x80, 0x00, 0x00, 0x00)); + skipField(bufferDecoder, WireType.FIXED32, 1); + expect(bufferDecoder.cursor()).toBe(4); + }); + + it('throws for fixed32 if length is too short', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00)); + if (CHECK_CRITICAL_STATE) { + expect(() => skipField(bufferDecoder, WireType.FIXED32, 1)) + .toThrowError(); + } + }); + + + it('skips length delimited', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0x03, 0x00, 0x00, 0x00)); + skipField(bufferDecoder, WireType.DELIMITED, 1); + expect(bufferDecoder.cursor()).toBe(4); + }); + + it('throws for length delimited if length is too short', () => { + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x03, 0x00, 0x00)); + if (CHECK_CRITICAL_STATE) { + expect(() => skipField(bufferDecoder, WireType.DELIMITED, 1)) + .toThrowError(); + } + }); + + it('skips groups', () => { + const bufferDecoder = BufferDecoder.fromArrayBuffer( + createArrayBuffer(0x0B, 0x08, 0x01, 0x0C)); + bufferDecoder.setCursor(1); + skipField(bufferDecoder, WireType.START_GROUP, 1); + expect(bufferDecoder.cursor()).toBe(4); + }); + + it('skips group in group', () => { + const buffer = createArrayBuffer( + 0x0B, // start outer + 0x10, 0x01, // field: 2, value: 1 + 0x0B, // start inner group + 0x10, 0x01, // payload inner group + 0x0C, // stop inner group + 0x0C // end outer + ); + const bufferDecoder = BufferDecoder.fromArrayBuffer(buffer); + bufferDecoder.setCursor(1); + skipField(bufferDecoder, WireType.START_GROUP, 1); + expect(bufferDecoder.cursor()).toBe(8); + }); + + it('throws for group if length is too short', () => { + // no closing group + const bufferDecoder = + BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0B, 0x00, 0x00)); + if (CHECK_CRITICAL_STATE) { + expect(() => skipField(bufferDecoder, WireType.START_GROUP, 1)) + .toThrowError(); + } + }); +}); + + +describe('tagToWireType', () => { + it('decodes numbers ', () => { + // simple numbers + expect(tagToWireType(0x00)).toBe(WireType.VARINT); + expect(tagToWireType(0x01)).toBe(WireType.FIXED64); + expect(tagToWireType(0x02)).toBe(WireType.DELIMITED); + expect(tagToWireType(0x03)).toBe(WireType.START_GROUP); + expect(tagToWireType(0x04)).toBe(WireType.END_GROUP); + expect(tagToWireType(0x05)).toBe(WireType.FIXED32); + + // upper bits should not matter + expect(tagToWireType(0x08)).toBe(WireType.VARINT); + expect(tagToWireType(0x09)).toBe(WireType.FIXED64); + expect(tagToWireType(0x0A)).toBe(WireType.DELIMITED); + expect(tagToWireType(0x0B)).toBe(WireType.START_GROUP); + expect(tagToWireType(0x0C)).toBe(WireType.END_GROUP); + expect(tagToWireType(0x0D)).toBe(WireType.FIXED32); + + // upper bits should not matter + expect(tagToWireType(0xF8)).toBe(WireType.VARINT); + expect(tagToWireType(0xF9)).toBe(WireType.FIXED64); + expect(tagToWireType(0xFA)).toBe(WireType.DELIMITED); + expect(tagToWireType(0xFB)).toBe(WireType.START_GROUP); + expect(tagToWireType(0xFC)).toBe(WireType.END_GROUP); + expect(tagToWireType(0xFD)).toBe(WireType.FIXED32); + + // negative numbers work + expect(tagToWireType(-8)).toBe(WireType.VARINT); + expect(tagToWireType(-7)).toBe(WireType.FIXED64); + expect(tagToWireType(-6)).toBe(WireType.DELIMITED); + expect(tagToWireType(-5)).toBe(WireType.START_GROUP); + expect(tagToWireType(-4)).toBe(WireType.END_GROUP); + expect(tagToWireType(-3)).toBe(WireType.FIXED32); + }); +}); + +describe('tagToFieldNumber', () => { + it('returns fieldNumber', () => { + expect(tagToFieldNumber(0x08)).toBe(1); + expect(tagToFieldNumber(0x09)).toBe(1); + expect(tagToFieldNumber(0x10)).toBe(2); + expect(tagToFieldNumber(0x12)).toBe(2); + }); +}); + +describe('createTag', () => { + it('combines fieldNumber and wireType', () => { + expect(createTag(WireType.VARINT, 1)).toBe(0x08); + expect(createTag(WireType.FIXED64, 1)).toBe(0x09); + expect(createTag(WireType.DELIMITED, 1)).toBe(0x0A); + expect(createTag(WireType.START_GROUP, 1)).toBe(0x0B); + expect(createTag(WireType.END_GROUP, 1)).toBe(0x0C); + expect(createTag(WireType.FIXED32, 1)).toBe(0x0D); + + expect(createTag(WireType.VARINT, 2)).toBe(0x10); + expect(createTag(WireType.FIXED64, 2)).toBe(0x11); + expect(createTag(WireType.DELIMITED, 2)).toBe(0x12); + expect(createTag(WireType.START_GROUP, 2)).toBe(0x13); + expect(createTag(WireType.END_GROUP, 2)).toBe(0x14); + expect(createTag(WireType.FIXED32, 2)).toBe(0x15); + + expect(createTag(WireType.VARINT, 0x1FFFFFFF)).toBe(0xFFFFFFF8 >>> 0); + expect(createTag(WireType.FIXED64, 0x1FFFFFFF)).toBe(0xFFFFFFF9 >>> 0); + expect(createTag(WireType.DELIMITED, 0x1FFFFFFF)).toBe(0xFFFFFFFA >>> 0); + expect(createTag(WireType.START_GROUP, 0x1FFFFFFF)).toBe(0xFFFFFFFB >>> 0); + expect(createTag(WireType.END_GROUP, 0x1FFFFFFF)).toBe(0xFFFFFFFC >>> 0); + expect(createTag(WireType.FIXED32, 0x1FFFFFFF)).toBe(0xFFFFFFFD >>> 0); + }); +}); + +describe('get32BitVarintLength', () => { + it('length of tag', () => { + expect(get32BitVarintLength(0)).toBe(1); + expect(get32BitVarintLength(1)).toBe(1); + expect(get32BitVarintLength(1)).toBe(1); + + expect(get32BitVarintLength(Math.pow(2, 7) - 1)).toBe(1); + expect(get32BitVarintLength(Math.pow(2, 7))).toBe(2); + + expect(get32BitVarintLength(Math.pow(2, 14) - 1)).toBe(2); + expect(get32BitVarintLength(Math.pow(2, 14))).toBe(3); + + expect(get32BitVarintLength(Math.pow(2, 21) - 1)).toBe(3); + expect(get32BitVarintLength(Math.pow(2, 21))).toBe(4); + + expect(get32BitVarintLength(Math.pow(2, 28) - 1)).toBe(4); + expect(get32BitVarintLength(Math.pow(2, 28))).toBe(5); + + expect(get32BitVarintLength(Math.pow(2, 31) - 1)).toBe(5); + + expect(get32BitVarintLength(-1)).toBe(5); + expect(get32BitVarintLength(-Math.pow(2, 31))).toBe(5); + + expect(get32BitVarintLength(createTag(WireType.VARINT, 0x1fffffff))) + .toBe(5); + expect(get32BitVarintLength(createTag(WireType.FIXED32, 0x1fffffff))) + .toBe(5); + }); +}); diff --git a/js/experimental/runtime/kernel/uint32_test_pairs.js b/js/experimental/runtime/kernel/uint32_test_pairs.js index 75be05e8dfe6..851996d0fcd1 100644 --- a/js/experimental/runtime/kernel/uint32_test_pairs.js +++ b/js/experimental/runtime/kernel/uint32_test_pairs.js @@ -10,7 +10,8 @@ const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper' * An array of Pairs of float values and their bit representation. * This is used to test encoding and decoding from/to the protobuf wire format. * @return {!Array<{name: string, intValue:number, bufferDecoder: - * !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>} + * !BufferDecoder, error: (boolean|undefined), + * skip_reader: (boolean|undefined), skip_writer: (boolean|undefined)}>} */ function getUint32Pairs() { const uint32Pairs = [ @@ -34,6 +35,12 @@ function getUint32Pairs() { intValue: Math.pow(2, 32) - 1, bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F), }, + { + name: 'negative one', + intValue: -1, + bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F), + skip_reader: true, + }, { name: 'truncates more than 32 bits', intValue: Math.pow(2, 32) - 1, diff --git a/js/experimental/runtime/kernel/writer.js b/js/experimental/runtime/kernel/writer.js index 1fc741869f68..5b8b79b6c351 100644 --- a/js/experimental/runtime/kernel/writer.js +++ b/js/experimental/runtime/kernel/writer.js @@ -10,6 +10,7 @@ const Int64 = goog.require('protobuf.Int64'); const WireType = goog.require('protobuf.binary.WireType'); const {POLYFILL_TEXT_ENCODING, checkFieldNumber, checkTypeUnsignedInt32, checkWireType} = goog.require('protobuf.internal.checks'); const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays'); +const {createTag, getTagLength} = goog.require('protobuf.binary.tag'); const {encode} = goog.require('protobuf.binary.textencoding'); /** @@ -92,7 +93,7 @@ class Writer { writeTag(fieldNumber, wireType) { checkFieldNumber(fieldNumber); checkWireType(wireType); - const tag = fieldNumber << 3 | wireType; + const tag = createTag(wireType, fieldNumber); this.writeUnsignedVarint32_(tag); } @@ -299,6 +300,22 @@ class Writer { this.writeSfixed64Value_(value); } + /** + * Writes a sfixed64 value field to the buffer. + * @param {number} fieldNumber + */ + writeStartGroup(fieldNumber) { + this.writeTag(fieldNumber, WireType.START_GROUP); + } + + /** + * Writes a sfixed64 value field to the buffer. + * @param {number} fieldNumber + */ + writeEndGroup(fieldNumber) { + this.writeTag(fieldNumber, WireType.END_GROUP); + } + /** * Writes a uint32 value field to the buffer as a varint without tag. * @param {number} value @@ -411,7 +428,8 @@ class Writer { this.writeTag(fieldNumber, WireType.DELIMITED); const array = encoderFunction(value); this.writeUnsignedVarint32_(array.length); - this.writeRaw_(array.buffer); + this.closeAndStartNewBuffer_(); + this.blocks_.push(array); } /** @@ -429,64 +447,17 @@ class Writer { * @param {!BufferDecoder} bufferDecoder * @param {number} start * @param {!WireType} wireType + * @param {number} fieldNumber * @package */ - writeBufferDecoder(bufferDecoder, start, wireType) { + writeBufferDecoder(bufferDecoder, start, wireType, fieldNumber) { this.closeAndStartNewBuffer_(); - const dataLength = this.getLength_(bufferDecoder, start, wireType); + const dataLength = + getTagLength(bufferDecoder, start, wireType, fieldNumber); this.blocks_.push( bufferDecoder.subBufferDecoder(start, dataLength).asUint8Array()); } - /** - * Returns the length of the data to serialize. Returns -1 when a STOP GROUP - * is found. - * @param {!BufferDecoder} bufferDecoder - * @param {number} start - * @param {!WireType} wireType - * @return {number} - * @private - */ - getLength_(bufferDecoder, start, wireType) { - switch (wireType) { - case WireType.VARINT: - return bufferDecoder.skipVarint(start) - start; - case WireType.FIXED64: - return 8; - case WireType.DELIMITED: - const {lowBits: dataLength, dataStart} = bufferDecoder.getVarint(start); - return dataLength + dataStart - start; - case WireType.START_GROUP: - return this.getGroupLength_(bufferDecoder, start); - case WireType.FIXED32: - return 4; - default: - throw new Error(`Invalid wire type: ${wireType}`); - } - } - - /** - * Skips over fields until it finds the end of a given group. - * @param {!BufferDecoder} bufferDecoder - * @param {number} start - * @return {number} - * @private - */ - getGroupLength_(bufferDecoder, start) { - // On a start group we need to keep skipping fields until we find a - // corresponding stop group - let cursor = start; - while (cursor < bufferDecoder.endIndex()) { - const {lowBits: tag, dataStart} = bufferDecoder.getVarint(cursor); - const wireType = /** @type {!WireType} */ (tag & 0x07); - if (wireType === WireType.END_GROUP) { - return dataStart - start; - } - cursor = dataStart + this.getLength_(bufferDecoder, dataStart, wireType); - } - throw new Error('No end group found'); - } - /** * Write the whole bytes as a length delimited field. * @param {number} fieldNumber diff --git a/js/experimental/runtime/kernel/writer_test.js b/js/experimental/runtime/kernel/writer_test.js index e4b2184e8420..019ae1e18aa6 100644 --- a/js/experimental/runtime/kernel/writer_test.js +++ b/js/experimental/runtime/kernel/writer_test.js @@ -60,6 +60,18 @@ describe('Writer does', () => { const writer = new Writer(); writer.writeTag(1, WireType.VARINT); expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08)); + + writer.writeTag(0x0FFFFFFF, WireType.VARINT); + expect(writer.getAndResetResultBuffer()) + .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x7)); + + writer.writeTag(0x10000000, WireType.VARINT); + expect(writer.getAndResetResultBuffer()) + .toEqual(createArrayBuffer(0x80, 0x80, 0x80, 0x80, 0x08)); + + writer.writeTag(0x1FFFFFFF, WireType.VARINT); + expect(writer.getAndResetResultBuffer()) + .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F)); }); it('reset after calling getAndResetResultBuffer', () => { @@ -95,7 +107,8 @@ describe('Writer does', () => { // These values might change at any point and are not considered // what the implementation should be doing here. writer.writeTag(-1, WireType.VARINT); - expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0xF8)); + expect(writer.getAndResetResultBuffer()) + .toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0xF)); } }); @@ -135,7 +148,7 @@ describe('Writer.writeBufferDecoder does', () => { const expected = createArrayBuffer( 0x08, /* varint start= */ 0xFF, /* varint end= */ 0x01, 0x08, 0x01); writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.VARINT); + BufferDecoder.fromArrayBuffer(expected), 1, WireType.VARINT, 1); const result = writer.getAndResetResultBuffer(); expect(result).toEqual(arrayBufferSlice(expected, 1, 3)); }); @@ -146,7 +159,7 @@ describe('Writer.writeBufferDecoder does', () => { 0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* fixed64 end= */ 0x08, 0x08, 0x01); writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED64); + BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED64, 1); const result = writer.getAndResetResultBuffer(); expect(result).toEqual(arrayBufferSlice(expected, 1, 9)); }); @@ -157,7 +170,7 @@ describe('Writer.writeBufferDecoder does', () => { 0xA, /* length= */ 0x03, /* data start= */ 0x01, 0x02, /* data end= */ 0x03, 0x08, 0x01); writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.DELIMITED); + BufferDecoder.fromArrayBuffer(expected), 1, WireType.DELIMITED, 1); const result = writer.getAndResetResultBuffer(); expect(result).toEqual(arrayBufferSlice(expected, 1, 5)); }); @@ -168,7 +181,7 @@ describe('Writer.writeBufferDecoder does', () => { 0xB, /* group start= */ 0x08, 0x01, /* nested group start= */ 0x0B, /* nested group end= */ 0x0C, /* group end= */ 0x0C, 0x08, 0x01); writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.START_GROUP); + BufferDecoder.fromArrayBuffer(expected), 1, WireType.START_GROUP, 1); const result = writer.getAndResetResultBuffer(); expect(result).toEqual(arrayBufferSlice(expected, 1, 6)); }); @@ -179,7 +192,7 @@ describe('Writer.writeBufferDecoder does', () => { 0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, /* fixed64 end= */ 0x04, 0x08, 0x01); writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED32); + BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED32, 1); const result = writer.getAndResetResultBuffer(); expect(result).toEqual(arrayBufferSlice(expected, 1, 5)); }); @@ -190,7 +203,7 @@ describe('Writer.writeBufferDecoder does', () => { const subBuffer = arrayBufferSlice(buffer, 0, 2); expect( () => writer.writeBufferDecoder( - BufferDecoder.fromArrayBuffer(subBuffer), 0, WireType.DELIMITED)) + BufferDecoder.fromArrayBuffer(subBuffer), 0, WireType.DELIMITED, 1)) .toThrow(); }); }); @@ -504,7 +517,11 @@ describe('Writer.writeString does', () => { expect(new Uint8Array(writer.getAndResetResultBuffer())) .toEqual(new Uint8Array(createArrayBuffer( -6, // invalid tag - 1, // string length + 0xff, + 0xff, + 0xff, + 0x0f, + 1, // string length 'a'.charCodeAt(0), ))); } diff --git a/js/experimental/runtime/testing/binary/test_message.js b/js/experimental/runtime/testing/binary/test_message.js index 8af6c3813211..cfd264b32497 100644 --- a/js/experimental/runtime/testing/binary/test_message.js +++ b/js/experimental/runtime/testing/binary/test_message.js @@ -1,20 +1,27 @@ /** - * @fileoverview LazyAccessor wrapper message. + * @fileoverview Kernel wrapper message. */ goog.module('protobuf.testing.binary.TestMessage'); const ByteString = goog.require('protobuf.ByteString'); const Int64 = goog.require('protobuf.Int64'); const InternalMessage = goog.require('protobuf.binary.InternalMessage'); -const LazyAccessor = goog.require('protobuf.binary.LazyAccessor'); +const Kernel = goog.require('protobuf.runtime.Kernel'); /** - * A protobuf message implemented as a LazyAccessor wrapper. + * A protobuf message implemented as a Kernel wrapper. * @implements {InternalMessage} */ class TestMessage { /** - * @param {!LazyAccessor} kernel + * @return {!TestMessage} + */ + static createEmpty() { + return TestMessage.instanceCreator(Kernel.createEmpty()); + } + + /** + * @param {!Kernel} kernel * @return {!TestMessage} */ static instanceCreator(kernel) { @@ -22,17 +29,16 @@ class TestMessage { } /** - * @param {!LazyAccessor} kernel + * @param {!Kernel} kernel */ constructor(kernel) { - /** @private @const {!LazyAccessor} */ + /** @private @const {!Kernel} */ this.kernel_ = kernel; } /** * @override - * @package - * @return {!LazyAccessor} + * @return {!Kernel} */ internalGetKernel() { return this.kernel_; @@ -182,7 +188,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @return {?T} * @template T */ @@ -192,7 +198,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @return {T} * @template T */ @@ -202,7 +208,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @return {T} * @template T */ @@ -212,7 +218,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @return {?LazyAccessor} + * @return {?Kernel} * @template T */ getMessageAccessorOrNull(fieldNumber) { @@ -594,7 +600,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number} index * @return {T} * @template T @@ -606,7 +612,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @return {!Iterable} * @template T */ @@ -617,7 +623,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @return {!Iterable} + * @return {!Iterable} * @template T */ getRepeatedMessageAccessorIterable(fieldNumber) { @@ -626,7 +632,7 @@ class TestMessage { /** * @param {number} fieldNumber - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @return {number} * @template T */ @@ -1728,7 +1734,7 @@ class TestMessage { /** * @param {number} fieldNumber * @param {!Iterable} values - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @template T */ addRepeatedMessageIterable(fieldNumber, values, instanceCreator) { @@ -1739,7 +1745,7 @@ class TestMessage { /** * @param {number} fieldNumber * @param {T} value - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @param {number} index * @throws {!Error} if index is out of range when check mode is critical * @template T @@ -1752,7 +1758,7 @@ class TestMessage { /** * @param {number} fieldNumber * @param {T} value - * @param {function(!LazyAccessor):T} instanceCreator + * @param {function(!Kernel):T} instanceCreator * @template T */ addRepeatedMessageElement(fieldNumber, value, instanceCreator) { @@ -1760,4 +1766,4 @@ class TestMessage { } } -exports = TestMessage; \ No newline at end of file +exports = TestMessage; diff --git a/js/gulpfile.js b/js/gulpfile.js index 1f0946caf09c..8137b9070205 100644 --- a/js/gulpfile.js +++ b/js/gulpfile.js @@ -37,6 +37,7 @@ var group1Protos = [ 'testbinary.proto', 'testempty.proto', 'test.proto', + 'testlargenumbers.proto', ]; var group2Protos = [ @@ -70,13 +71,16 @@ gulp.task('genproto_group1_closure', function (cb) { }); }); -gulp.task('genproto_group2_closure', function (cb) { - exec(protoc + ' --js_out=library=testproto_libs2,binary:. -I ../src -I . -I commonjs ' + group2Protos.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); +gulp.task('genproto_group2_closure', function(cb) { + exec( + protoc + + ' --experimental_allow_proto3_optional --js_out=library=testproto_libs2,binary:. -I ../src -I . -I commonjs ' + + group2Protos.join(' '), + function(err, stdout, stderr) { + console.log(stdout); + console.log(stderr); + cb(err); + }); }); gulp.task('genproto_well_known_types_commonjs', function (cb) { @@ -97,13 +101,16 @@ gulp.task('genproto_group1_commonjs', function (cb) { }); }); -gulp.task('genproto_group2_commonjs', function (cb) { - exec('mkdir -p commonjs_out && ' + protoc + ' --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . ' + group2Protos.join(' '), - function (err, stdout, stderr) { - console.log(stdout); - console.log(stderr); - cb(err); - }); +gulp.task('genproto_group2_commonjs', function(cb) { + exec( + 'mkdir -p commonjs_out && ' + protoc + + ' --experimental_allow_proto3_optional --js_out=import_style=commonjs,binary:commonjs_out -I ../src -I commonjs -I . ' + + group2Protos.join(' '), + function(err, stdout, stderr) { + console.log(stdout); + console.log(stderr); + cb(err); + }); }); gulp.task('genproto_commonjs_wellknowntypes', function (cb) { diff --git a/js/map.js b/js/map.js index 589a2938d5ed..61f0f3b63f19 100644 --- a/js/map.js +++ b/js/map.js @@ -1,3 +1,4 @@ + // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ @@ -28,6 +29,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/** + * @fileoverview + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed + */ goog.provide('jspb.Map'); goog.require('goog.asserts'); diff --git a/js/maps_test.js b/js/maps_test.js old mode 100755 new mode 100644 diff --git a/js/message.js b/js/message.js index 5c081129a9ac..905329fe4409 100644 --- a/js/message.js +++ b/js/message.js @@ -31,6 +31,7 @@ /** * @fileoverview Definition of jspb.Message. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author mwr@google.com (Mark Rawling) */ @@ -417,7 +418,7 @@ jspb.Message.EMPTY_LIST_SENTINEL_ = goog.DEBUG && Object.freeze ? */ jspb.Message.isArray_ = function(o) { return jspb.Message.ASSUME_LOCAL_ARRAYS ? o instanceof Array : - goog.isArray(o); + Array.isArray(o); }; /** @@ -1112,8 +1113,11 @@ jspb.Message.setFieldIgnoringDefault_ = function( goog.asserts.assertInstanceof(msg, jspb.Message); if (value !== defaultValue) { jspb.Message.setField(msg, fieldNumber, value); - } else { + } else if (fieldNumber < msg.pivot_) { msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = null; + } else { + jspb.Message.maybeInitEmptyExtensionObject_(msg); + delete msg.extensionObject_[fieldNumber]; } return msg; }; @@ -1430,7 +1434,7 @@ jspb.Message.prototype.syncMapFields_ = function() { if (this.wrappers_) { for (var fieldNumber in this.wrappers_) { var val = this.wrappers_[fieldNumber]; - if (goog.isArray(val)) { + if (Array.isArray(val)) { for (var i = 0; i < val.length; i++) { if (val[i]) { val[i].toArray(); @@ -1820,7 +1824,7 @@ jspb.Message.copyInto = function(fromMessage, toMessage) { */ jspb.Message.clone_ = function(obj) { var o; - if (goog.isArray(obj)) { + if (Array.isArray(obj)) { // Allocate array of correct size. var clonedArray = new Array(obj.length); // Use array iteration where possible because it is faster than for-in. diff --git a/js/message_test.js b/js/message_test.js index e038f65c519e..3db8716b8c52 100644 --- a/js/message_test.js +++ b/js/message_test.js @@ -118,6 +118,8 @@ goog.require('proto.jspb.test.ExtensionMessage'); goog.require('proto.jspb.test.TestExtensionsMessage'); goog.require('proto.jspb.test.TestAllowAliasEnum'); +// CommonJS-LoadFromFile: testlargenumbers_pb proto.jspb.test +goog.require('proto.jspb.test.MessageWithLargeFieldNumbers'); describe('Message test suite', function() { var stubs = new goog.testing.PropertyReplacer(); @@ -1075,4 +1077,36 @@ describe('Message test suite', function() { assertEquals(12, package2Message.getA()); }); + + it('testMessageWithLargeFieldNumbers', function() { + var message = new proto.jspb.test.MessageWithLargeFieldNumbers; + + message.setAString('string'); + assertEquals('string', message.getAString()); + + message.setAString(''); + assertEquals('', message.getAString()); + + message.setAString('new string'); + assertEquals('new string', message.getAString()); + + message.setABoolean(true); + assertEquals(true, message.getABoolean()); + + message.setABoolean(false); + assertEquals(false, message.getABoolean()); + + message.setABoolean(true); + assertEquals(true, message.getABoolean()); + + message.setAInt(42); + assertEquals(42, message.getAInt()); + + message.setAInt(0); + assertEquals(0, message.getAInt()); + + message.setAInt(42); + assertEquals(42, message.getAInt()); + }); + }); diff --git a/js/package.json b/js/package.json index a2fb37174269..6bbc115c044d 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "google-protobuf", - "version": "3.11.2", + "version": "3.14.0", "description": "Protocol Buffers for JavaScript", "main": "google-protobuf.js", "files": [ diff --git a/js/proto3_test.js b/js/proto3_test.js index 79acc3c26113..fd59ae50d607 100644 --- a/js/proto3_test.js +++ b/js/proto3_test.js @@ -77,7 +77,7 @@ describe('proto3Test', function() { it('testEqualsProto3', function() { var msg1 = new proto.jspb.test.TestProto3(); var msg2 = new proto.jspb.test.TestProto3(); - msg2.setOptionalString(''); + msg2.setSingularString(''); assertTrue(jspb.Message.equals(msg1, msg2)); }); @@ -90,12 +90,12 @@ describe('proto3Test', function() { var msg = new proto.jspb.test.TestProto3(); // Setting should work normally. - msg.setOptionalString('optionalString'); - assertEquals(msg.getOptionalString(), 'optionalString'); + msg.setSingularString('optionalString'); + assertEquals(msg.getSingularString(), 'optionalString'); // Clearing should work too ... - msg.setOptionalString(''); - assertEquals(msg.getOptionalString(), ''); + msg.setSingularString(''); + assertEquals(msg.getSingularString(), ''); // ... and shouldn't affect the equality with a brand new message. assertTrue(jspb.Message.equals(msg, new proto.jspb.test.TestProto3())); @@ -107,6 +107,58 @@ describe('proto3Test', function() { it('testProto3FieldDefaults', function() { var msg = new proto.jspb.test.TestProto3(); + assertEquals(msg.getSingularInt32(), 0); + assertEquals(msg.getSingularInt64(), 0); + assertEquals(msg.getSingularUint32(), 0); + assertEquals(msg.getSingularUint64(), 0); + assertEquals(msg.getSingularSint32(), 0); + assertEquals(msg.getSingularSint64(), 0); + assertEquals(msg.getSingularFixed32(), 0); + assertEquals(msg.getSingularFixed64(), 0); + assertEquals(msg.getSingularSfixed32(), 0); + assertEquals(msg.getSingularSfixed64(), 0); + assertEquals(msg.getSingularFloat(), 0); + assertEquals(msg.getSingularDouble(), 0); + assertEquals(msg.getSingularString(), ''); + + // TODO(b/26173701): when we change bytes fields default getter to return + // Uint8Array, we'll want to switch this assertion to match the u8 case. + assertEquals(typeof msg.getSingularBytes(), 'string'); + assertEquals(msg.getSingularBytes_asU8() instanceof Uint8Array, true); + assertEquals(typeof msg.getSingularBytes_asB64(), 'string'); + assertEquals(msg.getSingularBytes().length, 0); + assertEquals(msg.getSingularBytes_asU8().length, 0); + assertEquals(msg.getSingularBytes_asB64(), ''); + + assertEquals( + msg.getSingularForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO); + assertEquals(msg.getSingularForeignMessage(), undefined); + assertEquals(msg.getSingularForeignMessage(), undefined); + + assertEquals(msg.getRepeatedInt32List().length, 0); + assertEquals(msg.getRepeatedInt64List().length, 0); + assertEquals(msg.getRepeatedUint32List().length, 0); + assertEquals(msg.getRepeatedUint64List().length, 0); + assertEquals(msg.getRepeatedSint32List().length, 0); + assertEquals(msg.getRepeatedSint64List().length, 0); + assertEquals(msg.getRepeatedFixed32List().length, 0); + assertEquals(msg.getRepeatedFixed64List().length, 0); + assertEquals(msg.getRepeatedSfixed32List().length, 0); + assertEquals(msg.getRepeatedSfixed64List().length, 0); + assertEquals(msg.getRepeatedFloatList().length, 0); + assertEquals(msg.getRepeatedDoubleList().length, 0); + assertEquals(msg.getRepeatedStringList().length, 0); + assertEquals(msg.getRepeatedBytesList().length, 0); + assertEquals(msg.getRepeatedForeignEnumList().length, 0); + assertEquals(msg.getRepeatedForeignMessageList().length, 0); + }); + + /** + * Test presence for proto3 optional fields. + */ + it('testProto3Optional', function() { + var msg = new proto.jspb.test.TestProto3(); + assertEquals(msg.getOptionalInt32(), 0); assertEquals(msg.getOptionalInt64(), 0); assertEquals(msg.getOptionalUint32(), 0); @@ -135,51 +187,65 @@ describe('proto3Test', function() { assertEquals(msg.getOptionalForeignMessage(), undefined); assertEquals(msg.getOptionalForeignMessage(), undefined); - assertEquals(msg.getRepeatedInt32List().length, 0); - assertEquals(msg.getRepeatedInt64List().length, 0); - assertEquals(msg.getRepeatedUint32List().length, 0); - assertEquals(msg.getRepeatedUint64List().length, 0); - assertEquals(msg.getRepeatedSint32List().length, 0); - assertEquals(msg.getRepeatedSint64List().length, 0); - assertEquals(msg.getRepeatedFixed32List().length, 0); - assertEquals(msg.getRepeatedFixed64List().length, 0); - assertEquals(msg.getRepeatedSfixed32List().length, 0); - assertEquals(msg.getRepeatedSfixed64List().length, 0); - assertEquals(msg.getRepeatedFloatList().length, 0); - assertEquals(msg.getRepeatedDoubleList().length, 0); - assertEquals(msg.getRepeatedStringList().length, 0); - assertEquals(msg.getRepeatedBytesList().length, 0); - assertEquals(msg.getRepeatedForeignEnumList().length, 0); - assertEquals(msg.getRepeatedForeignMessageList().length, 0); + // Serializing an empty proto yields the empty string. + assertEquals(msg.serializeBinary().length, 0); - }); + // Values start as unset, but can be explicitly set even to default values + // like 0. + assertFalse(msg.hasOptionalInt32()); + msg.setOptionalInt32(0); + assertTrue(msg.hasOptionalInt32()); + + assertFalse(msg.hasOptionalInt64()); + msg.setOptionalInt64(0); + assertTrue(msg.hasOptionalInt64()); + + assertFalse(msg.hasOptionalString()); + msg.setOptionalString(''); + assertTrue(msg.hasOptionalString()); + + // Now the proto will have a non-zero size, even though its values are 0. + var serialized = msg.serializeBinary(); + assertNotEquals(serialized.length, 0); + + var msg2 = proto.jspb.test.TestProto3.deserializeBinary(serialized); + assertTrue(msg2.hasOptionalInt32()); + assertTrue(msg2.hasOptionalInt64()); + assertTrue(msg2.hasOptionalString()); + // We can clear fields to go back to empty. + msg2.clearOptionalInt32(); + assertFalse(msg2.hasOptionalInt32()); + + msg2.clearOptionalString(); + assertFalse(msg2.hasOptionalString()); + }); /** - * Test that all fields can be set and read via a serialization roundtrip. + * Test that all fields can be set ,and read via a serialization roundtrip. */ it('testProto3FieldSetGet', function() { var msg = new proto.jspb.test.TestProto3(); - msg.setOptionalInt32(-42); - msg.setOptionalInt64(-0x7fffffff00000000); - msg.setOptionalUint32(0x80000000); - msg.setOptionalUint64(0xf000000000000000); - msg.setOptionalSint32(-100); - msg.setOptionalSint64(-0x8000000000000000); - msg.setOptionalFixed32(1234); - msg.setOptionalFixed64(0x1234567800000000); - msg.setOptionalSfixed32(-1234); - msg.setOptionalSfixed64(-0x1234567800000000); - msg.setOptionalFloat(1.5); - msg.setOptionalDouble(-1.5); - msg.setOptionalBool(true); - msg.setOptionalString('hello world'); - msg.setOptionalBytes(BYTES); + msg.setSingularInt32(-42); + msg.setSingularInt64(-0x7fffffff00000000); + msg.setSingularUint32(0x80000000); + msg.setSingularUint64(0xf000000000000000); + msg.setSingularSint32(-100); + msg.setSingularSint64(-0x8000000000000000); + msg.setSingularFixed32(1234); + msg.setSingularFixed64(0x1234567800000000); + msg.setSingularSfixed32(-1234); + msg.setSingularSfixed64(-0x1234567800000000); + msg.setSingularFloat(1.5); + msg.setSingularDouble(-1.5); + msg.setSingularBool(true); + msg.setSingularString('hello world'); + msg.setSingularBytes(BYTES); var submsg = new proto.jspb.test.ForeignMessage(); submsg.setC(16); - msg.setOptionalForeignMessage(submsg); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); + msg.setSingularForeignMessage(submsg); + msg.setSingularForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); msg.setRepeatedInt32List([-42]); msg.setRepeatedInt64List([-0x7fffffff00000000]); @@ -206,24 +272,24 @@ describe('proto3Test', function() { var serialized = msg.serializeBinary(); msg = proto.jspb.test.TestProto3.deserializeBinary(serialized); - assertEquals(msg.getOptionalInt32(), -42); - assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000); - assertEquals(msg.getOptionalUint32(), 0x80000000); - assertEquals(msg.getOptionalUint64(), 0xf000000000000000); - assertEquals(msg.getOptionalSint32(), -100); - assertEquals(msg.getOptionalSint64(), -0x8000000000000000); - assertEquals(msg.getOptionalFixed32(), 1234); - assertEquals(msg.getOptionalFixed64(), 0x1234567800000000); - assertEquals(msg.getOptionalSfixed32(), -1234); - assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000); - assertEquals(msg.getOptionalFloat(), 1.5); - assertEquals(msg.getOptionalDouble(), -1.5); - assertEquals(msg.getOptionalBool(), true); - assertEquals(msg.getOptionalString(), 'hello world'); - assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES)); - assertEquals(msg.getOptionalForeignMessage().getC(), 16); - assertEquals(msg.getOptionalForeignEnum(), - proto.jspb.test.Proto3Enum.PROTO3_BAR); + assertEquals(msg.getSingularInt32(), -42); + assertEquals(msg.getSingularInt64(), -0x7fffffff00000000); + assertEquals(msg.getSingularUint32(), 0x80000000); + assertEquals(msg.getSingularUint64(), 0xf000000000000000); + assertEquals(msg.getSingularSint32(), -100); + assertEquals(msg.getSingularSint64(), -0x8000000000000000); + assertEquals(msg.getSingularFixed32(), 1234); + assertEquals(msg.getSingularFixed64(), 0x1234567800000000); + assertEquals(msg.getSingularSfixed32(), -1234); + assertEquals(msg.getSingularSfixed64(), -0x1234567800000000); + assertEquals(msg.getSingularFloat(), 1.5); + assertEquals(msg.getSingularDouble(), -1.5); + assertEquals(msg.getSingularBool(), true); + assertEquals(msg.getSingularString(), 'hello world'); + assertEquals(true, bytesCompare(msg.getSingularBytes(), BYTES)); + assertEquals(msg.getSingularForeignMessage().getC(), 16); + assertEquals( + msg.getSingularForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_BAR); assertElementsEquals(msg.getRepeatedInt32List(), [-42]); assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]); @@ -327,20 +393,20 @@ describe('proto3Test', function() { // Set each primitive to a non-default value, then back to its default, to // ensure that the serialization is actually checking the value and not just // whether it has ever been set. - msg.setOptionalInt32(42); - msg.setOptionalInt32(0); - msg.setOptionalDouble(3.14); - msg.setOptionalDouble(0.0); - msg.setOptionalBool(true); - msg.setOptionalBool(false); - msg.setOptionalString('hello world'); - msg.setOptionalString(''); - msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); - msg.setOptionalBytes(''); - msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage()); - msg.setOptionalForeignMessage(null); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); - msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO); + msg.setSingularInt32(42); + msg.setSingularInt32(0); + msg.setSingularDouble(3.14); + msg.setSingularDouble(0.0); + msg.setSingularBool(true); + msg.setSingularBool(false); + msg.setSingularString('hello world'); + msg.setSingularString(''); + msg.setSingularBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); + msg.setSingularBytes(''); + msg.setSingularForeignMessage(new proto.jspb.test.ForeignMessage()); + msg.setSingularForeignMessage(null); + msg.setSingularForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR); + msg.setSingularForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO); msg.setOneofUint32(32); msg.clearOneofUint32(); @@ -355,27 +421,25 @@ describe('proto3Test', function() { it('testBytesFieldsInterop', function() { var msg = new proto.jspb.test.TestProto3(); // Set as a base64 string and check all the getters work. - msg.setOptionalBytes(BYTES_B64); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + msg.setSingularBytes(BYTES_B64); + assertTrue(bytesCompare(msg.getSingularBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getSingularBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getSingularBytes(), BYTES)); // Test binary serialize round trip doesn't break it. msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary()); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); + assertTrue(bytesCompare(msg.getSingularBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getSingularBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getSingularBytes(), BYTES)); msg = new proto.jspb.test.TestProto3(); // Set as a Uint8Array and check all the getters work. - msg.setOptionalBytes(BYTES); - assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES)); - assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES)); - + msg.setSingularBytes(BYTES); + assertTrue(bytesCompare(msg.getSingularBytes_asU8(), BYTES)); + assertTrue(bytesCompare(msg.getSingularBytes_asB64(), BYTES)); + assertTrue(bytesCompare(msg.getSingularBytes(), BYTES)); }); - it('testTimestampWellKnownType', function() { var msg = new proto.google.protobuf.Timestamp(); msg.fromDate(new Date(123456789)); diff --git a/js/proto3_test.proto b/js/proto3_test.proto index f23e19c9d80d..14f104ef56d3 100644 --- a/js/proto3_test.proto +++ b/js/proto3_test.proto @@ -30,29 +30,48 @@ syntax = "proto3"; -import "testbinary.proto"; - package jspb.test; +import "testbinary.proto"; + message TestProto3 { - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - sint32 optional_sint32 = 5; - sint64 optional_sint64 = 6; - fixed32 optional_fixed32 = 7; - fixed64 optional_fixed64 = 8; - sfixed32 optional_sfixed32 = 9; - sfixed64 optional_sfixed64 = 10; - float optional_float = 11; - double optional_double = 12; - bool optional_bool = 13; - string optional_string = 14; - bytes optional_bytes = 15; + int32 singular_int32 = 1; + int64 singular_int64 = 2; + uint32 singular_uint32 = 3; + uint64 singular_uint64 = 4; + sint32 singular_sint32 = 5; + sint64 singular_sint64 = 6; + fixed32 singular_fixed32 = 7; + fixed64 singular_fixed64 = 8; + sfixed32 singular_sfixed32 = 9; + sfixed64 singular_sfixed64 = 10; + float singular_float = 11; + double singular_double = 12; + bool singular_bool = 13; + string singular_string = 14; + bytes singular_bytes = 15; - ForeignMessage optional_foreign_message = 19; - Proto3Enum optional_foreign_enum = 22; + ForeignMessage singular_foreign_message = 19; + Proto3Enum singular_foreign_enum = 22; + + optional int32 optional_int32 = 121; + optional int64 optional_int64 = 122; + optional uint32 optional_uint32 = 123; + optional uint64 optional_uint64 = 124; + optional sint32 optional_sint32 = 125; + optional sint64 optional_sint64 = 126; + optional fixed32 optional_fixed32 = 127; + optional fixed64 optional_fixed64 = 128; + optional sfixed32 optional_sfixed32 = 129; + optional sfixed64 optional_sfixed64 = 130; + optional float optional_float = 131; + optional double optional_double = 132; + optional bool optional_bool = 133; + optional string optional_string = 134; + optional bytes optional_bytes = 135; + + optional ForeignMessage optional_foreign_message = 136; + optional Proto3Enum optional_foreign_enum = 137; repeated int32 repeated_int32 = 31; repeated int64 repeated_int64 = 32; @@ -73,7 +92,6 @@ message TestProto3 { repeated ForeignMessage repeated_foreign_message = 49; repeated Proto3Enum repeated_foreign_enum = 52; - oneof oneof_field { uint32 oneof_uint32 = 111; ForeignMessage oneof_foreign_message = 112; diff --git a/src/google/protobuf/unittest_no_arena_import.proto b/js/testlargenumbers.proto similarity index 91% rename from src/google/protobuf/unittest_no_arena_import.proto rename to js/testlargenumbers.proto index 072af49e3c70..47aef35798a5 100644 --- a/src/google/protobuf/unittest_no_arena_import.proto +++ b/js/testlargenumbers.proto @@ -28,10 +28,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -syntax = "proto2"; +syntax = "proto3"; -package proto2_arena_unittest; +package jspb.test; -message ImportNoArenaNestedMessage { - optional int32 d = 1; -}; + +message MessageWithLargeFieldNumbers { + string a_string = 1; + bool a_boolean = 900; + int32 a_int = 5000; +} diff --git a/kokoro/docs/common.cfg b/kokoro/docs/common.cfg new file mode 100644 index 000000000000..771ca7f637c6 --- /dev/null +++ b/kokoro/docs/common.cfg @@ -0,0 +1,44 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "protobuf/kokoro/docs/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" +} + +env_vars: { + key: "STAGING_BUCKET" + value: "docs-staging" +} + +# Fetch the token needed for reporting release status to GitHub +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "yoshi-automation-github-key" + } + } +} + +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "docuploader_service_account" + } + } +} diff --git a/kokoro/docs/publish-python.sh b/kokoro/docs/publish-python.sh new file mode 100755 index 000000000000..eea17552b480 --- /dev/null +++ b/kokoro/docs/publish-python.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Adapted from https://github.com/googleapis/google-cloud-python/blob/master/.kokoro/publish-docs.sh + +set -eo pipefail + +# Disable buffering, so that the logs stream through. +export PYTHONUNBUFFERED=1 + +cd github/protobuf/python + +# install package +sudo apt-get update +sudo apt-get -y install software-properties-common +sudo add-apt-repository universe +sudo apt-get update +sudo apt-get -y install unzip +wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.2/protoc-3.11.2-linux-x86_64.zip +unzip protoc-3.11.2-linux-x86_64.zip bin/protoc +mv bin/protoc ../src/protoc +python3.6 -m venv venv +source venv/bin/activate +python setup.py install + +# install docs dependencies +python -m pip install -r docs/requirements.txt + +# build docs +cd docs +make html +cd .. +deactivate + +python3.6 -m pip install protobuf==3.11.1 gcp-docuploader + +# install a json parser +sudo apt-get -y install jq + +# create metadata +python3.6 -m docuploader create-metadata \ + --name=$(jq --raw-output '.name // empty' .repo-metadata.json) \ + --version=$(python3 setup.py --version) \ + --language=$(jq --raw-output '.language // empty' .repo-metadata.json) \ + --distribution-name=$(python3 setup.py --name) \ + --product-page=$(jq --raw-output '.product_documentation // empty' .repo-metadata.json) \ + --github-repository=$(jq --raw-output '.repo // empty' .repo-metadata.json) \ + --issue-tracker=$(jq --raw-output '.issue_tracker // empty' .repo-metadata.json) + +cat docs.metadata + +# upload docs +python3.6 -m docuploader upload docs/_build/html --metadata-file docs.metadata --staging-bucket docs-staging diff --git a/kokoro/docs/python.cfg b/kokoro/docs/python.cfg new file mode 100644 index 000000000000..382f431ad2f2 --- /dev/null +++ b/kokoro/docs/python.cfg @@ -0,0 +1,7 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Tell the trampoline which build file to use. +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/protobuf/kokoro/docs/publish-python.sh" +} diff --git a/kokoro/docs/trampoline.sh b/kokoro/docs/trampoline.sh new file mode 100755 index 000000000000..db7e90b2e8ca --- /dev/null +++ b/kokoro/docs/trampoline.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Copied from https://github.com/googleapis/google-cloud-python/blob/master/.kokoro/trampoline.sh + +set -eo pipefail + +python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" || ret_code=$? + +chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh +${KOKORO_GFILE_DIR}/trampoline_cleanup.sh || true + +exit ${ret_code} diff --git a/kokoro/linux/bazel/build.sh b/kokoro/linux/bazel/build.sh index b5991d773af2..5f34bea30ef1 100755 --- a/kokoro/linux/bazel/build.sh +++ b/kokoro/linux/bazel/build.sh @@ -25,9 +25,13 @@ git submodule update --init --recursive trap print_test_logs EXIT bazel test --copt=-Werror --host_copt=-Werror \ //:build_files_updated_unittest \ + //java/... \ + //:protoc \ + //:protobuf \ + //:protobuf_python \ //:protobuf_test \ @com_google_protobuf//:cc_proto_blacklist_test trap - EXIT cd examples -bazel build :all +bazel build //... diff --git a/kokoro/linux/benchmark/build.sh b/kokoro/linux/benchmark/build.sh old mode 100644 new mode 100755 diff --git a/kokoro/linux/benchmark/continuous.cfg b/kokoro/linux/benchmark/continuous.cfg old mode 100755 new mode 100644 diff --git a/kokoro/linux/build_and_run_docker.sh b/kokoro/linux/build_and_run_docker.sh index 3dc5dbb82fc5..cdbd6e29b0fb 100755 --- a/kokoro/linux/build_and_run_docker.sh +++ b/kokoro/linux/build_and_run_docker.sh @@ -28,8 +28,9 @@ else DOCKER_IMAGE_NAME=${DOCKERHUB_ORGANIZATION}/${DOCKERFILE_PREFIX}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) fi -# Pull dockerimage from Dockerhub -docker pull $DOCKER_IMAGE_NAME +# Pull dockerimage from Dockerhub. This sometimes fails intermittently, so we +# keep trying until we succeed. +until docker pull $DOCKER_IMAGE_NAME; do sleep 10; done # Ensure existence of ccache directory CCACHE_DIR=/tmp/protobuf-ccache diff --git a/kokoro/linux/cpp_distcheck/build.sh b/kokoro/linux/cpp_distcheck/build.sh index 1343a8cc848e..42ac88caffb4 100755 --- a/kokoro/linux/cpp_distcheck/build.sh +++ b/kokoro/linux/cpp_distcheck/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. # Run tests under release docker image. DOCKER_IMAGE_NAME=protobuf/protoc_$(sha1sum protoc-artifacts/Dockerfile | cut -f1 -d " ") -docker pull $DOCKER_IMAGE_NAME +until docker pull $DOCKER_IMAGE_NAME; do sleep 10; done docker run -v $(pwd):/var/local/protobuf --rm $DOCKER_IMAGE_NAME \ bash -l /var/local/protobuf/tests.sh cpp || FAILED="true" diff --git a/kokoro/linux/dockerfile/push_testing_images.sh b/kokoro/linux/dockerfile/push_testing_images.sh index 9a2983c8290e..2d82babba419 100755 --- a/kokoro/linux/dockerfile/push_testing_images.sh +++ b/kokoro/linux/dockerfile/push_testing_images.sh @@ -8,7 +8,7 @@ cd kokoro/linux/dockerfile DOCKERHUB_ORGANIZATION=protobuftesting -for DOCKERFILE_DIR in test/* release/* +for DOCKERFILE_DIR in test/* do # Generate image name based on Dockerfile checksum. That works well as long # as can count on dockerfiles being written in a way that changing the logical diff --git a/kokoro/linux/dockerfile/release/ruby_rake_compiler/Dockerfile b/kokoro/linux/dockerfile/release/ruby_rake_compiler/Dockerfile deleted file mode 100644 index 866b289343d7..000000000000 --- a/kokoro/linux/dockerfile/release/ruby_rake_compiler/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM grpctesting/rake-compiler-dock_53c22085d091183c528303791e7771359f699bcf - -RUN /bin/bash -l -c "gem update --system '2.7.9' && gem install bundler" diff --git a/kokoro/linux/dockerfile/test/csharp/Dockerfile b/kokoro/linux/dockerfile/test/csharp/Dockerfile index 3d54436bacc6..95bd653152f0 100644 --- a/kokoro/linux/dockerfile/test/csharp/Dockerfile +++ b/kokoro/linux/dockerfile/test/csharp/Dockerfile @@ -29,7 +29,7 @@ RUN apt-get update && apt-get install -y libunwind8 libicu57 && apt-get clean RUN wget -q https://dot.net/v1/dotnet-install.sh && \ chmod u+x dotnet-install.sh && \ ./dotnet-install.sh --version 2.1.802 && \ - ./dotnet-install.sh --version 3.0.100 && \ + ./dotnet-install.sh --version 3.1.301 && \ ln -s /root/.dotnet/dotnet /usr/local/bin RUN wget -q www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe diff --git a/kokoro/linux/dockerfile/test/php80/Dockerfile b/kokoro/linux/dockerfile/test/php80/Dockerfile new file mode 100644 index 000000000000..d6c9b4d273bf --- /dev/null +++ b/kokoro/linux/dockerfile/test/php80/Dockerfile @@ -0,0 +1,96 @@ +FROM debian:jessie + +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + parallel \ + time \ + wget \ + re2c \ + sqlite3 \ + vim \ + libonig-dev \ + libsqlite3-dev \ + && apt-get clean + +# Install php dependencies +RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ + php5 \ + libcurl4-openssl-dev \ + libgmp-dev \ + libgmp3-dev \ + libssl-dev \ + libxml2-dev \ + unzip \ + zlib1g-dev \ + pkg-config \ + && apt-get clean + +# Install other dependencies +RUN ln -sf /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h +RUN wget https://ftp.gnu.org/gnu/bison/bison-3.0.1.tar.gz -O /var/local/bison-3.0.1.tar.gz +RUN cd /var/local \ + && tar -zxvf bison-3.0.1.tar.gz \ + && cd /var/local/bison-3.0.1 \ + && ./configure \ + && make \ + && make install + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php +RUN mv composer.phar /usr/local/bin/composer + +# Download php source code +RUN git clone https://github.com/php/php-src + +# php 8.0 +RUN cd php-src \ + && git checkout php-8.0.0alpha3 \ + && ./buildconf --force +RUN cd php-src \ + && ./configure \ + --enable-bcmath \ + --enable-mbstring \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + --prefix=/usr/local/php-8.0 \ + && make \ + && make install \ + && make clean +RUN cd php-src \ + && ./configure \ + --enable-bcmath \ + --enable-mbstring \ + --enable-maintainer-zts \ + --with-gmp \ + --with-openssl \ + --with-zlib \ + --prefix=/usr/local/php-8.0-zts \ + && make \ + && make install \ + && make clean + +RUN wget -O phpunit https://phar.phpunit.de/phpunit-9.phar \ + && chmod +x phpunit \ + && cp phpunit /usr/local/php-8.0/bin \ + && mv phpunit /usr/local/php-8.0-zts/bin + +# Install php dependencies +RUN apt-get clean && apt-get update && apt-get install -y --force-yes \ + valgrind \ + && apt-get clean diff --git a/kokoro/linux/dockerfile/test/python27/Dockerfile b/kokoro/linux/dockerfile/test/python27/Dockerfile new file mode 100644 index 000000000000..6b0eaf72c862 --- /dev/null +++ b/kokoro/linux/dockerfile/test/python27/Dockerfile @@ -0,0 +1,31 @@ +FROM python:2.7-buster + +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + parallel \ + time \ + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python35/Dockerfile b/kokoro/linux/dockerfile/test/python35/Dockerfile new file mode 100644 index 000000000000..50ee18453619 --- /dev/null +++ b/kokoro/linux/dockerfile/test/python35/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.5-buster + +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + parallel \ + time \ + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python36/Dockerfile b/kokoro/linux/dockerfile/test/python36/Dockerfile new file mode 100644 index 000000000000..742503e5a417 --- /dev/null +++ b/kokoro/linux/dockerfile/test/python36/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.6-buster + +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + parallel \ + time \ + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python37/Dockerfile b/kokoro/linux/dockerfile/test/python37/Dockerfile new file mode 100644 index 000000000000..ee108dd03012 --- /dev/null +++ b/kokoro/linux/dockerfile/test/python37/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.7-buster + +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + parallel \ + time \ + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python38/Dockerfile b/kokoro/linux/dockerfile/test/python38/Dockerfile new file mode 100644 index 000000000000..56efc9d6bf39 --- /dev/null +++ b/kokoro/linux/dockerfile/test/python38/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.8-buster + +# Install dependencies. We start with the basic ones require to build protoc +# and the C++ build +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + gcc \ + git \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + parallel \ + time \ + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Python libraries. +RUN python -m pip install --no-cache-dir --upgrade \ + pip \ + setuptools \ + tox \ + wheel diff --git a/kokoro/linux/dockerfile/test/python_jessie/Dockerfile b/kokoro/linux/dockerfile/test/python_jessie/Dockerfile deleted file mode 100644 index b5a53a3e5fca..000000000000 --- a/kokoro/linux/dockerfile/test/python_jessie/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -FROM debian:jessie - -# Install dependencies. We start with the basic ones require to build protoc -# and the C++ build -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - ccache \ - curl \ - gcc \ - git \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - parallel \ - time \ - wget \ - && apt-get clean - -# Install python dependencies -RUN apt-get update && apt-get install -y \ - python-setuptools \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -RUN pip install --upgrade pip==10.0.1 -RUN pip install virtualenv -RUN pip install six==1.10.0 twisted==17.5.0 - -# Install pip and virtualenv for Python 3.4 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4 -RUN python3.4 -m pip install virtualenv diff --git a/kokoro/linux/dockerfile/test/python_stretch/Dockerfile b/kokoro/linux/dockerfile/test/python_stretch/Dockerfile deleted file mode 100644 index 10790b9c3e3d..000000000000 --- a/kokoro/linux/dockerfile/test/python_stretch/Dockerfile +++ /dev/null @@ -1,49 +0,0 @@ -FROM debian:stretch - -# Install dependencies. We start with the basic ones require to build protoc -# and the C++ build -RUN apt-get update && apt-get install -y \ - autoconf \ - autotools-dev \ - build-essential \ - bzip2 \ - ccache \ - curl \ - gcc \ - git \ - libc6 \ - libc6-dbg \ - libc6-dev \ - libgtest-dev \ - libtool \ - make \ - parallel \ - time \ - wget \ - && apt-get clean - -# Install Python 2.7 -RUN apt-get update && apt-get install -y python2.7 python-all-dev -RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 - -# Install python dependencies -RUN apt-get update && apt-get install -y \ - python-setuptools \ - python-pip - -# Add Debian 'testing' repository -RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list -RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local - -# Install Python3 -RUN apt-get update && apt-get -t testing install -y \ - python3.5 \ - python3.6 \ - python3.7 \ - python3.8 \ - python3-all-dev - -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.8 diff --git a/kokoro/linux/dockerfile/test/ruby/Dockerfile b/kokoro/linux/dockerfile/test/ruby/Dockerfile index 41bfedeb330f..9037da715f09 100644 --- a/kokoro/linux/dockerfile/test/ruby/Dockerfile +++ b/kokoro/linux/dockerfile/test/ruby/Dockerfile @@ -32,6 +32,7 @@ RUN /bin/bash -l -c "rvm install 2.3.8" RUN /bin/bash -l -c "rvm install 2.4.5" RUN /bin/bash -l -c "rvm install 2.5.1" RUN /bin/bash -l -c "rvm install 2.6.0" +RUN /bin/bash -l -c "rvm install 2.7.0" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" diff --git a/kokoro/linux/python34/build.sh b/kokoro/linux/php80/build.sh similarity index 85% rename from kokoro/linux/python34/build.sh rename to kokoro/linux/php80/build.sh index 25dfd5dfcd6a..6499b39af8be 100755 --- a/kokoro/linux/python34/build.sh +++ b/kokoro/linux/php80/build.sh @@ -11,8 +11,8 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/php export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput -export TEST_SET="python34" +export TEST_SET="php8.0_all" ./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python34/continuous.cfg b/kokoro/linux/php80/continuous.cfg similarity index 76% rename from kokoro/linux/python34/continuous.cfg rename to kokoro/linux/php80/continuous.cfg index e2fc4136f07e..8426318bbee4 100644 --- a/kokoro/linux/python34/continuous.cfg +++ b/kokoro/linux/php80/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/php80/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python34/presubmit.cfg b/kokoro/linux/php80/presubmit.cfg similarity index 76% rename from kokoro/linux/python34/presubmit.cfg rename to kokoro/linux/php80/presubmit.cfg index e2fc4136f07e..8426318bbee4 100644 --- a/kokoro/linux/python34/presubmit.cfg +++ b/kokoro/linux/php80/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/php80/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27/build.sh b/kokoro/linux/python27/build.sh index 8c40ba36045a..41531a15efe8 100755 --- a/kokoro/linux/python27/build.sh +++ b/kokoro/linux/python27/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python27 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python27" diff --git a/kokoro/linux/python27/continuous.cfg b/kokoro/linux/python27/continuous.cfg index e2fc4136f07e..dd98469a6fb6 100644 --- a/kokoro/linux/python27/continuous.cfg +++ b/kokoro/linux/python27/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27/presubmit.cfg b/kokoro/linux/python27/presubmit.cfg index e2fc4136f07e..dd98469a6fb6 100644 --- a/kokoro/linux/python27/presubmit.cfg +++ b/kokoro/linux/python27/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27_cpp/build.sh b/kokoro/linux/python27_cpp/build.sh index 2ff09a21fd81..1a972ee9f261 100755 --- a/kokoro/linux/python27_cpp/build.sh +++ b/kokoro/linux/python27_cpp/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python27 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python27_cpp" diff --git a/kokoro/linux/python27_cpp/continuous.cfg b/kokoro/linux/python27_cpp/continuous.cfg index b1b0e550ffd4..ace22d007717 100644 --- a/kokoro/linux/python27_cpp/continuous.cfg +++ b/kokoro/linux/python27_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python27_cpp/presubmit.cfg b/kokoro/linux/python27_cpp/presubmit.cfg index b1b0e550ffd4..ace22d007717 100644 --- a/kokoro/linux/python27_cpp/presubmit.cfg +++ b/kokoro/linux/python27_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python27_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python33_cpp/build.sh b/kokoro/linux/python33_cpp/build.sh deleted file mode 100755 index ad33e89d257a..000000000000 --- a/kokoro/linux/python33_cpp/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "pull request" project: -# -# This script selects a specific Dockerfile (for building a Docker image) and -# a script to run inside that image. Then we delegate to the general -# build_and_run_docker.sh script. - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="python33_cpp" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python33_cpp/continuous.cfg b/kokoro/linux/python33_cpp/continuous.cfg deleted file mode 100644 index b1b0e550ffd4..000000000000 --- a/kokoro/linux/python33_cpp/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python33_cpp/presubmit.cfg b/kokoro/linux/python33_cpp/presubmit.cfg deleted file mode 100644 index b1b0e550ffd4..000000000000 --- a/kokoro/linux/python33_cpp/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python34_cpp/build.sh b/kokoro/linux/python34_cpp/build.sh deleted file mode 100755 index e4590ffbad13..000000000000 --- a/kokoro/linux/python34_cpp/build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# This is the top-level script we give to Kokoro as the entry point for -# running the "pull request" project: -# -# This script selects a specific Dockerfile (for building a Docker image) and -# a script to run inside that image. Then we delegate to the general -# build_and_run_docker.sh script. - -# Change to repo root -cd $(dirname $0)/../../.. - -export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie -export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh -export OUTPUT_DIR=testoutput -export TEST_SET="python34_cpp" -./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python34_cpp/continuous.cfg b/kokoro/linux/python34_cpp/continuous.cfg deleted file mode 100644 index b1b0e550ffd4..000000000000 --- a/kokoro/linux/python34_cpp/continuous.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python34_cpp/presubmit.cfg b/kokoro/linux/python34_cpp/presubmit.cfg deleted file mode 100644 index b1b0e550ffd4..000000000000 --- a/kokoro/linux/python34_cpp/presubmit.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# Config file for running tests in Kokoro - -# Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" -timeout_mins: 120 - -action { - define_artifacts { - regex: "**/sponge_log.xml" - } -} diff --git a/kokoro/linux/python35/build.sh b/kokoro/linux/python35/build.sh index f978e2ad11e1..66ea03f0367a 100755 --- a/kokoro/linux/python35/build.sh +++ b/kokoro/linux/python35/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python35 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python35" diff --git a/kokoro/linux/python35/continuous.cfg b/kokoro/linux/python35/continuous.cfg index e2fc4136f07e..2b3e12cbb0cd 100644 --- a/kokoro/linux/python35/continuous.cfg +++ b/kokoro/linux/python35/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python35/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35/presubmit.cfg b/kokoro/linux/python35/presubmit.cfg index e2fc4136f07e..2b3e12cbb0cd 100644 --- a/kokoro/linux/python35/presubmit.cfg +++ b/kokoro/linux/python35/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python35/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35_cpp/build.sh b/kokoro/linux/python35_cpp/build.sh index 2a79246d5992..4d0dbd4986b2 100755 --- a/kokoro/linux/python35_cpp/build.sh +++ b/kokoro/linux/python35_cpp/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python35 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python35_cpp" diff --git a/kokoro/linux/python35_cpp/continuous.cfg b/kokoro/linux/python35_cpp/continuous.cfg index b1b0e550ffd4..ad5cc8657adc 100644 --- a/kokoro/linux/python35_cpp/continuous.cfg +++ b/kokoro/linux/python35_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python35_cpp/presubmit.cfg b/kokoro/linux/python35_cpp/presubmit.cfg index b1b0e550ffd4..ad5cc8657adc 100644 --- a/kokoro/linux/python35_cpp/presubmit.cfg +++ b/kokoro/linux/python35_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python35_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36/build.sh b/kokoro/linux/python36/build.sh index 633145bcec19..a483efc3027f 100755 --- a/kokoro/linux/python36/build.sh +++ b/kokoro/linux/python36/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python36 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python36" diff --git a/kokoro/linux/python36/continuous.cfg b/kokoro/linux/python36/continuous.cfg index e2fc4136f07e..ee7f4888f8c7 100644 --- a/kokoro/linux/python36/continuous.cfg +++ b/kokoro/linux/python36/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python36/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36/presubmit.cfg b/kokoro/linux/python36/presubmit.cfg index e2fc4136f07e..ee7f4888f8c7 100644 --- a/kokoro/linux/python36/presubmit.cfg +++ b/kokoro/linux/python36/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python36/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36_cpp/build.sh b/kokoro/linux/python36_cpp/build.sh index 8e120ff37c6e..eb71bda92c48 100755 --- a/kokoro/linux/python36_cpp/build.sh +++ b/kokoro/linux/python36_cpp/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python36 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python36_cpp" diff --git a/kokoro/linux/python36_cpp/continuous.cfg b/kokoro/linux/python36_cpp/continuous.cfg index b1b0e550ffd4..df9e7144943a 100644 --- a/kokoro/linux/python36_cpp/continuous.cfg +++ b/kokoro/linux/python36_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python36_cpp/presubmit.cfg b/kokoro/linux/python36_cpp/presubmit.cfg index b1b0e550ffd4..df9e7144943a 100644 --- a/kokoro/linux/python36_cpp/presubmit.cfg +++ b/kokoro/linux/python36_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python36_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37/build.sh b/kokoro/linux/python37/build.sh index 554aa0944889..2117a271ce64 100755 --- a/kokoro/linux/python37/build.sh +++ b/kokoro/linux/python37/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python37 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python37" diff --git a/kokoro/linux/python37/continuous.cfg b/kokoro/linux/python37/continuous.cfg index e2fc4136f07e..9fa20c19757e 100644 --- a/kokoro/linux/python37/continuous.cfg +++ b/kokoro/linux/python37/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python37/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37/presubmit.cfg b/kokoro/linux/python37/presubmit.cfg index e2fc4136f07e..9fa20c19757e 100644 --- a/kokoro/linux/python37/presubmit.cfg +++ b/kokoro/linux/python37/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python37/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37_cpp/build.sh b/kokoro/linux/python37_cpp/build.sh index 8fdc8f933974..3126b481e372 100755 --- a/kokoro/linux/python37_cpp/build.sh +++ b/kokoro/linux/python37_cpp/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python37 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python37_cpp" diff --git a/kokoro/linux/python37_cpp/continuous.cfg b/kokoro/linux/python37_cpp/continuous.cfg index b1b0e550ffd4..49c441ffe892 100644 --- a/kokoro/linux/python37_cpp/continuous.cfg +++ b/kokoro/linux/python37_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python37_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python37_cpp/presubmit.cfg b/kokoro/linux/python37_cpp/presubmit.cfg index b1b0e550ffd4..49c441ffe892 100644 --- a/kokoro/linux/python37_cpp/presubmit.cfg +++ b/kokoro/linux/python37_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python37_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38/build.sh b/kokoro/linux/python38/build.sh index 9609939a482c..299c7ba6f3bd 100755 --- a/kokoro/linux/python38/build.sh +++ b/kokoro/linux/python38/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python38 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python38" diff --git a/kokoro/linux/python38/continuous.cfg b/kokoro/linux/python38/continuous.cfg index e2fc4136f07e..76425d2f193a 100644 --- a/kokoro/linux/python38/continuous.cfg +++ b/kokoro/linux/python38/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python38/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38/presubmit.cfg b/kokoro/linux/python38/presubmit.cfg index e2fc4136f07e..76425d2f193a 100644 --- a/kokoro/linux/python38/presubmit.cfg +++ b/kokoro/linux/python38/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/python38/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38_cpp/build.sh b/kokoro/linux/python38_cpp/build.sh index c5cd6eeb4211..b43859b988a9 100755 --- a/kokoro/linux/python38_cpp/build.sh +++ b/kokoro/linux/python38_cpp/build.sh @@ -11,7 +11,7 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_stretch +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python38 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput export TEST_SET="python38_cpp" diff --git a/kokoro/linux/python38_cpp/continuous.cfg b/kokoro/linux/python38_cpp/continuous.cfg index b1b0e550ffd4..1e8888cc5d1b 100644 --- a/kokoro/linux/python38_cpp/continuous.cfg +++ b/kokoro/linux/python38_cpp/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python38_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python38_cpp/presubmit.cfg b/kokoro/linux/python38_cpp/presubmit.cfg index b1b0e550ffd4..1e8888cc5d1b 100644 --- a/kokoro/linux/python38_cpp/presubmit.cfg +++ b/kokoro/linux/python38_cpp/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python_cpp/build.sh" +build_file: "protobuf/kokoro/linux/python38_cpp/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python33/build.sh b/kokoro/linux/ruby27/build.sh similarity index 85% rename from kokoro/linux/python33/build.sh rename to kokoro/linux/ruby27/build.sh index 84a9acdb73d4..c38ee36e584a 100755 --- a/kokoro/linux/python33/build.sh +++ b/kokoro/linux/ruby27/build.sh @@ -11,8 +11,8 @@ cd $(dirname $0)/../../.. export DOCKERHUB_ORGANIZATION=protobuftesting -export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/python_jessie +export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/ruby export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh export OUTPUT_DIR=testoutput -export TEST_SET="python33" +export TEST_SET="ruby27" ./kokoro/linux/build_and_run_docker.sh diff --git a/kokoro/linux/python33/continuous.cfg b/kokoro/linux/ruby27/continuous.cfg similarity index 76% rename from kokoro/linux/python33/continuous.cfg rename to kokoro/linux/ruby27/continuous.cfg index e2fc4136f07e..9cce8c90e1ff 100644 --- a/kokoro/linux/python33/continuous.cfg +++ b/kokoro/linux/ruby27/continuous.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/ruby27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/linux/python33/presubmit.cfg b/kokoro/linux/ruby27/presubmit.cfg similarity index 76% rename from kokoro/linux/python33/presubmit.cfg rename to kokoro/linux/ruby27/presubmit.cfg index e2fc4136f07e..9cce8c90e1ff 100644 --- a/kokoro/linux/python33/presubmit.cfg +++ b/kokoro/linux/ruby27/presubmit.cfg @@ -1,7 +1,7 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/linux/python/build.sh" +build_file: "protobuf/kokoro/linux/ruby27/build.sh" timeout_mins: 120 action { diff --git a/kokoro/macos/objectivec_cocoapods_integration/build.sh b/kokoro/macos/objectivec_cocoapods_integration/build.sh index f96d2899d909..8f3c9b4c15d6 100755 --- a/kokoro/macos/objectivec_cocoapods_integration/build.sh +++ b/kokoro/macos/objectivec_cocoapods_integration/build.sh @@ -6,6 +6,7 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests +KOKORO_INSTALL_COCOAPODS=yes source kokoro/macos/prepare_build_macos_rc ./tests.sh objectivec_cocoapods_integration diff --git a/kokoro/macos/php5.6_mac/build.sh b/kokoro/macos/php7.3_mac/build.sh similarity index 89% rename from kokoro/macos/php5.6_mac/build.sh rename to kokoro/macos/php7.3_mac/build.sh index 74878898faa7..2d2f679da2ca 100755 --- a/kokoro/macos/php5.6_mac/build.sh +++ b/kokoro/macos/php7.3_mac/build.sh @@ -8,4 +8,4 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests source kokoro/macos/prepare_build_macos_rc -./tests.sh php5.6_mac +./tests.sh php7.3_mac diff --git a/kokoro/macos/php5.6_mac/continuous.cfg b/kokoro/macos/php7.3_mac/continuous.cfg similarity index 65% rename from kokoro/macos/php5.6_mac/continuous.cfg rename to kokoro/macos/php7.3_mac/continuous.cfg index ff345e9fc41d..9a717451d373 100644 --- a/kokoro/macos/php5.6_mac/continuous.cfg +++ b/kokoro/macos/php7.3_mac/continuous.cfg @@ -1,5 +1,5 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/macos/php5.6_mac/build.sh" +build_file: "protobuf/kokoro/macos/php7.3_mac/build.sh" timeout_mins: 1440 diff --git a/kokoro/macos/php5.6_mac/presubmit.cfg b/kokoro/macos/php7.3_mac/presubmit.cfg similarity index 65% rename from kokoro/macos/php5.6_mac/presubmit.cfg rename to kokoro/macos/php7.3_mac/presubmit.cfg index ff345e9fc41d..9a717451d373 100644 --- a/kokoro/macos/php5.6_mac/presubmit.cfg +++ b/kokoro/macos/php7.3_mac/presubmit.cfg @@ -1,5 +1,5 @@ # Config file for running tests in Kokoro # Location of the build script in repository -build_file: "protobuf/kokoro/macos/php5.6_mac/build.sh" +build_file: "protobuf/kokoro/macos/php7.3_mac/build.sh" timeout_mins: 1440 diff --git a/kokoro/macos/prepare_build_macos_rc b/kokoro/macos/prepare_build_macos_rc index 5b134f4b9795..830e7eee6731 100755 --- a/kokoro/macos/prepare_build_macos_rc +++ b/kokoro/macos/prepare_build_macos_rc @@ -2,14 +2,16 @@ # # This script sets up a Kokoro MacOS worker for running Protobuf tests +set -eux + ## # Select Xcode version -# Remember to update the Xcode version when Xcode_11.0.app is not available. +# Remember to update the Xcode version when Xcode_11.3.app is not available. # If xcode is not available, it will probably encounter the failure for # "autom4te: need GNU m4 1.4 or later: /usr/bin/m4" # go/kokoro/userdocs/macos/selecting_xcode.md for more information. -export DEVELOPER_DIR=/Applications/Xcode_11.0.app/Contents/Developer +export DEVELOPER_DIR=/Applications/Xcode_11.3.app/Contents/Developer ## # Select C/C++ compilers @@ -18,24 +20,61 @@ export CC=gcc export CXX=g++ ## -# Install Brew and core softwares +# Brew: update, then upgrade the installed tools to current version and install +# some needed ones not in the Kokoro base image. This ensure current versions +# of CMake, autotools, etc. + +# But first... +# +# The transitive deps of the installed tools need protobuf, but Kokoro manually +# installed it outside of brew so it needs to be removed so brew can install the +# tools (and a newer version of protobuf). g/kokoro-users/7FRvQMUdN40 about why +# it is a manual install vs. a brew install in the first place. +sudo rm -rf \ + /usr/local/include/google/protobuf \ + /usr/local/bin/protoc +# Likewise, updating python can have issues because of some existing binaries. +sudo rm -rf \ + /usr/local/bin/2to3* \ + /usr/local/bin/idle3* \ + /usr/local/bin/pydoc3* \ + /usr/local/bin/python3* \ + /usr/local/bin/pyvenv* + +brew update +brew upgrade + +## +# Install Ruby -ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" -source $HOME/.rvm/scripts/rvm -brew uninstall node icu4c cmake wget -brew prune -brew install gflags gpg gpg2 node openssl pcre ruby cmake wget -sudo chown -R $(whoami) /usr/local -brew postinstall node +if [[ "${KOKORO_INSTALL_RUBY:-}" == "yes" ]] ; then + brew install ruby +fi + +## +# Install Cocoapods + +if [[ "${KOKORO_INSTALL_COCOAPODS:-}" == "yes" ]] ; then + # The existing cocoapods was installed via gem, but that doesn't work well + # with the overlap in deps with things managed by brew (errors around ruby + # versions, etc.); so remove it and install in via brew instead. + gem uninstall -a "$(gem list | grep cocoapods | cut -d ' ' -f 1)" + brew install cocoapods +fi ## # Install Tox -sudo pip install tox==2.4.1 +if [[ "${KOKORO_INSTALL_TOX:-}" == "yes" ]] ; then + sudo python3 -m pip install --upgrade pip tox +fi ## # Install RVM -gpg2 --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 -command curl -sSL https://rvm.io/mpapis.asc | gpg2 --import - -curl -sSL https://get.rvm.io | bash -s stable --ruby +if [[ "${KOKORO_INSTALL_RVM:-}" == "yes" ]] ; then + curl -sSL https://rvm.io/mpapis.asc | gpg --import - + curl -sSL https://rvm.io/pkuczynski.asc | gpg --import - + + curl -sSL https://get.rvm.io | bash -s stable --ruby +fi diff --git a/kokoro/macos/python/build.sh b/kokoro/macos/python/build.sh index 6b17b9544647..388e24b4ac12 100755 --- a/kokoro/macos/python/build.sh +++ b/kokoro/macos/python/build.sh @@ -6,6 +6,7 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests +KOKORO_INSTALL_TOX=yes source kokoro/macos/prepare_build_macos_rc ./tests.sh python diff --git a/kokoro/macos/python_cpp/build.sh b/kokoro/macos/python_cpp/build.sh index cb53def9d31a..f86dd6f76e49 100755 --- a/kokoro/macos/python_cpp/build.sh +++ b/kokoro/macos/python_cpp/build.sh @@ -6,6 +6,7 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests +KOKORO_INSTALL_TOX=yes source kokoro/macos/prepare_build_macos_rc g++ --version diff --git a/kokoro/macos/ruby23/build.sh b/kokoro/macos/ruby23/build.sh index dc950a20d4eb..9317838781ce 100755 --- a/kokoro/macos/ruby23/build.sh +++ b/kokoro/macos/ruby23/build.sh @@ -6,6 +6,8 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests +KOKORO_INSTALL_RUBY=yes +KOKORO_INSTALL_RVM=yes source kokoro/macos/prepare_build_macos_rc ./tests.sh ruby23 diff --git a/kokoro/macos/ruby24/build.sh b/kokoro/macos/ruby24/build.sh index 3c3a190d9d7e..51bb2e603b8c 100755 --- a/kokoro/macos/ruby24/build.sh +++ b/kokoro/macos/ruby24/build.sh @@ -6,6 +6,8 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests +KOKORO_INSTALL_RUBY=yes +KOKORO_INSTALL_RVM=yes source kokoro/macos/prepare_build_macos_rc ./tests.sh ruby24 diff --git a/kokoro/macos/ruby25/build.sh b/kokoro/macos/ruby25/build.sh index 38e90aa75c52..ba2d0a4d1926 100755 --- a/kokoro/macos/ruby25/build.sh +++ b/kokoro/macos/ruby25/build.sh @@ -6,6 +6,8 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests +KOKORO_INSTALL_RUBY=yes +KOKORO_INSTALL_RVM=yes source kokoro/macos/prepare_build_macos_rc ./tests.sh ruby25 diff --git a/kokoro/macos/ruby26/build.sh b/kokoro/macos/ruby26/build.sh index 6c33ed0a7e66..5a4c2432227e 100755 --- a/kokoro/macos/ruby26/build.sh +++ b/kokoro/macos/ruby26/build.sh @@ -6,6 +6,8 @@ cd $(dirname $0)/../../.. # Prepare worker environment to run tests +KOKORO_INSTALL_RUBY=yes +KOKORO_INSTALL_RVM=yes source kokoro/macos/prepare_build_macos_rc ./tests.sh ruby26 diff --git a/kokoro/macos/ruby27/build.sh b/kokoro/macos/ruby27/build.sh new file mode 100755 index 000000000000..b1529b9da02b --- /dev/null +++ b/kokoro/macos/ruby27/build.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# +# Build file to set up and run tests + +# Change to repo root +cd $(dirname $0)/../../.. + +# Prepare worker environment to run tests +KOKORO_INSTALL_RUBY=yes +KOKORO_INSTALL_RVM=yes +source kokoro/macos/prepare_build_macos_rc + +./tests.sh ruby27 diff --git a/kokoro/macos/ruby27/continuous.cfg b/kokoro/macos/ruby27/continuous.cfg new file mode 100644 index 000000000000..b10b455da3fb --- /dev/null +++ b/kokoro/macos/ruby27/continuous.cfg @@ -0,0 +1,5 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/macos/ruby27/build.sh" +timeout_mins: 1440 diff --git a/kokoro/macos/ruby27/presubmit.cfg b/kokoro/macos/ruby27/presubmit.cfg new file mode 100644 index 000000000000..b10b455da3fb --- /dev/null +++ b/kokoro/macos/ruby27/presubmit.cfg @@ -0,0 +1,5 @@ +# Config file for running tests in Kokoro + +# Location of the build script in repository +build_file: "protobuf/kokoro/macos/ruby27/build.sh" +timeout_mins: 1440 diff --git a/kokoro/release/collect_all_artifacts.sh b/kokoro/release/collect_all_artifacts.sh index 0023937d53a0..8f6e9db9a0ef 100755 --- a/kokoro/release/collect_all_artifacts.sh +++ b/kokoro/release/collect_all_artifacts.sh @@ -39,13 +39,11 @@ cp ${INPUT_ARTIFACTS_DIR}/build64/Release/protoc.exe protoc/windows_x64/protoc.e mkdir -p protoc/linux_x86 mkdir -p protoc/linux_x64 # Because of maven unrelated reasonse the linux protoc binaries have a dummy .exe extension. -# For the Google.Protobuf.Tools nuget, we don't want that expection, so we just remove it. +# For the Google.Protobuf.Tools nuget, we don't want that exception, so we just remove it. cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_32/protoc.exe protoc/linux_x86/protoc cp ${INPUT_ARTIFACTS_DIR}/protoc-artifacts/target/linux/x86_64/protoc.exe protoc/linux_x64/protoc -mkdir -p protoc/macosx_x86 mkdir -p protoc/macosx_x64 -cp ${INPUT_ARTIFACTS_DIR}/build32/src/protoc protoc/macosx_x86/protoc cp ${INPUT_ARTIFACTS_DIR}/build64/src/protoc protoc/macosx_x64/protoc # Install nuget (will also install mono) diff --git a/kokoro/release/protoc/macos/build.sh b/kokoro/release/protoc/macos/build.sh old mode 100644 new mode 100755 index 6a4c79c7dec9..47c9bfa9685e --- a/kokoro/release/protoc/macos/build.sh +++ b/kokoro/release/protoc/macos/build.sh @@ -6,14 +6,6 @@ CXXFLAGS_COMMON="-std=c++14 -DNDEBUG -mmacosx-version-min=10.9" cd github/protobuf ./autogen.sh -mkdir build32 && cd build32 -export CXXFLAGS="$CXXFLAGS_COMMON -m32" -../configure --disable-shared -make -j4 -file src/protoc -otool -L src/protoc | grep dylib -cd .. - mkdir build64 && cd build64 export CXXFLAGS="$CXXFLAGS_COMMON -m64" ../configure --disable-shared diff --git a/kokoro/release/python/macos/config.sh b/kokoro/release/python/macos/config.sh index 741988a6b581..1b0a302e4cb3 100644 --- a/kokoro/release/python/macos/config.sh +++ b/kokoro/release/python/macos/config.sh @@ -1,6 +1,25 @@ # Define custom utilities # Test for OSX with [ -n "$IS_OSX" ] +function remove_travis_ve_pip { + # Removing the system virtualenv or pip can be very problematic for + # macOS on Kokoro, so just leave them be. + :; +} + +function install_pip { + check_python + PIP_CMD="sudo $PYTHON_EXE -m pip${pip_args:+ $pip_args}" + $PIP_CMD install --upgrade pip +} + +function install_virtualenv { + check_python + check_pip + $PIP_CMD install --upgrade virtualenv + VIRTUALENV_CMD="$PYTHON_EXE -m virtualenv" +} + function pre_build { # Any stuff that you need to do before you start building the wheels # Runs in the root directory of this repository. diff --git a/kokoro/release/ruby/linux/prepare_build.sh b/kokoro/release/ruby/linux/prepare_build.sh index f2257c3c7530..91d186898cbd 100755 --- a/kokoro/release/ruby/linux/prepare_build.sh +++ b/kokoro/release/ruby/linux/prepare_build.sh @@ -7,12 +7,6 @@ echo 'DOCKER_OPTS="${DOCKER_OPTS} --graph=/tmpfs/docker"' | sudo tee --append /e echo 'DOCKER_OPTS="${DOCKER_OPTS} --registry-mirror=https://mirror.gcr.io"' | sudo tee --append /etc/default/docker sudo service docker restart -# Download Docker images from DockerHub -DOCKERHUB_ORGANIZATION=protobuftesting -DOCKERFILE_DIR=kokoro/linux/dockerfile/release/ruby_rake_compiler -DOCKERFILE_PREFIX=$(basename $DOCKERFILE_DIR) -export RAKE_COMPILER_DOCK_IMAGE=${DOCKERHUB_ORGANIZATION}/${DOCKERFILE_PREFIX}_$(sha1sum $DOCKERFILE_DIR/Dockerfile | cut -f1 -d\ ) - # All artifacts come here mkdir artifacts export ARTIFACT_DIR=$(pwd)/artifacts diff --git a/kokoro/release/ruby/linux/ruby/ruby_build.sh b/kokoro/release/ruby/linux/ruby/ruby_build.sh index 9fc42b13eb48..f8ae9623f255 100755 --- a/kokoro/release/ruby/linux/ruby/ruby_build.sh +++ b/kokoro/release/ruby/linux/ruby/ruby_build.sh @@ -11,7 +11,8 @@ fi umask 0022 pushd ruby -bundle install && bundle exec rake gem:native +gem install bundler -v 2.1.4 +bundle update && bundle exec rake gem:native ls pkg mv pkg/* $ARTIFACT_DIR popd diff --git a/kokoro/release/ruby/macos/ruby/ruby_build.sh b/kokoro/release/ruby/macos/ruby/ruby_build.sh index 9fc42b13eb48..7f6c18fe8e8d 100755 --- a/kokoro/release/ruby/macos/ruby/ruby_build.sh +++ b/kokoro/release/ruby/macos/ruby/ruby_build.sh @@ -11,7 +11,7 @@ fi umask 0022 pushd ruby -bundle install && bundle exec rake gem:native +bundle update && bundle exec rake gem:native ls pkg mv pkg/* $ARTIFACT_DIR popd diff --git a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh index 5776e3c3496e..880c23390cfb 100755 --- a/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh +++ b/kokoro/release/ruby/macos/ruby/ruby_build_environment.sh @@ -6,7 +6,11 @@ set +ex # rvm script is very verbose and exits with errorcode source $HOME/.rvm/scripts/rvm set -e # rvm commands are very verbose time rvm install 2.5.0 -rvm use 2.5.0 --default +rvm use 2.5.0 +gem install rake-compiler --no-document +gem install bundler --no-document +time rvm install 2.7.0 +rvm use 2.7.0 --default gem install rake-compiler --no-document gem install bundler --no-document rvm osx-ssl-certs status all @@ -17,13 +21,13 @@ rm -rf ~/.rake-compiler CROSS_RUBY=$(mktemp tmpfile.XXXXXXXX) -curl https://raw.githubusercontent.com/rake-compiler/rake-compiler/v1.0.3/tasks/bin/cross-ruby.rake > "$CROSS_RUBY" +curl https://raw.githubusercontent.com/rake-compiler/rake-compiler/v1.1.0/tasks/bin/cross-ruby.rake > "$CROSS_RUBY" # See https://github.com/grpc/grpc/issues/12161 for verconf.h patch details patch "$CROSS_RUBY" << EOF --- cross-ruby.rake 2018-04-10 11:32:16.000000000 -0700 +++ patched 2018-04-10 11:40:25.000000000 -0700 -@@ -133,8 +133,10 @@ +@@ -141,8 +141,10 @@ "--host=#{MINGW_HOST}", "--target=#{MINGW_TARGET}", "--build=#{RUBY_BUILD}", @@ -35,9 +39,9 @@ patch "$CROSS_RUBY" << EOF '--with-ext=' ] -@@ -151,6 +153,7 @@ +@@ -159,6 +161,7 @@ # make - file "#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/ruby.exe" => ["#{USER_HOME}/builds/#{MINGW_HOST}/#{RUBY_CC_VERSION}/Makefile"] do |t| + file "#{build_dir}/ruby.exe" => ["#{build_dir}/Makefile"] do |t| chdir File.dirname(t.prerequisites.first) do + sh "test -s verconf.h || rm -f verconf.h" # if verconf.h has size 0, make sure it gets re-built by make sh MAKE @@ -47,10 +51,25 @@ EOF MAKE="make -j8" -for v in 2.6.0 2.5.1 2.4.0 2.3.0 ; do +set +x # rvm commands are very verbose +rvm use 2.7.0 +set -x +ruby --version | grep 'ruby 2.7.0' +for v in 2.7.0 ; do + ccache -c + rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" +done +set +x +rvm use 2.5.0 +set -x +ruby --version | grep 'ruby 2.5.0' +for v in 2.6.0 2.5.1 2.4.0 2.3.0; do ccache -c rake -f "$CROSS_RUBY" cross-ruby VERSION="$v" HOST=x86_64-darwin11 MAKE="$MAKE" done +set +x +rvm use 2.7.0 +set -x sed 's/x86_64-darwin-11/universal-darwin/' ~/.rake-compiler/config.yml > "$CROSS_RUBY" mv "$CROSS_RUBY" ~/.rake-compiler/config.yml diff --git a/objectivec/BUILD b/objectivec/BUILD new file mode 100644 index 000000000000..9f702ec95fde --- /dev/null +++ b/objectivec/BUILD @@ -0,0 +1,90 @@ +load("@rules_cc//cc:defs.bzl", "objc_library") + +objc_library( + name = "objectivec", + hdrs = [ + "GPBAny.pbobjc.h", + "GPBApi.pbobjc.h", + "GPBDuration.pbobjc.h", + "GPBEmpty.pbobjc.h", + "GPBFieldMask.pbobjc.h", + "GPBSourceContext.pbobjc.h", + "GPBStruct.pbobjc.h", + "GPBTimestamp.pbobjc.h", + "GPBType.pbobjc.h", + "GPBWrappers.pbobjc.h", + "GPBArray.h", + "GPBBootstrap.h", + "GPBCodedInputStream.h", + "GPBCodedOutputStream.h", + "GPBDescriptor.h", + "GPBDictionary.h", + "GPBExtensionInternals.h", + "GPBExtensionRegistry.h", + "GPBMessage.h", + "GPBProtocolBuffers.h", + "GPBProtocolBuffers_RuntimeSupport.h", + "GPBRootObject.h", + "GPBRuntimeTypes.h", + "GPBUnknownField.h", + "GPBUnknownFieldSet.h", + "GPBUtilities.h", + "GPBWellKnownTypes.h", + "GPBWireFormat.h", + "google/protobuf/Any.pbobjc.h", + "google/protobuf/Api.pbobjc.h", + "google/protobuf/Duration.pbobjc.h", + "google/protobuf/Empty.pbobjc.h", + "google/protobuf/FieldMask.pbobjc.h", + "google/protobuf/SourceContext.pbobjc.h", + "google/protobuf/Struct.pbobjc.h", + "google/protobuf/Timestamp.pbobjc.h", + "google/protobuf/Type.pbobjc.h", + "google/protobuf/Wrappers.pbobjc.h", + # Package private headers, but exposed because the generated sources + # need to use them. + "GPBArray_PackagePrivate.h", + "GPBCodedInputStream_PackagePrivate.h", + "GPBCodedOutputStream_PackagePrivate.h", + "GPBDescriptor_PackagePrivate.h", + "GPBDictionary_PackagePrivate.h", + "GPBMessage_PackagePrivate.h", + "GPBRootObject_PackagePrivate.h", + "GPBUnknownFieldSet_PackagePrivate.h", + "GPBUnknownField_PackagePrivate.h", + "GPBUtilities_PackagePrivate.h", + ], + copts = [ + "-Wno-vla", + ], + includes = [ + ".", + ], + non_arc_srcs = [ + "GPBAny.pbobjc.m", + "GPBApi.pbobjc.m", + "GPBDuration.pbobjc.m", + "GPBEmpty.pbobjc.m", + "GPBFieldMask.pbobjc.m", + "GPBSourceContext.pbobjc.m", + "GPBStruct.pbobjc.m", + "GPBTimestamp.pbobjc.m", + "GPBType.pbobjc.m", + "GPBWrappers.pbobjc.m", + "GPBArray.m", + "GPBCodedInputStream.m", + "GPBCodedOutputStream.m", + "GPBDescriptor.m", + "GPBDictionary.m", + "GPBExtensionInternals.m", + "GPBExtensionRegistry.m", + "GPBMessage.m", + "GPBRootObject.m", + "GPBUnknownField.m", + "GPBUnknownFieldSet.m", + "GPBUtilities.m", + "GPBWellKnownTypes.m", + "GPBWireFormat.m", + ], + visibility = ["//visibility:public"], +) diff --git a/objectivec/DevTools/compile_testing_protos.sh b/objectivec/DevTools/compile_testing_protos.sh index dc1d6d2e980f..69c32f920bdc 100755 --- a/objectivec/DevTools/compile_testing_protos.sh +++ b/objectivec/DevTools/compile_testing_protos.sh @@ -42,8 +42,6 @@ CORE_PROTO_FILES=( src/google/protobuf/unittest_lite.proto src/google/protobuf/unittest_mset.proto src/google/protobuf/unittest_mset_wire_format.proto - src/google/protobuf/unittest_no_arena.proto - src/google/protobuf/unittest_no_arena_import.proto src/google/protobuf/unittest_no_generic_services.proto src/google/protobuf/unittest_optimize_for.proto src/google/protobuf/unittest.proto @@ -97,7 +95,7 @@ cd "${SRCROOT}/.." # ----------------------------------------------------------------------------- RUN_PROTOC=no -# Check to if all the output files exist (incase a new one got added). +# Check to if all the output files exist (in case a new one got added). for PROTO_FILE in "${CORE_PROTO_FILES[@]}" "${OBJC_TEST_PROTO_FILES[@]}"; do DIR=${PROTO_FILE%/*} @@ -158,6 +156,7 @@ compile_protos() { --objc_out="${OUTPUT_DIR}/google/protobuf" \ --proto_path=src/google/protobuf/ \ --proto_path=src \ + --experimental_allow_proto3_optional \ "$@" } diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh index 5584b0ae44c5..9319b5587176 100755 --- a/objectivec/DevTools/full_mac_build.sh +++ b/objectivec/DevTools/full_mac_build.sh @@ -285,17 +285,14 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit -destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit # 10.x also seems to often fail running destinations in parallel (with - # 32bit one include atleast) + # 32bit one include at least) -disable-concurrent-destination-testing ) ;; - 11.*) + 11.* | 12.*) + # Dropped 32bit as Apple doesn't seem support the simulators either. XCODEBUILD_TEST_BASE_IOS+=( - -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit -destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit - # 10.x also seems to often fail running destinations in parallel (with - # 32bit one include atleast) - -disable-concurrent-destination-testing ) ;; * ) @@ -355,10 +352,8 @@ if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then echo "ERROR: Xcode 10.0 or higher is required to build the test suite." 1>&2 exit 11 ;; - 10.* | 11.* ) + 10.* | 11.* | 12.*) XCODEBUILD_TEST_BASE_TVOS+=( - # Test on the oldest and current. - -destination "platform=tvOS Simulator,name=Apple TV,OS=11.0" -destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest" ) ;; diff --git a/objectivec/DevTools/pddm.py b/objectivec/DevTools/pddm.py index dacf7bba00db..b572cc75b618 100755 --- a/objectivec/DevTools/pddm.py +++ b/objectivec/DevTools/pddm.py @@ -645,7 +645,7 @@ def main(args): opts, extra_args = parser.parse_args(args) if not extra_args: - parser.error('Need atleast one file to process') + parser.error('Need at least one file to process') result = 0 for a_path in extra_args: diff --git a/objectivec/GPBAny.pbobjc.h b/objectivec/GPBAny.pbobjc.h new file mode 100644 index 000000000000..21b7dcf4afb4 --- /dev/null +++ b/objectivec/GPBAny.pbobjc.h @@ -0,0 +1,186 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/any.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBAnyRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBAnyRoot : GPBRootObject +@end + +#pragma mark - GPBAny + +typedef GPB_ENUM(GPBAny_FieldNumber) { + GPBAny_FieldNumber_TypeURL = 1, + GPBAny_FieldNumber_Value = 2, +}; + +/** + * `Any` contains an arbitrary serialized protocol buffer message along with a + * URL that describes the type of the serialized message. + * + * Protobuf library provides support to pack/unpack Any values in the form + * of utility functions or additional generated methods of the Any type. + * + * Example 1: Pack and unpack a message in C++. + * + * Foo foo = ...; + * Any any; + * any.PackFrom(foo); + * ... + * if (any.UnpackTo(&foo)) { + * ... + * } + * + * Example 2: Pack and unpack a message in Java. + * + * Foo foo = ...; + * Any any = Any.pack(foo); + * ... + * if (any.is(Foo.class)) { + * foo = any.unpack(Foo.class); + * } + * + * Example 3: Pack and unpack a message in Python. + * + * foo = Foo(...) + * any = Any() + * any.Pack(foo) + * ... + * if any.Is(Foo.DESCRIPTOR): + * any.Unpack(foo) + * ... + * + * Example 4: Pack and unpack a message in Go + * + * foo := &pb.Foo{...} + * any, err := anypb.New(foo) + * if err != nil { + * ... + * } + * ... + * foo := &pb.Foo{} + * if err := any.UnmarshalTo(foo); err != nil { + * ... + * } + * + * The pack methods provided by protobuf library will by default use + * 'type.googleapis.com/full.type.name' as the type URL and the unpack + * methods only use the fully qualified type name after the last '/' + * in the type URL, for example "foo.bar.com/x/y.z" will yield type + * name "y.z". + * + * + * JSON + * ==== + * The JSON representation of an `Any` value uses the regular + * representation of the deserialized, embedded message, with an + * additional field `\@type` which contains the type URL. Example: + * + * package google.profile; + * message Person { + * string first_name = 1; + * string last_name = 2; + * } + * + * { + * "\@type": "type.googleapis.com/google.profile.Person", + * "firstName": , + * "lastName": + * } + * + * If the embedded message type is well-known and has a custom JSON + * representation, that representation will be embedded adding a field + * `value` which holds the custom JSON in addition to the `\@type` + * field. Example (for message [google.protobuf.Duration][]): + * + * { + * "\@type": "type.googleapis.com/google.protobuf.Duration", + * "value": "1.212s" + * } + **/ +GPB_FINAL @interface GPBAny : GPBMessage + +/** + * A URL/resource name that uniquely identifies the type of the serialized + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent + * the fully qualified name of the type (as in + * `path/google.protobuf.Duration`). The name should be in a canonical form + * (e.g., leading "." is not accepted). + * + * In practice, teams usually precompile into the binary all types that they + * expect it to use in the context of Any. However, for URLs which use the + * scheme `http`, `https`, or no scheme, one can optionally set up a type + * server that maps type URLs to message definitions as follows: + * + * * If no scheme is provided, `https` is assumed. + * * An HTTP GET on the URL must yield a [google.protobuf.Type][] + * value in binary format, or produce an error. + * * Applications are allowed to cache lookup results based on the + * URL, or have them precompiled into a binary to avoid any + * lookup. Therefore, binary compatibility needs to be preserved + * on changes to types. (Use versioned type names to manage + * breaking changes.) + * + * Note: this functionality is not currently available in the official + * protobuf release, and it is not used for type URLs beginning with + * type.googleapis.com. + * + * Schemes other than `http`, `https` (or the empty scheme) might be + * used with implementation specific semantics. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL; + +/** Must be a valid serialized protocol buffer of the above specified type. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *value; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Any.pbobjc.m b/objectivec/GPBAny.pbobjc.m similarity index 88% rename from objectivec/google/protobuf/Any.pbobjc.m rename to objectivec/GPBAny.pbobjc.m index d396e8422a46..a5143f15dc3c 100644 --- a/objectivec/google/protobuf/Any.pbobjc.m +++ b/objectivec/GPBAny.pbobjc.m @@ -8,15 +8,15 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/Any.pbobjc.h" + #import "GPBAny.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -72,7 +72,7 @@ + (GPBDescriptor *)descriptor { .number = GPBAny_FieldNumber_TypeURL, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBAny__storage_, typeURL), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -81,7 +81,7 @@ + (GPBDescriptor *)descriptor { .number = GPBAny_FieldNumber_Value, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBAny__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeBytes, }, }; @@ -92,7 +92,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBAny__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS static const char *extraTextFormatInfo = "\001\001\004\241!!\000"; diff --git a/objectivec/GPBApi.pbobjc.h b/objectivec/GPBApi.pbobjc.h new file mode 100644 index 000000000000..5d55ebf39921 --- /dev/null +++ b/objectivec/GPBApi.pbobjc.h @@ -0,0 +1,311 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/api.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GPBMethod; +@class GPBMixin; +@class GPBOption; +@class GPBSourceContext; +GPB_ENUM_FWD_DECLARE(GPBSyntax); + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBApiRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBApiRoot : GPBRootObject +@end + +#pragma mark - GPBApi + +typedef GPB_ENUM(GPBApi_FieldNumber) { + GPBApi_FieldNumber_Name = 1, + GPBApi_FieldNumber_MethodsArray = 2, + GPBApi_FieldNumber_OptionsArray = 3, + GPBApi_FieldNumber_Version = 4, + GPBApi_FieldNumber_SourceContext = 5, + GPBApi_FieldNumber_MixinsArray = 6, + GPBApi_FieldNumber_Syntax = 7, +}; + +/** + * Api is a light-weight descriptor for an API Interface. + * + * Interfaces are also described as "protocol buffer services" in some contexts, + * such as by the "service" keyword in a .proto file, but they are different + * from API Services, which represent a concrete implementation of an interface + * as opposed to simply a description of methods and bindings. They are also + * sometimes simply referred to as "APIs" in other contexts, such as the name of + * this message itself. See https://cloud.google.com/apis/design/glossary for + * detailed terminology. + **/ +GPB_FINAL @interface GPBApi : GPBMessage + +/** + * The fully qualified name of this interface, including package name + * followed by the interface's simple name. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** The methods of this interface, in unspecified order. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *methodsArray; +/** The number of items in @c methodsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger methodsArray_Count; + +/** Any metadata attached to the interface. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; +/** The number of items in @c optionsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger optionsArray_Count; + +/** + * A version string for this interface. If specified, must have the form + * `major-version.minor-version`, as in `1.10`. If the minor version is + * omitted, it defaults to zero. If the entire version field is empty, the + * major version is derived from the package name, as outlined below. If the + * field is not empty, the version in the package name will be verified to be + * consistent with what is provided here. + * + * The versioning schema uses [semantic + * versioning](http://semver.org) where the major version number + * indicates a breaking change and the minor version an additive, + * non-breaking change. Both version numbers are signals to users + * what to expect from different versions, and should be carefully + * chosen based on the product plan. + * + * The major version is also reflected in the package name of the + * interface, which must end in `v`, as in + * `google.feature.v1`. For major versions 0 and 1, the suffix can + * be omitted. Zero major versions must only be used for + * experimental, non-GA interfaces. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *version; + +/** + * Source context for the protocol buffer service represented by this + * message. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext; +/** Test to see if @c sourceContext has been set. */ +@property(nonatomic, readwrite) BOOL hasSourceContext; + +/** Included interfaces. See [Mixin][]. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *mixinsArray; +/** The number of items in @c mixinsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger mixinsArray_Count; + +/** The source syntax of the service. */ +@property(nonatomic, readwrite) enum GPBSyntax syntax; + +@end + +/** + * Fetches the raw value of a @c GPBApi's @c syntax property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GPBApi_Syntax_RawValue(GPBApi *message); +/** + * Sets the raw value of an @c GPBApi's @c syntax property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value); + +#pragma mark - GPBMethod + +typedef GPB_ENUM(GPBMethod_FieldNumber) { + GPBMethod_FieldNumber_Name = 1, + GPBMethod_FieldNumber_RequestTypeURL = 2, + GPBMethod_FieldNumber_RequestStreaming = 3, + GPBMethod_FieldNumber_ResponseTypeURL = 4, + GPBMethod_FieldNumber_ResponseStreaming = 5, + GPBMethod_FieldNumber_OptionsArray = 6, + GPBMethod_FieldNumber_Syntax = 7, +}; + +/** + * Method represents a method of an API interface. + **/ +GPB_FINAL @interface GPBMethod : GPBMessage + +/** The simple name of this method. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** A URL of the input message type. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *requestTypeURL; + +/** If true, the request is streamed. */ +@property(nonatomic, readwrite) BOOL requestStreaming; + +/** The URL of the output message type. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *responseTypeURL; + +/** If true, the response is streamed. */ +@property(nonatomic, readwrite) BOOL responseStreaming; + +/** Any metadata attached to the method. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; +/** The number of items in @c optionsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger optionsArray_Count; + +/** The source syntax of this method. */ +@property(nonatomic, readwrite) enum GPBSyntax syntax; + +@end + +/** + * Fetches the raw value of a @c GPBMethod's @c syntax property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GPBMethod_Syntax_RawValue(GPBMethod *message); +/** + * Sets the raw value of an @c GPBMethod's @c syntax property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGPBMethod_Syntax_RawValue(GPBMethod *message, int32_t value); + +#pragma mark - GPBMixin + +typedef GPB_ENUM(GPBMixin_FieldNumber) { + GPBMixin_FieldNumber_Name = 1, + GPBMixin_FieldNumber_Root = 2, +}; + +/** + * Declares an API Interface to be included in this interface. The including + * interface must redeclare all the methods from the included interface, but + * documentation and options are inherited as follows: + * + * - If after comment and whitespace stripping, the documentation + * string of the redeclared method is empty, it will be inherited + * from the original method. + * + * - Each annotation belonging to the service config (http, + * visibility) which is not set in the redeclared method will be + * inherited. + * + * - If an http annotation is inherited, the path pattern will be + * modified as follows. Any version prefix will be replaced by the + * version of the including interface plus the [root][] path if + * specified. + * + * Example of a simple mixin: + * + * package google.acl.v1; + * service AccessControl { + * // Get the underlying ACL object. + * rpc GetAcl(GetAclRequest) returns (Acl) { + * option (google.api.http).get = "/v1/{resource=**}:getAcl"; + * } + * } + * + * package google.storage.v2; + * service Storage { + * rpc GetAcl(GetAclRequest) returns (Acl); + * + * // Get a data record. + * rpc GetData(GetDataRequest) returns (Data) { + * option (google.api.http).get = "/v2/{resource=**}"; + * } + * } + * + * Example of a mixin configuration: + * + * apis: + * - name: google.storage.v2.Storage + * mixins: + * - name: google.acl.v1.AccessControl + * + * The mixin construct implies that all methods in `AccessControl` are + * also declared with same name and request/response types in + * `Storage`. A documentation generator or annotation processor will + * see the effective `Storage.GetAcl` method after inheriting + * documentation and annotations as follows: + * + * service Storage { + * // Get the underlying ACL object. + * rpc GetAcl(GetAclRequest) returns (Acl) { + * option (google.api.http).get = "/v2/{resource=**}:getAcl"; + * } + * ... + * } + * + * Note how the version in the path pattern changed from `v1` to `v2`. + * + * If the `root` field in the mixin is specified, it should be a + * relative path under which inherited HTTP paths are placed. Example: + * + * apis: + * - name: google.storage.v2.Storage + * mixins: + * - name: google.acl.v1.AccessControl + * root: acls + * + * This implies the following inherited HTTP annotation: + * + * service Storage { + * // Get the underlying ACL object. + * rpc GetAcl(GetAclRequest) returns (Acl) { + * option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; + * } + * ... + * } + **/ +GPB_FINAL @interface GPBMixin : GPBMessage + +/** The fully qualified name of the interface which is included. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** + * If non-empty specifies a path under which inherited HTTP paths + * are rooted. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *root; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Api.pbobjc.m b/objectivec/GPBApi.pbobjc.m similarity index 86% rename from objectivec/google/protobuf/Api.pbobjc.m rename to objectivec/GPBApi.pbobjc.m index b9d644e6fe7c..5915ce112262 100644 --- a/objectivec/google/protobuf/Api.pbobjc.m +++ b/objectivec/GPBApi.pbobjc.m @@ -8,19 +8,19 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import + #import + #import + #import #else - #import "google/protobuf/Api.pbobjc.h" - #import "google/protobuf/SourceContext.pbobjc.h" - #import "google/protobuf/Type.pbobjc.h" + #import "GPBApi.pbobjc.h" + #import "GPBSourceContext.pbobjc.h" + #import "GPBType.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -96,7 +96,7 @@ + (GPBDescriptor *)descriptor { .number = GPBApi_FieldNumber_Name, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBApi__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -123,7 +123,7 @@ + (GPBDescriptor *)descriptor { .number = GPBApi_FieldNumber_Version, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBApi__storage_, version), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -150,7 +150,7 @@ + (GPBDescriptor *)descriptor { .number = GPBApi_FieldNumber_Syntax, .hasIndex = 3, .offset = (uint32_t)offsetof(GPBApi__storage_, syntax), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeEnum, }, }; @@ -161,7 +161,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBApi__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -175,13 +175,13 @@ + (GPBDescriptor *)descriptor { int32_t GPBApi_Syntax_RawValue(GPBApi *message) { GPBDescriptor *descriptor = [GPBApi descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBApi_FieldNumber_Syntax]; - return GPBGetMessageInt32Field(message, field); + return GPBGetMessageRawEnumField(message, field); } void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value) { GPBDescriptor *descriptor = [GPBApi descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBApi_FieldNumber_Syntax]; - GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); + GPBSetMessageRawEnumField(message, field, value); } #pragma mark - GPBMethod @@ -217,7 +217,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMethod_FieldNumber_Name, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBMethod__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -226,7 +226,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMethod_FieldNumber_RequestTypeURL, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBMethod__storage_, requestTypeURL), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -235,7 +235,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMethod_FieldNumber_RequestStreaming, .hasIndex = 2, .offset = 3, // Stored in _has_storage_ to save space. - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeBool, }, { @@ -244,7 +244,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMethod_FieldNumber_ResponseTypeURL, .hasIndex = 4, .offset = (uint32_t)offsetof(GPBMethod__storage_, responseTypeURL), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -253,7 +253,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMethod_FieldNumber_ResponseStreaming, .hasIndex = 5, .offset = 6, // Stored in _has_storage_ to save space. - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeBool, }, { @@ -271,7 +271,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMethod_FieldNumber_Syntax, .hasIndex = 7, .offset = (uint32_t)offsetof(GPBMethod__storage_, syntax), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeEnum, }, }; @@ -282,7 +282,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBMethod__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS static const char *extraTextFormatInfo = "\002\002\007\244\241!!\000\004\010\244\241!!\000"; @@ -301,13 +301,13 @@ + (GPBDescriptor *)descriptor { int32_t GPBMethod_Syntax_RawValue(GPBMethod *message) { GPBDescriptor *descriptor = [GPBMethod descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBMethod_FieldNumber_Syntax]; - return GPBGetMessageInt32Field(message, field); + return GPBGetMessageRawEnumField(message, field); } void SetGPBMethod_Syntax_RawValue(GPBMethod *message, int32_t value) { GPBDescriptor *descriptor = [GPBMethod descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBMethod_FieldNumber_Syntax]; - GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); + GPBSetMessageRawEnumField(message, field, value); } #pragma mark - GPBMixin @@ -335,7 +335,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMixin_FieldNumber_Name, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBMixin__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -344,7 +344,7 @@ + (GPBDescriptor *)descriptor { .number = GPBMixin_FieldNumber_Root, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBMixin__storage_, root), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, }; @@ -355,7 +355,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBMixin__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBBootstrap.h b/objectivec/GPBBootstrap.h index 198ff9c71d9a..ea5986b8bf1c 100644 --- a/objectivec/GPBBootstrap.h +++ b/objectivec/GPBBootstrap.h @@ -132,7 +132,7 @@ // Current library runtime version. // - Gets bumped when the runtime makes changes to the interfaces between the // generated code and runtime (things added/removed, etc). -#define GOOGLE_PROTOBUF_OBJC_VERSION 30003 +#define GOOGLE_PROTOBUF_OBJC_VERSION 30004 // Minimum runtime version supported for compiling/running against. // - Gets changed when support for the older generated code is dropped. diff --git a/objectivec/GPBDescriptor.m b/objectivec/GPBDescriptor.m index 130f1b96a83f..c29b95539f51 100644 --- a/objectivec/GPBDescriptor.m +++ b/objectivec/GPBDescriptor.m @@ -128,6 +128,8 @@ @implementation GPBDescriptor { (flags & GPBDescriptorInitializationFlag_FieldsWithDefault) != 0; BOOL usesClassRefs = (flags & GPBDescriptorInitializationFlag_UsesClassRefs) != 0; + BOOL proto3OptionalKnown = + (flags & GPBDescriptorInitializationFlag_Proto3OptionalKnown) != 0; void *desc; for (uint32_t i = 0; i < fieldCount; ++i) { @@ -146,6 +148,7 @@ @implementation GPBDescriptor { [[GPBFieldDescriptor alloc] initWithFieldDescription:desc includesDefault:fieldsIncludeDefault usesClassRefs:usesClassRefs + proto3OptionalKnown:proto3OptionalKnown syntax:syntax]; [fields addObject:fieldDescriptor]; [fieldDescriptor release]; @@ -488,6 +491,7 @@ - (instancetype)init { - (instancetype)initWithFieldDescription:(void *)description includesDefault:(BOOL)includesDefault usesClassRefs:(BOOL)usesClassRefs + proto3OptionalKnown:(BOOL)proto3OptionalKnown syntax:(GPBFileSyntax)syntax { if ((self = [super init])) { GPBMessageFieldDescription *coreDesc; @@ -504,20 +508,34 @@ - (instancetype)initWithFieldDescription:(void *)description BOOL isMessage = GPBDataTypeIsMessage(dataType); BOOL isMapOrArray = GPBFieldIsMapOrArray(self); + // If proto3 optionals weren't known (i.e. generated code from an + // older version), compute the flag for the rest of the runtime. + if (!proto3OptionalKnown) { + // If it was... + // - proto3 syntax + // - not repeated/map + // - not in a oneof (negative has index) + // - not a message (the flag doesn't make sense for messages) + BOOL clearOnZero = ((syntax == GPBFileSyntaxProto3) && + !isMapOrArray && + (coreDesc->hasIndex >= 0) && + !isMessage); + if (clearOnZero) { + coreDesc->flags |= GPBFieldClearHasIvarOnZero; + } + } + if (isMapOrArray) { // map<>/repeated fields get a *Count property (inplace of a has*) to // support checking if there are any entries without triggering // autocreation. hasOrCountSel_ = SelFromStrings(NULL, coreDesc->name, "_Count", NO); } else { - // If there is a positive hasIndex, then: - // - All fields types for proto2 messages get has* selectors. - // - Only message fields for proto3 messages get has* selectors. - // Note: the positive check is to handle oneOfs, we can't check - // containingOneof_ because it isn't set until after initialization. + // It is a single field; it gets has/setHas selectors if... + // - not in a oneof (negative has index) + // - not clearing on zero if ((coreDesc->hasIndex >= 0) && - (coreDesc->hasIndex != GPBNoHasBit) && - ((syntax != GPBFileSyntaxProto3) || isMessage)) { + ((coreDesc->flags & GPBFieldClearHasIvarOnZero) == 0)) { hasOrCountSel_ = SelFromStrings("has", coreDesc->name, NULL, NO); setHasSel_ = SelFromStrings("setHas", coreDesc->name, NULL, YES); } @@ -567,15 +585,6 @@ - (instancetype)initWithFieldDescription:(void *)description return self; } -- (instancetype)initWithFieldDescription:(void *)description - includesDefault:(BOOL)includesDefault - syntax:(GPBFileSyntax)syntax { - return [self initWithFieldDescription:description - includesDefault:includesDefault - usesClassRefs:NO - syntax:syntax]; -} - - (void)dealloc { if (description_->dataType == GPBDataTypeBytes && !(description_->flags & GPBFieldRepeated)) { diff --git a/objectivec/GPBDescriptor_PackagePrivate.h b/objectivec/GPBDescriptor_PackagePrivate.h index 09c1202a0747..408f8d4e1014 100644 --- a/objectivec/GPBDescriptor_PackagePrivate.h +++ b/objectivec/GPBDescriptor_PackagePrivate.h @@ -45,6 +45,10 @@ typedef NS_OPTIONS(uint16_t, GPBFieldFlags) { GPBFieldOptional = 1 << 3, GPBFieldHasDefaultValue = 1 << 4, + // Indicate that the field should "clear" when set to zero value. This is the + // proto3 non optional behavior for singular data (ints, data, string, enum) + // fields. + GPBFieldClearHasIvarOnZero = 1 << 5, // Indicates the field needs custom handling for the TextFormat name, if not // set, the name can be derived from the ObjC name. GPBFieldTextFormatNameCustom = 1 << 6, @@ -127,14 +131,29 @@ typedef NS_OPTIONS(uint8_t, GPBExtensionOptions) { typedef struct GPBExtensionDescription { GPBGenericValue defaultValue; const char *singletonName; + // Before 3.12, `extendedClass` was just a `const char *`. Thanks to nested + // initialization (https://en.cppreference.com/w/c/language/struct_initialization#Nested_initialization) + // old generated code with `.extendedClass = GPBStringifySymbol(Something)` + // still works; and the current generator can use `extendedClass.clazz`, to + // pass a Class reference. union { const char *name; Class clazz; } extendedClass; + // Before 3.12, this was `const char *messageOrGroupClassName`. In the + // initial 3.12 release, we moved the `union messageOrGroupClass`, and failed + // to realize that would break existing source code for extensions. So to + // keep existing source code working, we added an unnamed union (C11) to + // provide both the old field name and the new union. This keeps both older + // and newer code working. + // Background: https://github.com/protocolbuffers/protobuf/issues/7555 union { - const char *name; - Class clazz; - } messageOrGroupClass; + const char *messageOrGroupClassName; + union { + const char *name; + Class clazz; + } messageOrGroupClass; + }; GPBEnumDescriptorFunc enumDescriptorFunc; int32_t fieldNumber; GPBDataType dataType; @@ -149,7 +168,13 @@ typedef NS_OPTIONS(uint32_t, GPBDescriptorInitializationFlags) { // This is used as a stopgap as we move from using class names to class // references. The runtime needs to support both until we allow a // breaking change in the runtime. - GPBDescriptorInitializationFlag_UsesClassRefs = 1 << 2, + GPBDescriptorInitializationFlag_UsesClassRefs = 1 << 2, + + // This flag is used to indicate that the generated sources already contain + // the `GPBFieldClearHasIvarOnZero` flag and it doesn't have to be computed + // at startup. This allows older generated code to still work with the + // current runtime library. + GPBDescriptorInitializationFlag_Proto3OptionalKnown = 1 << 3, }; @interface GPBDescriptor () { @@ -225,14 +250,9 @@ typedef NS_OPTIONS(uint32_t, GPBDescriptorInitializationFlags) { - (instancetype)initWithFieldDescription:(void *)description includesDefault:(BOOL)includesDefault usesClassRefs:(BOOL)usesClassRefs + proto3OptionalKnown:(BOOL)proto3OptionalKnown syntax:(GPBFileSyntax)syntax; -// Deprecated. Equivalent to calling above with `usesClassRefs = NO`. -- (instancetype)initWithFieldDescription:(void *)description - includesDefault:(BOOL)includesDefault - syntax:(GPBFileSyntax)syntax; - - @end @interface GPBEnumDescriptor () diff --git a/objectivec/GPBDuration.pbobjc.h b/objectivec/GPBDuration.pbobjc.h new file mode 100644 index 000000000000..88527f520d3c --- /dev/null +++ b/objectivec/GPBDuration.pbobjc.h @@ -0,0 +1,145 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/duration.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBDurationRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBDurationRoot : GPBRootObject +@end + +#pragma mark - GPBDuration + +typedef GPB_ENUM(GPBDuration_FieldNumber) { + GPBDuration_FieldNumber_Seconds = 1, + GPBDuration_FieldNumber_Nanos = 2, +}; + +/** + * A Duration represents a signed, fixed-length span of time represented + * as a count of seconds and fractions of seconds at nanosecond + * resolution. It is independent of any calendar and concepts like "day" + * or "month". It is related to Timestamp in that the difference between + * two Timestamp values is a Duration and it can be added or subtracted + * from a Timestamp. Range is approximately +-10,000 years. + * + * # Examples + * + * Example 1: Compute Duration from two Timestamps in pseudo code. + * + * Timestamp start = ...; + * Timestamp end = ...; + * Duration duration = ...; + * + * duration.seconds = end.seconds - start.seconds; + * duration.nanos = end.nanos - start.nanos; + * + * if (duration.seconds < 0 && duration.nanos > 0) { + * duration.seconds += 1; + * duration.nanos -= 1000000000; + * } else if (duration.seconds > 0 && duration.nanos < 0) { + * duration.seconds -= 1; + * duration.nanos += 1000000000; + * } + * + * Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. + * + * Timestamp start = ...; + * Duration duration = ...; + * Timestamp end = ...; + * + * end.seconds = start.seconds + duration.seconds; + * end.nanos = start.nanos + duration.nanos; + * + * if (end.nanos < 0) { + * end.seconds -= 1; + * end.nanos += 1000000000; + * } else if (end.nanos >= 1000000000) { + * end.seconds += 1; + * end.nanos -= 1000000000; + * } + * + * Example 3: Compute Duration from datetime.timedelta in Python. + * + * td = datetime.timedelta(days=3, minutes=10) + * duration = Duration() + * duration.FromTimedelta(td) + * + * # JSON Mapping + * + * In JSON format, the Duration type is encoded as a string rather than an + * object, where the string ends in the suffix "s" (indicating seconds) and + * is preceded by the number of seconds, with nanoseconds expressed as + * fractional seconds. For example, 3 seconds with 0 nanoseconds should be + * encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should + * be expressed in JSON format as "3.000000001s", and 3 seconds and 1 + * microsecond should be expressed in JSON format as "3.000001s". + **/ +GPB_FINAL @interface GPBDuration : GPBMessage + +/** + * Signed seconds of the span of time. Must be from -315,576,000,000 + * to +315,576,000,000 inclusive. Note: these bounds are computed from: + * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + **/ +@property(nonatomic, readwrite) int64_t seconds; + +/** + * Signed fractions of a second at nanosecond resolution of the span + * of time. Durations less than one second are represented with a 0 + * `seconds` field and a positive or negative `nanos` field. For durations + * of one second or more, a non-zero value for the `nanos` field must be + * of the same sign as the `seconds` field. Must be from -999,999,999 + * to +999,999,999 inclusive. + **/ +@property(nonatomic, readwrite) int32_t nanos; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Duration.pbobjc.m b/objectivec/GPBDuration.pbobjc.m similarity index 86% rename from objectivec/google/protobuf/Duration.pbobjc.m rename to objectivec/GPBDuration.pbobjc.m index 5d1134bdad08..d3cc7e31ca3f 100644 --- a/objectivec/google/protobuf/Duration.pbobjc.m +++ b/objectivec/GPBDuration.pbobjc.m @@ -8,15 +8,15 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/Duration.pbobjc.h" + #import "GPBDuration.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -72,7 +72,7 @@ + (GPBDescriptor *)descriptor { .number = GPBDuration_FieldNumber_Seconds, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBDuration__storage_, seconds), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt64, }, { @@ -81,7 +81,7 @@ + (GPBDescriptor *)descriptor { .number = GPBDuration_FieldNumber_Nanos, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBDuration__storage_, nanos), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt32, }, }; @@ -92,7 +92,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBDuration__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBEmpty.pbobjc.h b/objectivec/GPBEmpty.pbobjc.h new file mode 100644 index 000000000000..45600ead863a --- /dev/null +++ b/objectivec/GPBEmpty.pbobjc.h @@ -0,0 +1,74 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/empty.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBEmptyRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBEmptyRoot : GPBRootObject +@end + +#pragma mark - GPBEmpty + +/** + * A generic empty message that you can re-use to avoid defining duplicated + * empty messages in your APIs. A typical example is to use it as the request + * or the response type of an API method. For instance: + * + * service Foo { + * rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); + * } + * + * The JSON representation for `Empty` is empty JSON object `{}`. + **/ +GPB_FINAL @interface GPBEmpty : GPBMessage + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Empty.pbobjc.m b/objectivec/GPBEmpty.pbobjc.m similarity index 88% rename from objectivec/google/protobuf/Empty.pbobjc.m rename to objectivec/GPBEmpty.pbobjc.m index 9738b0a6b356..df3e398170af 100644 --- a/objectivec/google/protobuf/Empty.pbobjc.m +++ b/objectivec/GPBEmpty.pbobjc.m @@ -8,15 +8,15 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/Empty.pbobjc.h" + #import "GPBEmpty.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -68,7 +68,7 @@ + (GPBDescriptor *)descriptor { fields:NULL fieldCount:0 storageSize:sizeof(GPBEmpty__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBExtensionInternals.m b/objectivec/GPBExtensionInternals.m index 290c82a1bb82..bacec5740a50 100644 --- a/objectivec/GPBExtensionInternals.m +++ b/objectivec/GPBExtensionInternals.m @@ -361,8 +361,8 @@ static id NewSingleValueFromInputStream(GPBExtensionDescriptor *extension, if (existingValue) { message = [existingValue retain]; } else { - GPBDescriptor *decriptor = [extension.msgClass descriptor]; - message = [[decriptor.messageClass alloc] init]; + GPBDescriptor *descriptor = [extension.msgClass descriptor]; + message = [[descriptor.messageClass alloc] init]; } if (description->dataType == GPBDataTypeGroup) { diff --git a/objectivec/GPBFieldMask.pbobjc.h b/objectivec/GPBFieldMask.pbobjc.h new file mode 100644 index 000000000000..3028b775dcd6 --- /dev/null +++ b/objectivec/GPBFieldMask.pbobjc.h @@ -0,0 +1,273 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/field_mask.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBFieldMaskRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBFieldMaskRoot : GPBRootObject +@end + +#pragma mark - GPBFieldMask + +typedef GPB_ENUM(GPBFieldMask_FieldNumber) { + GPBFieldMask_FieldNumber_PathsArray = 1, +}; + +/** + * `FieldMask` represents a set of symbolic field paths, for example: + * + * paths: "f.a" + * paths: "f.b.d" + * + * Here `f` represents a field in some root message, `a` and `b` + * fields in the message found in `f`, and `d` a field found in the + * message in `f.b`. + * + * Field masks are used to specify a subset of fields that should be + * returned by a get operation or modified by an update operation. + * Field masks also have a custom JSON encoding (see below). + * + * # Field Masks in Projections + * + * When used in the context of a projection, a response message or + * sub-message is filtered by the API to only contain those fields as + * specified in the mask. For example, if the mask in the previous + * example is applied to a response message as follows: + * + * f { + * a : 22 + * b { + * d : 1 + * x : 2 + * } + * y : 13 + * } + * z: 8 + * + * The result will not contain specific values for fields x,y and z + * (their value will be set to the default, and omitted in proto text + * output): + * + * + * f { + * a : 22 + * b { + * d : 1 + * } + * } + * + * A repeated field is not allowed except at the last position of a + * paths string. + * + * If a FieldMask object is not present in a get operation, the + * operation applies to all fields (as if a FieldMask of all fields + * had been specified). + * + * Note that a field mask does not necessarily apply to the + * top-level response message. In case of a REST get operation, the + * field mask applies directly to the response, but in case of a REST + * list operation, the mask instead applies to each individual message + * in the returned resource list. In case of a REST custom method, + * other definitions may be used. Where the mask applies will be + * clearly documented together with its declaration in the API. In + * any case, the effect on the returned resource/resources is required + * behavior for APIs. + * + * # Field Masks in Update Operations + * + * A field mask in update operations specifies which fields of the + * targeted resource are going to be updated. The API is required + * to only change the values of the fields as specified in the mask + * and leave the others untouched. If a resource is passed in to + * describe the updated values, the API ignores the values of all + * fields not covered by the mask. + * + * If a repeated field is specified for an update operation, new values will + * be appended to the existing repeated field in the target resource. Note that + * a repeated field is only allowed in the last position of a `paths` string. + * + * If a sub-message is specified in the last position of the field mask for an + * update operation, then new value will be merged into the existing sub-message + * in the target resource. + * + * For example, given the target message: + * + * f { + * b { + * d: 1 + * x: 2 + * } + * c: [1] + * } + * + * And an update message: + * + * f { + * b { + * d: 10 + * } + * c: [2] + * } + * + * then if the field mask is: + * + * paths: ["f.b", "f.c"] + * + * then the result will be: + * + * f { + * b { + * d: 10 + * x: 2 + * } + * c: [1, 2] + * } + * + * An implementation may provide options to override this default behavior for + * repeated and message fields. + * + * In order to reset a field's value to the default, the field must + * be in the mask and set to the default value in the provided resource. + * Hence, in order to reset all fields of a resource, provide a default + * instance of the resource and set all fields in the mask, or do + * not provide a mask as described below. + * + * If a field mask is not present on update, the operation applies to + * all fields (as if a field mask of all fields has been specified). + * Note that in the presence of schema evolution, this may mean that + * fields the client does not know and has therefore not filled into + * the request will be reset to their default. If this is unwanted + * behavior, a specific service may require a client to always specify + * a field mask, producing an error if not. + * + * As with get operations, the location of the resource which + * describes the updated values in the request message depends on the + * operation kind. In any case, the effect of the field mask is + * required to be honored by the API. + * + * ## Considerations for HTTP REST + * + * The HTTP kind of an update operation which uses a field mask must + * be set to PATCH instead of PUT in order to satisfy HTTP semantics + * (PUT must only be used for full updates). + * + * # JSON Encoding of Field Masks + * + * In JSON, a field mask is encoded as a single string where paths are + * separated by a comma. Fields name in each path are converted + * to/from lower-camel naming conventions. + * + * As an example, consider the following message declarations: + * + * message Profile { + * User user = 1; + * Photo photo = 2; + * } + * message User { + * string display_name = 1; + * string address = 2; + * } + * + * In proto a field mask for `Profile` may look as such: + * + * mask { + * paths: "user.display_name" + * paths: "photo" + * } + * + * In JSON, the same mask is represented as below: + * + * { + * mask: "user.displayName,photo" + * } + * + * # Field Masks and Oneof Fields + * + * Field masks treat fields in oneofs just as regular fields. Consider the + * following message: + * + * message SampleMessage { + * oneof test_oneof { + * string name = 4; + * SubMessage sub_message = 9; + * } + * } + * + * The field mask can be: + * + * mask { + * paths: "name" + * } + * + * Or: + * + * mask { + * paths: "sub_message" + * } + * + * Note that oneof type names ("test_oneof" in this case) cannot be used in + * paths. + * + * ## Field Mask Verification + * + * The implementation of any API method which has a FieldMask type field in the + * request should verify the included field paths, and return an + * `INVALID_ARGUMENT` error if any path is unmappable. + **/ +GPB_FINAL @interface GPBFieldMask : GPBMessage + +/** The set of field mask paths. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *pathsArray; +/** The number of items in @c pathsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger pathsArray_Count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.m b/objectivec/GPBFieldMask.pbobjc.m similarity index 90% rename from objectivec/google/protobuf/FieldMask.pbobjc.m rename to objectivec/GPBFieldMask.pbobjc.m index 4d72efbd2c32..3605f89d8057 100644 --- a/objectivec/google/protobuf/FieldMask.pbobjc.m +++ b/objectivec/GPBFieldMask.pbobjc.m @@ -8,15 +8,15 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/FieldMask.pbobjc.h" + #import "GPBFieldMask.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -81,7 +81,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBFieldMask__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index 973c18b42368..20ae9aee989c 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -71,6 +71,8 @@ @interface GPBMessage () { @package GPBUnknownFieldSet *unknownFields_; NSMutableDictionary *extensionMap_; + // Readonly access to autocreatedExtensionMap_ is protected via + // readOnlySemaphore_. NSMutableDictionary *autocreatedExtensionMap_; // If the object was autocreated, we remember the creator so that if we get @@ -79,10 +81,10 @@ @interface GPBMessage () { GPBFieldDescriptor *autocreatorField_; GPBExtensionDescriptor *autocreatorExtension_; - // A lock to provide mutual exclusion from internal data that can be modified - // by *read* operations such as getters (autocreation of message fields and - // message extensions, not setting of values). Used to guarantee thread safety - // for concurrent reads on the message. + // Message can only be mutated from one thread. But some *readonly* operations + // modifify internal state because they autocreate things. The + // autocreatedExtensionMap_ is one such structure. Access during readonly + // operations is protected via this semaphore. // NOTE: OSSpinLock may seem like a good fit here but Apple engineers have // pointed out that they are vulnerable to live locking on iOS in cases of // priority inversion: @@ -99,15 +101,13 @@ static id CreateArrayForField(GPBFieldDescriptor *field, GPBMessage *autocreator) __attribute__((ns_returns_retained)); static id GetOrCreateArrayIvarWithField(GPBMessage *self, - GPBFieldDescriptor *field, - GPBFileSyntax syntax); + GPBFieldDescriptor *field); static id GetArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field); static id CreateMapForField(GPBFieldDescriptor *field, GPBMessage *autocreator) __attribute__((ns_returns_retained)); static id GetOrCreateMapIvarWithField(GPBMessage *self, - GPBFieldDescriptor *field, - GPBFileSyntax syntax); + GPBFieldDescriptor *field); static id GetMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field); static NSMutableDictionary *CloneExtensionMap(NSDictionary *extensionMap, NSZone *zone) @@ -560,10 +560,10 @@ static id CreateMapForField(GPBFieldDescriptor *field, #if !defined(__clang_analyzer__) // These functions are blocked from the analyzer because the analyzer sees the -// GPBSetRetainedObjectIvarWithFieldInternal() call as consuming the array/map, +// GPBSetRetainedObjectIvarWithFieldPrivate() call as consuming the array/map, // so use of the array/map after the call returns is flagged as a use after // free. -// But GPBSetRetainedObjectIvarWithFieldInternal() is "consuming" the retain +// But GPBSetRetainedObjectIvarWithFieldPrivate() is "consuming" the retain // count be holding onto the object (it is transferring it), the object is // still valid after returning from the call. The other way to avoid this // would be to add a -retain/-autorelease, but that would force every @@ -571,14 +571,13 @@ static id CreateMapForField(GPBFieldDescriptor *field, // and performance hit. static id GetOrCreateArrayIvarWithField(GPBMessage *self, - GPBFieldDescriptor *field, - GPBFileSyntax syntax) { + GPBFieldDescriptor *field) { id array = GPBGetObjectIvarWithFieldNoAutocreate(self, field); if (!array) { // No lock needed, this is called from places expecting to mutate // so no threading protection is needed. array = CreateArrayForField(field, nil); - GPBSetRetainedObjectIvarWithFieldInternal(self, field, array, syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, array); } return array; } @@ -586,30 +585,40 @@ static id GetOrCreateArrayIvarWithField(GPBMessage *self, // This is like GPBGetObjectIvarWithField(), but for arrays, it should // only be used to wire the method into the class. static id GetArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { - id array = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!array) { - // Check again after getting the lock. - GPBPrepareReadOnlySemaphore(self); - dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); - array = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!array) { - array = CreateArrayForField(field, self); - GPBSetAutocreatedRetainedObjectIvarWithField(self, field, array); - } - dispatch_semaphore_signal(self->readOnlySemaphore_); + uint8_t *storage = (uint8_t *)self->messageStorage_; + _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset]; + id array = atomic_load(typePtr); + if (array) { + return array; } - return array; + + id expected = nil; + id autocreated = CreateArrayForField(field, self); + if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) { + // Value was set, return it. + return autocreated; + } + + // Some other thread set it, release the one created and return what got set. + if (GPBFieldDataTypeIsObject(field)) { + GPBAutocreatedArray *autoArray = autocreated; + autoArray->_autocreator = nil; + } else { + GPBInt32Array *gpbArray = autocreated; + gpbArray->_autocreator = nil; + } + [autocreated release]; + return expected; } static id GetOrCreateMapIvarWithField(GPBMessage *self, - GPBFieldDescriptor *field, - GPBFileSyntax syntax) { + GPBFieldDescriptor *field) { id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field); if (!dict) { // No lock needed, this is called from places expecting to mutate // so no threading protection is needed. dict = CreateMapForField(field, nil); - GPBSetRetainedObjectIvarWithFieldInternal(self, field, dict, syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, dict); } return dict; } @@ -617,19 +626,31 @@ static id GetOrCreateMapIvarWithField(GPBMessage *self, // This is like GPBGetObjectIvarWithField(), but for maps, it should // only be used to wire the method into the class. static id GetMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { - id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!dict) { - // Check again after getting the lock. - GPBPrepareReadOnlySemaphore(self); - dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); - dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!dict) { - dict = CreateMapForField(field, self); - GPBSetAutocreatedRetainedObjectIvarWithField(self, field, dict); - } - dispatch_semaphore_signal(self->readOnlySemaphore_); + uint8_t *storage = (uint8_t *)self->messageStorage_; + _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset]; + id dict = atomic_load(typePtr); + if (dict) { + return dict; } - return dict; + + id expected = nil; + id autocreated = CreateMapForField(field, self); + if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) { + // Value was set, return it. + return autocreated; + } + + // Some other thread set it, release the one created and return what got set. + if ((field.mapKeyDataType == GPBDataTypeString) && + GPBFieldDataTypeIsObject(field)) { + GPBAutocreatedDictionary *autoDict = autocreated; + autoDict->_autocreator = nil; + } else { + GPBInt32Int32Dictionary *gpbDict = autocreated; + gpbDict->_autocreator = nil; + } + [autocreated release]; + return expected; } #endif // !defined(__clang_analyzer__) @@ -668,9 +689,8 @@ void GPBBecomeVisibleToAutocreator(GPBMessage *self) { // This will recursively make all parent messages visible until it reaches a // super-creator that's visible. if (self->autocreatorField_) { - GPBFileSyntax syntax = [self->autocreator_ descriptor].file.syntax; - GPBSetObjectIvarWithFieldInternal(self->autocreator_, - self->autocreatorField_, self, syntax); + GPBSetObjectIvarWithFieldPrivate(self->autocreator_, + self->autocreatorField_, self); } else { [self->autocreator_ setExtension:self->autocreatorExtension_ value:self]; } @@ -936,8 +956,6 @@ - (void)copyFieldsInto:(GPBMessage *)message // Copy all the storage... memcpy(message->messageStorage_, messageStorage_, descriptor->storageSize_); - GPBFileSyntax syntax = descriptor.file.syntax; - // Loop over the fields doing fixup... for (GPBFieldDescriptor *field in descriptor->fields_) { if (GPBFieldIsMapOrArray(field)) { @@ -1005,8 +1023,7 @@ - (void)copyFieldsInto:(GPBMessage *)message // We retain here because the memcpy picked up the pointer value and // the next call to SetRetainedObject... will release the current value. [value retain]; - GPBSetRetainedObjectIvarWithFieldInternal(message, field, newValue, - syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(message, field, newValue); } } else if (GPBFieldDataTypeIsMessage(field)) { // For object types, if we have a value, copy it. If we don't, @@ -1018,8 +1035,7 @@ - (void)copyFieldsInto:(GPBMessage *)message // We retain here because the memcpy picked up the pointer value and // the next call to SetRetainedObject... will release the current value. [value retain]; - GPBSetRetainedObjectIvarWithFieldInternal(message, field, newValue, - syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(message, field, newValue); } else { uint8_t *storage = (uint8_t *)message->messageStorage_; id *typePtr = (id *)&storage[field->description_->offset]; @@ -1033,8 +1049,7 @@ - (void)copyFieldsInto:(GPBMessage *)message // We retain here because the memcpy picked up the pointer value and // the next call to SetRetainedObject... will release the current value. [value retain]; - GPBSetRetainedObjectIvarWithFieldInternal(message, field, newValue, - syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(message, field, newValue); } else { // memcpy took care of the rest of the primitive fields if they were set. } @@ -2161,13 +2176,13 @@ static void MergeSingleFieldFromCodedInputStream( #define CASE_SINGLE_POD(NAME, TYPE, FUNC_TYPE) \ case GPBDataType##NAME: { \ TYPE val = GPBCodedInputStreamRead##NAME(&input->state_); \ - GPBSet##FUNC_TYPE##IvarWithFieldInternal(self, field, val, syntax); \ + GPBSet##FUNC_TYPE##IvarWithFieldPrivate(self, field, val); \ break; \ } #define CASE_SINGLE_OBJECT(NAME) \ case GPBDataType##NAME: { \ id val = GPBCodedInputStreamReadRetained##NAME(&input->state_); \ - GPBSetRetainedObjectIvarWithFieldInternal(self, field, val, syntax); \ + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, val); \ break; \ } CASE_SINGLE_POD(Bool, BOOL, Bool) @@ -2198,7 +2213,7 @@ static void MergeSingleFieldFromCodedInputStream( } else { GPBMessage *message = [[field.msgClass alloc] init]; [input readMessage:message extensionRegistry:extensionRegistry]; - GPBSetRetainedObjectIvarWithFieldInternal(self, field, message, syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message); } break; } @@ -2217,7 +2232,7 @@ static void MergeSingleFieldFromCodedInputStream( [input readGroup:GPBFieldNumber(field) message:message extensionRegistry:extensionRegistry]; - GPBSetRetainedObjectIvarWithFieldInternal(self, field, message, syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message); } break; } @@ -2226,7 +2241,7 @@ static void MergeSingleFieldFromCodedInputStream( int32_t val = GPBCodedInputStreamReadEnum(&input->state_); if (GPBHasPreservingUnknownEnumSemantics(syntax) || [field isValidEnumValue:val]) { - GPBSetInt32IvarWithFieldInternal(self, field, val, syntax); + GPBSetInt32IvarWithFieldPrivate(self, field, val); } else { GPBUnknownFieldSet *unknownFields = GetOrMakeUnknownFields(self); [unknownFields mergeVarintField:GPBFieldNumber(field) value:val]; @@ -2240,7 +2255,7 @@ static void MergeRepeatedPackedFieldFromCodedInputStream( GPBCodedInputStream *input) { GPBDataType fieldDataType = GPBGetFieldDataType(field); GPBCodedInputStreamState *state = &input->state_; - id genericArray = GetOrCreateArrayIvarWithField(self, field, syntax); + id genericArray = GetOrCreateArrayIvarWithField(self, field); int32_t length = GPBCodedInputStreamReadInt32(state); size_t limit = GPBCodedInputStreamPushLimit(state, length); while (GPBCodedInputStreamBytesUntilLimit(state) > 0) { @@ -2293,7 +2308,7 @@ static void MergeRepeatedNotPackedFieldFromCodedInputStream( GPBMessage *self, GPBFieldDescriptor *field, GPBFileSyntax syntax, GPBCodedInputStream *input, GPBExtensionRegistry *extensionRegistry) { GPBCodedInputStreamState *state = &input->state_; - id genericArray = GetOrCreateArrayIvarWithField(self, field, syntax); + id genericArray = GetOrCreateArrayIvarWithField(self, field); switch (GPBGetFieldDataType(field)) { #define CASE_REPEATED_NOT_PACKED_POD(NAME, TYPE, ARRAY_TYPE) \ case GPBDataType##NAME: { \ @@ -2395,7 +2410,7 @@ - (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input } else { // fieldType == GPBFieldTypeMap // GPB*Dictionary or NSDictionary, exact type doesn't matter at this // point. - id map = GetOrCreateMapIvarWithField(self, fieldDescriptor, syntax); + id map = GetOrCreateMapIvarWithField(self, fieldDescriptor); [input readMapEntry:map extensionRegistry:extensionRegistry field:fieldDescriptor @@ -2469,7 +2484,6 @@ - (void)mergeFrom:(GPBMessage *)other { GPBBecomeVisibleToAutocreator(self); GPBDescriptor *descriptor = [[self class] descriptor]; - GPBFileSyntax syntax = descriptor.file.syntax; for (GPBFieldDescriptor *field in descriptor->fields_) { GPBFieldType fieldType = field.fieldType; @@ -2483,44 +2497,44 @@ - (void)mergeFrom:(GPBMessage *)other { GPBDataType fieldDataType = GPBGetFieldDataType(field); switch (fieldDataType) { case GPBDataTypeBool: - GPBSetBoolIvarWithFieldInternal( - self, field, GPBGetMessageBoolField(other, field), syntax); + GPBSetBoolIvarWithFieldPrivate( + self, field, GPBGetMessageBoolField(other, field)); break; case GPBDataTypeSFixed32: case GPBDataTypeEnum: case GPBDataTypeInt32: case GPBDataTypeSInt32: - GPBSetInt32IvarWithFieldInternal( - self, field, GPBGetMessageInt32Field(other, field), syntax); + GPBSetInt32IvarWithFieldPrivate( + self, field, GPBGetMessageInt32Field(other, field)); break; case GPBDataTypeFixed32: case GPBDataTypeUInt32: - GPBSetUInt32IvarWithFieldInternal( - self, field, GPBGetMessageUInt32Field(other, field), syntax); + GPBSetUInt32IvarWithFieldPrivate( + self, field, GPBGetMessageUInt32Field(other, field)); break; case GPBDataTypeSFixed64: case GPBDataTypeInt64: case GPBDataTypeSInt64: - GPBSetInt64IvarWithFieldInternal( - self, field, GPBGetMessageInt64Field(other, field), syntax); + GPBSetInt64IvarWithFieldPrivate( + self, field, GPBGetMessageInt64Field(other, field)); break; case GPBDataTypeFixed64: case GPBDataTypeUInt64: - GPBSetUInt64IvarWithFieldInternal( - self, field, GPBGetMessageUInt64Field(other, field), syntax); + GPBSetUInt64IvarWithFieldPrivate( + self, field, GPBGetMessageUInt64Field(other, field)); break; case GPBDataTypeFloat: - GPBSetFloatIvarWithFieldInternal( - self, field, GPBGetMessageFloatField(other, field), syntax); + GPBSetFloatIvarWithFieldPrivate( + self, field, GPBGetMessageFloatField(other, field)); break; case GPBDataTypeDouble: - GPBSetDoubleIvarWithFieldInternal( - self, field, GPBGetMessageDoubleField(other, field), syntax); + GPBSetDoubleIvarWithFieldPrivate( + self, field, GPBGetMessageDoubleField(other, field)); break; case GPBDataTypeBytes: case GPBDataTypeString: { id otherVal = GPBGetObjectIvarWithFieldNoAutocreate(other, field); - GPBSetObjectIvarWithFieldInternal(self, field, otherVal, syntax); + GPBSetObjectIvarWithFieldPrivate(self, field, otherVal); break; } case GPBDataTypeMessage: @@ -2532,8 +2546,7 @@ - (void)mergeFrom:(GPBMessage *)other { [message mergeFrom:otherVal]; } else { GPBMessage *message = [otherVal copy]; - GPBSetRetainedObjectIvarWithFieldInternal(self, field, message, - syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, message); } break; } @@ -2547,17 +2560,17 @@ - (void)mergeFrom:(GPBMessage *)other { GPBDataType fieldDataType = field->description_->dataType; if (GPBDataTypeIsObject(fieldDataType)) { NSMutableArray *resultArray = - GetOrCreateArrayIvarWithField(self, field, syntax); + GetOrCreateArrayIvarWithField(self, field); [resultArray addObjectsFromArray:otherArray]; } else if (fieldDataType == GPBDataTypeEnum) { GPBEnumArray *resultArray = - GetOrCreateArrayIvarWithField(self, field, syntax); + GetOrCreateArrayIvarWithField(self, field); [resultArray addRawValuesFromArray:otherArray]; } else { // The array type doesn't matter, that all implement // -addValuesFromArray:. GPBInt32Array *resultArray = - GetOrCreateArrayIvarWithField(self, field, syntax); + GetOrCreateArrayIvarWithField(self, field); [resultArray addValuesFromArray:otherArray]; } } @@ -2571,19 +2584,19 @@ - (void)mergeFrom:(GPBMessage *)other { if (GPBDataTypeIsObject(keyDataType) && GPBDataTypeIsObject(valueDataType)) { NSMutableDictionary *resultDict = - GetOrCreateMapIvarWithField(self, field, syntax); + GetOrCreateMapIvarWithField(self, field); [resultDict addEntriesFromDictionary:otherDict]; } else if (valueDataType == GPBDataTypeEnum) { // The exact type doesn't matter, just need to know it is a // GPB*EnumDictionary. GPBInt32EnumDictionary *resultDict = - GetOrCreateMapIvarWithField(self, field, syntax); + GetOrCreateMapIvarWithField(self, field); [resultDict addRawEntriesFromDictionary:otherDict]; } else { // The exact type doesn't matter, they all implement // -addEntriesFromDictionary:. GPBInt32Int32Dictionary *resultDict = - GetOrCreateMapIvarWithField(self, field, syntax); + GetOrCreateMapIvarWithField(self, field); [resultDict addEntriesFromDictionary:otherDict]; } } @@ -3115,14 +3128,13 @@ static void ResolveIvarGet(__unsafe_unretained GPBFieldDescriptor *field, // See comment about __unsafe_unretained on ResolveIvarGet. static void ResolveIvarSet(__unsafe_unretained GPBFieldDescriptor *field, - GPBFileSyntax syntax, ResolveIvarAccessorMethodResult *result) { GPBDataType fieldDataType = GPBGetFieldDataType(field); switch (fieldDataType) { #define CASE_SET(NAME, TYPE, TRUE_NAME) \ case GPBDataType##NAME: { \ result->impToAdd = imp_implementationWithBlock(^(id obj, TYPE value) { \ - return GPBSet##TRUE_NAME##IvarWithFieldInternal(obj, field, value, syntax); \ + return GPBSet##TRUE_NAME##IvarWithFieldPrivate(obj, field, value); \ }); \ result->encodingSelector = @selector(set##NAME:); \ break; \ @@ -3130,7 +3142,7 @@ static void ResolveIvarSet(__unsafe_unretained GPBFieldDescriptor *field, #define CASE_SET_COPY(NAME) \ case GPBDataType##NAME: { \ result->impToAdd = imp_implementationWithBlock(^(id obj, id value) { \ - return GPBSetRetainedObjectIvarWithFieldInternal(obj, field, [value copy], syntax); \ + return GPBSetRetainedObjectIvarWithFieldPrivate(obj, field, [value copy]); \ }); \ result->encodingSelector = @selector(set##NAME:); \ break; \ @@ -3177,7 +3189,7 @@ + (BOOL)resolveInstanceMethod:(SEL)sel { ResolveIvarGet(field, &result); break; } else if (sel == field->setSel_) { - ResolveIvarSet(field, descriptor.file.syntax, &result); + ResolveIvarSet(field, &result); break; } else if (sel == field->hasOrCountSel_) { int32_t index = GPBFieldHasIndex(field); @@ -3227,9 +3239,8 @@ + (BOOL)resolveInstanceMethod:(SEL)sel { } else if (sel == field->setSel_) { // Local for syntax so the block can directly capture it and not the // full lookup. - const GPBFileSyntax syntax = descriptor.file.syntax; result.impToAdd = imp_implementationWithBlock(^(id obj, id value) { - GPBSetObjectIvarWithFieldInternal(obj, field, value, syntax); + GPBSetObjectIvarWithFieldPrivate(obj, field, value); }); result.encodingSelector = @selector(setArray:); break; @@ -3267,7 +3278,7 @@ + (BOOL)resolveInstanceMethod:(SEL)sel { + (BOOL)resolveClassMethod:(SEL)sel { // Extensions scoped to a Message and looked up via class methods. - if (GPBResolveExtensionClassMethod([self descriptor].messageClass, sel)) { + if (GPBResolveExtensionClassMethod(self, sel)) { return YES; } return [super resolveClassMethod:sel]; @@ -3300,7 +3311,7 @@ - (void)encodeWithCoder:(NSCoder *)aCoder { // if a sub message in a field has extensions, the issue still exists. A // recursive check could be done here (like the work in // GPBMessageDropUnknownFieldsRecursively()), but that has the potential to - // be expensive and could slow down serialization in DEBUG enought to cause + // be expensive and could slow down serialization in DEBUG enough to cause // developers other problems. NSLog(@"Warning: writing out a GPBMessage (%@) via NSCoding and it" @" has %ld extensions; when read back in, those fields will be" @@ -3334,9 +3345,7 @@ id GPBGetMessageRepeatedField(GPBMessage *self, GPBFieldDescriptor *field) { [self class], field.name]; } #endif - GPBDescriptor *descriptor = [[self class] descriptor]; - GPBFileSyntax syntax = descriptor.file.syntax; - return GetOrCreateArrayIvarWithField(self, field, syntax); + return GetOrCreateArrayIvarWithField(self, field); } // Only exists for public api, no core code should use this. @@ -3348,37 +3357,39 @@ id GPBGetMessageMapField(GPBMessage *self, GPBFieldDescriptor *field) { [self class], field.name]; } #endif - GPBDescriptor *descriptor = [[self class] descriptor]; - GPBFileSyntax syntax = descriptor.file.syntax; - return GetOrCreateMapIvarWithField(self, field, syntax); + return GetOrCreateMapIvarWithField(self, field); } id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { NSCAssert(!GPBFieldIsMapOrArray(field), @"Shouldn't get here"); - if (GPBGetHasIvarField(self, field)) { - uint8_t *storage = (uint8_t *)self->messageStorage_; - id *typePtr = (id *)&storage[field->description_->offset]; - return *typePtr; - } - // Not set... - - // Non messages (string/data), get their default. if (!GPBFieldDataTypeIsMessage(field)) { + if (GPBGetHasIvarField(self, field)) { + uint8_t *storage = (uint8_t *)self->messageStorage_; + id *typePtr = (id *)&storage[field->description_->offset]; + return *typePtr; + } + // Not set...non messages (string/data), get their default. return field.defaultValue.valueMessage; } - GPBPrepareReadOnlySemaphore(self); - dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); - GPBMessage *result = GPBGetObjectIvarWithFieldNoAutocreate(self, field); - if (!result) { - // For non repeated messages, create the object, set it and return it. - // This object will not initially be visible via GPBGetHasIvar, so - // we save its creator so it can become visible if it's mutated later. - result = GPBCreateMessageWithAutocreator(field.msgClass, self, field); - GPBSetAutocreatedRetainedObjectIvarWithField(self, field, result); - } - dispatch_semaphore_signal(self->readOnlySemaphore_); - return result; + uint8_t *storage = (uint8_t *)self->messageStorage_; + _Atomic(id) *typePtr = (_Atomic(id) *)&storage[field->description_->offset]; + id msg = atomic_load(typePtr); + if (msg) { + return msg; + } + + id expected = nil; + id autocreated = GPBCreateMessageWithAutocreator(field.msgClass, self, field); + if (atomic_compare_exchange_strong(typePtr, &expected, autocreated)) { + // Value was set, return it. + return autocreated; + } + + // Some other thread set it, release the one created and return what got set. + GPBClearMessageAutocreator(autocreated); + [autocreated release]; + return expected; } #pragma clang diagnostic pop diff --git a/objectivec/GPBProtocolBuffers.h b/objectivec/GPBProtocolBuffers.h index 32f9f5de221c..c5df91639698 100644 --- a/objectivec/GPBProtocolBuffers.h +++ b/objectivec/GPBProtocolBuffers.h @@ -52,25 +52,25 @@ // Well-known proto types #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import - #import - #import - #import - #import - #import - #import - #import + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import #else - #import "google/protobuf/Any.pbobjc.h" - #import "google/protobuf/Api.pbobjc.h" - #import "google/protobuf/Duration.pbobjc.h" - #import "google/protobuf/Empty.pbobjc.h" - #import "google/protobuf/FieldMask.pbobjc.h" - #import "google/protobuf/SourceContext.pbobjc.h" - #import "google/protobuf/Struct.pbobjc.h" - #import "google/protobuf/Timestamp.pbobjc.h" - #import "google/protobuf/Type.pbobjc.h" - #import "google/protobuf/Wrappers.pbobjc.h" + #import "GPBAny.pbobjc.h" + #import "GPBApi.pbobjc.h" + #import "GPBDuration.pbobjc.h" + #import "GPBEmpty.pbobjc.h" + #import "GPBFieldMask.pbobjc.h" + #import "GPBSourceContext.pbobjc.h" + #import "GPBStruct.pbobjc.h" + #import "GPBTimestamp.pbobjc.h" + #import "GPBType.pbobjc.h" + #import "GPBWrappers.pbobjc.h" #endif diff --git a/objectivec/GPBProtocolBuffers.m b/objectivec/GPBProtocolBuffers.m index d04c8be155ff..0545ae9b2b63 100644 --- a/objectivec/GPBProtocolBuffers.m +++ b/objectivec/GPBProtocolBuffers.m @@ -54,13 +54,13 @@ #import "GPBWellKnownTypes.m" #import "GPBWireFormat.m" -#import "google/protobuf/Any.pbobjc.m" -#import "google/protobuf/Api.pbobjc.m" -#import "google/protobuf/Duration.pbobjc.m" -#import "google/protobuf/Empty.pbobjc.m" -#import "google/protobuf/FieldMask.pbobjc.m" -#import "google/protobuf/SourceContext.pbobjc.m" -#import "google/protobuf/Struct.pbobjc.m" -#import "google/protobuf/Timestamp.pbobjc.m" -#import "google/protobuf/Type.pbobjc.m" -#import "google/protobuf/Wrappers.pbobjc.m" +#import "GPBAny.pbobjc.m" +#import "GPBApi.pbobjc.m" +#import "GPBDuration.pbobjc.m" +#import "GPBEmpty.pbobjc.m" +#import "GPBFieldMask.pbobjc.m" +#import "GPBSourceContext.pbobjc.m" +#import "GPBStruct.pbobjc.m" +#import "GPBTimestamp.pbobjc.m" +#import "GPBType.pbobjc.m" +#import "GPBWrappers.pbobjc.m" diff --git a/objectivec/GPBSourceContext.pbobjc.h b/objectivec/GPBSourceContext.pbobjc.h new file mode 100644 index 000000000000..7a103362b565 --- /dev/null +++ b/objectivec/GPBSourceContext.pbobjc.h @@ -0,0 +1,77 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/source_context.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBSourceContextRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBSourceContextRoot : GPBRootObject +@end + +#pragma mark - GPBSourceContext + +typedef GPB_ENUM(GPBSourceContext_FieldNumber) { + GPBSourceContext_FieldNumber_FileName = 1, +}; + +/** + * `SourceContext` represents information about the source of a + * protobuf element, like the file in which it is defined. + **/ +GPB_FINAL @interface GPBSourceContext : GPBMessage + +/** + * The path-qualified name of the .proto file that contained the associated + * protobuf element. For example: `"google/protobuf/source_context.proto"`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *fileName; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.m b/objectivec/GPBSourceContext.pbobjc.m similarity index 87% rename from objectivec/google/protobuf/SourceContext.pbobjc.m rename to objectivec/GPBSourceContext.pbobjc.m index d425cc85b3be..b3e6fa759ce4 100644 --- a/objectivec/google/protobuf/SourceContext.pbobjc.m +++ b/objectivec/GPBSourceContext.pbobjc.m @@ -8,15 +8,15 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/SourceContext.pbobjc.h" + #import "GPBSourceContext.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -70,7 +70,7 @@ + (GPBDescriptor *)descriptor { .number = GPBSourceContext_FieldNumber_FileName, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBSourceContext__storage_, fileName), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, }; @@ -81,7 +81,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBSourceContext__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBStruct.pbobjc.h b/objectivec/GPBStruct.pbobjc.h new file mode 100644 index 000000000000..e36df3f1a3a1 --- /dev/null +++ b/objectivec/GPBStruct.pbobjc.h @@ -0,0 +1,204 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/struct.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GPBListValue; +@class GPBStruct; +@class GPBValue; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GPBNullValue + +/** + * `NullValue` is a singleton enumeration to represent the null value for the + * `Value` type union. + * + * The JSON representation for `NullValue` is JSON `null`. + **/ +typedef GPB_ENUM(GPBNullValue) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GPBNullValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Null value. */ + GPBNullValue_NullValue = 0, +}; + +GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GPBNullValue_IsValidValue(int32_t value); + +#pragma mark - GPBStructRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBStructRoot : GPBRootObject +@end + +#pragma mark - GPBStruct + +typedef GPB_ENUM(GPBStruct_FieldNumber) { + GPBStruct_FieldNumber_Fields = 1, +}; + +/** + * `Struct` represents a structured data value, consisting of fields + * which map to dynamically typed values. In some languages, `Struct` + * might be supported by a native representation. For example, in + * scripting languages like JS a struct is represented as an + * object. The details of that representation are described together + * with the proto support for the language. + * + * The JSON representation for `Struct` is JSON object. + **/ +GPB_FINAL @interface GPBStruct : GPBMessage + +/** Unordered map of dynamically typed values. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *fields; +/** The number of items in @c fields without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fields_Count; + +@end + +#pragma mark - GPBValue + +typedef GPB_ENUM(GPBValue_FieldNumber) { + GPBValue_FieldNumber_NullValue = 1, + GPBValue_FieldNumber_NumberValue = 2, + GPBValue_FieldNumber_StringValue = 3, + GPBValue_FieldNumber_BoolValue = 4, + GPBValue_FieldNumber_StructValue = 5, + GPBValue_FieldNumber_ListValue = 6, +}; + +typedef GPB_ENUM(GPBValue_Kind_OneOfCase) { + GPBValue_Kind_OneOfCase_GPBUnsetOneOfCase = 0, + GPBValue_Kind_OneOfCase_NullValue = 1, + GPBValue_Kind_OneOfCase_NumberValue = 2, + GPBValue_Kind_OneOfCase_StringValue = 3, + GPBValue_Kind_OneOfCase_BoolValue = 4, + GPBValue_Kind_OneOfCase_StructValue = 5, + GPBValue_Kind_OneOfCase_ListValue = 6, +}; + +/** + * `Value` represents a dynamically typed value which can be either + * null, a number, a string, a boolean, a recursive struct value, or a + * list of values. A producer of value is expected to set one of that + * variants, absence of any variant indicates an error. + * + * The JSON representation for `Value` is JSON value. + **/ +GPB_FINAL @interface GPBValue : GPBMessage + +/** The kind of value. */ +@property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase; + +/** Represents a null value. */ +@property(nonatomic, readwrite) GPBNullValue nullValue; + +/** Represents a double value. */ +@property(nonatomic, readwrite) double numberValue; + +/** Represents a string value. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue; + +/** Represents a boolean value. */ +@property(nonatomic, readwrite) BOOL boolValue; + +/** Represents a structured value. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBStruct *structValue; + +/** Represents a repeated `Value`. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBListValue *listValue; + +@end + +/** + * Fetches the raw value of a @c GPBValue's @c nullValue property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GPBValue_NullValue_RawValue(GPBValue *message); +/** + * Sets the raw value of an @c GPBValue's @c nullValue property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value); + +/** + * Clears whatever value was set for the oneof 'kind'. + **/ +void GPBValue_ClearKindOneOfCase(GPBValue *message); + +#pragma mark - GPBListValue + +typedef GPB_ENUM(GPBListValue_FieldNumber) { + GPBListValue_FieldNumber_ValuesArray = 1, +}; + +/** + * `ListValue` is a wrapper around a repeated field of values. + * + * The JSON representation for `ListValue` is JSON array. + **/ +GPB_FINAL @interface GPBListValue : GPBMessage + +/** Repeated field of dynamically typed values. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *valuesArray; +/** The number of items in @c valuesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger valuesArray_Count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Struct.pbobjc.m b/objectivec/GPBStruct.pbobjc.m similarity index 91% rename from objectivec/google/protobuf/Struct.pbobjc.m rename to objectivec/GPBStruct.pbobjc.m index d36be9c2950c..554046a9fe50 100644 --- a/objectivec/google/protobuf/Struct.pbobjc.m +++ b/objectivec/GPBStruct.pbobjc.m @@ -8,7 +8,7 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif @@ -16,9 +16,9 @@ #import #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/Struct.pbobjc.h" + #import "GPBStruct.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -126,7 +126,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBStruct__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -226,7 +226,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; static const char *oneofs[] = { "kind", }; @@ -246,19 +246,19 @@ + (GPBDescriptor *)descriptor { int32_t GPBValue_NullValue_RawValue(GPBValue *message) { GPBDescriptor *descriptor = [GPBValue descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBValue_FieldNumber_NullValue]; - return GPBGetMessageInt32Field(message, field); + return GPBGetMessageRawEnumField(message, field); } void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value) { GPBDescriptor *descriptor = [GPBValue descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBValue_FieldNumber_NullValue]; - GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); + GPBSetMessageRawEnumField(message, field, value); } void GPBValue_ClearKindOneOfCase(GPBValue *message) { - GPBDescriptor *descriptor = [message descriptor]; + GPBDescriptor *descriptor = [GPBValue descriptor]; GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; - GPBMaybeClearOneof(message, oneof, -1, 0); + GPBClearOneof(message, oneof); } #pragma mark - GPBListValue @@ -294,7 +294,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBListValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBTimestamp.pbobjc.h b/objectivec/GPBTimestamp.pbobjc.h new file mode 100644 index 000000000000..a328afc7c93d --- /dev/null +++ b/objectivec/GPBTimestamp.pbobjc.h @@ -0,0 +1,176 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/timestamp.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBTimestampRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBTimestampRoot : GPBRootObject +@end + +#pragma mark - GPBTimestamp + +typedef GPB_ENUM(GPBTimestamp_FieldNumber) { + GPBTimestamp_FieldNumber_Seconds = 1, + GPBTimestamp_FieldNumber_Nanos = 2, +}; + +/** + * A Timestamp represents a point in time independent of any time zone or local + * calendar, encoded as a count of seconds and fractions of seconds at + * nanosecond resolution. The count is relative to an epoch at UTC midnight on + * January 1, 1970, in the proleptic Gregorian calendar which extends the + * Gregorian calendar backwards to year one. + * + * All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + * second table is needed for interpretation, using a [24-hour linear + * smear](https://developers.google.com/time/smear). + * + * The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By + * restricting to that range, we ensure that we can convert to and from [RFC + * 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. + * + * # Examples + * + * Example 1: Compute Timestamp from POSIX `time()`. + * + * Timestamp timestamp; + * timestamp.set_seconds(time(NULL)); + * timestamp.set_nanos(0); + * + * Example 2: Compute Timestamp from POSIX `gettimeofday()`. + * + * struct timeval tv; + * gettimeofday(&tv, NULL); + * + * Timestamp timestamp; + * timestamp.set_seconds(tv.tv_sec); + * timestamp.set_nanos(tv.tv_usec * 1000); + * + * Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. + * + * FILETIME ft; + * GetSystemTimeAsFileTime(&ft); + * UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + * + * // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z + * // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. + * Timestamp timestamp; + * timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); + * timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); + * + * Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. + * + * long millis = System.currentTimeMillis(); + * + * Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) + * .setNanos((int) ((millis % 1000) * 1000000)).build(); + * + * + * Example 5: Compute Timestamp from Java `Instant.now()`. + * + * Instant now = Instant.now(); + * + * Timestamp timestamp = + * Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + * .setNanos(now.getNano()).build(); + * + * + * Example 6: Compute Timestamp from current time in Python. + * + * timestamp = Timestamp() + * timestamp.GetCurrentTime() + * + * # JSON Mapping + * + * In JSON format, the Timestamp type is encoded as a string in the + * [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the + * format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" + * where {year} is always expressed using four digits while {month}, {day}, + * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional + * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), + * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone + * is required. A proto3 JSON serializer should always use UTC (as indicated by + * "Z") when printing the Timestamp type and a proto3 JSON parser should be + * able to accept both UTC and other timezones (as indicated by an offset). + * + * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past + * 01:30 UTC on January 15, 2017. + * + * In JavaScript, one can convert a Date object to this format using the + * standard + * [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) + * method. In Python, a standard `datetime.datetime` object can be converted + * to this format using + * [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with + * the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use + * the Joda Time's [`ISODateTimeFormat.dateTime()`]( + * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D + * ) to obtain a formatter capable of generating timestamps in this format. + **/ +GPB_FINAL @interface GPBTimestamp : GPBMessage + +/** + * Represents seconds of UTC time since Unix epoch + * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + * 9999-12-31T23:59:59Z inclusive. + **/ +@property(nonatomic, readwrite) int64_t seconds; + +/** + * Non-negative fractions of a second at nanosecond resolution. Negative + * second values with fractions must still have non-negative nanos values + * that count forward in time. Must be from 0 to 999,999,999 + * inclusive. + **/ +@property(nonatomic, readwrite) int32_t nanos; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.m b/objectivec/GPBTimestamp.pbobjc.m similarity index 86% rename from objectivec/google/protobuf/Timestamp.pbobjc.m rename to objectivec/GPBTimestamp.pbobjc.m index 6368885df018..736a75d19f9d 100644 --- a/objectivec/google/protobuf/Timestamp.pbobjc.m +++ b/objectivec/GPBTimestamp.pbobjc.m @@ -8,15 +8,15 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/Timestamp.pbobjc.h" + #import "GPBTimestamp.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -72,7 +72,7 @@ + (GPBDescriptor *)descriptor { .number = GPBTimestamp_FieldNumber_Seconds, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBTimestamp__storage_, seconds), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt64, }, { @@ -81,7 +81,7 @@ + (GPBDescriptor *)descriptor { .number = GPBTimestamp_FieldNumber_Nanos, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBTimestamp__storage_, nanos), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt32, }, }; @@ -92,7 +92,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBTimestamp__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBType.pbobjc.h b/objectivec/GPBType.pbobjc.h new file mode 100644 index 000000000000..747e15d455dc --- /dev/null +++ b/objectivec/GPBType.pbobjc.h @@ -0,0 +1,444 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/type.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GPBAny; +@class GPBEnumValue; +@class GPBField; +@class GPBOption; +@class GPBSourceContext; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GPBSyntax + +/** The syntax in which a protocol buffer element is defined. */ +typedef GPB_ENUM(GPBSyntax) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GPBSyntax_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Syntax `proto2`. */ + GPBSyntax_SyntaxProto2 = 0, + + /** Syntax `proto3`. */ + GPBSyntax_SyntaxProto3 = 1, +}; + +GPBEnumDescriptor *GPBSyntax_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GPBSyntax_IsValidValue(int32_t value); + +#pragma mark - Enum GPBField_Kind + +/** Basic field types. */ +typedef GPB_ENUM(GPBField_Kind) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GPBField_Kind_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Field type unknown. */ + GPBField_Kind_TypeUnknown = 0, + + /** Field type double. */ + GPBField_Kind_TypeDouble = 1, + + /** Field type float. */ + GPBField_Kind_TypeFloat = 2, + + /** Field type int64. */ + GPBField_Kind_TypeInt64 = 3, + + /** Field type uint64. */ + GPBField_Kind_TypeUint64 = 4, + + /** Field type int32. */ + GPBField_Kind_TypeInt32 = 5, + + /** Field type fixed64. */ + GPBField_Kind_TypeFixed64 = 6, + + /** Field type fixed32. */ + GPBField_Kind_TypeFixed32 = 7, + + /** Field type bool. */ + GPBField_Kind_TypeBool = 8, + + /** Field type string. */ + GPBField_Kind_TypeString = 9, + + /** Field type group. Proto2 syntax only, and deprecated. */ + GPBField_Kind_TypeGroup = 10, + + /** Field type message. */ + GPBField_Kind_TypeMessage = 11, + + /** Field type bytes. */ + GPBField_Kind_TypeBytes = 12, + + /** Field type uint32. */ + GPBField_Kind_TypeUint32 = 13, + + /** Field type enum. */ + GPBField_Kind_TypeEnum = 14, + + /** Field type sfixed32. */ + GPBField_Kind_TypeSfixed32 = 15, + + /** Field type sfixed64. */ + GPBField_Kind_TypeSfixed64 = 16, + + /** Field type sint32. */ + GPBField_Kind_TypeSint32 = 17, + + /** Field type sint64. */ + GPBField_Kind_TypeSint64 = 18, +}; + +GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GPBField_Kind_IsValidValue(int32_t value); + +#pragma mark - Enum GPBField_Cardinality + +/** Whether a field is optional, required, or repeated. */ +typedef GPB_ENUM(GPBField_Cardinality) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GPBField_Cardinality_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** For fields with unknown cardinality. */ + GPBField_Cardinality_CardinalityUnknown = 0, + + /** For optional fields. */ + GPBField_Cardinality_CardinalityOptional = 1, + + /** For required fields. Proto2 syntax only. */ + GPBField_Cardinality_CardinalityRequired = 2, + + /** For repeated fields. */ + GPBField_Cardinality_CardinalityRepeated = 3, +}; + +GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GPBField_Cardinality_IsValidValue(int32_t value); + +#pragma mark - GPBTypeRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBTypeRoot : GPBRootObject +@end + +#pragma mark - GPBType + +typedef GPB_ENUM(GPBType_FieldNumber) { + GPBType_FieldNumber_Name = 1, + GPBType_FieldNumber_FieldsArray = 2, + GPBType_FieldNumber_OneofsArray = 3, + GPBType_FieldNumber_OptionsArray = 4, + GPBType_FieldNumber_SourceContext = 5, + GPBType_FieldNumber_Syntax = 6, +}; + +/** + * A protocol buffer message type. + **/ +GPB_FINAL @interface GPBType : GPBMessage + +/** The fully qualified message name. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** The list of fields. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fieldsArray; +/** The number of items in @c fieldsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fieldsArray_Count; + +/** The list of types appearing in `oneof` definitions in this type. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *oneofsArray; +/** The number of items in @c oneofsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger oneofsArray_Count; + +/** The protocol buffer options. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; +/** The number of items in @c optionsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger optionsArray_Count; + +/** The source context. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext; +/** Test to see if @c sourceContext has been set. */ +@property(nonatomic, readwrite) BOOL hasSourceContext; + +/** The source syntax. */ +@property(nonatomic, readwrite) GPBSyntax syntax; + +@end + +/** + * Fetches the raw value of a @c GPBType's @c syntax property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GPBType_Syntax_RawValue(GPBType *message); +/** + * Sets the raw value of an @c GPBType's @c syntax property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value); + +#pragma mark - GPBField + +typedef GPB_ENUM(GPBField_FieldNumber) { + GPBField_FieldNumber_Kind = 1, + GPBField_FieldNumber_Cardinality = 2, + GPBField_FieldNumber_Number = 3, + GPBField_FieldNumber_Name = 4, + GPBField_FieldNumber_TypeURL = 6, + GPBField_FieldNumber_OneofIndex = 7, + GPBField_FieldNumber_Packed = 8, + GPBField_FieldNumber_OptionsArray = 9, + GPBField_FieldNumber_JsonName = 10, + GPBField_FieldNumber_DefaultValue = 11, +}; + +/** + * A single field of a message type. + **/ +GPB_FINAL @interface GPBField : GPBMessage + +/** The field type. */ +@property(nonatomic, readwrite) GPBField_Kind kind; + +/** The field cardinality. */ +@property(nonatomic, readwrite) GPBField_Cardinality cardinality; + +/** The field number. */ +@property(nonatomic, readwrite) int32_t number; + +/** The field name. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** + * The field type URL, without the scheme, for message or enumeration + * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL; + +/** + * The index of the field type in `Type.oneofs`, for message or enumeration + * types. The first type has index 1; zero means the type is not in the list. + **/ +@property(nonatomic, readwrite) int32_t oneofIndex; + +/** Whether to use alternative packed wire representation. */ +@property(nonatomic, readwrite) BOOL packed; + +/** The protocol buffer options. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; +/** The number of items in @c optionsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger optionsArray_Count; + +/** The field JSON name. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *jsonName; + +/** The string value of the default value of this field. Proto2 syntax only. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *defaultValue; + +@end + +/** + * Fetches the raw value of a @c GPBField's @c kind property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GPBField_Kind_RawValue(GPBField *message); +/** + * Sets the raw value of an @c GPBField's @c kind property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGPBField_Kind_RawValue(GPBField *message, int32_t value); + +/** + * Fetches the raw value of a @c GPBField's @c cardinality property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GPBField_Cardinality_RawValue(GPBField *message); +/** + * Sets the raw value of an @c GPBField's @c cardinality property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value); + +#pragma mark - GPBEnum + +typedef GPB_ENUM(GPBEnum_FieldNumber) { + GPBEnum_FieldNumber_Name = 1, + GPBEnum_FieldNumber_EnumvalueArray = 2, + GPBEnum_FieldNumber_OptionsArray = 3, + GPBEnum_FieldNumber_SourceContext = 4, + GPBEnum_FieldNumber_Syntax = 5, +}; + +/** + * Enum type definition. + **/ +GPB_FINAL @interface GPBEnum : GPBMessage + +/** Enum type name. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** Enum value definitions. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *enumvalueArray; +/** The number of items in @c enumvalueArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger enumvalueArray_Count; + +/** Protocol buffer options. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; +/** The number of items in @c optionsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger optionsArray_Count; + +/** The source context. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext; +/** Test to see if @c sourceContext has been set. */ +@property(nonatomic, readwrite) BOOL hasSourceContext; + +/** The source syntax. */ +@property(nonatomic, readwrite) GPBSyntax syntax; + +@end + +/** + * Fetches the raw value of a @c GPBEnum's @c syntax property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GPBEnum_Syntax_RawValue(GPBEnum *message); +/** + * Sets the raw value of an @c GPBEnum's @c syntax property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGPBEnum_Syntax_RawValue(GPBEnum *message, int32_t value); + +#pragma mark - GPBEnumValue + +typedef GPB_ENUM(GPBEnumValue_FieldNumber) { + GPBEnumValue_FieldNumber_Name = 1, + GPBEnumValue_FieldNumber_Number = 2, + GPBEnumValue_FieldNumber_OptionsArray = 3, +}; + +/** + * Enum value definition. + **/ +GPB_FINAL @interface GPBEnumValue : GPBMessage + +/** Enum value name. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** Enum value number. */ +@property(nonatomic, readwrite) int32_t number; + +/** Protocol buffer options. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; +/** The number of items in @c optionsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger optionsArray_Count; + +@end + +#pragma mark - GPBOption + +typedef GPB_ENUM(GPBOption_FieldNumber) { + GPBOption_FieldNumber_Name = 1, + GPBOption_FieldNumber_Value = 2, +}; + +/** + * A protocol buffer option, which can be attached to a message, field, + * enumeration, etc. + **/ +GPB_FINAL @interface GPBOption : GPBMessage + +/** + * The option's name. For protobuf built-in options (options defined in + * descriptor.proto), this is the short name. For example, `"map_entry"`. + * For custom options, it should be the fully-qualified name. For example, + * `"google.api.http"`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** + * The option's value packed in an Any message. If the value is a primitive, + * the corresponding wrapper type defined in google/protobuf/wrappers.proto + * should be used. If the value is an enum, it should be stored as an int32 + * value using the google.protobuf.Int32Value type. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBAny *value; +/** Test to see if @c value has been set. */ +@property(nonatomic, readwrite) BOOL hasValue; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Type.pbobjc.m b/objectivec/GPBType.pbobjc.m similarity index 89% rename from objectivec/google/protobuf/Type.pbobjc.m rename to objectivec/GPBType.pbobjc.m index da04392760f3..70dae31c68a0 100644 --- a/objectivec/google/protobuf/Type.pbobjc.m +++ b/objectivec/GPBType.pbobjc.m @@ -8,7 +8,7 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif @@ -16,13 +16,13 @@ #import #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import + #import + #import + #import #else - #import "google/protobuf/Type.pbobjc.h" - #import "google/protobuf/Any.pbobjc.h" - #import "google/protobuf/SourceContext.pbobjc.h" + #import "GPBType.pbobjc.h" + #import "GPBAny.pbobjc.h" + #import "GPBSourceContext.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -132,7 +132,7 @@ + (GPBDescriptor *)descriptor { .number = GPBType_FieldNumber_Name, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBType__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -177,7 +177,7 @@ + (GPBDescriptor *)descriptor { .number = GPBType_FieldNumber_Syntax, .hasIndex = 2, .offset = (uint32_t)offsetof(GPBType__storage_, syntax), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeEnum, }, }; @@ -188,7 +188,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBType__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -202,13 +202,13 @@ + (GPBDescriptor *)descriptor { int32_t GPBType_Syntax_RawValue(GPBType *message) { GPBDescriptor *descriptor = [GPBType descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBType_FieldNumber_Syntax]; - return GPBGetMessageInt32Field(message, field); + return GPBGetMessageRawEnumField(message, field); } void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value) { GPBDescriptor *descriptor = [GPBType descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBType_FieldNumber_Syntax]; - GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); + GPBSetMessageRawEnumField(message, field, value); } #pragma mark - GPBField @@ -251,7 +251,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_Kind, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBField__storage_, kind), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeEnum, }, { @@ -260,7 +260,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_Cardinality, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBField__storage_, cardinality), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeEnum, }, { @@ -269,7 +269,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_Number, .hasIndex = 2, .offset = (uint32_t)offsetof(GPBField__storage_, number), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt32, }, { @@ -278,7 +278,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_Name, .hasIndex = 3, .offset = (uint32_t)offsetof(GPBField__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -287,7 +287,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_TypeURL, .hasIndex = 4, .offset = (uint32_t)offsetof(GPBField__storage_, typeURL), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldTextFormatNameCustom | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -296,7 +296,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_OneofIndex, .hasIndex = 5, .offset = (uint32_t)offsetof(GPBField__storage_, oneofIndex), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt32, }, { @@ -305,7 +305,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_Packed, .hasIndex = 6, .offset = 7, // Stored in _has_storage_ to save space. - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeBool, }, { @@ -323,7 +323,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_JsonName, .hasIndex = 8, .offset = (uint32_t)offsetof(GPBField__storage_, jsonName), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -332,7 +332,7 @@ + (GPBDescriptor *)descriptor { .number = GPBField_FieldNumber_DefaultValue, .hasIndex = 9, .offset = (uint32_t)offsetof(GPBField__storage_, defaultValue), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, }; @@ -343,7 +343,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBField__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS static const char *extraTextFormatInfo = "\001\006\004\241!!\000"; @@ -362,25 +362,25 @@ + (GPBDescriptor *)descriptor { int32_t GPBField_Kind_RawValue(GPBField *message) { GPBDescriptor *descriptor = [GPBField descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Kind]; - return GPBGetMessageInt32Field(message, field); + return GPBGetMessageRawEnumField(message, field); } void SetGPBField_Kind_RawValue(GPBField *message, int32_t value) { GPBDescriptor *descriptor = [GPBField descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Kind]; - GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); + GPBSetMessageRawEnumField(message, field, value); } int32_t GPBField_Cardinality_RawValue(GPBField *message) { GPBDescriptor *descriptor = [GPBField descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Cardinality]; - return GPBGetMessageInt32Field(message, field); + return GPBGetMessageRawEnumField(message, field); } void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value) { GPBDescriptor *descriptor = [GPBField descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBField_FieldNumber_Cardinality]; - GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); + GPBSetMessageRawEnumField(message, field, value); } #pragma mark - Enum GPBField_Kind @@ -528,7 +528,7 @@ + (GPBDescriptor *)descriptor { .number = GPBEnum_FieldNumber_Name, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBEnum__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -564,7 +564,7 @@ + (GPBDescriptor *)descriptor { .number = GPBEnum_FieldNumber_Syntax, .hasIndex = 2, .offset = (uint32_t)offsetof(GPBEnum__storage_, syntax), - .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeEnum, }, }; @@ -575,7 +575,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBEnum__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -589,13 +589,13 @@ + (GPBDescriptor *)descriptor { int32_t GPBEnum_Syntax_RawValue(GPBEnum *message) { GPBDescriptor *descriptor = [GPBEnum descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBEnum_FieldNumber_Syntax]; - return GPBGetMessageInt32Field(message, field); + return GPBGetMessageRawEnumField(message, field); } void SetGPBEnum_Syntax_RawValue(GPBEnum *message, int32_t value) { GPBDescriptor *descriptor = [GPBEnum descriptor]; GPBFieldDescriptor *field = [descriptor fieldWithNumber:GPBEnum_FieldNumber_Syntax]; - GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); + GPBSetMessageRawEnumField(message, field, value); } #pragma mark - GPBEnumValue @@ -625,7 +625,7 @@ + (GPBDescriptor *)descriptor { .number = GPBEnumValue_FieldNumber_Name, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBEnumValue__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -634,7 +634,7 @@ + (GPBDescriptor *)descriptor { .number = GPBEnumValue_FieldNumber_Number, .hasIndex = 1, .offset = (uint32_t)offsetof(GPBEnumValue__storage_, number), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt32, }, { @@ -654,7 +654,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBEnumValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -690,7 +690,7 @@ + (GPBDescriptor *)descriptor { .number = GPBOption_FieldNumber_Name, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBOption__storage_, name), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, { @@ -710,7 +710,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBOption__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/GPBUtilities.h b/objectivec/GPBUtilities.h index ef4f8552b973..75759b233407 100644 --- a/objectivec/GPBUtilities.h +++ b/objectivec/GPBUtilities.h @@ -34,6 +34,8 @@ #import "GPBMessage.h" #import "GPBRuntimeTypes.h" +@class GPBOneofDescriptor; + CF_EXTERN_C_BEGIN NS_ASSUME_NONNULL_BEGIN @@ -92,6 +94,14 @@ BOOL GPBMessageHasFieldSet(GPBMessage *self, GPBFieldDescriptor *field); **/ void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field); +/** + * Clears the given oneof field for the given message. + * + * @param self The message for which to clear the field. + * @param oneof The oneof to clear. + **/ +void GPBClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof); + //%PDDM-EXPAND GPB_ACCESSORS() // This block of code is generated, do not edit it directly. // clang-format off diff --git a/objectivec/GPBUtilities.m b/objectivec/GPBUtilities.m index bf1b92621731..08dd358225fb 100644 --- a/objectivec/GPBUtilities.m +++ b/objectivec/GPBUtilities.m @@ -62,6 +62,12 @@ static BOOL DataTypesEquivalent(GPBDataType type1, // Marked unused because currently only called from asserts/debug. static NSString *TypeToString(GPBDataType dataType) __attribute__ ((unused)); +// Helper for clearing oneofs. +static void GPBMaybeClearOneofPrivate(GPBMessage *self, + GPBOneofDescriptor *oneof, + int32_t oneofHasIndex, + uint32_t fieldNumberNotToClear); + NSData *GPBEmptyNSData(void) { static dispatch_once_t onceToken; static NSData *defaultNSData = nil; @@ -213,7 +219,7 @@ void GPBCheckRuntimeVersionSupport(int32_t objcRuntimeVersion) { // Library is too old for headers. [NSException raise:NSInternalInconsistencyException format:@"Linked to ProtocolBuffer runtime version %d," - @" but code compiled needing atleast %d!", + @" but code compiled needing at least %d!", GOOGLE_PROTOBUF_OBJC_VERSION, objcRuntimeVersion]; } if (objcRuntimeVersion < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION) { @@ -267,17 +273,28 @@ void GPBClearMessageField(GPBMessage *self, GPBFieldDescriptor *field) { return; } + GPBMessageFieldDescription *fieldDesc = field->description_; if (GPBFieldStoresObject(field)) { // Object types are handled slightly differently, they need to be released. uint8_t *storage = (uint8_t *)self->messageStorage_; - id *typePtr = (id *)&storage[field->description_->offset]; + id *typePtr = (id *)&storage[fieldDesc->offset]; [*typePtr release]; *typePtr = nil; } else { // POD types just need to clear the has bit as the Get* method will // fetch the default when needed. } - GPBSetHasIvarField(self, field, NO); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, NO); +} + +void GPBClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof) { + #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof, + @"OneofDescriptor %@ doesn't appear to be for %@ messages.", + oneof.name, [self class]); + #endif + GPBFieldDescriptor *firstField = oneof->fields_[0]; + GPBMaybeClearOneofPrivate(self, oneof, firstField->description_->hasIndex, 0); } BOOL GPBGetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber) { @@ -324,8 +341,10 @@ void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber, } } -void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, - int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) { +static void GPBMaybeClearOneofPrivate(GPBMessage *self, + GPBOneofDescriptor *oneof, + int32_t oneofHasIndex, + uint32_t fieldNumberNotToClear) { uint32_t fieldNumberSet = GPBGetHasOneof(self, oneofHasIndex); if ((fieldNumberSet == fieldNumberNotToClear) || (fieldNumberSet == 0)) { // Do nothing/nothing set in the oneof. @@ -356,6 +375,9 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, //%TYPE GPBGetMessage##NAME##Field(GPBMessage *self, //% TYPE$S NAME$S GPBFieldDescriptor *field) { //%#if defined(DEBUG) && DEBUG +//% NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, +//% @"FieldDescriptor %@ doesn't appear to be for %@ messages.", +//% field.name, [self class]); //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), //% GPBDataType##NAME), //% @"Attempting to get value of TYPE from field %@ " @@ -377,15 +399,10 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, //% NAME$S GPBFieldDescriptor *field, //% NAME$S TYPE value) { //% if (self == nil || field == nil) return; -//% GPBFileSyntax syntax = [self descriptor].file.syntax; -//% GPBSet##NAME##IvarWithFieldInternal(self, field, value, syntax); -//%} -//% -//%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self, -//% NAME$S GPBFieldDescriptor *field, -//% NAME$S TYPE value, -//% NAME$S GPBFileSyntax syntax) { //%#if defined(DEBUG) && DEBUG +//% NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, +//% @"FieldDescriptor %@ doesn't appear to be for %@ messages.", +//% field.name, [self class]); //% NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), //% GPBDataType##NAME), //% @"Attempting to set field %@ of %@ which is of type %@ with " @@ -393,10 +410,16 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, //% [self class], field.name, //% TypeToString(GPBGetFieldDataType(field))); //%#endif +//% GPBSet##NAME##IvarWithFieldPrivate(self, field, value); +//%} +//% +//%void GPBSet##NAME##IvarWithFieldPrivate(GPBMessage *self, +//% NAME$S GPBFieldDescriptor *field, +//% NAME$S TYPE value) { //% GPBOneofDescriptor *oneof = field->containingOneof_; +//% GPBMessageFieldDescription *fieldDesc = field->description_; //% if (oneof) { -//% GPBMessageFieldDescription *fieldDesc = field->description_; -//% GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); +//% GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); //% } //%#if defined(DEBUG) && DEBUG //% NSCAssert(self->messageStorage_ != NULL, @@ -407,14 +430,13 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, //% if (self->messageStorage_ == NULL) return; //%#endif //% uint8_t *storage = (uint8_t *)self->messageStorage_; -//% TYPE *typePtr = (TYPE *)&storage[field->description_->offset]; +//% TYPE *typePtr = (TYPE *)&storage[fieldDesc->offset]; //% *typePtr = value; -//% // proto2: any value counts as having been set; proto3, it -//% // has to be a non zero value or be in a oneof. -//% BOOL hasValue = ((syntax == GPBFileSyntaxProto2) -//% || (value != (TYPE)0) -//% || (field->containingOneof_ != NULL)); -//% GPBSetHasIvarField(self, field, hasValue); +//% // If the value is zero, then we only count the field as "set" if the field +//% // shouldn't auto clear on zero. +//% BOOL hasValue = ((value != (TYPE)0) +//% || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); +//% GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); //% GPBBecomeVisibleToAutocreator(self); //%} //% @@ -482,15 +504,6 @@ void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, // Object types are handled slightly differently, they need to be released // and retained. -void GPBSetAutocreatedRetainedObjectIvarWithField( - GPBMessage *self, GPBFieldDescriptor *field, - id __attribute__((ns_consumed)) value) { - uint8_t *storage = (uint8_t *)self->messageStorage_; - id *typePtr = (id *)&storage[field->description_->offset]; - NSCAssert(*typePtr == NULL, @"Can't set autocreated object more than once."); - *typePtr = value; -} - void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { if (GPBGetHasIvarField(self, field)) { @@ -508,16 +521,14 @@ void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, static void GPBSetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field, id value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetRetainedObjectIvarWithFieldInternal(self, field, [value retain], - syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value retain]); } static void GPBSetCopyObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field, id value); // GPBSetCopyObjectIvarWithField is blocked from the analyzer because it flags -// a leak for the -copy even though GPBSetRetainedObjectIvarWithFieldInternal +// a leak for the -copy even though GPBSetRetainedObjectIvarWithFieldPrivate // is marked as consuming the value. Note: For some reason this doesn't happen // with the -retain in GPBSetObjectIvarWithField. #if !defined(__clang_analyzer__) @@ -525,22 +536,18 @@ static void GPBSetCopyObjectIvarWithField(GPBMessage *self, static void GPBSetCopyObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field, id value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetRetainedObjectIvarWithFieldInternal(self, field, [value copy], - syntax); + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value copy]); } #endif // !defined(__clang_analyzer__) -void GPBSetObjectIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, id value, - GPBFileSyntax syntax) { - GPBSetRetainedObjectIvarWithFieldInternal(self, field, [value retain], - syntax); +void GPBSetObjectIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, id value) { + GPBSetRetainedObjectIvarWithFieldPrivate(self, field, [value retain]); } -void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - id value, GPBFileSyntax syntax) { +void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + id value) { NSCAssert(self->messageStorage_ != NULL, @"%@: All messages should have storage (from init)", [self class]); @@ -579,39 +586,30 @@ void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self, // valueData/valueMessage. } #endif // DEBUG + GPBMessageFieldDescription *fieldDesc = field->description_; if (!isMapOrArray) { // Non repeated/map can be in an oneof, clear any existing value from the // oneof. GPBOneofDescriptor *oneof = field->containingOneof_; if (oneof) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } // Clear "has" if they are being set to nil. BOOL setHasValue = (value != nil); - // Under proto3, Bytes & String fields get cleared by resetting them to - // their default (empty) values, so if they are set to something of length - // zero, they are being cleared. - if ((syntax == GPBFileSyntaxProto3) && !fieldIsMessage && + // If the field should clear on a "zero" value, then check if the string/data + // was zero length, and clear instead. + if (((fieldDesc->flags & GPBFieldClearHasIvarOnZero) != 0) && ([value length] == 0)) { - // Except, if the field was in a oneof, then it still gets recorded as - // having been set so the state of the oneof can be serialized back out. - if (!oneof) { - setHasValue = NO; - } - if (setHasValue) { - NSCAssert(value != nil, @"Should never be setting has for nil"); - } else { - // The value passed in was retained, it must be released since we - // aren't saving anything in the field. - [value release]; - value = nil; - } + setHasValue = NO; + // The value passed in was retained, it must be released since we + // aren't saving anything in the field. + [value release]; + value = nil; } - GPBSetHasIvarField(self, field, setHasValue); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, setHasValue); } uint8_t *storage = (uint8_t *)self->messageStorage_; - id *typePtr = (id *)&storage[field->description_->offset]; + id *typePtr = (id *)&storage[fieldDesc->offset]; id oldValue = *typePtr; @@ -678,23 +676,22 @@ id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self, // Only exists for public api, no core code should use this. int32_t GPBGetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field) { - GPBFileSyntax syntax = [self descriptor].file.syntax; - return GPBGetEnumIvarWithFieldInternal(self, field, syntax); -} + #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); + NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum, + @"Attempting to get value of type Enum from field %@ " + @"of %@ which is of type %@.", + [self class], field.name, + TypeToString(GPBGetFieldDataType(field))); + #endif -int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - GPBFileSyntax syntax) { -#if defined(DEBUG) && DEBUG - NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum, - @"Attempting to get value of type Enum from field %@ " - @"of %@ which is of type %@.", - [self class], field.name, - TypeToString(GPBGetFieldDataType(field))); -#endif int32_t result = GPBGetMessageInt32Field(self, field); // If this is presevering unknown enums, make sure the value is valid before // returning it. + + GPBFileSyntax syntax = [self descriptor].file.syntax; if (GPBHasPreservingUnknownEnumSemantics(syntax) && ![field isValidEnumValue:result]) { result = kGPBUnrecognizedEnumeratorValue; @@ -705,27 +702,28 @@ int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self, // Only exists for public api, no core code should use this. void GPBSetMessageEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value) { - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetInt32IvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetEnumIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, int32_t value, - GPBFileSyntax syntax) { -#if defined(DEBUG) && DEBUG - NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum, - @"Attempting to set field %@ of %@ which is of type %@ with " - @"value of type Enum.", - [self class], field.name, - TypeToString(GPBGetFieldDataType(field))); -#endif + #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); + NSCAssert(GPBGetFieldDataType(field) == GPBDataTypeEnum, + @"Attempting to set field %@ of %@ which is of type %@ with " + @"value of type Enum.", + [self class], field.name, + TypeToString(GPBGetFieldDataType(field))); + #endif + GPBSetEnumIvarWithFieldPrivate(self, field, value); +} + +void GPBSetEnumIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, int32_t value) { // Don't allow in unknown values. Proto3 can use the Raw method. if (![field isValidEnumValue:value]) { [NSException raise:NSInvalidArgumentException format:@"%@.%@: Attempt to set an unknown enum value (%d)", [self class], field.name, value]; } - GPBSetInt32IvarWithFieldInternal(self, field, value, syntax); + GPBSetInt32IvarWithFieldPrivate(self, field, value); } // Only exists for public api, no core code should use this. @@ -738,13 +736,15 @@ int32_t GPBGetMessageRawEnumField(GPBMessage *self, // Only exists for public api, no core code should use this. void GPBSetMessageRawEnumField(GPBMessage *self, GPBFieldDescriptor *field, int32_t value) { - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetInt32IvarWithFieldInternal(self, field, value, syntax); + GPBSetInt32IvarWithFieldPrivate(self, field, value); } BOOL GPBGetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeBool), @"Attempting to get value of type bool from field %@ " @"of %@ which is of type %@.", @@ -768,25 +768,26 @@ void GPBSetMessageBoolField(GPBMessage *self, GPBFieldDescriptor *field, BOOL value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetBoolIvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetBoolIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - BOOL value, - GPBFileSyntax syntax) { -#if defined(DEBUG) && DEBUG - NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeBool), - @"Attempting to set field %@ of %@ which is of type %@ with " - @"value of type bool.", - [self class], field.name, - TypeToString(GPBGetFieldDataType(field))); -#endif + #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); + NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeBool), + @"Attempting to set field %@ of %@ which is of type %@ with " + @"value of type bool.", + [self class], field.name, + TypeToString(GPBGetFieldDataType(field))); + #endif + GPBSetBoolIvarWithFieldPrivate(self, field, value); +} + +void GPBSetBoolIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + BOOL value) { GPBMessageFieldDescription *fieldDesc = field->description_; GPBOneofDescriptor *oneof = field->containingOneof_; if (oneof) { - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } // Bools are stored in the has bits to avoid needing explicit space in the @@ -795,12 +796,11 @@ void GPBSetBoolIvarWithFieldInternal(GPBMessage *self, // the offset is never negative) GPBSetHasIvar(self, (int32_t)(fieldDesc->offset), fieldDesc->number, value); - // proto2: any value counts as having been set; proto3, it - // has to be a non zero value or be in a oneof. - BOOL hasValue = ((syntax == GPBFileSyntaxProto2) - || (value != (BOOL)0) - || (field->containingOneof_ != NULL)); - GPBSetHasIvarField(self, field, hasValue); + // If the value is zero, then we only count the field as "set" if the field + // shouldn't auto clear on zero. + BOOL hasValue = ((value != (BOOL)0) + || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); GPBBecomeVisibleToAutocreator(self); } @@ -811,6 +811,9 @@ void GPBSetBoolIvarWithFieldInternal(GPBMessage *self, int32_t GPBGetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeInt32), @"Attempting to get value of int32_t from field %@ " @@ -832,15 +835,10 @@ void GPBSetMessageInt32Field(GPBMessage *self, GPBFieldDescriptor *field, int32_t value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetInt32IvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - int32_t value, - GPBFileSyntax syntax) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeInt32), @"Attempting to set field %@ of %@ which is of type %@ with " @@ -848,10 +846,16 @@ void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, [self class], field.name, TypeToString(GPBGetFieldDataType(field))); #endif + GPBSetInt32IvarWithFieldPrivate(self, field, value); +} + +void GPBSetInt32IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + int32_t value) { GPBOneofDescriptor *oneof = field->containingOneof_; + GPBMessageFieldDescription *fieldDesc = field->description_; if (oneof) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } #if defined(DEBUG) && DEBUG NSCAssert(self->messageStorage_ != NULL, @@ -862,14 +866,13 @@ void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, if (self->messageStorage_ == NULL) return; #endif uint8_t *storage = (uint8_t *)self->messageStorage_; - int32_t *typePtr = (int32_t *)&storage[field->description_->offset]; + int32_t *typePtr = (int32_t *)&storage[fieldDesc->offset]; *typePtr = value; - // proto2: any value counts as having been set; proto3, it - // has to be a non zero value or be in a oneof. - BOOL hasValue = ((syntax == GPBFileSyntaxProto2) - || (value != (int32_t)0) - || (field->containingOneof_ != NULL)); - GPBSetHasIvarField(self, field, hasValue); + // If the value is zero, then we only count the field as "set" if the field + // shouldn't auto clear on zero. + BOOL hasValue = ((value != (int32_t)0) + || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); GPBBecomeVisibleToAutocreator(self); } @@ -881,6 +884,9 @@ void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, uint32_t GPBGetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeUInt32), @"Attempting to get value of uint32_t from field %@ " @@ -902,15 +908,10 @@ void GPBSetMessageUInt32Field(GPBMessage *self, GPBFieldDescriptor *field, uint32_t value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetUInt32IvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - uint32_t value, - GPBFileSyntax syntax) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeUInt32), @"Attempting to set field %@ of %@ which is of type %@ with " @@ -918,10 +919,16 @@ void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self, [self class], field.name, TypeToString(GPBGetFieldDataType(field))); #endif + GPBSetUInt32IvarWithFieldPrivate(self, field, value); +} + +void GPBSetUInt32IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + uint32_t value) { GPBOneofDescriptor *oneof = field->containingOneof_; + GPBMessageFieldDescription *fieldDesc = field->description_; if (oneof) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } #if defined(DEBUG) && DEBUG NSCAssert(self->messageStorage_ != NULL, @@ -932,14 +939,13 @@ void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self, if (self->messageStorage_ == NULL) return; #endif uint8_t *storage = (uint8_t *)self->messageStorage_; - uint32_t *typePtr = (uint32_t *)&storage[field->description_->offset]; + uint32_t *typePtr = (uint32_t *)&storage[fieldDesc->offset]; *typePtr = value; - // proto2: any value counts as having been set; proto3, it - // has to be a non zero value or be in a oneof. - BOOL hasValue = ((syntax == GPBFileSyntaxProto2) - || (value != (uint32_t)0) - || (field->containingOneof_ != NULL)); - GPBSetHasIvarField(self, field, hasValue); + // If the value is zero, then we only count the field as "set" if the field + // shouldn't auto clear on zero. + BOOL hasValue = ((value != (uint32_t)0) + || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); GPBBecomeVisibleToAutocreator(self); } @@ -951,6 +957,9 @@ void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self, int64_t GPBGetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeInt64), @"Attempting to get value of int64_t from field %@ " @@ -972,15 +981,10 @@ void GPBSetMessageInt64Field(GPBMessage *self, GPBFieldDescriptor *field, int64_t value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetInt64IvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetInt64IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - int64_t value, - GPBFileSyntax syntax) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeInt64), @"Attempting to set field %@ of %@ which is of type %@ with " @@ -988,10 +992,16 @@ void GPBSetInt64IvarWithFieldInternal(GPBMessage *self, [self class], field.name, TypeToString(GPBGetFieldDataType(field))); #endif + GPBSetInt64IvarWithFieldPrivate(self, field, value); +} + +void GPBSetInt64IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + int64_t value) { GPBOneofDescriptor *oneof = field->containingOneof_; + GPBMessageFieldDescription *fieldDesc = field->description_; if (oneof) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } #if defined(DEBUG) && DEBUG NSCAssert(self->messageStorage_ != NULL, @@ -1002,14 +1012,13 @@ void GPBSetInt64IvarWithFieldInternal(GPBMessage *self, if (self->messageStorage_ == NULL) return; #endif uint8_t *storage = (uint8_t *)self->messageStorage_; - int64_t *typePtr = (int64_t *)&storage[field->description_->offset]; + int64_t *typePtr = (int64_t *)&storage[fieldDesc->offset]; *typePtr = value; - // proto2: any value counts as having been set; proto3, it - // has to be a non zero value or be in a oneof. - BOOL hasValue = ((syntax == GPBFileSyntaxProto2) - || (value != (int64_t)0) - || (field->containingOneof_ != NULL)); - GPBSetHasIvarField(self, field, hasValue); + // If the value is zero, then we only count the field as "set" if the field + // shouldn't auto clear on zero. + BOOL hasValue = ((value != (int64_t)0) + || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); GPBBecomeVisibleToAutocreator(self); } @@ -1021,6 +1030,9 @@ void GPBSetInt64IvarWithFieldInternal(GPBMessage *self, uint64_t GPBGetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeUInt64), @"Attempting to get value of uint64_t from field %@ " @@ -1042,15 +1054,10 @@ void GPBSetMessageUInt64Field(GPBMessage *self, GPBFieldDescriptor *field, uint64_t value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetUInt64IvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - uint64_t value, - GPBFileSyntax syntax) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeUInt64), @"Attempting to set field %@ of %@ which is of type %@ with " @@ -1058,10 +1065,16 @@ void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self, [self class], field.name, TypeToString(GPBGetFieldDataType(field))); #endif + GPBSetUInt64IvarWithFieldPrivate(self, field, value); +} + +void GPBSetUInt64IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + uint64_t value) { GPBOneofDescriptor *oneof = field->containingOneof_; + GPBMessageFieldDescription *fieldDesc = field->description_; if (oneof) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } #if defined(DEBUG) && DEBUG NSCAssert(self->messageStorage_ != NULL, @@ -1072,14 +1085,13 @@ void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self, if (self->messageStorage_ == NULL) return; #endif uint8_t *storage = (uint8_t *)self->messageStorage_; - uint64_t *typePtr = (uint64_t *)&storage[field->description_->offset]; + uint64_t *typePtr = (uint64_t *)&storage[fieldDesc->offset]; *typePtr = value; - // proto2: any value counts as having been set; proto3, it - // has to be a non zero value or be in a oneof. - BOOL hasValue = ((syntax == GPBFileSyntaxProto2) - || (value != (uint64_t)0) - || (field->containingOneof_ != NULL)); - GPBSetHasIvarField(self, field, hasValue); + // If the value is zero, then we only count the field as "set" if the field + // shouldn't auto clear on zero. + BOOL hasValue = ((value != (uint64_t)0) + || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); GPBBecomeVisibleToAutocreator(self); } @@ -1091,6 +1103,9 @@ void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self, float GPBGetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeFloat), @"Attempting to get value of float from field %@ " @@ -1112,15 +1127,10 @@ void GPBSetMessageFloatField(GPBMessage *self, GPBFieldDescriptor *field, float value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetFloatIvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetFloatIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - float value, - GPBFileSyntax syntax) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeFloat), @"Attempting to set field %@ of %@ which is of type %@ with " @@ -1128,10 +1138,16 @@ void GPBSetFloatIvarWithFieldInternal(GPBMessage *self, [self class], field.name, TypeToString(GPBGetFieldDataType(field))); #endif + GPBSetFloatIvarWithFieldPrivate(self, field, value); +} + +void GPBSetFloatIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + float value) { GPBOneofDescriptor *oneof = field->containingOneof_; + GPBMessageFieldDescription *fieldDesc = field->description_; if (oneof) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } #if defined(DEBUG) && DEBUG NSCAssert(self->messageStorage_ != NULL, @@ -1142,14 +1158,13 @@ void GPBSetFloatIvarWithFieldInternal(GPBMessage *self, if (self->messageStorage_ == NULL) return; #endif uint8_t *storage = (uint8_t *)self->messageStorage_; - float *typePtr = (float *)&storage[field->description_->offset]; + float *typePtr = (float *)&storage[fieldDesc->offset]; *typePtr = value; - // proto2: any value counts as having been set; proto3, it - // has to be a non zero value or be in a oneof. - BOOL hasValue = ((syntax == GPBFileSyntaxProto2) - || (value != (float)0) - || (field->containingOneof_ != NULL)); - GPBSetHasIvarField(self, field, hasValue); + // If the value is zero, then we only count the field as "set" if the field + // shouldn't auto clear on zero. + BOOL hasValue = ((value != (float)0) + || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); GPBBecomeVisibleToAutocreator(self); } @@ -1161,6 +1176,9 @@ void GPBSetFloatIvarWithFieldInternal(GPBMessage *self, double GPBGetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeDouble), @"Attempting to get value of double from field %@ " @@ -1182,15 +1200,10 @@ void GPBSetMessageDoubleField(GPBMessage *self, GPBFieldDescriptor *field, double value) { if (self == nil || field == nil) return; - GPBFileSyntax syntax = [self descriptor].file.syntax; - GPBSetDoubleIvarWithFieldInternal(self, field, value, syntax); -} - -void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - double value, - GPBFileSyntax syntax) { #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] fieldWithNumber:field.number] == field, + @"FieldDescriptor %@ doesn't appear to be for %@ messages.", + field.name, [self class]); NSCAssert(DataTypesEquivalent(GPBGetFieldDataType(field), GPBDataTypeDouble), @"Attempting to set field %@ of %@ which is of type %@ with " @@ -1198,10 +1211,16 @@ void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self, [self class], field.name, TypeToString(GPBGetFieldDataType(field))); #endif + GPBSetDoubleIvarWithFieldPrivate(self, field, value); +} + +void GPBSetDoubleIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + double value) { GPBOneofDescriptor *oneof = field->containingOneof_; + GPBMessageFieldDescription *fieldDesc = field->description_; if (oneof) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBMaybeClearOneof(self, oneof, fieldDesc->hasIndex, fieldDesc->number); + GPBMaybeClearOneofPrivate(self, oneof, fieldDesc->hasIndex, fieldDesc->number); } #if defined(DEBUG) && DEBUG NSCAssert(self->messageStorage_ != NULL, @@ -1212,14 +1231,13 @@ void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self, if (self->messageStorage_ == NULL) return; #endif uint8_t *storage = (uint8_t *)self->messageStorage_; - double *typePtr = (double *)&storage[field->description_->offset]; + double *typePtr = (double *)&storage[fieldDesc->offset]; *typePtr = value; - // proto2: any value counts as having been set; proto3, it - // has to be a non zero value or be in a oneof. - BOOL hasValue = ((syntax == GPBFileSyntaxProto2) - || (value != (double)0) - || (field->containingOneof_ != NULL)); - GPBSetHasIvarField(self, field, hasValue); + // If the value is zero, then we only count the field as "set" if the field + // shouldn't auto clear on zero. + BOOL hasValue = ((value != (double)0) + || ((fieldDesc->flags & GPBFieldClearHasIvarOnZero) == 0)); + GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, hasValue); GPBBecomeVisibleToAutocreator(self); } @@ -2212,8 +2230,36 @@ static int32_t ReadRawVarint32FromData(const uint8_t **data) { return result; } +#pragma mark Legacy methods old generated code calls + +// Shim from the older generated code into the runtime. +void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, + GPBFieldDescriptor *field, + int32_t value, + GPBFileSyntax syntax) { +#pragma unused(syntax) + GPBSetMessageInt32Field(self, field, value); +} + +void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, + int32_t oneofHasIndex, uint32_t fieldNumberNotToClear) { +#pragma unused(fieldNumberNotToClear) + #if defined(DEBUG) && DEBUG + NSCAssert([[self descriptor] oneofWithName:oneof.name] == oneof, + @"OneofDescriptor %@ doesn't appear to be for %@ messages.", + oneof.name, [self class]); + GPBFieldDescriptor *firstField = oneof->fields_[0]; + NSCAssert(firstField->description_->hasIndex == oneofHasIndex, + @"Internal error, oneofHasIndex (%d) doesn't match (%d).", + firstField->description_->hasIndex, oneofHasIndex); + #endif + GPBMaybeClearOneofPrivate(self, oneof, oneofHasIndex, 0); +} + #pragma clang diagnostic pop +#pragma mark Misc Helpers + BOOL GPBClassHasSel(Class aClass, SEL sel) { // NOTE: We have to use class_copyMethodList, all other runtime method // lookups actually also resolve the method implementation and this diff --git a/objectivec/GPBUtilities_PackagePrivate.h b/objectivec/GPBUtilities_PackagePrivate.h index a20789632d64..3d3d7349ec78 100644 --- a/objectivec/GPBUtilities_PackagePrivate.h +++ b/objectivec/GPBUtilities_PackagePrivate.h @@ -206,120 +206,89 @@ GPBGetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field) { GPBMessageFieldDescription *fieldDesc = field->description_; return GPBGetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number); } -GPB_INLINE void GPBSetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field, - BOOL value) { - GPBMessageFieldDescription *fieldDesc = field->description_; - GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, value); -} - -void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, - int32_t oneofHasIndex, uint32_t fieldNumberNotToClear); #pragma clang diagnostic pop //%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE) -//%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self, -//% NAME$S GPBFieldDescriptor *field, -//% NAME$S TYPE value, -//% NAME$S GPBFileSyntax syntax); +//%void GPBSet##NAME##IvarWithFieldPrivate(GPBMessage *self, +//% NAME$S GPBFieldDescriptor *field, +//% NAME$S TYPE value); //%PDDM-EXPAND GPB_IVAR_SET_DECL(Bool, BOOL) // This block of code is generated, do not edit it directly. // clang-format off -void GPBSetBoolIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - BOOL value, - GPBFileSyntax syntax); +void GPBSetBoolIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + BOOL value); // clang-format on //%PDDM-EXPAND GPB_IVAR_SET_DECL(Int32, int32_t) // This block of code is generated, do not edit it directly. // clang-format off -void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - int32_t value, - GPBFileSyntax syntax); +void GPBSetInt32IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + int32_t value); // clang-format on //%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt32, uint32_t) // This block of code is generated, do not edit it directly. // clang-format off -void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - uint32_t value, - GPBFileSyntax syntax); +void GPBSetUInt32IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + uint32_t value); // clang-format on //%PDDM-EXPAND GPB_IVAR_SET_DECL(Int64, int64_t) // This block of code is generated, do not edit it directly. // clang-format off -void GPBSetInt64IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - int64_t value, - GPBFileSyntax syntax); +void GPBSetInt64IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + int64_t value); // clang-format on //%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt64, uint64_t) // This block of code is generated, do not edit it directly. // clang-format off -void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - uint64_t value, - GPBFileSyntax syntax); +void GPBSetUInt64IvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + uint64_t value); // clang-format on //%PDDM-EXPAND GPB_IVAR_SET_DECL(Float, float) // This block of code is generated, do not edit it directly. // clang-format off -void GPBSetFloatIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - float value, - GPBFileSyntax syntax); +void GPBSetFloatIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + float value); // clang-format on //%PDDM-EXPAND GPB_IVAR_SET_DECL(Double, double) // This block of code is generated, do not edit it directly. // clang-format off -void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - double value, - GPBFileSyntax syntax); -// clang-format on -//%PDDM-EXPAND GPB_IVAR_SET_DECL(Enum, int32_t) -// This block of code is generated, do not edit it directly. -// clang-format off - -void GPBSetEnumIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - int32_t value, - GPBFileSyntax syntax); +void GPBSetDoubleIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + double value); // clang-format on -//%PDDM-EXPAND-END (8 expansions) +//%PDDM-EXPAND-END (7 expansions) -int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - GPBFileSyntax syntax); +void GPBSetEnumIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + int32_t value); id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field); -void GPBSetObjectIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, id value, - GPBFileSyntax syntax); -void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self, - GPBFieldDescriptor *field, - id __attribute__((ns_consumed)) - value, - GPBFileSyntax syntax); +void GPBSetObjectIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, id value); +void GPBSetRetainedObjectIvarWithFieldPrivate(GPBMessage *self, + GPBFieldDescriptor *field, + id __attribute__((ns_consumed)) + value); // GPBGetObjectIvarWithField will automatically create the field (message) if // it doesn't exist. GPBGetObjectIvarWithFieldNoAutocreate will return nil. id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self, GPBFieldDescriptor *field); -void GPBSetAutocreatedRetainedObjectIvarWithField( - GPBMessage *self, GPBFieldDescriptor *field, - id __attribute__((ns_consumed)) value); - // Clears and releases the autocreated message ivar, if it's autocreated. If // it's not set as autocreated, this method does nothing. void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, @@ -331,11 +300,20 @@ void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self, const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel); // Helper for text format name encoding. -// decodeData is the data describing the sepecial decodes. +// decodeData is the data describing the special decodes. // key and inputString are the input that needs decoding. NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key, NSString *inputString); + +// Shims from the older generated code into the runtime. +void GPBSetInt32IvarWithFieldInternal(GPBMessage *self, + GPBFieldDescriptor *field, + int32_t value, + GPBFileSyntax syntax); +void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof, + int32_t oneofHasIndex, uint32_t fieldNumberNotToClear); + // A series of selectors that are used solely to get @encoding values // for them by the dynamic protobuf runtime code. See // GPBMessageEncodingForSelector for details. GPBRootObject conforms to diff --git a/objectivec/GPBWellKnownTypes.h b/objectivec/GPBWellKnownTypes.h index bb6c780a7d89..784ba9ff99e8 100644 --- a/objectivec/GPBWellKnownTypes.h +++ b/objectivec/GPBWellKnownTypes.h @@ -37,13 +37,13 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import + #import + #import + #import #else - #import "google/protobuf/Any.pbobjc.h" - #import "google/protobuf/Duration.pbobjc.h" - #import "google/protobuf/Timestamp.pbobjc.h" + #import "GPBAny.pbobjc.h" + #import "GPBDuration.pbobjc.h" + #import "GPBTimestamp.pbobjc.h" #endif NS_ASSUME_NONNULL_BEGIN diff --git a/objectivec/GPBWrappers.pbobjc.h b/objectivec/GPBWrappers.pbobjc.h new file mode 100644 index 000000000000..713bafc89b02 --- /dev/null +++ b/objectivec/GPBWrappers.pbobjc.h @@ -0,0 +1,219 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/wrappers.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "GPBDescriptor.h" + #import "GPBMessage.h" + #import "GPBRootObject.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30004 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GPBWrappersRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +GPB_FINAL @interface GPBWrappersRoot : GPBRootObject +@end + +#pragma mark - GPBDoubleValue + +typedef GPB_ENUM(GPBDoubleValue_FieldNumber) { + GPBDoubleValue_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `double`. + * + * The JSON representation for `DoubleValue` is JSON number. + **/ +GPB_FINAL @interface GPBDoubleValue : GPBMessage + +/** The double value. */ +@property(nonatomic, readwrite) double value; + +@end + +#pragma mark - GPBFloatValue + +typedef GPB_ENUM(GPBFloatValue_FieldNumber) { + GPBFloatValue_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `float`. + * + * The JSON representation for `FloatValue` is JSON number. + **/ +GPB_FINAL @interface GPBFloatValue : GPBMessage + +/** The float value. */ +@property(nonatomic, readwrite) float value; + +@end + +#pragma mark - GPBInt64Value + +typedef GPB_ENUM(GPBInt64Value_FieldNumber) { + GPBInt64Value_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `int64`. + * + * The JSON representation for `Int64Value` is JSON string. + **/ +GPB_FINAL @interface GPBInt64Value : GPBMessage + +/** The int64 value. */ +@property(nonatomic, readwrite) int64_t value; + +@end + +#pragma mark - GPBUInt64Value + +typedef GPB_ENUM(GPBUInt64Value_FieldNumber) { + GPBUInt64Value_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `uint64`. + * + * The JSON representation for `UInt64Value` is JSON string. + **/ +GPB_FINAL @interface GPBUInt64Value : GPBMessage + +/** The uint64 value. */ +@property(nonatomic, readwrite) uint64_t value; + +@end + +#pragma mark - GPBInt32Value + +typedef GPB_ENUM(GPBInt32Value_FieldNumber) { + GPBInt32Value_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `int32`. + * + * The JSON representation for `Int32Value` is JSON number. + **/ +GPB_FINAL @interface GPBInt32Value : GPBMessage + +/** The int32 value. */ +@property(nonatomic, readwrite) int32_t value; + +@end + +#pragma mark - GPBUInt32Value + +typedef GPB_ENUM(GPBUInt32Value_FieldNumber) { + GPBUInt32Value_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `uint32`. + * + * The JSON representation for `UInt32Value` is JSON number. + **/ +GPB_FINAL @interface GPBUInt32Value : GPBMessage + +/** The uint32 value. */ +@property(nonatomic, readwrite) uint32_t value; + +@end + +#pragma mark - GPBBoolValue + +typedef GPB_ENUM(GPBBoolValue_FieldNumber) { + GPBBoolValue_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `bool`. + * + * The JSON representation for `BoolValue` is JSON `true` and `false`. + **/ +GPB_FINAL @interface GPBBoolValue : GPBMessage + +/** The bool value. */ +@property(nonatomic, readwrite) BOOL value; + +@end + +#pragma mark - GPBStringValue + +typedef GPB_ENUM(GPBStringValue_FieldNumber) { + GPBStringValue_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `string`. + * + * The JSON representation for `StringValue` is JSON string. + **/ +GPB_FINAL @interface GPBStringValue : GPBMessage + +/** The string value. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *value; + +@end + +#pragma mark - GPBBytesValue + +typedef GPB_ENUM(GPBBytesValue_FieldNumber) { + GPBBytesValue_FieldNumber_Value = 1, +}; + +/** + * Wrapper message for `bytes`. + * + * The JSON representation for `BytesValue` is JSON string. + **/ +GPB_FINAL @interface GPBBytesValue : GPBMessage + +/** The bytes value. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *value; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.m b/objectivec/GPBWrappers.pbobjc.m similarity index 84% rename from objectivec/google/protobuf/Wrappers.pbobjc.m rename to objectivec/GPBWrappers.pbobjc.m index 19bca6f5c468..32201d4d8305 100644 --- a/objectivec/google/protobuf/Wrappers.pbobjc.m +++ b/objectivec/GPBWrappers.pbobjc.m @@ -8,15 +8,15 @@ #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else #import "GPBProtocolBuffers_RuntimeSupport.h" #endif #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import + #import #else - #import "google/protobuf/Wrappers.pbobjc.h" + #import "GPBWrappers.pbobjc.h" #endif // @@protoc_insertion_point(imports) @@ -70,7 +70,7 @@ + (GPBDescriptor *)descriptor { .number = GPBDoubleValue_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBDoubleValue__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeDouble, }, }; @@ -81,7 +81,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBDoubleValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -115,7 +115,7 @@ + (GPBDescriptor *)descriptor { .number = GPBFloatValue_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBFloatValue__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeFloat, }, }; @@ -126,7 +126,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBFloatValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -160,7 +160,7 @@ + (GPBDescriptor *)descriptor { .number = GPBInt64Value_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBInt64Value__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt64, }, }; @@ -171,7 +171,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBInt64Value__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -205,7 +205,7 @@ + (GPBDescriptor *)descriptor { .number = GPBUInt64Value_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBUInt64Value__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeUInt64, }, }; @@ -216,7 +216,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBUInt64Value__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -250,7 +250,7 @@ + (GPBDescriptor *)descriptor { .number = GPBInt32Value_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBInt32Value__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeInt32, }, }; @@ -261,7 +261,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBInt32Value__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -295,7 +295,7 @@ + (GPBDescriptor *)descriptor { .number = GPBUInt32Value_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBUInt32Value__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeUInt32, }, }; @@ -306,7 +306,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBUInt32Value__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -339,7 +339,7 @@ + (GPBDescriptor *)descriptor { .number = GPBBoolValue_FieldNumber_Value, .hasIndex = 0, .offset = 1, // Stored in _has_storage_ to save space. - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeBool, }, }; @@ -350,7 +350,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBBoolValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -384,7 +384,7 @@ + (GPBDescriptor *)descriptor { .number = GPBStringValue_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBStringValue__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeString, }, }; @@ -395,7 +395,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBStringValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG @@ -429,7 +429,7 @@ + (GPBDescriptor *)descriptor { .number = GPBBytesValue_FieldNumber_Value, .hasIndex = 0, .offset = (uint32_t)offsetof(GPBBytesValue__storage_, value), - .flags = GPBFieldOptional, + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldClearHasIvarOnZero), .dataType = GPBDataTypeBytes, }, }; @@ -440,7 +440,7 @@ + (GPBDescriptor *)descriptor { fields:fields fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) storageSize:sizeof(GPBBytesValue__storage_) - flags:GPBDescriptorInitializationFlag_UsesClassRefs]; + flags:(GPBDescriptorInitializationFlags)(GPBDescriptorInitializationFlag_UsesClassRefs | GPBDescriptorInitializationFlag_Proto3OptionalKnown)]; #if defined(DEBUG) && DEBUG NSAssert(descriptor == nil, @"Startup recursed!"); #endif // DEBUG diff --git a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj index 6bc4d322e348..365fdc30ca07 100644 --- a/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj +++ b/objectivec/ProtocolBuffers_OSX.xcodeproj/project.pbxproj @@ -81,18 +81,18 @@ F4584D821ECCB52A00803AB6 /* GPBExtensionRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F4584D7E1ECCB38900803AB6 /* GPBExtensionRegistryTest.m */; }; F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */; }; F45E57C71AE6DC6A000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */; }; - F47476E51D21A524007C7B1A /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */; }; - F47476E61D21A524007C7B1A /* Timestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248D61A92826400BC1EC6 /* Timestamp.pbobjc.m */; }; + F47CF92B23D9006000C7B24C /* GPBStruct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF91F23D9005F00C7B24C /* GPBStruct.pbobjc.m */; }; + F47CF92F23D9006000C7B24C /* GPBSourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF92323D9006000C7B24C /* GPBSourceContext.pbobjc.m */; }; + F47CF93123D9006000C7B24C /* GPBType.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF92523D9006000C7B24C /* GPBType.pbobjc.m */; }; + F47CF93223D9006000C7B24C /* GPBWrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF92623D9006000C7B24C /* GPBWrappers.pbobjc.m */; }; + F47CF93423D9006000C7B24C /* GPBFieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF92823D9006000C7B24C /* GPBFieldMask.pbobjc.m */; }; + F47CF93523D9006000C7B24C /* GPBTimestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF92923D9006000C7B24C /* GPBTimestamp.pbobjc.m */; }; + F47CF94123D902D500C7B24C /* GPBEmpty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF93923D902D500C7B24C /* GPBEmpty.pbobjc.m */; }; + F47CF94223D902D500C7B24C /* GPBApi.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF93A23D902D500C7B24C /* GPBApi.pbobjc.m */; }; + F47CF94323D902D500C7B24C /* GPBAny.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF93B23D902D500C7B24C /* GPBAny.pbobjc.m */; }; + F47CF94623D902D500C7B24C /* GPBDuration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF93E23D902D500C7B24C /* GPBDuration.pbobjc.m */; }; F4B51B1E1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4B51B1D1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm */; }; F4C4B9E41E1D976300D3B61D /* GPBDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C4B9E21E1D974F00D3B61D /* GPBDictionaryTests.m */; }; - F4E675971B21D0000054530B /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675871B21D0000054530B /* Any.pbobjc.m */; }; - F4E675991B21D0000054530B /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675891B21D0000054530B /* Api.pbobjc.m */; }; - F4E6759B1B21D0000054530B /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E6758B1B21D0000054530B /* Empty.pbobjc.m */; }; - F4E6759D1B21D0000054530B /* FieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E6758D1B21D0000054530B /* FieldMask.pbobjc.m */; }; - F4E6759F1B21D0000054530B /* SourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E6758F1B21D0000054530B /* SourceContext.pbobjc.m */; }; - F4E675A11B21D0000054530B /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675911B21D0000054530B /* Struct.pbobjc.m */; }; - F4E675A31B21D0000054530B /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675931B21D0000054530B /* Type.pbobjc.m */; }; - F4E675A51B21D0000054530B /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675951B21D0000054530B /* Wrappers.pbobjc.m */; }; F4F53F8A219CC4F2001EABF4 /* text_format_extensions_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F4F53F89219CC4F2001EABF4 /* text_format_extensions_unittest_data.txt */; }; F4F8D8831D789FD9002CE128 /* GPBUnittestProtos2.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F8D8811D789FCE002CE128 /* GPBUnittestProtos2.m */; }; /* End PBXBuildFile section */ @@ -156,10 +156,6 @@ 8B4248BA1A8C256A00BC1EC6 /* GPBSwiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GPBSwiftTests.swift; sourceTree = ""; }; 8B4248CF1A927E1500BC1EC6 /* GPBWellKnownTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWellKnownTypes.h; sourceTree = ""; }; 8B4248D01A927E1500BC1EC6 /* GPBWellKnownTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypes.m; sourceTree = ""; }; - 8B4248D31A92826400BC1EC6 /* Duration.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Duration.pbobjc.h; path = google/protobuf/Duration.pbobjc.h; sourceTree = ""; }; - 8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Duration.pbobjc.m; path = google/protobuf/Duration.pbobjc.m; sourceTree = ""; }; - 8B4248D51A92826400BC1EC6 /* Timestamp.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Timestamp.pbobjc.h; path = google/protobuf/Timestamp.pbobjc.h; sourceTree = ""; }; - 8B4248D61A92826400BC1EC6 /* Timestamp.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Timestamp.pbobjc.m; path = google/protobuf/Timestamp.pbobjc.m; sourceTree = ""; }; 8B4248DB1A92933A00BC1EC6 /* GPBWellKnownTypesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypesTest.m; sourceTree = ""; }; 8B42494C1A92A16600BC1EC6 /* duration.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = duration.proto; path = ../src/google/protobuf/duration.proto; sourceTree = ""; }; 8B42494D1A92A16600BC1EC6 /* timestamp.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = timestamp.proto; path = ../src/google/protobuf/timestamp.proto; sourceTree = ""; }; @@ -237,6 +233,26 @@ F4584D7E1ECCB38900803AB6 /* GPBExtensionRegistryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionRegistryTest.m; sourceTree = ""; }; F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = ""; }; F45E57C61AE6DC6A000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = ""; }; + F47CF91F23D9005F00C7B24C /* GPBStruct.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBStruct.pbobjc.m; sourceTree = ""; }; + F47CF92023D9006000C7B24C /* GPBSourceContext.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBSourceContext.pbobjc.h; sourceTree = ""; }; + F47CF92123D9006000C7B24C /* GPBStruct.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBStruct.pbobjc.h; sourceTree = ""; }; + F47CF92223D9006000C7B24C /* GPBFieldMask.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBFieldMask.pbobjc.h; sourceTree = ""; }; + F47CF92323D9006000C7B24C /* GPBSourceContext.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBSourceContext.pbobjc.m; sourceTree = ""; }; + F47CF92423D9006000C7B24C /* GPBTimestamp.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBTimestamp.pbobjc.h; sourceTree = ""; }; + F47CF92523D9006000C7B24C /* GPBType.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBType.pbobjc.m; sourceTree = ""; }; + F47CF92623D9006000C7B24C /* GPBWrappers.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWrappers.pbobjc.m; sourceTree = ""; }; + F47CF92723D9006000C7B24C /* GPBWrappers.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWrappers.pbobjc.h; sourceTree = ""; }; + F47CF92823D9006000C7B24C /* GPBFieldMask.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBFieldMask.pbobjc.m; sourceTree = ""; }; + F47CF92923D9006000C7B24C /* GPBTimestamp.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBTimestamp.pbobjc.m; sourceTree = ""; }; + F47CF92A23D9006000C7B24C /* GPBType.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBType.pbobjc.h; sourceTree = ""; }; + F47CF93723D902D500C7B24C /* GPBAny.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBAny.pbobjc.h; sourceTree = ""; }; + F47CF93823D902D500C7B24C /* GPBEmpty.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBEmpty.pbobjc.h; sourceTree = ""; }; + F47CF93923D902D500C7B24C /* GPBEmpty.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBEmpty.pbobjc.m; sourceTree = ""; }; + F47CF93A23D902D500C7B24C /* GPBApi.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBApi.pbobjc.m; sourceTree = ""; }; + F47CF93B23D902D500C7B24C /* GPBAny.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBAny.pbobjc.m; sourceTree = ""; }; + F47CF93C23D902D500C7B24C /* GPBDuration.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBDuration.pbobjc.h; sourceTree = ""; }; + F47CF93D23D902D500C7B24C /* GPBApi.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBApi.pbobjc.h; sourceTree = ""; }; + F47CF93E23D902D500C7B24C /* GPBDuration.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDuration.pbobjc.m; sourceTree = ""; }; F4AC9E1D1A8BEB3500BD6E83 /* unittest_cycle.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_cycle.proto; sourceTree = ""; }; F4B51B1D1BBC610700744318 /* GPBObjectiveCPlusPlusTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GPBObjectiveCPlusPlusTest.mm; sourceTree = ""; }; F4B6B8AF1A9CC98000892426 /* GPBUnknownField_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUnknownField_PackagePrivate.h; sourceTree = ""; }; @@ -245,22 +261,6 @@ F4B6B8B81A9CD1DE00892426 /* GPBRootObject_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBRootObject_PackagePrivate.h; sourceTree = ""; }; F4C4B9E21E1D974F00D3B61D /* GPBDictionaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDictionaryTests.m; sourceTree = ""; }; F4CF31701B162ED800BD9B06 /* unittest_objc_startup.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_objc_startup.proto; sourceTree = ""; }; - F4E675861B21D0000054530B /* Any.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Any.pbobjc.h; path = google/protobuf/Any.pbobjc.h; sourceTree = ""; }; - F4E675871B21D0000054530B /* Any.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Any.pbobjc.m; path = google/protobuf/Any.pbobjc.m; sourceTree = ""; }; - F4E675881B21D0000054530B /* Api.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Api.pbobjc.h; path = google/protobuf/Api.pbobjc.h; sourceTree = ""; }; - F4E675891B21D0000054530B /* Api.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Api.pbobjc.m; path = google/protobuf/Api.pbobjc.m; sourceTree = ""; }; - F4E6758A1B21D0000054530B /* Empty.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Empty.pbobjc.h; path = google/protobuf/Empty.pbobjc.h; sourceTree = ""; }; - F4E6758B1B21D0000054530B /* Empty.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Empty.pbobjc.m; path = google/protobuf/Empty.pbobjc.m; sourceTree = ""; }; - F4E6758C1B21D0000054530B /* FieldMask.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FieldMask.pbobjc.h; path = google/protobuf/FieldMask.pbobjc.h; sourceTree = ""; }; - F4E6758D1B21D0000054530B /* FieldMask.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FieldMask.pbobjc.m; path = google/protobuf/FieldMask.pbobjc.m; sourceTree = ""; }; - F4E6758E1B21D0000054530B /* SourceContext.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SourceContext.pbobjc.h; path = google/protobuf/SourceContext.pbobjc.h; sourceTree = ""; }; - F4E6758F1B21D0000054530B /* SourceContext.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SourceContext.pbobjc.m; path = google/protobuf/SourceContext.pbobjc.m; sourceTree = ""; }; - F4E675901B21D0000054530B /* Struct.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Struct.pbobjc.h; path = google/protobuf/Struct.pbobjc.h; sourceTree = ""; }; - F4E675911B21D0000054530B /* Struct.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Struct.pbobjc.m; path = google/protobuf/Struct.pbobjc.m; sourceTree = ""; }; - F4E675921B21D0000054530B /* Type.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Type.pbobjc.h; path = google/protobuf/Type.pbobjc.h; sourceTree = ""; }; - F4E675931B21D0000054530B /* Type.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Type.pbobjc.m; path = google/protobuf/Type.pbobjc.m; sourceTree = ""; }; - F4E675941B21D0000054530B /* Wrappers.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Wrappers.pbobjc.h; path = google/protobuf/Wrappers.pbobjc.h; sourceTree = ""; }; - F4E675951B21D0000054530B /* Wrappers.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Wrappers.pbobjc.m; path = google/protobuf/Wrappers.pbobjc.m; sourceTree = ""; }; F4E675A61B21D05C0054530B /* any.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = any.proto; path = ../src/google/protobuf/any.proto; sourceTree = ""; }; F4E675A71B21D05C0054530B /* api.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = api.proto; path = ../src/google/protobuf/api.proto; sourceTree = ""; }; F4E675A81B21D05C0054530B /* empty.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = empty.proto; path = ../src/google/protobuf/empty.proto; sourceTree = ""; }; @@ -342,35 +342,35 @@ 29B97315FDCFA39411CA2CEA /* Generated */ = { isa = PBXGroup; children = ( - F4E675861B21D0000054530B /* Any.pbobjc.h */, - F4E675871B21D0000054530B /* Any.pbobjc.m */, + F47CF93723D902D500C7B24C /* GPBAny.pbobjc.h */, + F47CF93B23D902D500C7B24C /* GPBAny.pbobjc.m */, + F47CF93D23D902D500C7B24C /* GPBApi.pbobjc.h */, + F47CF93A23D902D500C7B24C /* GPBApi.pbobjc.m */, + F47CF93C23D902D500C7B24C /* GPBDuration.pbobjc.h */, + F47CF93E23D902D500C7B24C /* GPBDuration.pbobjc.m */, + F47CF93823D902D500C7B24C /* GPBEmpty.pbobjc.h */, + F47CF93923D902D500C7B24C /* GPBEmpty.pbobjc.m */, + F47CF92223D9006000C7B24C /* GPBFieldMask.pbobjc.h */, + F47CF92823D9006000C7B24C /* GPBFieldMask.pbobjc.m */, + F47CF92023D9006000C7B24C /* GPBSourceContext.pbobjc.h */, + F47CF92323D9006000C7B24C /* GPBSourceContext.pbobjc.m */, + F47CF92123D9006000C7B24C /* GPBStruct.pbobjc.h */, + F47CF91F23D9005F00C7B24C /* GPBStruct.pbobjc.m */, + F47CF92423D9006000C7B24C /* GPBTimestamp.pbobjc.h */, + F47CF92923D9006000C7B24C /* GPBTimestamp.pbobjc.m */, + F47CF92A23D9006000C7B24C /* GPBType.pbobjc.h */, + F47CF92523D9006000C7B24C /* GPBType.pbobjc.m */, + F47CF92723D9006000C7B24C /* GPBWrappers.pbobjc.h */, + F47CF92623D9006000C7B24C /* GPBWrappers.pbobjc.m */, F4E675A61B21D05C0054530B /* any.proto */, - F4E675881B21D0000054530B /* Api.pbobjc.h */, - F4E675891B21D0000054530B /* Api.pbobjc.m */, F4E675A71B21D05C0054530B /* api.proto */, - 8B4248D31A92826400BC1EC6 /* Duration.pbobjc.h */, - 8B4248D41A92826400BC1EC6 /* Duration.pbobjc.m */, 8B42494C1A92A16600BC1EC6 /* duration.proto */, - F4E6758A1B21D0000054530B /* Empty.pbobjc.h */, - F4E6758B1B21D0000054530B /* Empty.pbobjc.m */, F4E675A81B21D05C0054530B /* empty.proto */, F4E675A91B21D05C0054530B /* field_mask.proto */, - F4E6758C1B21D0000054530B /* FieldMask.pbobjc.h */, - F4E6758D1B21D0000054530B /* FieldMask.pbobjc.m */, F4E675AA1B21D05C0054530B /* source_context.proto */, - F4E6758E1B21D0000054530B /* SourceContext.pbobjc.h */, - F4E6758F1B21D0000054530B /* SourceContext.pbobjc.m */, - F4E675901B21D0000054530B /* Struct.pbobjc.h */, - F4E675911B21D0000054530B /* Struct.pbobjc.m */, F4E675AB1B21D05C0054530B /* struct.proto */, - 8B4248D51A92826400BC1EC6 /* Timestamp.pbobjc.h */, - 8B4248D61A92826400BC1EC6 /* Timestamp.pbobjc.m */, 8B42494D1A92A16600BC1EC6 /* timestamp.proto */, - F4E675921B21D0000054530B /* Type.pbobjc.h */, - F4E675931B21D0000054530B /* Type.pbobjc.m */, F4E675AC1B21D05C0054530B /* type.proto */, - F4E675941B21D0000054530B /* Wrappers.pbobjc.h */, - F4E675951B21D0000054530B /* Wrappers.pbobjc.m */, F4E675AD1B21D05C0054530B /* wrappers.proto */, ); name = Generated; @@ -712,30 +712,30 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F47CF93123D9006000C7B24C /* GPBType.pbobjc.m in Sources */, 7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */, - F4E6759B1B21D0000054530B /* Empty.pbobjc.m in Sources */, + F47CF93223D9006000C7B24C /* GPBWrappers.pbobjc.m in Sources */, + F47CF94123D902D500C7B24C /* GPBEmpty.pbobjc.m in Sources */, + F47CF94623D902D500C7B24C /* GPBDuration.pbobjc.m in Sources */, + F47CF92F23D9006000C7B24C /* GPBSourceContext.pbobjc.m in Sources */, 7461B53D0F94FB4E00A0C422 /* GPBCodedOutputStream.m in Sources */, F401DC2D1A8D444600FCC765 /* GPBArray.m in Sources */, 7461B5490F94FB4E00A0C422 /* GPBExtensionRegistry.m in Sources */, - F4E6759D1B21D0000054530B /* FieldMask.pbobjc.m in Sources */, 7461B54C0F94FB4E00A0C422 /* GPBUnknownField.m in Sources */, 7461B5530F94FB4E00A0C422 /* GPBMessage.m in Sources */, - F47476E51D21A524007C7B1A /* Duration.pbobjc.m in Sources */, 7461B5610F94FB4E00A0C422 /* GPBUnknownFieldSet.m in Sources */, + F47CF93423D9006000C7B24C /* GPBFieldMask.pbobjc.m in Sources */, 7461B5630F94FB4E00A0C422 /* GPBUtilities.m in Sources */, 7461B5640F94FB4E00A0C422 /* GPBWireFormat.m in Sources */, - F4E675991B21D0000054530B /* Api.pbobjc.m in Sources */, - F4E6759F1B21D0000054530B /* SourceContext.pbobjc.m in Sources */, F4353D231ABB1537005A6198 /* GPBDictionary.m in Sources */, 8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */, + F47CF93523D9006000C7B24C /* GPBTimestamp.pbobjc.m in Sources */, 8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */, - F4E675971B21D0000054530B /* Any.pbobjc.m in Sources */, F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */, + F47CF92B23D9006000C7B24C /* GPBStruct.pbobjc.m in Sources */, + F47CF94323D902D500C7B24C /* GPBAny.pbobjc.m in Sources */, 8B4248D21A927E1500BC1EC6 /* GPBWellKnownTypes.m in Sources */, - F4E675A31B21D0000054530B /* Type.pbobjc.m in Sources */, - F4E675A11B21D0000054530B /* Struct.pbobjc.m in Sources */, - F4E675A51B21D0000054530B /* Wrappers.pbobjc.m in Sources */, - F47476E61D21A524007C7B1A /* Timestamp.pbobjc.m in Sources */, + F47CF94223D902D500C7B24C /* GPBApi.pbobjc.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj index 1b60be25a423..f0f82c828937 100644 --- a/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj +++ b/objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj @@ -82,18 +82,18 @@ F4584D831ECCB53600803AB6 /* GPBExtensionRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F4584D801ECCB39E00803AB6 /* GPBExtensionRegistryTest.m */; }; F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */; }; F45E57C91AE6DC98000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */; }; - F47476E91D21A537007C7B1A /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */; }; - F47476EA1D21A537007C7B1A /* Timestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248E01A929C7D00BC1EC6 /* Timestamp.pbobjc.m */; }; + F47CF95F23D903C600C7B24C /* GPBDuration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF94B23D903C600C7B24C /* GPBDuration.pbobjc.m */; }; + F47CF96023D903C600C7B24C /* GPBWrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF94C23D903C600C7B24C /* GPBWrappers.pbobjc.m */; }; + F47CF96223D903C600C7B24C /* GPBFieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF94E23D903C600C7B24C /* GPBFieldMask.pbobjc.m */; }; + F47CF96423D903C600C7B24C /* GPBStruct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF95023D903C600C7B24C /* GPBStruct.pbobjc.m */; }; + F47CF96523D903C600C7B24C /* GPBApi.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF95123D903C600C7B24C /* GPBApi.pbobjc.m */; }; + F47CF96623D903C600C7B24C /* GPBSourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF95223D903C600C7B24C /* GPBSourceContext.pbobjc.m */; }; + F47CF96723D903C600C7B24C /* GPBEmpty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF95323D903C600C7B24C /* GPBEmpty.pbobjc.m */; }; + F47CF96923D903C600C7B24C /* GPBTimestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF95523D903C600C7B24C /* GPBTimestamp.pbobjc.m */; }; + F47CF96C23D903C600C7B24C /* GPBType.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF95823D903C600C7B24C /* GPBType.pbobjc.m */; }; + F47CF96D23D903C600C7B24C /* GPBAny.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF95923D903C600C7B24C /* GPBAny.pbobjc.m */; }; F4B51B1C1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4B51B1B1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm */; }; F4C4B9E71E1D97BF00D3B61D /* GPBDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C4B9E51E1D97BB00D3B61D /* GPBDictionaryTests.m */; }; - F4E675D01B21D1620054530B /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B71B21D1440054530B /* Any.pbobjc.m */; }; - F4E675D11B21D1620054530B /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B91B21D1440054530B /* Api.pbobjc.m */; }; - F4E675D21B21D1620054530B /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675BC1B21D1440054530B /* Empty.pbobjc.m */; }; - F4E675D31B21D1620054530B /* FieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675BE1B21D1440054530B /* FieldMask.pbobjc.m */; }; - F4E675D41B21D1620054530B /* SourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C01B21D1440054530B /* SourceContext.pbobjc.m */; }; - F4E675D51B21D1620054530B /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C21B21D1440054530B /* Struct.pbobjc.m */; }; - F4E675D61B21D1620054530B /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C51B21D1440054530B /* Type.pbobjc.m */; }; - F4E675D71B21D1620054530B /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C71B21D1440054530B /* Wrappers.pbobjc.m */; }; F4F53F8C219CC5DF001EABF4 /* text_format_extensions_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F4F53F8B219CC5DF001EABF4 /* text_format_extensions_unittest_data.txt */; }; F4F8D8861D78A193002CE128 /* GPBUnittestProtos2.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F8D8841D78A186002CE128 /* GPBUnittestProtos2.m */; }; /* End PBXBuildFile section */ @@ -155,9 +155,6 @@ 8B35468621A61EB2000BD30D /* unittest_objc_options.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_objc_options.proto; sourceTree = ""; }; 8B4248B21A8BD96D00BC1EC6 /* UnitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnitTests-Bridging-Header.h"; sourceTree = ""; }; 8B4248B31A8BD96E00BC1EC6 /* GPBSwiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GPBSwiftTests.swift; sourceTree = ""; }; - 8B4248DD1A929C7D00BC1EC6 /* Duration.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Duration.pbobjc.h; path = google/protobuf/Duration.pbobjc.h; sourceTree = ""; }; - 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Duration.pbobjc.m; path = google/protobuf/Duration.pbobjc.m; sourceTree = ""; }; - 8B4248E01A929C7D00BC1EC6 /* Timestamp.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Timestamp.pbobjc.m; path = google/protobuf/Timestamp.pbobjc.m; sourceTree = ""; }; 8B4248E11A929C8900BC1EC6 /* GPBWellKnownTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWellKnownTypes.h; sourceTree = ""; }; 8B4248E21A929C8900BC1EC6 /* GPBWellKnownTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypes.m; sourceTree = ""; }; 8B4248E51A929C9900BC1EC6 /* GPBWellKnownTypesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypesTest.m; sourceTree = ""; }; @@ -239,6 +236,26 @@ F4584D801ECCB39E00803AB6 /* GPBExtensionRegistryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPBExtensionRegistryTest.m; path = Tests/GPBExtensionRegistryTest.m; sourceTree = SOURCE_ROOT; }; F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = ""; }; F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = ""; }; + F47CF94723D903C500C7B24C /* GPBFieldMask.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBFieldMask.pbobjc.h; sourceTree = ""; }; + F47CF94823D903C500C7B24C /* GPBDuration.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBDuration.pbobjc.h; sourceTree = ""; }; + F47CF94923D903C500C7B24C /* GPBApi.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBApi.pbobjc.h; sourceTree = ""; }; + F47CF94A23D903C500C7B24C /* GPBEmpty.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBEmpty.pbobjc.h; sourceTree = ""; }; + F47CF94B23D903C600C7B24C /* GPBDuration.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDuration.pbobjc.m; sourceTree = ""; }; + F47CF94C23D903C600C7B24C /* GPBWrappers.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWrappers.pbobjc.m; sourceTree = ""; }; + F47CF94D23D903C600C7B24C /* GPBWrappers.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWrappers.pbobjc.h; sourceTree = ""; }; + F47CF94E23D903C600C7B24C /* GPBFieldMask.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBFieldMask.pbobjc.m; sourceTree = ""; }; + F47CF94F23D903C600C7B24C /* GPBStruct.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBStruct.pbobjc.h; sourceTree = ""; }; + F47CF95023D903C600C7B24C /* GPBStruct.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBStruct.pbobjc.m; sourceTree = ""; }; + F47CF95123D903C600C7B24C /* GPBApi.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBApi.pbobjc.m; sourceTree = ""; }; + F47CF95223D903C600C7B24C /* GPBSourceContext.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBSourceContext.pbobjc.m; sourceTree = ""; }; + F47CF95323D903C600C7B24C /* GPBEmpty.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBEmpty.pbobjc.m; sourceTree = ""; }; + F47CF95423D903C600C7B24C /* GPBAny.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBAny.pbobjc.h; sourceTree = ""; }; + F47CF95523D903C600C7B24C /* GPBTimestamp.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBTimestamp.pbobjc.m; sourceTree = ""; }; + F47CF95623D903C600C7B24C /* GPBType.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBType.pbobjc.h; sourceTree = ""; }; + F47CF95723D903C600C7B24C /* GPBTimestamp.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBTimestamp.pbobjc.h; sourceTree = ""; }; + F47CF95823D903C600C7B24C /* GPBType.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBType.pbobjc.m; sourceTree = ""; }; + F47CF95923D903C600C7B24C /* GPBAny.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBAny.pbobjc.m; sourceTree = ""; }; + F47CF95A23D903C600C7B24C /* GPBSourceContext.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBSourceContext.pbobjc.h; sourceTree = ""; }; F4AC9E1C1A8BEB1000BD6E83 /* unittest_cycle.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_cycle.proto; sourceTree = ""; }; F4B51B1B1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GPBObjectiveCPlusPlusTest.mm; sourceTree = ""; }; F4B6B8B01A9CC99500892426 /* GPBUnknownField_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUnknownField_PackagePrivate.h; sourceTree = ""; }; @@ -247,23 +264,6 @@ F4B6B8B51A9CD1C600892426 /* GPBRootObject_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBRootObject_PackagePrivate.h; sourceTree = ""; }; F4C4B9E51E1D97BB00D3B61D /* GPBDictionaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDictionaryTests.m; sourceTree = ""; }; F4CF31711B162EF500BD9B06 /* unittest_objc_startup.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_objc_startup.proto; sourceTree = ""; }; - F4E675B61B21D1440054530B /* Any.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Any.pbobjc.h; path = google/protobuf/Any.pbobjc.h; sourceTree = ""; }; - F4E675B71B21D1440054530B /* Any.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Any.pbobjc.m; path = google/protobuf/Any.pbobjc.m; sourceTree = ""; }; - F4E675B81B21D1440054530B /* Api.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Api.pbobjc.h; path = google/protobuf/Api.pbobjc.h; sourceTree = ""; }; - F4E675B91B21D1440054530B /* Api.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Api.pbobjc.m; path = google/protobuf/Api.pbobjc.m; sourceTree = ""; }; - F4E675BB1B21D1440054530B /* Empty.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Empty.pbobjc.h; path = google/protobuf/Empty.pbobjc.h; sourceTree = ""; }; - F4E675BC1B21D1440054530B /* Empty.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Empty.pbobjc.m; path = google/protobuf/Empty.pbobjc.m; sourceTree = ""; }; - F4E675BD1B21D1440054530B /* FieldMask.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FieldMask.pbobjc.h; path = google/protobuf/FieldMask.pbobjc.h; sourceTree = ""; }; - F4E675BE1B21D1440054530B /* FieldMask.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FieldMask.pbobjc.m; path = google/protobuf/FieldMask.pbobjc.m; sourceTree = ""; }; - F4E675BF1B21D1440054530B /* SourceContext.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SourceContext.pbobjc.h; path = google/protobuf/SourceContext.pbobjc.h; sourceTree = ""; }; - F4E675C01B21D1440054530B /* SourceContext.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SourceContext.pbobjc.m; path = google/protobuf/SourceContext.pbobjc.m; sourceTree = ""; }; - F4E675C11B21D1440054530B /* Struct.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Struct.pbobjc.h; path = google/protobuf/Struct.pbobjc.h; sourceTree = ""; }; - F4E675C21B21D1440054530B /* Struct.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Struct.pbobjc.m; path = google/protobuf/Struct.pbobjc.m; sourceTree = ""; }; - F4E675C31B21D1440054530B /* Timestamp.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Timestamp.pbobjc.h; path = google/protobuf/Timestamp.pbobjc.h; sourceTree = ""; }; - F4E675C41B21D1440054530B /* Type.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Type.pbobjc.h; path = google/protobuf/Type.pbobjc.h; sourceTree = ""; }; - F4E675C51B21D1440054530B /* Type.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Type.pbobjc.m; path = google/protobuf/Type.pbobjc.m; sourceTree = ""; }; - F4E675C61B21D1440054530B /* Wrappers.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Wrappers.pbobjc.h; path = google/protobuf/Wrappers.pbobjc.h; sourceTree = ""; }; - F4E675C71B21D1440054530B /* Wrappers.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Wrappers.pbobjc.m; path = google/protobuf/Wrappers.pbobjc.m; sourceTree = ""; }; F4E675D81B21D1DE0054530B /* any.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = any.proto; path = ../src/google/protobuf/any.proto; sourceTree = ""; }; F4E675D91B21D1DE0054530B /* api.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = api.proto; path = ../src/google/protobuf/api.proto; sourceTree = ""; }; F4E675DA1B21D1DE0054530B /* empty.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = empty.proto; path = ../src/google/protobuf/empty.proto; sourceTree = ""; }; @@ -346,35 +346,35 @@ 29B97315FDCFA39411CA2CEA /* Generated */ = { isa = PBXGroup; children = ( - F4E675B61B21D1440054530B /* Any.pbobjc.h */, - F4E675B71B21D1440054530B /* Any.pbobjc.m */, + F47CF95423D903C600C7B24C /* GPBAny.pbobjc.h */, + F47CF95923D903C600C7B24C /* GPBAny.pbobjc.m */, + F47CF94923D903C500C7B24C /* GPBApi.pbobjc.h */, + F47CF95123D903C600C7B24C /* GPBApi.pbobjc.m */, + F47CF94823D903C500C7B24C /* GPBDuration.pbobjc.h */, + F47CF94B23D903C600C7B24C /* GPBDuration.pbobjc.m */, + F47CF94A23D903C500C7B24C /* GPBEmpty.pbobjc.h */, + F47CF95323D903C600C7B24C /* GPBEmpty.pbobjc.m */, + F47CF94723D903C500C7B24C /* GPBFieldMask.pbobjc.h */, + F47CF94E23D903C600C7B24C /* GPBFieldMask.pbobjc.m */, + F47CF95A23D903C600C7B24C /* GPBSourceContext.pbobjc.h */, + F47CF95223D903C600C7B24C /* GPBSourceContext.pbobjc.m */, + F47CF94F23D903C600C7B24C /* GPBStruct.pbobjc.h */, + F47CF95023D903C600C7B24C /* GPBStruct.pbobjc.m */, + F47CF95723D903C600C7B24C /* GPBTimestamp.pbobjc.h */, + F47CF95523D903C600C7B24C /* GPBTimestamp.pbobjc.m */, + F47CF95623D903C600C7B24C /* GPBType.pbobjc.h */, + F47CF95823D903C600C7B24C /* GPBType.pbobjc.m */, + F47CF94D23D903C600C7B24C /* GPBWrappers.pbobjc.h */, + F47CF94C23D903C600C7B24C /* GPBWrappers.pbobjc.m */, F4E675D81B21D1DE0054530B /* any.proto */, - F4E675B81B21D1440054530B /* Api.pbobjc.h */, - F4E675B91B21D1440054530B /* Api.pbobjc.m */, F4E675D91B21D1DE0054530B /* api.proto */, - 8B4248DD1A929C7D00BC1EC6 /* Duration.pbobjc.h */, - 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */, 8B42494A1A92A0BA00BC1EC6 /* duration.proto */, - F4E675BB1B21D1440054530B /* Empty.pbobjc.h */, - F4E675BC1B21D1440054530B /* Empty.pbobjc.m */, F4E675DA1B21D1DE0054530B /* empty.proto */, F4E675DB1B21D1DE0054530B /* field_mask.proto */, - F4E675BD1B21D1440054530B /* FieldMask.pbobjc.h */, - F4E675BE1B21D1440054530B /* FieldMask.pbobjc.m */, F4E675DC1B21D1DE0054530B /* source_context.proto */, - F4E675BF1B21D1440054530B /* SourceContext.pbobjc.h */, - F4E675C01B21D1440054530B /* SourceContext.pbobjc.m */, - F4E675C11B21D1440054530B /* Struct.pbobjc.h */, - F4E675C21B21D1440054530B /* Struct.pbobjc.m */, F4E675DD1B21D1DE0054530B /* struct.proto */, - F4E675C31B21D1440054530B /* Timestamp.pbobjc.h */, - 8B4248E01A929C7D00BC1EC6 /* Timestamp.pbobjc.m */, 8B4249481A92A02300BC1EC6 /* timestamp.proto */, - F4E675C41B21D1440054530B /* Type.pbobjc.h */, - F4E675C51B21D1440054530B /* Type.pbobjc.m */, F4E675DE1B21D1DE0054530B /* type.proto */, - F4E675C61B21D1440054530B /* Wrappers.pbobjc.h */, - F4E675C71B21D1440054530B /* Wrappers.pbobjc.m */, F4E675DF1B21D1DE0054530B /* wrappers.proto */, ); name = Generated; @@ -720,29 +720,29 @@ buildActionMask = 2147483647; files = ( 7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */, - F4E675D21B21D1620054530B /* Empty.pbobjc.m in Sources */, + F47CF96D23D903C600C7B24C /* GPBAny.pbobjc.m in Sources */, + F47CF96623D903C600C7B24C /* GPBSourceContext.pbobjc.m in Sources */, + F47CF96C23D903C600C7B24C /* GPBType.pbobjc.m in Sources */, + F47CF96423D903C600C7B24C /* GPBStruct.pbobjc.m in Sources */, + F47CF96723D903C600C7B24C /* GPBEmpty.pbobjc.m in Sources */, F4487C731A9F906200531423 /* GPBArray.m in Sources */, 7461B53D0F94FB4E00A0C422 /* GPBCodedOutputStream.m in Sources */, 7461B5490F94FB4E00A0C422 /* GPBExtensionRegistry.m in Sources */, - F4E675D31B21D1620054530B /* FieldMask.pbobjc.m in Sources */, + F47CF95F23D903C600C7B24C /* GPBDuration.pbobjc.m in Sources */, 7461B54C0F94FB4E00A0C422 /* GPBUnknownField.m in Sources */, 7461B5530F94FB4E00A0C422 /* GPBMessage.m in Sources */, - F47476E91D21A537007C7B1A /* Duration.pbobjc.m in Sources */, 7461B5610F94FB4E00A0C422 /* GPBUnknownFieldSet.m in Sources */, 7461B5630F94FB4E00A0C422 /* GPBUtilities.m in Sources */, 7461B5640F94FB4E00A0C422 /* GPBWireFormat.m in Sources */, - F4E675D11B21D1620054530B /* Api.pbobjc.m in Sources */, - F4E675D41B21D1620054530B /* SourceContext.pbobjc.m in Sources */, + F47CF96023D903C600C7B24C /* GPBWrappers.pbobjc.m in Sources */, + F47CF96523D903C600C7B24C /* GPBApi.pbobjc.m in Sources */, F4353D271ABB156F005A6198 /* GPBDictionary.m in Sources */, 8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */, + F47CF96223D903C600C7B24C /* GPBFieldMask.pbobjc.m in Sources */, 8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */, - F4E675D01B21D1620054530B /* Any.pbobjc.m in Sources */, F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */, 8B4248E41A929C8900BC1EC6 /* GPBWellKnownTypes.m in Sources */, - F4E675D61B21D1620054530B /* Type.pbobjc.m in Sources */, - F4E675D51B21D1620054530B /* Struct.pbobjc.m in Sources */, - F4E675D71B21D1620054530B /* Wrappers.pbobjc.m in Sources */, - F47476EA1D21A537007C7B1A /* Timestamp.pbobjc.m in Sources */, + F47CF96923D903C600C7B24C /* GPBTimestamp.pbobjc.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -856,13 +856,11 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; - ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", "$(inherited)", ); INFOPLIST_FILE = "Tests/UnitTests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -889,13 +887,11 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; - ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( "\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"", "$(inherited)", ); INFOPLIST_FILE = "Tests/UnitTests-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -972,7 +968,7 @@ GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_PROFILING_CODE = NO; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; ONLY_ACTIVE_ARCH = YES; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; @@ -1041,7 +1037,7 @@ GCC_WARN_UNUSED_PARAMETER = YES; GCC_WARN_UNUSED_VARIABLE = YES; GENERATE_PROFILING_CODE = NO; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; diff --git a/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj b/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj index 3962083c18fd..c7a8d854c748 100644 --- a/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj +++ b/objectivec/ProtocolBuffers_tvOS.xcodeproj/project.pbxproj @@ -82,18 +82,18 @@ F4584D831ECCB53600803AB6 /* GPBExtensionRegistryTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F4584D801ECCB39E00803AB6 /* GPBExtensionRegistryTest.m */; }; F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */ = {isa = PBXBuildFile; fileRef = F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */; }; F45E57C91AE6DC98000B7D99 /* text_format_map_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */; }; - F47476E91D21A537007C7B1A /* Duration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */; }; - F47476EA1D21A537007C7B1A /* Timestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4248E01A929C7D00BC1EC6 /* Timestamp.pbobjc.m */; }; + F47CF98523D904E600C7B24C /* GPBApi.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97123D904E500C7B24C /* GPBApi.pbobjc.m */; }; + F47CF98623D904E600C7B24C /* GPBEmpty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97223D904E500C7B24C /* GPBEmpty.pbobjc.m */; }; + F47CF98923D904E600C7B24C /* GPBStruct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97523D904E500C7B24C /* GPBStruct.pbobjc.m */; }; + F47CF98A23D904E600C7B24C /* GPBFieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97623D904E500C7B24C /* GPBFieldMask.pbobjc.m */; }; + F47CF98B23D904E600C7B24C /* GPBDuration.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97723D904E500C7B24C /* GPBDuration.pbobjc.m */; }; + F47CF98E23D904E600C7B24C /* GPBType.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97A23D904E600C7B24C /* GPBType.pbobjc.m */; }; + F47CF98F23D904E600C7B24C /* GPBTimestamp.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97B23D904E600C7B24C /* GPBTimestamp.pbobjc.m */; }; + F47CF99323D904E600C7B24C /* GPBWrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF97F23D904E600C7B24C /* GPBWrappers.pbobjc.m */; }; + F47CF99423D904E600C7B24C /* GPBAny.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF98023D904E600C7B24C /* GPBAny.pbobjc.m */; }; + F47CF99623D904E600C7B24C /* GPBSourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F47CF98223D904E600C7B24C /* GPBSourceContext.pbobjc.m */; }; F4B51B1C1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = F4B51B1B1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm */; }; F4C4B9E71E1D97BF00D3B61D /* GPBDictionaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F4C4B9E51E1D97BB00D3B61D /* GPBDictionaryTests.m */; }; - F4E675D01B21D1620054530B /* Any.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B71B21D1440054530B /* Any.pbobjc.m */; }; - F4E675D11B21D1620054530B /* Api.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675B91B21D1440054530B /* Api.pbobjc.m */; }; - F4E675D21B21D1620054530B /* Empty.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675BC1B21D1440054530B /* Empty.pbobjc.m */; }; - F4E675D31B21D1620054530B /* FieldMask.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675BE1B21D1440054530B /* FieldMask.pbobjc.m */; }; - F4E675D41B21D1620054530B /* SourceContext.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C01B21D1440054530B /* SourceContext.pbobjc.m */; }; - F4E675D51B21D1620054530B /* Struct.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C21B21D1440054530B /* Struct.pbobjc.m */; }; - F4E675D61B21D1620054530B /* Type.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C51B21D1440054530B /* Type.pbobjc.m */; }; - F4E675D71B21D1620054530B /* Wrappers.pbobjc.m in Sources */ = {isa = PBXBuildFile; fileRef = F4E675C71B21D1440054530B /* Wrappers.pbobjc.m */; }; F4F53F8C219CC5DF001EABF4 /* text_format_extensions_unittest_data.txt in Resources */ = {isa = PBXBuildFile; fileRef = F4F53F8B219CC5DF001EABF4 /* text_format_extensions_unittest_data.txt */; }; F4F8D8861D78A193002CE128 /* GPBUnittestProtos2.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F8D8841D78A186002CE128 /* GPBUnittestProtos2.m */; }; /* End PBXBuildFile section */ @@ -155,9 +155,6 @@ 8B35468621A61EB2000BD30D /* unittest_objc_options.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = unittest_objc_options.proto; sourceTree = ""; }; 8B4248B21A8BD96D00BC1EC6 /* UnitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnitTests-Bridging-Header.h"; sourceTree = ""; }; 8B4248B31A8BD96E00BC1EC6 /* GPBSwiftTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GPBSwiftTests.swift; sourceTree = ""; }; - 8B4248DD1A929C7D00BC1EC6 /* Duration.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Duration.pbobjc.h; path = google/protobuf/Duration.pbobjc.h; sourceTree = ""; }; - 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Duration.pbobjc.m; path = google/protobuf/Duration.pbobjc.m; sourceTree = ""; }; - 8B4248E01A929C7D00BC1EC6 /* Timestamp.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Timestamp.pbobjc.m; path = google/protobuf/Timestamp.pbobjc.m; sourceTree = ""; }; 8B4248E11A929C8900BC1EC6 /* GPBWellKnownTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWellKnownTypes.h; sourceTree = ""; }; 8B4248E21A929C8900BC1EC6 /* GPBWellKnownTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypes.m; sourceTree = ""; }; 8B4248E51A929C9900BC1EC6 /* GPBWellKnownTypesTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWellKnownTypesTest.m; sourceTree = ""; }; @@ -239,6 +236,26 @@ F4584D801ECCB39E00803AB6 /* GPBExtensionRegistryTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GPBExtensionRegistryTest.m; path = Tests/GPBExtensionRegistryTest.m; sourceTree = SOURCE_ROOT; }; F45C69CB16DFD08D0081955B /* GPBExtensionInternals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBExtensionInternals.m; sourceTree = ""; }; F45E57C81AE6DC98000B7D99 /* text_format_map_unittest_data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = text_format_map_unittest_data.txt; sourceTree = ""; }; + F47CF96F23D904E500C7B24C /* GPBWrappers.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBWrappers.pbobjc.h; sourceTree = ""; }; + F47CF97023D904E500C7B24C /* GPBFieldMask.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBFieldMask.pbobjc.h; sourceTree = ""; }; + F47CF97123D904E500C7B24C /* GPBApi.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBApi.pbobjc.m; sourceTree = ""; }; + F47CF97223D904E500C7B24C /* GPBEmpty.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBEmpty.pbobjc.m; sourceTree = ""; }; + F47CF97323D904E500C7B24C /* GPBSourceContext.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBSourceContext.pbobjc.h; sourceTree = ""; }; + F47CF97423D904E500C7B24C /* GPBDuration.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBDuration.pbobjc.h; sourceTree = ""; }; + F47CF97523D904E500C7B24C /* GPBStruct.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBStruct.pbobjc.m; sourceTree = ""; }; + F47CF97623D904E500C7B24C /* GPBFieldMask.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBFieldMask.pbobjc.m; sourceTree = ""; }; + F47CF97723D904E500C7B24C /* GPBDuration.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDuration.pbobjc.m; sourceTree = ""; }; + F47CF97823D904E600C7B24C /* GPBTimestamp.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBTimestamp.pbobjc.h; sourceTree = ""; }; + F47CF97923D904E600C7B24C /* GPBType.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBType.pbobjc.h; sourceTree = ""; }; + F47CF97A23D904E600C7B24C /* GPBType.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBType.pbobjc.m; sourceTree = ""; }; + F47CF97B23D904E600C7B24C /* GPBTimestamp.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBTimestamp.pbobjc.m; sourceTree = ""; }; + F47CF97C23D904E600C7B24C /* GPBApi.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBApi.pbobjc.h; sourceTree = ""; }; + F47CF97D23D904E600C7B24C /* GPBAny.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBAny.pbobjc.h; sourceTree = ""; }; + F47CF97E23D904E600C7B24C /* GPBEmpty.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBEmpty.pbobjc.h; sourceTree = ""; }; + F47CF97F23D904E600C7B24C /* GPBWrappers.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBWrappers.pbobjc.m; sourceTree = ""; }; + F47CF98023D904E600C7B24C /* GPBAny.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBAny.pbobjc.m; sourceTree = ""; }; + F47CF98123D904E600C7B24C /* GPBStruct.pbobjc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GPBStruct.pbobjc.h; sourceTree = ""; }; + F47CF98223D904E600C7B24C /* GPBSourceContext.pbobjc.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBSourceContext.pbobjc.m; sourceTree = ""; }; F4AC9E1C1A8BEB1000BD6E83 /* unittest_cycle.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_cycle.proto; sourceTree = ""; }; F4B51B1B1BBC5C7100744318 /* GPBObjectiveCPlusPlusTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = GPBObjectiveCPlusPlusTest.mm; sourceTree = ""; }; F4B6B8B01A9CC99500892426 /* GPBUnknownField_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBUnknownField_PackagePrivate.h; sourceTree = ""; }; @@ -247,23 +264,6 @@ F4B6B8B51A9CD1C600892426 /* GPBRootObject_PackagePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPBRootObject_PackagePrivate.h; sourceTree = ""; }; F4C4B9E51E1D97BB00D3B61D /* GPBDictionaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GPBDictionaryTests.m; sourceTree = ""; }; F4CF31711B162EF500BD9B06 /* unittest_objc_startup.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = unittest_objc_startup.proto; sourceTree = ""; }; - F4E675B61B21D1440054530B /* Any.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Any.pbobjc.h; path = google/protobuf/Any.pbobjc.h; sourceTree = ""; }; - F4E675B71B21D1440054530B /* Any.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Any.pbobjc.m; path = google/protobuf/Any.pbobjc.m; sourceTree = ""; }; - F4E675B81B21D1440054530B /* Api.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Api.pbobjc.h; path = google/protobuf/Api.pbobjc.h; sourceTree = ""; }; - F4E675B91B21D1440054530B /* Api.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Api.pbobjc.m; path = google/protobuf/Api.pbobjc.m; sourceTree = ""; }; - F4E675BB1B21D1440054530B /* Empty.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Empty.pbobjc.h; path = google/protobuf/Empty.pbobjc.h; sourceTree = ""; }; - F4E675BC1B21D1440054530B /* Empty.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Empty.pbobjc.m; path = google/protobuf/Empty.pbobjc.m; sourceTree = ""; }; - F4E675BD1B21D1440054530B /* FieldMask.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FieldMask.pbobjc.h; path = google/protobuf/FieldMask.pbobjc.h; sourceTree = ""; }; - F4E675BE1B21D1440054530B /* FieldMask.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FieldMask.pbobjc.m; path = google/protobuf/FieldMask.pbobjc.m; sourceTree = ""; }; - F4E675BF1B21D1440054530B /* SourceContext.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SourceContext.pbobjc.h; path = google/protobuf/SourceContext.pbobjc.h; sourceTree = ""; }; - F4E675C01B21D1440054530B /* SourceContext.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SourceContext.pbobjc.m; path = google/protobuf/SourceContext.pbobjc.m; sourceTree = ""; }; - F4E675C11B21D1440054530B /* Struct.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Struct.pbobjc.h; path = google/protobuf/Struct.pbobjc.h; sourceTree = ""; }; - F4E675C21B21D1440054530B /* Struct.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Struct.pbobjc.m; path = google/protobuf/Struct.pbobjc.m; sourceTree = ""; }; - F4E675C31B21D1440054530B /* Timestamp.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Timestamp.pbobjc.h; path = google/protobuf/Timestamp.pbobjc.h; sourceTree = ""; }; - F4E675C41B21D1440054530B /* Type.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Type.pbobjc.h; path = google/protobuf/Type.pbobjc.h; sourceTree = ""; }; - F4E675C51B21D1440054530B /* Type.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Type.pbobjc.m; path = google/protobuf/Type.pbobjc.m; sourceTree = ""; }; - F4E675C61B21D1440054530B /* Wrappers.pbobjc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Wrappers.pbobjc.h; path = google/protobuf/Wrappers.pbobjc.h; sourceTree = ""; }; - F4E675C71B21D1440054530B /* Wrappers.pbobjc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = Wrappers.pbobjc.m; path = google/protobuf/Wrappers.pbobjc.m; sourceTree = ""; }; F4E675D81B21D1DE0054530B /* any.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = any.proto; path = ../src/google/protobuf/any.proto; sourceTree = ""; }; F4E675D91B21D1DE0054530B /* api.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = api.proto; path = ../src/google/protobuf/api.proto; sourceTree = ""; }; F4E675DA1B21D1DE0054530B /* empty.proto */ = {isa = PBXFileReference; lastKnownFileType = text; name = empty.proto; path = ../src/google/protobuf/empty.proto; sourceTree = ""; }; @@ -346,35 +346,35 @@ 29B97315FDCFA39411CA2CEA /* Generated */ = { isa = PBXGroup; children = ( - F4E675B61B21D1440054530B /* Any.pbobjc.h */, - F4E675B71B21D1440054530B /* Any.pbobjc.m */, + F47CF97D23D904E600C7B24C /* GPBAny.pbobjc.h */, + F47CF98023D904E600C7B24C /* GPBAny.pbobjc.m */, + F47CF97C23D904E600C7B24C /* GPBApi.pbobjc.h */, + F47CF97123D904E500C7B24C /* GPBApi.pbobjc.m */, + F47CF97423D904E500C7B24C /* GPBDuration.pbobjc.h */, + F47CF97723D904E500C7B24C /* GPBDuration.pbobjc.m */, + F47CF97E23D904E600C7B24C /* GPBEmpty.pbobjc.h */, + F47CF97223D904E500C7B24C /* GPBEmpty.pbobjc.m */, + F47CF97023D904E500C7B24C /* GPBFieldMask.pbobjc.h */, + F47CF97623D904E500C7B24C /* GPBFieldMask.pbobjc.m */, + F47CF97323D904E500C7B24C /* GPBSourceContext.pbobjc.h */, + F47CF98223D904E600C7B24C /* GPBSourceContext.pbobjc.m */, + F47CF98123D904E600C7B24C /* GPBStruct.pbobjc.h */, + F47CF97523D904E500C7B24C /* GPBStruct.pbobjc.m */, + F47CF97823D904E600C7B24C /* GPBTimestamp.pbobjc.h */, + F47CF97B23D904E600C7B24C /* GPBTimestamp.pbobjc.m */, + F47CF97923D904E600C7B24C /* GPBType.pbobjc.h */, + F47CF97A23D904E600C7B24C /* GPBType.pbobjc.m */, + F47CF96F23D904E500C7B24C /* GPBWrappers.pbobjc.h */, + F47CF97F23D904E600C7B24C /* GPBWrappers.pbobjc.m */, F4E675D81B21D1DE0054530B /* any.proto */, - F4E675B81B21D1440054530B /* Api.pbobjc.h */, - F4E675B91B21D1440054530B /* Api.pbobjc.m */, F4E675D91B21D1DE0054530B /* api.proto */, - 8B4248DD1A929C7D00BC1EC6 /* Duration.pbobjc.h */, - 8B4248DE1A929C7D00BC1EC6 /* Duration.pbobjc.m */, 8B42494A1A92A0BA00BC1EC6 /* duration.proto */, - F4E675BB1B21D1440054530B /* Empty.pbobjc.h */, - F4E675BC1B21D1440054530B /* Empty.pbobjc.m */, F4E675DA1B21D1DE0054530B /* empty.proto */, F4E675DB1B21D1DE0054530B /* field_mask.proto */, - F4E675BD1B21D1440054530B /* FieldMask.pbobjc.h */, - F4E675BE1B21D1440054530B /* FieldMask.pbobjc.m */, F4E675DC1B21D1DE0054530B /* source_context.proto */, - F4E675BF1B21D1440054530B /* SourceContext.pbobjc.h */, - F4E675C01B21D1440054530B /* SourceContext.pbobjc.m */, - F4E675C11B21D1440054530B /* Struct.pbobjc.h */, - F4E675C21B21D1440054530B /* Struct.pbobjc.m */, F4E675DD1B21D1DE0054530B /* struct.proto */, - F4E675C31B21D1440054530B /* Timestamp.pbobjc.h */, - 8B4248E01A929C7D00BC1EC6 /* Timestamp.pbobjc.m */, 8B4249481A92A02300BC1EC6 /* timestamp.proto */, - F4E675C41B21D1440054530B /* Type.pbobjc.h */, - F4E675C51B21D1440054530B /* Type.pbobjc.m */, F4E675DE1B21D1DE0054530B /* type.proto */, - F4E675C61B21D1440054530B /* Wrappers.pbobjc.h */, - F4E675C71B21D1440054530B /* Wrappers.pbobjc.m */, F4E675DF1B21D1DE0054530B /* wrappers.proto */, ); name = Generated; @@ -720,29 +720,29 @@ buildActionMask = 2147483647; files = ( 7461B53C0F94FB4E00A0C422 /* GPBCodedInputStream.m in Sources */, - F4E675D21B21D1620054530B /* Empty.pbobjc.m in Sources */, F4487C731A9F906200531423 /* GPBArray.m in Sources */, + F47CF98923D904E600C7B24C /* GPBStruct.pbobjc.m in Sources */, + F47CF98623D904E600C7B24C /* GPBEmpty.pbobjc.m in Sources */, 7461B53D0F94FB4E00A0C422 /* GPBCodedOutputStream.m in Sources */, + F47CF98523D904E600C7B24C /* GPBApi.pbobjc.m in Sources */, 7461B5490F94FB4E00A0C422 /* GPBExtensionRegistry.m in Sources */, - F4E675D31B21D1620054530B /* FieldMask.pbobjc.m in Sources */, 7461B54C0F94FB4E00A0C422 /* GPBUnknownField.m in Sources */, + F47CF98E23D904E600C7B24C /* GPBType.pbobjc.m in Sources */, + F47CF99623D904E600C7B24C /* GPBSourceContext.pbobjc.m in Sources */, 7461B5530F94FB4E00A0C422 /* GPBMessage.m in Sources */, - F47476E91D21A537007C7B1A /* Duration.pbobjc.m in Sources */, + F47CF99323D904E600C7B24C /* GPBWrappers.pbobjc.m in Sources */, + F47CF98F23D904E600C7B24C /* GPBTimestamp.pbobjc.m in Sources */, 7461B5610F94FB4E00A0C422 /* GPBUnknownFieldSet.m in Sources */, 7461B5630F94FB4E00A0C422 /* GPBUtilities.m in Sources */, 7461B5640F94FB4E00A0C422 /* GPBWireFormat.m in Sources */, - F4E675D11B21D1620054530B /* Api.pbobjc.m in Sources */, - F4E675D41B21D1620054530B /* SourceContext.pbobjc.m in Sources */, F4353D271ABB156F005A6198 /* GPBDictionary.m in Sources */, + F47CF98B23D904E600C7B24C /* GPBDuration.pbobjc.m in Sources */, 8B79657B14992E3F002FFBFC /* GPBRootObject.m in Sources */, 8B96157414C8C38C00A2AC0B /* GPBDescriptor.m in Sources */, - F4E675D01B21D1620054530B /* Any.pbobjc.m in Sources */, + F47CF98A23D904E600C7B24C /* GPBFieldMask.pbobjc.m in Sources */, + F47CF99423D904E600C7B24C /* GPBAny.pbobjc.m in Sources */, F45C69CC16DFD08D0081955B /* GPBExtensionInternals.m in Sources */, 8B4248E41A929C8900BC1EC6 /* GPBWellKnownTypes.m in Sources */, - F4E675D61B21D1620054530B /* Type.pbobjc.m in Sources */, - F4E675D51B21D1620054530B /* Struct.pbobjc.m in Sources */, - F4E675D71B21D1620054530B /* Wrappers.pbobjc.m in Sources */, - F47476EA1D21A537007C7B1A /* Timestamp.pbobjc.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/objectivec/README.md b/objectivec/README.md index 69fe63164495..2583779d38f0 100644 --- a/objectivec/README.md +++ b/objectivec/README.md @@ -168,10 +168,16 @@ supported keys are: Any number of files can be listed for a framework, just separate them with commas. - There can be multiple lines listing the same frameworkName incase it has a + There can be multiple lines listing the same frameworkName in case it has a lot of proto files included in it; and having multiple lines makes things easier to read. + * `runtime_import_prefix`: The `value` used for this key to be used as a + prefix on `#import`s of runtime provided headers in the generated files. + When integrating ObjC protos into a build system, this can be used to avoid + having to add the runtime directory to the header search path since the + generate `#import` will be more complete. + Contributing ------------ diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework index 913a289b8ec1..e0ee90551452 100644 --- a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework +++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-framework @@ -1,5 +1,5 @@ source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' +platform :ios, '9.0' install! 'cocoapods', :deterministic_uuids => false diff --git a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static index e9b3c235dd16..1bb8cb2e1aa4 100644 --- a/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static +++ b/objectivec/Tests/CocoaPods/iOSCocoaPodsTester/Podfile-static @@ -1,5 +1,5 @@ source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' +platform :ios, '9.0' install! 'cocoapods', :deterministic_uuids => false diff --git a/objectivec/Tests/CocoaPods/run_tests.sh b/objectivec/Tests/CocoaPods/run_tests.sh index 6d3e12be30f2..35bcc18df7a9 100755 --- a/objectivec/Tests/CocoaPods/run_tests.sh +++ b/objectivec/Tests/CocoaPods/run_tests.sh @@ -90,7 +90,7 @@ cleanup() { echo "Cleaning up..." # Generally don't let things fail, and eat common stdout, but let stderr show - # incase something does hiccup. + # in case something does hiccup. xcodebuild -workspace "${TEST_NAME}.xcworkspace" -scheme "${TEST_NAME}" clean > /dev/null || true pod deintegrate > /dev/null || true # Flush the cache so nothing is left behind. diff --git a/objectivec/Tests/GPBCodedInputStreamTests.m b/objectivec/Tests/GPBCodedInputStreamTests.m index f5aa69038f5c..6cd5a1ffd769 100644 --- a/objectivec/Tests/GPBCodedInputStreamTests.m +++ b/objectivec/Tests/GPBCodedInputStreamTests.m @@ -422,7 +422,7 @@ - (void)testReadMalformedString { - (void)testBOMWithinStrings { // We've seen servers that end up with BOMs within strings (not always at the // start, and sometimes in multiple places), make sure they always parse - // correctly. (Again, this is inpart incase a custom string class is ever + // correctly. (Again, this is inpart in case a custom string class is ever // used again.) const char* strs[] = { "\xEF\xBB\xBF String with BOM", diff --git a/objectivec/Tests/GPBCodedOuputStreamTests.m b/objectivec/Tests/GPBCodedOuputStreamTests.m index 6c9144fb577d..a9934acdac1a 100644 --- a/objectivec/Tests/GPBCodedOuputStreamTests.m +++ b/objectivec/Tests/GPBCodedOuputStreamTests.m @@ -400,7 +400,7 @@ - (void)testCFStringGetCStringPtrAndStringsWithNullChars { - (void)testWriteStringsWithZeroChar { // Unicode allows `\0` as a character, and NSString is a class cluster, so - // there are a few different classes that could end up beind a given string. + // there are a few different classes that could end up behind a given string. // Historically, we've seen differences based on constant strings in code and // strings built via the NSString apis. So this round trips them to ensure // they are acting as expected. diff --git a/objectivec/Tests/GPBCompileTest14.m b/objectivec/Tests/GPBCompileTest14.m index ae04349ab8f1..1e64b7116dcf 100644 --- a/objectivec/Tests/GPBCompileTest14.m +++ b/objectivec/Tests/GPBCompileTest14.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Any.pbobjc.h" +#import "GPBAny.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest15.m b/objectivec/Tests/GPBCompileTest15.m index 889243aa3874..2eaedb26fbd6 100644 --- a/objectivec/Tests/GPBCompileTest15.m +++ b/objectivec/Tests/GPBCompileTest15.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Api.pbobjc.h" +#import "GPBApi.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest16.m b/objectivec/Tests/GPBCompileTest16.m index c5aaf14f7d4f..25af89e0029a 100644 --- a/objectivec/Tests/GPBCompileTest16.m +++ b/objectivec/Tests/GPBCompileTest16.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Duration.pbobjc.h" +#import "GPBDuration.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest17.m b/objectivec/Tests/GPBCompileTest17.m index feb64d669472..c719ad31cc9d 100644 --- a/objectivec/Tests/GPBCompileTest17.m +++ b/objectivec/Tests/GPBCompileTest17.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Empty.pbobjc.h" +#import "GPBEmpty.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest18.m b/objectivec/Tests/GPBCompileTest18.m index 66784c4ffcea..a02b2590e3fa 100644 --- a/objectivec/Tests/GPBCompileTest18.m +++ b/objectivec/Tests/GPBCompileTest18.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/FieldMask.pbobjc.h" +#import "GPBFieldMask.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest19.m b/objectivec/Tests/GPBCompileTest19.m index 435dea01327a..b4472846e078 100644 --- a/objectivec/Tests/GPBCompileTest19.m +++ b/objectivec/Tests/GPBCompileTest19.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/SourceContext.pbobjc.h" +#import "GPBSourceContext.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest20.m b/objectivec/Tests/GPBCompileTest20.m index c2da80668c24..120ef5546d7b 100644 --- a/objectivec/Tests/GPBCompileTest20.m +++ b/objectivec/Tests/GPBCompileTest20.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Struct.pbobjc.h" +#import "GPBStruct.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest21.m b/objectivec/Tests/GPBCompileTest21.m index d7110b9377d2..766d890b70c0 100644 --- a/objectivec/Tests/GPBCompileTest21.m +++ b/objectivec/Tests/GPBCompileTest21.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Timestamp.pbobjc.h" +#import "GPBTimestamp.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest22.m b/objectivec/Tests/GPBCompileTest22.m index 173806180c73..6d0955b73a9c 100644 --- a/objectivec/Tests/GPBCompileTest22.m +++ b/objectivec/Tests/GPBCompileTest22.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Type.pbobjc.h" +#import "GPBType.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBCompileTest23.m b/objectivec/Tests/GPBCompileTest23.m index f22f9bdd52aa..22f2db63bf3a 100644 --- a/objectivec/Tests/GPBCompileTest23.m +++ b/objectivec/Tests/GPBCompileTest23.m @@ -32,7 +32,7 @@ // This is a test including a single public header to ensure things build. // It helps test that imports are complete/ordered correctly. -#import "google/protobuf/Wrappers.pbobjc.h" +#import "GPBWrappers.pbobjc.h" // Something in the body of this file so the compiler/linker won't complain diff --git a/objectivec/Tests/GPBMessageTests+Runtime.m b/objectivec/Tests/GPBMessageTests+Runtime.m index 190ff514d2dc..1dac79754e93 100644 --- a/objectivec/Tests/GPBMessageTests+Runtime.m +++ b/objectivec/Tests/GPBMessageTests+Runtime.m @@ -252,7 +252,7 @@ - (void)testProto3HasMethodSupport { // build the selector, i.e. - repeatedInt32Array_Count SEL countSel = NSSelectorFromString( [NSString stringWithFormat:@"repeated%@Array_Count", name]); - XCTAssertTrue([Message2 instancesRespondToSelector:countSel], @"field: %@", + XCTAssertTrue([Message3 instancesRespondToSelector:countSel], @"field: %@", name); } @@ -264,12 +264,29 @@ - (void)testProto3HasMethodSupport { NSSelectorFromString([NSString stringWithFormat:@"hasOneof%@", name]); SEL setHasSel = NSSelectorFromString( [NSString stringWithFormat:@"setHasOneof%@:", name]); - XCTAssertFalse([Message2 instancesRespondToSelector:hasSel], @"field: %@", + XCTAssertFalse([Message3 instancesRespondToSelector:hasSel], @"field: %@", name); - XCTAssertFalse([Message2 instancesRespondToSelector:setHasSel], + XCTAssertFalse([Message3 instancesRespondToSelector:setHasSel], @"field: %@", name); } + // Single Optional fields + // - has*/setHas* thanks to the optional keyword in proto3, they exist + // for primitive types. + // - has*/setHas* valid for Message. + + for (NSString *name in names) { + // build the selector, i.e. - hasOptionalInt32/setHasOptionalInt32: + SEL hasSel = NSSelectorFromString( + [NSString stringWithFormat:@"hasOptional%@", name]); + SEL setHasSel = NSSelectorFromString( + [NSString stringWithFormat:@"setHasOptional%@:", name]); + XCTAssertTrue([Message3Optional instancesRespondToSelector:hasSel], @"field: %@", + name); + XCTAssertTrue([Message3Optional instancesRespondToSelector:setHasSel], + @"field: %@", name); + } + // map<> fields // - no has*/setHas* // - *Count @@ -302,14 +319,14 @@ - (void)testProto3HasMethodSupport { [NSString stringWithFormat:@"hasMap%@", name]); SEL setHasSel = NSSelectorFromString( [NSString stringWithFormat:@"setHasMap%@:", name]); - XCTAssertFalse([Message2 instancesRespondToSelector:hasSel], @"field: %@", + XCTAssertFalse([Message3 instancesRespondToSelector:hasSel], @"field: %@", name); - XCTAssertFalse([Message2 instancesRespondToSelector:setHasSel], + XCTAssertFalse([Message3 instancesRespondToSelector:setHasSel], @"field: %@", name); // build the selector, i.e. - mapInt32Int32Count SEL countSel = NSSelectorFromString( [NSString stringWithFormat:@"map%@_Count", name]); - XCTAssertTrue([Message2 instancesRespondToSelector:countSel], @"field: %@", + XCTAssertTrue([Message3 instancesRespondToSelector:countSel], @"field: %@", name); } } @@ -1002,6 +1019,249 @@ - (void)testProto3SingleFieldHasBehavior { //%PDDM-EXPAND-END PROTO3_TEST_HAS_FIELDS() } +- (void)testProto3SingleOptionalFieldHasBehavior { + // + // Setting to any value including the default (0) should result in true. + // + +//%PDDM-DEFINE PROTO3_TEST_OPTIONAL_HAS_FIELD(FIELD, NON_ZERO_VALUE, ZERO_VALUE) +//% { // optional##FIELD +//% Message3Optional *msg = [[Message3Optional alloc] init]; +//% XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_Optional##FIELD)); +//% msg.optional##FIELD = NON_ZERO_VALUE; +//% XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_Optional##FIELD)); +//% msg.hasOptional##FIELD = NO; +//% XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_Optional##FIELD)); +//% msg.optional##FIELD = ZERO_VALUE; +//% XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_Optional##FIELD)); +//% [msg release]; +//% } +//% +//%PDDM-DEFINE PROTO3_TEST_OPTIONAL_HAS_FIELDS() +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Int32, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Int64, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Uint32, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Uint64, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Sint32, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Sint64, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Fixed32, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Fixed64, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Sfixed32, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Sfixed64, 1, 0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Float, 1.0f, 0.0f) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Double, 1.0, 0.0) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Bool, YES, NO) +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(String, @"foo", @"") +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Bytes, [@"foo" dataUsingEncoding:NSUTF8StringEncoding], [NSData data]) +//% // +//% // Test doesn't apply to optionalMessage (no groups in proto3). +//% // +//% +//%PROTO3_TEST_OPTIONAL_HAS_FIELD(Enum, Message3Optional_Enum_Bar, Message3Optional_Enum_Foo) +//%PDDM-EXPAND PROTO3_TEST_OPTIONAL_HAS_FIELDS() +// This block of code is generated, do not edit it directly. +// clang-format off + + { // optionalInt32 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt32)); + msg.optionalInt32 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt32)); + msg.hasOptionalInt32 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt32)); + msg.optionalInt32 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt32)); + [msg release]; + } + + { // optionalInt64 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt64)); + msg.optionalInt64 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt64)); + msg.hasOptionalInt64 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt64)); + msg.optionalInt64 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalInt64)); + [msg release]; + } + + { // optionalUint32 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint32)); + msg.optionalUint32 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint32)); + msg.hasOptionalUint32 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint32)); + msg.optionalUint32 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint32)); + [msg release]; + } + + { // optionalUint64 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint64)); + msg.optionalUint64 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint64)); + msg.hasOptionalUint64 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint64)); + msg.optionalUint64 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalUint64)); + [msg release]; + } + + { // optionalSint32 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint32)); + msg.optionalSint32 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint32)); + msg.hasOptionalSint32 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint32)); + msg.optionalSint32 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint32)); + [msg release]; + } + + { // optionalSint64 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint64)); + msg.optionalSint64 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint64)); + msg.hasOptionalSint64 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint64)); + msg.optionalSint64 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSint64)); + [msg release]; + } + + { // optionalFixed32 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed32)); + msg.optionalFixed32 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed32)); + msg.hasOptionalFixed32 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed32)); + msg.optionalFixed32 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed32)); + [msg release]; + } + + { // optionalFixed64 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed64)); + msg.optionalFixed64 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed64)); + msg.hasOptionalFixed64 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed64)); + msg.optionalFixed64 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFixed64)); + [msg release]; + } + + { // optionalSfixed32 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed32)); + msg.optionalSfixed32 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed32)); + msg.hasOptionalSfixed32 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed32)); + msg.optionalSfixed32 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed32)); + [msg release]; + } + + { // optionalSfixed64 + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed64)); + msg.optionalSfixed64 = 1; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed64)); + msg.hasOptionalSfixed64 = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed64)); + msg.optionalSfixed64 = 0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalSfixed64)); + [msg release]; + } + + { // optionalFloat + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFloat)); + msg.optionalFloat = 1.0f; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFloat)); + msg.hasOptionalFloat = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFloat)); + msg.optionalFloat = 0.0f; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalFloat)); + [msg release]; + } + + { // optionalDouble + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalDouble)); + msg.optionalDouble = 1.0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalDouble)); + msg.hasOptionalDouble = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalDouble)); + msg.optionalDouble = 0.0; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalDouble)); + [msg release]; + } + + { // optionalBool + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBool)); + msg.optionalBool = YES; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBool)); + msg.hasOptionalBool = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBool)); + msg.optionalBool = NO; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBool)); + [msg release]; + } + + { // optionalString + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalString)); + msg.optionalString = @"foo"; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalString)); + msg.hasOptionalString = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalString)); + msg.optionalString = @""; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalString)); + [msg release]; + } + + { // optionalBytes + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBytes)); + msg.optionalBytes = [@"foo" dataUsingEncoding:NSUTF8StringEncoding]; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBytes)); + msg.hasOptionalBytes = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBytes)); + msg.optionalBytes = [NSData data]; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalBytes)); + [msg release]; + } + + // + // Test doesn't apply to optionalMessage (no groups in proto3). + // + + { // optionalEnum + Message3Optional *msg = [[Message3Optional alloc] init]; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalEnum)); + msg.optionalEnum = Message3Optional_Enum_Bar; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalEnum)); + msg.hasOptionalEnum = NO; + XCTAssertFalse(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalEnum)); + msg.optionalEnum = Message3Optional_Enum_Foo; + XCTAssertTrue(GPBMessageHasFieldNumberSet(msg, Message3Optional_FieldNumber_OptionalEnum)); + [msg release]; + } + +// clang-format on +//%PDDM-EXPAND-END PROTO3_TEST_OPTIONAL_HAS_FIELDS() +} + - (void)testAccessingProto2UnknownEnumValues { Message2 *msg = [[Message2 alloc] init]; diff --git a/objectivec/Tests/GPBMessageTests+Serialization.m b/objectivec/Tests/GPBMessageTests+Serialization.m index ef6e589e39aa..6f20797aeee7 100644 --- a/objectivec/Tests/GPBMessageTests+Serialization.m +++ b/objectivec/Tests/GPBMessageTests+Serialization.m @@ -109,6 +109,317 @@ - (void)testProto3SerializationHandlingDefaults { [msg release]; } +- (void)testProto3SerializationHandlingOptionals { + // + // Proto3 optionals should be just like proto2, zero values also get serialized. + // + +//%PDDM-DEFINE PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(FIELD, ZERO_VALUE, EXPECTED_LEN) +//% { // optional##FIELD +//% Message3Optional *msg = [[Message3Optional alloc] init]; +//% NSData *data = [msg data]; +//% XCTAssertEqual([data length], 0U); +//% msg.optional##FIELD = ZERO_VALUE; +//% data = [msg data]; +//% XCTAssertEqual(data.length, EXPECTED_LEN); +//% NSError *err = nil; +//% Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; +//% XCTAssertNotNil(msg2); +//% XCTAssertNil(err); +//% XCTAssertTrue(msg2.hasOptional##FIELD); +//% XCTAssertEqualObjects(msg, msg2); +//% [msg release]; +//% } +//% +//%PDDM-DEFINE PROTO3_TEST_SERIALIZE_OPTIONAL_FIELDS() +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Int32, 0, 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Int64, 0, 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Uint32, 0, 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Uint64, 0, 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Sint32, 0, 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Sint64, 0, 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Fixed32, 0, 5) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Fixed64, 0, 9) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Sfixed32, 0, 5) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Sfixed64, 0, 9) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Float, 0.0f, 5) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Double, 0.0, 9) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Bool, NO, 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(String, @"", 2) +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Bytes, [NSData data], 2) +//% // +//% // Test doesn't apply to optionalMessage (no groups in proto3). +//% // +//% +//%PROTO3_TEST_SERIALIZE_OPTIONAL_FIELD(Enum, Message3Optional_Enum_Foo, 3) +//%PDDM-EXPAND PROTO3_TEST_SERIALIZE_OPTIONAL_FIELDS() +// This block of code is generated, do not edit it directly. +// clang-format off + + { // optionalInt32 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalInt32 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalInt32); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalInt64 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalInt64 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalInt64); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalUint32 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalUint32 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalUint32); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalUint64 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalUint64 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalUint64); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalSint32 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalSint32 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalSint32); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalSint64 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalSint64 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalSint64); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalFixed32 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalFixed32 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 5); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalFixed32); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalFixed64 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalFixed64 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 9); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalFixed64); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalSfixed32 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalSfixed32 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 5); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalSfixed32); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalSfixed64 + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalSfixed64 = 0; + data = [msg data]; + XCTAssertEqual(data.length, 9); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalSfixed64); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalFloat + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalFloat = 0.0f; + data = [msg data]; + XCTAssertEqual(data.length, 5); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalFloat); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalDouble + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalDouble = 0.0; + data = [msg data]; + XCTAssertEqual(data.length, 9); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalDouble); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalBool + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalBool = NO; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalBool); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalString + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalString = @""; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalString); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + { // optionalBytes + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalBytes = [NSData data]; + data = [msg data]; + XCTAssertEqual(data.length, 2); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalBytes); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + + // + // Test doesn't apply to optionalMessage (no groups in proto3). + // + + { // optionalEnum + Message3Optional *msg = [[Message3Optional alloc] init]; + NSData *data = [msg data]; + XCTAssertEqual([data length], 0U); + msg.optionalEnum = Message3Optional_Enum_Foo; + data = [msg data]; + XCTAssertEqual(data.length, 3); + NSError *err = nil; + Message3Optional *msg2 = [Message3Optional parseFromData:data error:&err]; + XCTAssertNotNil(msg2); + XCTAssertNil(err); + XCTAssertTrue(msg2.hasOptionalEnum); + XCTAssertEqualObjects(msg, msg2); + [msg release]; + } + +// clang-format on +//%PDDM-EXPAND-END PROTO3_TEST_SERIALIZE_OPTIONAL_FIELDS() +} + - (void)testProto2UnknownEnumToUnknownField { Message3 *orig = [[Message3 alloc] init]; diff --git a/objectivec/Tests/GPBSwiftTests.swift b/objectivec/Tests/GPBSwiftTests.swift index cedf0e487e06..03d7510680bc 100644 --- a/objectivec/Tests/GPBSwiftTests.swift +++ b/objectivec/Tests/GPBSwiftTests.swift @@ -355,7 +355,7 @@ class GPBBridgeTests: XCTestCase { msg.oneof = nil XCTAssertEqual(msg.oneof.optionalInt32, Int32(0)) // Default XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase) -} + } func testProto3OneOfSupport() { let msg = Message3() diff --git a/objectivec/Tests/GPBTestUtilities.m b/objectivec/Tests/GPBTestUtilities.m index 0362bdde647c..48d75e794ab8 100644 --- a/objectivec/Tests/GPBTestUtilities.m +++ b/objectivec/Tests/GPBTestUtilities.m @@ -779,7 +779,7 @@ - (void)setAllFields:(TestAllTypes *)message repeatedCount:(uint32_t)count { [message.repeatedSfixed64Array addValue:210 + i * 100]; [message.repeatedFloatArray addValue:211 + i * 100]; [message.repeatedDoubleArray addValue:212 + i * 100]; - [message.repeatedBoolArray addValue:(i % 2)]; + [message.repeatedBoolArray addValue:(BOOL)(i % 2)]; NSString *string = [[NSString alloc] initWithFormat:@"%d", 215 + i * 100]; [message.repeatedStringArray addObject:string]; [string release]; diff --git a/objectivec/Tests/GPBUnittestProtos.m b/objectivec/Tests/GPBUnittestProtos.m index 756bd99ef77d..1c6eddfbacfb 100644 --- a/objectivec/Tests/GPBUnittestProtos.m +++ b/objectivec/Tests/GPBUnittestProtos.m @@ -56,8 +56,6 @@ #import "google/protobuf/UnittestLite.pbobjc.m" #import "google/protobuf/UnittestMset.pbobjc.m" #import "google/protobuf/UnittestMsetWireFormat.pbobjc.m" -#import "google/protobuf/UnittestNoArena.pbobjc.m" -#import "google/protobuf/UnittestNoArenaImport.pbobjc.m" #import "google/protobuf/UnittestNoGenericServices.pbobjc.m" #import "google/protobuf/UnittestObjc.pbobjc.m" #import "google/protobuf/UnittestObjcStartup.pbobjc.m" diff --git a/objectivec/Tests/unittest_runtime_proto3.proto b/objectivec/Tests/unittest_runtime_proto3.proto index ad2e3620d3e3..c2ee5fb52faa 100644 --- a/objectivec/Tests/unittest_runtime_proto3.proto +++ b/objectivec/Tests/unittest_runtime_proto3.proto @@ -119,3 +119,31 @@ message Message3 { map map_int32_enum = 87; map map_int32_message = 88; } + +message Message3Optional { + enum Enum { + FOO = 0; + BAR = 1; + BAZ = 2; + EXTRA_3 = 30; + } + + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + // No 'group' in proto3. + optional Message3 optional_message = 18; + optional Enum optional_enum = 19; +} diff --git a/objectivec/generate_well_known_types.sh b/objectivec/generate_well_known_types.sh index 36c346031c85..1b9de6ec55ee 100755 --- a/objectivec/generate_well_known_types.sh +++ b/objectivec/generate_well_known_types.sh @@ -10,7 +10,8 @@ set -eu readonly ScriptDir=$(dirname "$(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,")") -readonly ProtoRootDir="${ScriptDir}/.." +readonly ObjCDir="${ScriptDir}" +readonly ProtoRootDir="${ObjCDir}/.." # Flag for continuous integration to check that everything is current. CHECK_ONLY=0 @@ -19,9 +20,9 @@ if [[ $# -ge 1 && ( "$1" == "--check-only" ) ]] ; then shift fi -pushd "${ProtoRootDir}" > /dev/null +cd "${ProtoRootDir}" -if test ! -e src/google/protobuf/stubs/common.h; then +if [[ ! -e src/google/protobuf/stubs/common.h ]]; then cat >&2 << __EOF__ Could not find source code. Make sure you are running this script from the root of the distribution tree. @@ -29,7 +30,7 @@ __EOF__ exit 1 fi -if test ! -e src/Makefile; then +if [[ ! -e src/Makefile ]]; then cat >&2 << __EOF__ Could not find src/Makefile. You must run ./configure (and perhaps ./autogen.sh) first. @@ -53,24 +54,36 @@ declare -a RUNTIME_PROTO_FILES=( \ google/protobuf/type.proto \ google/protobuf/wrappers.proto) +declare -a OBJC_EXTENSIONS=( .pbobjc.h .pbobjc.m ) + # Generate to a temp directory to see if they match. TMP_DIR=$(mktemp -d) trap "rm -rf ${TMP_DIR}" EXIT ./protoc --objc_out="${TMP_DIR}" ${RUNTIME_PROTO_FILES[@]} -set +e -diff -r "${TMP_DIR}/google" "${ProtoRootDir}/objectivec/google" > /dev/null -if [[ $? -eq 0 ]] ; then - echo "Generated source for WellKnownTypes is current." - exit 0 -fi -set -e -# If check only mode, error out. -if [[ "${CHECK_ONLY}" == 1 ]] ; then - echo "ERROR: The WKTs need to be regenerated! Run $0" - exit 1 -fi +DID_COPY=0 +for PROTO_FILE in "${RUNTIME_PROTO_FILES[@]}"; do + DIR=${PROTO_FILE%/*} + BASE_NAME=${PROTO_FILE##*/} + # Drop the extension + BASE_NAME=${BASE_NAME%.*} + OBJC_NAME=$(echo "${BASE_NAME}" | awk -F _ '{for(i=1; i<=NF; i++) printf "%s", toupper(substr($i,1,1)) substr($i,2);}') -# Copy them over. -echo "Copying over updated WellKnownType sources." -cp -r "${TMP_DIR}/google/." "${ProtoRootDir}/objectivec/google/" + for EXT in "${OBJC_EXTENSIONS[@]}"; do + if ! diff "${ObjCDir}/GPB${OBJC_NAME}${EXT}" "${TMP_DIR}/${DIR}/${OBJC_NAME}${EXT}" > /dev/null 2>&1 ; then + if [[ "${CHECK_ONLY}" == 1 ]] ; then + echo "ERROR: The WKTs need to be regenerated! Run $0" + exit 1 + fi + + echo "INFO: Updating GPB${OBJC_NAME}${EXT}" + cp "${TMP_DIR}/${DIR}/${OBJC_NAME}${EXT}" "${ObjCDir}/GPB${OBJC_NAME}${EXT}" + DID_COPY=1 + fi + done +done + +if [[ "${DID_COPY}" == 0 ]]; then + echo "INFO: Generated source for WellKnownTypes is current." + exit 0 +fi diff --git a/objectivec/google/protobuf/Any.pbobjc.h b/objectivec/google/protobuf/Any.pbobjc.h index d39741413db2..e6d1b7450abe 100644 --- a/objectivec/google/protobuf/Any.pbobjc.h +++ b/objectivec/google/protobuf/Any.pbobjc.h @@ -1,183 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/any.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBAnyRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBAnyRoot : GPBRootObject -@end - -#pragma mark - GPBAny - -typedef GPB_ENUM(GPBAny_FieldNumber) { - GPBAny_FieldNumber_TypeURL = 1, - GPBAny_FieldNumber_Value = 2, -}; - -/** - * `Any` contains an arbitrary serialized protocol buffer message along with a - * URL that describes the type of the serialized message. - * - * Protobuf library provides support to pack/unpack Any values in the form - * of utility functions or additional generated methods of the Any type. - * - * Example 1: Pack and unpack a message in C++. - * - * Foo foo = ...; - * Any any; - * any.PackFrom(foo); - * ... - * if (any.UnpackTo(&foo)) { - * ... - * } - * - * Example 2: Pack and unpack a message in Java. - * - * Foo foo = ...; - * Any any = Any.pack(foo); - * ... - * if (any.is(Foo.class)) { - * foo = any.unpack(Foo.class); - * } - * - * Example 3: Pack and unpack a message in Python. - * - * foo = Foo(...) - * any = Any() - * any.Pack(foo) - * ... - * if any.Is(Foo.DESCRIPTOR): - * any.Unpack(foo) - * ... - * - * Example 4: Pack and unpack a message in Go - * - * foo := &pb.Foo{...} - * any, err := ptypes.MarshalAny(foo) - * ... - * foo := &pb.Foo{} - * if err := ptypes.UnmarshalAny(any, foo); err != nil { - * ... - * } - * - * The pack methods provided by protobuf library will by default use - * 'type.googleapis.com/full.type.name' as the type URL and the unpack - * methods only use the fully qualified type name after the last '/' - * in the type URL, for example "foo.bar.com/x/y.z" will yield type - * name "y.z". - * - * - * JSON - * ==== - * The JSON representation of an `Any` value uses the regular - * representation of the deserialized, embedded message, with an - * additional field `\@type` which contains the type URL. Example: - * - * package google.profile; - * message Person { - * string first_name = 1; - * string last_name = 2; - * } - * - * { - * "\@type": "type.googleapis.com/google.profile.Person", - * "firstName": , - * "lastName": - * } - * - * If the embedded message type is well-known and has a custom JSON - * representation, that representation will be embedded adding a field - * `value` which holds the custom JSON in addition to the `\@type` - * field. Example (for message [google.protobuf.Duration][]): - * - * { - * "\@type": "type.googleapis.com/google.protobuf.Duration", - * "value": "1.212s" - * } - **/ -GPB_FINAL @interface GPBAny : GPBMessage - -/** - * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. This string must contain at least - * one "/" character. The last segment of the URL's path must represent - * the fully qualified name of the type (as in - * `path/google.protobuf.Duration`). The name should be in a canonical form - * (e.g., leading "." is not accepted). - * - * In practice, teams usually precompile into the binary all types that they - * expect it to use in the context of Any. However, for URLs which use the - * scheme `http`, `https`, or no scheme, one can optionally set up a type - * server that maps type URLs to message definitions as follows: - * - * * If no scheme is provided, `https` is assumed. - * * An HTTP GET on the URL must yield a [google.protobuf.Type][] - * value in binary format, or produce an error. - * * Applications are allowed to cache lookup results based on the - * URL, or have them precompiled into a binary to avoid any - * lookup. Therefore, binary compatibility needs to be preserved - * on changes to types. (Use versioned type names to manage - * breaking changes.) - * - * Note: this functionality is not currently available in the official - * protobuf release, and it is not used for type URLs beginning with - * type.googleapis.com. - * - * Schemes other than `http`, `https` (or the empty scheme) might be - * used with implementation specific semantics. - **/ -@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL; - -/** Must be a valid serialized protocol buffer of the above specified type. */ -@property(nonatomic, readwrite, copy, null_resettable) NSData *value; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBAny.pbobjc.h" diff --git a/objectivec/google/protobuf/Api.pbobjc.h b/objectivec/google/protobuf/Api.pbobjc.h index e8ccc1a0f111..e7957db4e122 100644 --- a/objectivec/google/protobuf/Api.pbobjc.h +++ b/objectivec/google/protobuf/Api.pbobjc.h @@ -1,311 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/api.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -@class GPBMethod; -@class GPBMixin; -@class GPBOption; -@class GPBSourceContext; -GPB_ENUM_FWD_DECLARE(GPBSyntax); - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBApiRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBApiRoot : GPBRootObject -@end - -#pragma mark - GPBApi - -typedef GPB_ENUM(GPBApi_FieldNumber) { - GPBApi_FieldNumber_Name = 1, - GPBApi_FieldNumber_MethodsArray = 2, - GPBApi_FieldNumber_OptionsArray = 3, - GPBApi_FieldNumber_Version = 4, - GPBApi_FieldNumber_SourceContext = 5, - GPBApi_FieldNumber_MixinsArray = 6, - GPBApi_FieldNumber_Syntax = 7, -}; - -/** - * Api is a light-weight descriptor for an API Interface. - * - * Interfaces are also described as "protocol buffer services" in some contexts, - * such as by the "service" keyword in a .proto file, but they are different - * from API Services, which represent a concrete implementation of an interface - * as opposed to simply a description of methods and bindings. They are also - * sometimes simply referred to as "APIs" in other contexts, such as the name of - * this message itself. See https://cloud.google.com/apis/design/glossary for - * detailed terminology. - **/ -GPB_FINAL @interface GPBApi : GPBMessage - -/** - * The fully qualified name of this interface, including package name - * followed by the interface's simple name. - **/ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** The methods of this interface, in unspecified order. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *methodsArray; -/** The number of items in @c methodsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger methodsArray_Count; - -/** Any metadata attached to the interface. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; -/** The number of items in @c optionsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger optionsArray_Count; - -/** - * A version string for this interface. If specified, must have the form - * `major-version.minor-version`, as in `1.10`. If the minor version is - * omitted, it defaults to zero. If the entire version field is empty, the - * major version is derived from the package name, as outlined below. If the - * field is not empty, the version in the package name will be verified to be - * consistent with what is provided here. - * - * The versioning schema uses [semantic - * versioning](http://semver.org) where the major version number - * indicates a breaking change and the minor version an additive, - * non-breaking change. Both version numbers are signals to users - * what to expect from different versions, and should be carefully - * chosen based on the product plan. - * - * The major version is also reflected in the package name of the - * interface, which must end in `v`, as in - * `google.feature.v1`. For major versions 0 and 1, the suffix can - * be omitted. Zero major versions must only be used for - * experimental, non-GA interfaces. - **/ -@property(nonatomic, readwrite, copy, null_resettable) NSString *version; - -/** - * Source context for the protocol buffer service represented by this - * message. - **/ -@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext; -/** Test to see if @c sourceContext has been set. */ -@property(nonatomic, readwrite) BOOL hasSourceContext; - -/** Included interfaces. See [Mixin][]. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *mixinsArray; -/** The number of items in @c mixinsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger mixinsArray_Count; - -/** The source syntax of the service. */ -@property(nonatomic, readwrite) enum GPBSyntax syntax; - -@end - -/** - * Fetches the raw value of a @c GPBApi's @c syntax property, even - * if the value was not defined by the enum at the time the code was generated. - **/ -int32_t GPBApi_Syntax_RawValue(GPBApi *message); -/** - * Sets the raw value of an @c GPBApi's @c syntax property, allowing - * it to be set to a value that was not defined by the enum at the time the code - * was generated. - **/ -void SetGPBApi_Syntax_RawValue(GPBApi *message, int32_t value); - -#pragma mark - GPBMethod - -typedef GPB_ENUM(GPBMethod_FieldNumber) { - GPBMethod_FieldNumber_Name = 1, - GPBMethod_FieldNumber_RequestTypeURL = 2, - GPBMethod_FieldNumber_RequestStreaming = 3, - GPBMethod_FieldNumber_ResponseTypeURL = 4, - GPBMethod_FieldNumber_ResponseStreaming = 5, - GPBMethod_FieldNumber_OptionsArray = 6, - GPBMethod_FieldNumber_Syntax = 7, -}; - -/** - * Method represents a method of an API interface. - **/ -GPB_FINAL @interface GPBMethod : GPBMessage - -/** The simple name of this method. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** A URL of the input message type. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *requestTypeURL; - -/** If true, the request is streamed. */ -@property(nonatomic, readwrite) BOOL requestStreaming; - -/** The URL of the output message type. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *responseTypeURL; - -/** If true, the response is streamed. */ -@property(nonatomic, readwrite) BOOL responseStreaming; - -/** Any metadata attached to the method. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; -/** The number of items in @c optionsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger optionsArray_Count; - -/** The source syntax of this method. */ -@property(nonatomic, readwrite) enum GPBSyntax syntax; - -@end - -/** - * Fetches the raw value of a @c GPBMethod's @c syntax property, even - * if the value was not defined by the enum at the time the code was generated. - **/ -int32_t GPBMethod_Syntax_RawValue(GPBMethod *message); -/** - * Sets the raw value of an @c GPBMethod's @c syntax property, allowing - * it to be set to a value that was not defined by the enum at the time the code - * was generated. - **/ -void SetGPBMethod_Syntax_RawValue(GPBMethod *message, int32_t value); - -#pragma mark - GPBMixin - -typedef GPB_ENUM(GPBMixin_FieldNumber) { - GPBMixin_FieldNumber_Name = 1, - GPBMixin_FieldNumber_Root = 2, -}; - -/** - * Declares an API Interface to be included in this interface. The including - * interface must redeclare all the methods from the included interface, but - * documentation and options are inherited as follows: - * - * - If after comment and whitespace stripping, the documentation - * string of the redeclared method is empty, it will be inherited - * from the original method. - * - * - Each annotation belonging to the service config (http, - * visibility) which is not set in the redeclared method will be - * inherited. - * - * - If an http annotation is inherited, the path pattern will be - * modified as follows. Any version prefix will be replaced by the - * version of the including interface plus the [root][] path if - * specified. - * - * Example of a simple mixin: - * - * package google.acl.v1; - * service AccessControl { - * // Get the underlying ACL object. - * rpc GetAcl(GetAclRequest) returns (Acl) { - * option (google.api.http).get = "/v1/{resource=**}:getAcl"; - * } - * } - * - * package google.storage.v2; - * service Storage { - * rpc GetAcl(GetAclRequest) returns (Acl); - * - * // Get a data record. - * rpc GetData(GetDataRequest) returns (Data) { - * option (google.api.http).get = "/v2/{resource=**}"; - * } - * } - * - * Example of a mixin configuration: - * - * apis: - * - name: google.storage.v2.Storage - * mixins: - * - name: google.acl.v1.AccessControl - * - * The mixin construct implies that all methods in `AccessControl` are - * also declared with same name and request/response types in - * `Storage`. A documentation generator or annotation processor will - * see the effective `Storage.GetAcl` method after inherting - * documentation and annotations as follows: - * - * service Storage { - * // Get the underlying ACL object. - * rpc GetAcl(GetAclRequest) returns (Acl) { - * option (google.api.http).get = "/v2/{resource=**}:getAcl"; - * } - * ... - * } - * - * Note how the version in the path pattern changed from `v1` to `v2`. - * - * If the `root` field in the mixin is specified, it should be a - * relative path under which inherited HTTP paths are placed. Example: - * - * apis: - * - name: google.storage.v2.Storage - * mixins: - * - name: google.acl.v1.AccessControl - * root: acls - * - * This implies the following inherited HTTP annotation: - * - * service Storage { - * // Get the underlying ACL object. - * rpc GetAcl(GetAclRequest) returns (Acl) { - * option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; - * } - * ... - * } - **/ -GPB_FINAL @interface GPBMixin : GPBMessage - -/** The fully qualified name of the interface which is included. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** - * If non-empty specifies a path under which inherited HTTP paths - * are rooted. - **/ -@property(nonatomic, readwrite, copy, null_resettable) NSString *root; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBApi.pbobjc.h" diff --git a/objectivec/google/protobuf/Duration.pbobjc.h b/objectivec/google/protobuf/Duration.pbobjc.h index 8bf295cac833..fabf00f413d1 100644 --- a/objectivec/google/protobuf/Duration.pbobjc.h +++ b/objectivec/google/protobuf/Duration.pbobjc.h @@ -1,145 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/duration.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBDurationRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBDurationRoot : GPBRootObject -@end - -#pragma mark - GPBDuration - -typedef GPB_ENUM(GPBDuration_FieldNumber) { - GPBDuration_FieldNumber_Seconds = 1, - GPBDuration_FieldNumber_Nanos = 2, -}; - -/** - * A Duration represents a signed, fixed-length span of time represented - * as a count of seconds and fractions of seconds at nanosecond - * resolution. It is independent of any calendar and concepts like "day" - * or "month". It is related to Timestamp in that the difference between - * two Timestamp values is a Duration and it can be added or subtracted - * from a Timestamp. Range is approximately +-10,000 years. - * - * # Examples - * - * Example 1: Compute Duration from two Timestamps in pseudo code. - * - * Timestamp start = ...; - * Timestamp end = ...; - * Duration duration = ...; - * - * duration.seconds = end.seconds - start.seconds; - * duration.nanos = end.nanos - start.nanos; - * - * if (duration.seconds < 0 && duration.nanos > 0) { - * duration.seconds += 1; - * duration.nanos -= 1000000000; - * } else if (duration.seconds > 0 && duration.nanos < 0) { - * duration.seconds -= 1; - * duration.nanos += 1000000000; - * } - * - * Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. - * - * Timestamp start = ...; - * Duration duration = ...; - * Timestamp end = ...; - * - * end.seconds = start.seconds + duration.seconds; - * end.nanos = start.nanos + duration.nanos; - * - * if (end.nanos < 0) { - * end.seconds -= 1; - * end.nanos += 1000000000; - * } else if (end.nanos >= 1000000000) { - * end.seconds += 1; - * end.nanos -= 1000000000; - * } - * - * Example 3: Compute Duration from datetime.timedelta in Python. - * - * td = datetime.timedelta(days=3, minutes=10) - * duration = Duration() - * duration.FromTimedelta(td) - * - * # JSON Mapping - * - * In JSON format, the Duration type is encoded as a string rather than an - * object, where the string ends in the suffix "s" (indicating seconds) and - * is preceded by the number of seconds, with nanoseconds expressed as - * fractional seconds. For example, 3 seconds with 0 nanoseconds should be - * encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should - * be expressed in JSON format as "3.000000001s", and 3 seconds and 1 - * microsecond should be expressed in JSON format as "3.000001s". - **/ -GPB_FINAL @interface GPBDuration : GPBMessage - -/** - * Signed seconds of the span of time. Must be from -315,576,000,000 - * to +315,576,000,000 inclusive. Note: these bounds are computed from: - * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years - **/ -@property(nonatomic, readwrite) int64_t seconds; - -/** - * Signed fractions of a second at nanosecond resolution of the span - * of time. Durations less than one second are represented with a 0 - * `seconds` field and a positive or negative `nanos` field. For durations - * of one second or more, a non-zero value for the `nanos` field must be - * of the same sign as the `seconds` field. Must be from -999,999,999 - * to +999,999,999 inclusive. - **/ -@property(nonatomic, readwrite) int32_t nanos; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBDuration.pbobjc.h" diff --git a/objectivec/google/protobuf/Empty.pbobjc.h b/objectivec/google/protobuf/Empty.pbobjc.h index db95c119487e..4de910870aa1 100644 --- a/objectivec/google/protobuf/Empty.pbobjc.h +++ b/objectivec/google/protobuf/Empty.pbobjc.h @@ -1,74 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/empty.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBEmptyRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBEmptyRoot : GPBRootObject -@end - -#pragma mark - GPBEmpty - -/** - * A generic empty message that you can re-use to avoid defining duplicated - * empty messages in your APIs. A typical example is to use it as the request - * or the response type of an API method. For instance: - * - * service Foo { - * rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); - * } - * - * The JSON representation for `Empty` is empty JSON object `{}`. - **/ -GPB_FINAL @interface GPBEmpty : GPBMessage - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBEmpty.pbobjc.h" diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.h b/objectivec/google/protobuf/FieldMask.pbobjc.h index afc3272a466e..26913200467a 100644 --- a/objectivec/google/protobuf/FieldMask.pbobjc.h +++ b/objectivec/google/protobuf/FieldMask.pbobjc.h @@ -1,273 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/field_mask.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBFieldMaskRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBFieldMaskRoot : GPBRootObject -@end - -#pragma mark - GPBFieldMask - -typedef GPB_ENUM(GPBFieldMask_FieldNumber) { - GPBFieldMask_FieldNumber_PathsArray = 1, -}; - -/** - * `FieldMask` represents a set of symbolic field paths, for example: - * - * paths: "f.a" - * paths: "f.b.d" - * - * Here `f` represents a field in some root message, `a` and `b` - * fields in the message found in `f`, and `d` a field found in the - * message in `f.b`. - * - * Field masks are used to specify a subset of fields that should be - * returned by a get operation or modified by an update operation. - * Field masks also have a custom JSON encoding (see below). - * - * # Field Masks in Projections - * - * When used in the context of a projection, a response message or - * sub-message is filtered by the API to only contain those fields as - * specified in the mask. For example, if the mask in the previous - * example is applied to a response message as follows: - * - * f { - * a : 22 - * b { - * d : 1 - * x : 2 - * } - * y : 13 - * } - * z: 8 - * - * The result will not contain specific values for fields x,y and z - * (their value will be set to the default, and omitted in proto text - * output): - * - * - * f { - * a : 22 - * b { - * d : 1 - * } - * } - * - * A repeated field is not allowed except at the last position of a - * paths string. - * - * If a FieldMask object is not present in a get operation, the - * operation applies to all fields (as if a FieldMask of all fields - * had been specified). - * - * Note that a field mask does not necessarily apply to the - * top-level response message. In case of a REST get operation, the - * field mask applies directly to the response, but in case of a REST - * list operation, the mask instead applies to each individual message - * in the returned resource list. In case of a REST custom method, - * other definitions may be used. Where the mask applies will be - * clearly documented together with its declaration in the API. In - * any case, the effect on the returned resource/resources is required - * behavior for APIs. - * - * # Field Masks in Update Operations - * - * A field mask in update operations specifies which fields of the - * targeted resource are going to be updated. The API is required - * to only change the values of the fields as specified in the mask - * and leave the others untouched. If a resource is passed in to - * describe the updated values, the API ignores the values of all - * fields not covered by the mask. - * - * If a repeated field is specified for an update operation, new values will - * be appended to the existing repeated field in the target resource. Note that - * a repeated field is only allowed in the last position of a `paths` string. - * - * If a sub-message is specified in the last position of the field mask for an - * update operation, then new value will be merged into the existing sub-message - * in the target resource. - * - * For example, given the target message: - * - * f { - * b { - * d: 1 - * x: 2 - * } - * c: [1] - * } - * - * And an update message: - * - * f { - * b { - * d: 10 - * } - * c: [2] - * } - * - * then if the field mask is: - * - * paths: ["f.b", "f.c"] - * - * then the result will be: - * - * f { - * b { - * d: 10 - * x: 2 - * } - * c: [1, 2] - * } - * - * An implementation may provide options to override this default behavior for - * repeated and message fields. - * - * In order to reset a field's value to the default, the field must - * be in the mask and set to the default value in the provided resource. - * Hence, in order to reset all fields of a resource, provide a default - * instance of the resource and set all fields in the mask, or do - * not provide a mask as described below. - * - * If a field mask is not present on update, the operation applies to - * all fields (as if a field mask of all fields has been specified). - * Note that in the presence of schema evolution, this may mean that - * fields the client does not know and has therefore not filled into - * the request will be reset to their default. If this is unwanted - * behavior, a specific service may require a client to always specify - * a field mask, producing an error if not. - * - * As with get operations, the location of the resource which - * describes the updated values in the request message depends on the - * operation kind. In any case, the effect of the field mask is - * required to be honored by the API. - * - * ## Considerations for HTTP REST - * - * The HTTP kind of an update operation which uses a field mask must - * be set to PATCH instead of PUT in order to satisfy HTTP semantics - * (PUT must only be used for full updates). - * - * # JSON Encoding of Field Masks - * - * In JSON, a field mask is encoded as a single string where paths are - * separated by a comma. Fields name in each path are converted - * to/from lower-camel naming conventions. - * - * As an example, consider the following message declarations: - * - * message Profile { - * User user = 1; - * Photo photo = 2; - * } - * message User { - * string display_name = 1; - * string address = 2; - * } - * - * In proto a field mask for `Profile` may look as such: - * - * mask { - * paths: "user.display_name" - * paths: "photo" - * } - * - * In JSON, the same mask is represented as below: - * - * { - * mask: "user.displayName,photo" - * } - * - * # Field Masks and Oneof Fields - * - * Field masks treat fields in oneofs just as regular fields. Consider the - * following message: - * - * message SampleMessage { - * oneof test_oneof { - * string name = 4; - * SubMessage sub_message = 9; - * } - * } - * - * The field mask can be: - * - * mask { - * paths: "name" - * } - * - * Or: - * - * mask { - * paths: "sub_message" - * } - * - * Note that oneof type names ("test_oneof" in this case) cannot be used in - * paths. - * - * ## Field Mask Verification - * - * The implementation of any API method which has a FieldMask type field in the - * request should verify the included field paths, and return an - * `INVALID_ARGUMENT` error if any path is unmappable. - **/ -GPB_FINAL @interface GPBFieldMask : GPBMessage - -/** The set of field mask paths. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *pathsArray; -/** The number of items in @c pathsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger pathsArray_Count; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBFieldMask.pbobjc.h" diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.h b/objectivec/google/protobuf/SourceContext.pbobjc.h index 40fa6b808191..321dfec993b2 100644 --- a/objectivec/google/protobuf/SourceContext.pbobjc.h +++ b/objectivec/google/protobuf/SourceContext.pbobjc.h @@ -1,77 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/source_context.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBSourceContextRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBSourceContextRoot : GPBRootObject -@end - -#pragma mark - GPBSourceContext - -typedef GPB_ENUM(GPBSourceContext_FieldNumber) { - GPBSourceContext_FieldNumber_FileName = 1, -}; - -/** - * `SourceContext` represents information about the source of a - * protobuf element, like the file in which it is defined. - **/ -GPB_FINAL @interface GPBSourceContext : GPBMessage - -/** - * The path-qualified name of the .proto file that contained the associated - * protobuf element. For example: `"google/protobuf/source_context.proto"`. - **/ -@property(nonatomic, readwrite, copy, null_resettable) NSString *fileName; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBSourceContext.pbobjc.h" diff --git a/objectivec/google/protobuf/Struct.pbobjc.h b/objectivec/google/protobuf/Struct.pbobjc.h index ce666bec5aee..1173d16fac60 100644 --- a/objectivec/google/protobuf/Struct.pbobjc.h +++ b/objectivec/google/protobuf/Struct.pbobjc.h @@ -1,204 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/struct.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -@class GPBListValue; -@class GPBStruct; -@class GPBValue; - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - Enum GPBNullValue - -/** - * `NullValue` is a singleton enumeration to represent the null value for the - * `Value` type union. - * - * The JSON representation for `NullValue` is JSON `null`. - **/ -typedef GPB_ENUM(GPBNullValue) { - /** - * Value used if any message's field encounters a value that is not defined - * by this enum. The message will also have C functions to get/set the rawValue - * of the field. - **/ - GPBNullValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, - /** Null value. */ - GPBNullValue_NullValue = 0, -}; - -GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void); - -/** - * Checks to see if the given value is defined by the enum or was not known at - * the time this source was generated. - **/ -BOOL GPBNullValue_IsValidValue(int32_t value); - -#pragma mark - GPBStructRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBStructRoot : GPBRootObject -@end - -#pragma mark - GPBStruct - -typedef GPB_ENUM(GPBStruct_FieldNumber) { - GPBStruct_FieldNumber_Fields = 1, -}; - -/** - * `Struct` represents a structured data value, consisting of fields - * which map to dynamically typed values. In some languages, `Struct` - * might be supported by a native representation. For example, in - * scripting languages like JS a struct is represented as an - * object. The details of that representation are described together - * with the proto support for the language. - * - * The JSON representation for `Struct` is JSON object. - **/ -GPB_FINAL @interface GPBStruct : GPBMessage - -/** Unordered map of dynamically typed values. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *fields; -/** The number of items in @c fields without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger fields_Count; - -@end - -#pragma mark - GPBValue - -typedef GPB_ENUM(GPBValue_FieldNumber) { - GPBValue_FieldNumber_NullValue = 1, - GPBValue_FieldNumber_NumberValue = 2, - GPBValue_FieldNumber_StringValue = 3, - GPBValue_FieldNumber_BoolValue = 4, - GPBValue_FieldNumber_StructValue = 5, - GPBValue_FieldNumber_ListValue = 6, -}; - -typedef GPB_ENUM(GPBValue_Kind_OneOfCase) { - GPBValue_Kind_OneOfCase_GPBUnsetOneOfCase = 0, - GPBValue_Kind_OneOfCase_NullValue = 1, - GPBValue_Kind_OneOfCase_NumberValue = 2, - GPBValue_Kind_OneOfCase_StringValue = 3, - GPBValue_Kind_OneOfCase_BoolValue = 4, - GPBValue_Kind_OneOfCase_StructValue = 5, - GPBValue_Kind_OneOfCase_ListValue = 6, -}; - -/** - * `Value` represents a dynamically typed value which can be either - * null, a number, a string, a boolean, a recursive struct value, or a - * list of values. A producer of value is expected to set one of that - * variants, absence of any variant indicates an error. - * - * The JSON representation for `Value` is JSON value. - **/ -GPB_FINAL @interface GPBValue : GPBMessage - -/** The kind of value. */ -@property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase; - -/** Represents a null value. */ -@property(nonatomic, readwrite) GPBNullValue nullValue; - -/** Represents a double value. */ -@property(nonatomic, readwrite) double numberValue; - -/** Represents a string value. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue; - -/** Represents a boolean value. */ -@property(nonatomic, readwrite) BOOL boolValue; - -/** Represents a structured value. */ -@property(nonatomic, readwrite, strong, null_resettable) GPBStruct *structValue; - -/** Represents a repeated `Value`. */ -@property(nonatomic, readwrite, strong, null_resettable) GPBListValue *listValue; - -@end - -/** - * Fetches the raw value of a @c GPBValue's @c nullValue property, even - * if the value was not defined by the enum at the time the code was generated. - **/ -int32_t GPBValue_NullValue_RawValue(GPBValue *message); -/** - * Sets the raw value of an @c GPBValue's @c nullValue property, allowing - * it to be set to a value that was not defined by the enum at the time the code - * was generated. - **/ -void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value); - -/** - * Clears whatever value was set for the oneof 'kind'. - **/ -void GPBValue_ClearKindOneOfCase(GPBValue *message); - -#pragma mark - GPBListValue - -typedef GPB_ENUM(GPBListValue_FieldNumber) { - GPBListValue_FieldNumber_ValuesArray = 1, -}; - -/** - * `ListValue` is a wrapper around a repeated field of values. - * - * The JSON representation for `ListValue` is JSON array. - **/ -GPB_FINAL @interface GPBListValue : GPBMessage - -/** Repeated field of dynamically typed values. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *valuesArray; -/** The number of items in @c valuesArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger valuesArray_Count; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBStruct.pbobjc.h" diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.h b/objectivec/google/protobuf/Timestamp.pbobjc.h index 0871e5cdd4ea..6a7cef84492a 100644 --- a/objectivec/google/protobuf/Timestamp.pbobjc.h +++ b/objectivec/google/protobuf/Timestamp.pbobjc.h @@ -1,167 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/timestamp.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBTimestampRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBTimestampRoot : GPBRootObject -@end - -#pragma mark - GPBTimestamp - -typedef GPB_ENUM(GPBTimestamp_FieldNumber) { - GPBTimestamp_FieldNumber_Seconds = 1, - GPBTimestamp_FieldNumber_Nanos = 2, -}; - -/** - * A Timestamp represents a point in time independent of any time zone or local - * calendar, encoded as a count of seconds and fractions of seconds at - * nanosecond resolution. The count is relative to an epoch at UTC midnight on - * January 1, 1970, in the proleptic Gregorian calendar which extends the - * Gregorian calendar backwards to year one. - * - * All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap - * second table is needed for interpretation, using a [24-hour linear - * smear](https://developers.google.com/time/smear). - * - * The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By - * restricting to that range, we ensure that we can convert to and from [RFC - * 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. - * - * # Examples - * - * Example 1: Compute Timestamp from POSIX `time()`. - * - * Timestamp timestamp; - * timestamp.set_seconds(time(NULL)); - * timestamp.set_nanos(0); - * - * Example 2: Compute Timestamp from POSIX `gettimeofday()`. - * - * struct timeval tv; - * gettimeofday(&tv, NULL); - * - * Timestamp timestamp; - * timestamp.set_seconds(tv.tv_sec); - * timestamp.set_nanos(tv.tv_usec * 1000); - * - * Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. - * - * FILETIME ft; - * GetSystemTimeAsFileTime(&ft); - * UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; - * - * // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z - * // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. - * Timestamp timestamp; - * timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); - * timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); - * - * Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. - * - * long millis = System.currentTimeMillis(); - * - * Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) - * .setNanos((int) ((millis % 1000) * 1000000)).build(); - * - * - * Example 5: Compute Timestamp from current time in Python. - * - * timestamp = Timestamp() - * timestamp.GetCurrentTime() - * - * # JSON Mapping - * - * In JSON format, the Timestamp type is encoded as a string in the - * [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the - * format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" - * where {year} is always expressed using four digits while {month}, {day}, - * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional - * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), - * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone - * is required. A proto3 JSON serializer should always use UTC (as indicated by - * "Z") when printing the Timestamp type and a proto3 JSON parser should be - * able to accept both UTC and other timezones (as indicated by an offset). - * - * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past - * 01:30 UTC on January 15, 2017. - * - * In JavaScript, one can convert a Date object to this format using the - * standard - * [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) - * method. In Python, a standard `datetime.datetime` object can be converted - * to this format using - * [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with - * the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use - * the Joda Time's [`ISODateTimeFormat.dateTime()`]( - * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D - * ) to obtain a formatter capable of generating timestamps in this format. - **/ -GPB_FINAL @interface GPBTimestamp : GPBMessage - -/** - * Represents seconds of UTC time since Unix epoch - * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - * 9999-12-31T23:59:59Z inclusive. - **/ -@property(nonatomic, readwrite) int64_t seconds; - -/** - * Non-negative fractions of a second at nanosecond resolution. Negative - * second values with fractions must still have non-negative nanos values - * that count forward in time. Must be from 0 to 999,999,999 - * inclusive. - **/ -@property(nonatomic, readwrite) int32_t nanos; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBTimestamp.pbobjc.h" diff --git a/objectivec/google/protobuf/Type.pbobjc.h b/objectivec/google/protobuf/Type.pbobjc.h index c2e997bb489a..e14e7cdcae8f 100644 --- a/objectivec/google/protobuf/Type.pbobjc.h +++ b/objectivec/google/protobuf/Type.pbobjc.h @@ -1,444 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/type.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -@class GPBAny; -@class GPBEnumValue; -@class GPBField; -@class GPBOption; -@class GPBSourceContext; - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - Enum GPBSyntax - -/** The syntax in which a protocol buffer element is defined. */ -typedef GPB_ENUM(GPBSyntax) { - /** - * Value used if any message's field encounters a value that is not defined - * by this enum. The message will also have C functions to get/set the rawValue - * of the field. - **/ - GPBSyntax_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, - /** Syntax `proto2`. */ - GPBSyntax_SyntaxProto2 = 0, - - /** Syntax `proto3`. */ - GPBSyntax_SyntaxProto3 = 1, -}; - -GPBEnumDescriptor *GPBSyntax_EnumDescriptor(void); - -/** - * Checks to see if the given value is defined by the enum or was not known at - * the time this source was generated. - **/ -BOOL GPBSyntax_IsValidValue(int32_t value); - -#pragma mark - Enum GPBField_Kind - -/** Basic field types. */ -typedef GPB_ENUM(GPBField_Kind) { - /** - * Value used if any message's field encounters a value that is not defined - * by this enum. The message will also have C functions to get/set the rawValue - * of the field. - **/ - GPBField_Kind_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, - /** Field type unknown. */ - GPBField_Kind_TypeUnknown = 0, - - /** Field type double. */ - GPBField_Kind_TypeDouble = 1, - - /** Field type float. */ - GPBField_Kind_TypeFloat = 2, - - /** Field type int64. */ - GPBField_Kind_TypeInt64 = 3, - - /** Field type uint64. */ - GPBField_Kind_TypeUint64 = 4, - - /** Field type int32. */ - GPBField_Kind_TypeInt32 = 5, - - /** Field type fixed64. */ - GPBField_Kind_TypeFixed64 = 6, - - /** Field type fixed32. */ - GPBField_Kind_TypeFixed32 = 7, - - /** Field type bool. */ - GPBField_Kind_TypeBool = 8, - - /** Field type string. */ - GPBField_Kind_TypeString = 9, - - /** Field type group. Proto2 syntax only, and deprecated. */ - GPBField_Kind_TypeGroup = 10, - - /** Field type message. */ - GPBField_Kind_TypeMessage = 11, - - /** Field type bytes. */ - GPBField_Kind_TypeBytes = 12, - - /** Field type uint32. */ - GPBField_Kind_TypeUint32 = 13, - - /** Field type enum. */ - GPBField_Kind_TypeEnum = 14, - - /** Field type sfixed32. */ - GPBField_Kind_TypeSfixed32 = 15, - - /** Field type sfixed64. */ - GPBField_Kind_TypeSfixed64 = 16, - - /** Field type sint32. */ - GPBField_Kind_TypeSint32 = 17, - - /** Field type sint64. */ - GPBField_Kind_TypeSint64 = 18, -}; - -GPBEnumDescriptor *GPBField_Kind_EnumDescriptor(void); - -/** - * Checks to see if the given value is defined by the enum or was not known at - * the time this source was generated. - **/ -BOOL GPBField_Kind_IsValidValue(int32_t value); - -#pragma mark - Enum GPBField_Cardinality - -/** Whether a field is optional, required, or repeated. */ -typedef GPB_ENUM(GPBField_Cardinality) { - /** - * Value used if any message's field encounters a value that is not defined - * by this enum. The message will also have C functions to get/set the rawValue - * of the field. - **/ - GPBField_Cardinality_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, - /** For fields with unknown cardinality. */ - GPBField_Cardinality_CardinalityUnknown = 0, - - /** For optional fields. */ - GPBField_Cardinality_CardinalityOptional = 1, - - /** For required fields. Proto2 syntax only. */ - GPBField_Cardinality_CardinalityRequired = 2, - - /** For repeated fields. */ - GPBField_Cardinality_CardinalityRepeated = 3, -}; - -GPBEnumDescriptor *GPBField_Cardinality_EnumDescriptor(void); - -/** - * Checks to see if the given value is defined by the enum or was not known at - * the time this source was generated. - **/ -BOOL GPBField_Cardinality_IsValidValue(int32_t value); - -#pragma mark - GPBTypeRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBTypeRoot : GPBRootObject -@end - -#pragma mark - GPBType - -typedef GPB_ENUM(GPBType_FieldNumber) { - GPBType_FieldNumber_Name = 1, - GPBType_FieldNumber_FieldsArray = 2, - GPBType_FieldNumber_OneofsArray = 3, - GPBType_FieldNumber_OptionsArray = 4, - GPBType_FieldNumber_SourceContext = 5, - GPBType_FieldNumber_Syntax = 6, -}; - -/** - * A protocol buffer message type. - **/ -GPB_FINAL @interface GPBType : GPBMessage - -/** The fully qualified message name. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** The list of fields. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fieldsArray; -/** The number of items in @c fieldsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger fieldsArray_Count; - -/** The list of types appearing in `oneof` definitions in this type. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *oneofsArray; -/** The number of items in @c oneofsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger oneofsArray_Count; - -/** The protocol buffer options. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; -/** The number of items in @c optionsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger optionsArray_Count; - -/** The source context. */ -@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext; -/** Test to see if @c sourceContext has been set. */ -@property(nonatomic, readwrite) BOOL hasSourceContext; - -/** The source syntax. */ -@property(nonatomic, readwrite) GPBSyntax syntax; - -@end - -/** - * Fetches the raw value of a @c GPBType's @c syntax property, even - * if the value was not defined by the enum at the time the code was generated. - **/ -int32_t GPBType_Syntax_RawValue(GPBType *message); -/** - * Sets the raw value of an @c GPBType's @c syntax property, allowing - * it to be set to a value that was not defined by the enum at the time the code - * was generated. - **/ -void SetGPBType_Syntax_RawValue(GPBType *message, int32_t value); - -#pragma mark - GPBField - -typedef GPB_ENUM(GPBField_FieldNumber) { - GPBField_FieldNumber_Kind = 1, - GPBField_FieldNumber_Cardinality = 2, - GPBField_FieldNumber_Number = 3, - GPBField_FieldNumber_Name = 4, - GPBField_FieldNumber_TypeURL = 6, - GPBField_FieldNumber_OneofIndex = 7, - GPBField_FieldNumber_Packed = 8, - GPBField_FieldNumber_OptionsArray = 9, - GPBField_FieldNumber_JsonName = 10, - GPBField_FieldNumber_DefaultValue = 11, -}; - -/** - * A single field of a message type. - **/ -GPB_FINAL @interface GPBField : GPBMessage - -/** The field type. */ -@property(nonatomic, readwrite) GPBField_Kind kind; - -/** The field cardinality. */ -@property(nonatomic, readwrite) GPBField_Cardinality cardinality; - -/** The field number. */ -@property(nonatomic, readwrite) int32_t number; - -/** The field name. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** - * The field type URL, without the scheme, for message or enumeration - * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. - **/ -@property(nonatomic, readwrite, copy, null_resettable) NSString *typeURL; - -/** - * The index of the field type in `Type.oneofs`, for message or enumeration - * types. The first type has index 1; zero means the type is not in the list. - **/ -@property(nonatomic, readwrite) int32_t oneofIndex; - -/** Whether to use alternative packed wire representation. */ -@property(nonatomic, readwrite) BOOL packed; - -/** The protocol buffer options. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; -/** The number of items in @c optionsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger optionsArray_Count; - -/** The field JSON name. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *jsonName; - -/** The string value of the default value of this field. Proto2 syntax only. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *defaultValue; - -@end - -/** - * Fetches the raw value of a @c GPBField's @c kind property, even - * if the value was not defined by the enum at the time the code was generated. - **/ -int32_t GPBField_Kind_RawValue(GPBField *message); -/** - * Sets the raw value of an @c GPBField's @c kind property, allowing - * it to be set to a value that was not defined by the enum at the time the code - * was generated. - **/ -void SetGPBField_Kind_RawValue(GPBField *message, int32_t value); - -/** - * Fetches the raw value of a @c GPBField's @c cardinality property, even - * if the value was not defined by the enum at the time the code was generated. - **/ -int32_t GPBField_Cardinality_RawValue(GPBField *message); -/** - * Sets the raw value of an @c GPBField's @c cardinality property, allowing - * it to be set to a value that was not defined by the enum at the time the code - * was generated. - **/ -void SetGPBField_Cardinality_RawValue(GPBField *message, int32_t value); - -#pragma mark - GPBEnum - -typedef GPB_ENUM(GPBEnum_FieldNumber) { - GPBEnum_FieldNumber_Name = 1, - GPBEnum_FieldNumber_EnumvalueArray = 2, - GPBEnum_FieldNumber_OptionsArray = 3, - GPBEnum_FieldNumber_SourceContext = 4, - GPBEnum_FieldNumber_Syntax = 5, -}; - -/** - * Enum type definition. - **/ -GPB_FINAL @interface GPBEnum : GPBMessage - -/** Enum type name. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** Enum value definitions. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *enumvalueArray; -/** The number of items in @c enumvalueArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger enumvalueArray_Count; - -/** Protocol buffer options. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; -/** The number of items in @c optionsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger optionsArray_Count; - -/** The source context. */ -@property(nonatomic, readwrite, strong, null_resettable) GPBSourceContext *sourceContext; -/** Test to see if @c sourceContext has been set. */ -@property(nonatomic, readwrite) BOOL hasSourceContext; - -/** The source syntax. */ -@property(nonatomic, readwrite) GPBSyntax syntax; - -@end - -/** - * Fetches the raw value of a @c GPBEnum's @c syntax property, even - * if the value was not defined by the enum at the time the code was generated. - **/ -int32_t GPBEnum_Syntax_RawValue(GPBEnum *message); -/** - * Sets the raw value of an @c GPBEnum's @c syntax property, allowing - * it to be set to a value that was not defined by the enum at the time the code - * was generated. - **/ -void SetGPBEnum_Syntax_RawValue(GPBEnum *message, int32_t value); - -#pragma mark - GPBEnumValue - -typedef GPB_ENUM(GPBEnumValue_FieldNumber) { - GPBEnumValue_FieldNumber_Name = 1, - GPBEnumValue_FieldNumber_Number = 2, - GPBEnumValue_FieldNumber_OptionsArray = 3, -}; - -/** - * Enum value definition. - **/ -GPB_FINAL @interface GPBEnumValue : GPBMessage - -/** Enum value name. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** Enum value number. */ -@property(nonatomic, readwrite) int32_t number; - -/** Protocol buffer options. */ -@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *optionsArray; -/** The number of items in @c optionsArray without causing the array to be created. */ -@property(nonatomic, readonly) NSUInteger optionsArray_Count; - -@end - -#pragma mark - GPBOption - -typedef GPB_ENUM(GPBOption_FieldNumber) { - GPBOption_FieldNumber_Name = 1, - GPBOption_FieldNumber_Value = 2, -}; - -/** - * A protocol buffer option, which can be attached to a message, field, - * enumeration, etc. - **/ -GPB_FINAL @interface GPBOption : GPBMessage - -/** - * The option's name. For protobuf built-in options (options defined in - * descriptor.proto), this is the short name. For example, `"map_entry"`. - * For custom options, it should be the fully-qualified name. For example, - * `"google.api.http"`. - **/ -@property(nonatomic, readwrite, copy, null_resettable) NSString *name; - -/** - * The option's value packed in an Any message. If the value is a primitive, - * the corresponding wrapper type defined in google/protobuf/wrappers.proto - * should be used. If the value is an enum, it should be stored as an int32 - * value using the google.protobuf.Int32Value type. - **/ -@property(nonatomic, readwrite, strong, null_resettable) GPBAny *value; -/** Test to see if @c value has been set. */ -@property(nonatomic, readwrite) BOOL hasValue; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBType.pbobjc.h" diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.h b/objectivec/google/protobuf/Wrappers.pbobjc.h index 37f284405467..8365afc6df21 100644 --- a/objectivec/google/protobuf/Wrappers.pbobjc.h +++ b/objectivec/google/protobuf/Wrappers.pbobjc.h @@ -1,219 +1,2 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: google/protobuf/wrappers.proto - -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif - -#if GOOGLE_PROTOBUF_OBJC_VERSION < 30003 -#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. -#endif -#if 30003 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION -#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. -#endif - -// @@protoc_insertion_point(imports) - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -CF_EXTERN_C_BEGIN - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - GPBWrappersRoot - -/** - * Exposes the extension registry for this file. - * - * The base class provides: - * @code - * + (GPBExtensionRegistry *)extensionRegistry; - * @endcode - * which is a @c GPBExtensionRegistry that includes all the extensions defined by - * this file and all files that it depends on. - **/ -GPB_FINAL @interface GPBWrappersRoot : GPBRootObject -@end - -#pragma mark - GPBDoubleValue - -typedef GPB_ENUM(GPBDoubleValue_FieldNumber) { - GPBDoubleValue_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `double`. - * - * The JSON representation for `DoubleValue` is JSON number. - **/ -GPB_FINAL @interface GPBDoubleValue : GPBMessage - -/** The double value. */ -@property(nonatomic, readwrite) double value; - -@end - -#pragma mark - GPBFloatValue - -typedef GPB_ENUM(GPBFloatValue_FieldNumber) { - GPBFloatValue_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `float`. - * - * The JSON representation for `FloatValue` is JSON number. - **/ -GPB_FINAL @interface GPBFloatValue : GPBMessage - -/** The float value. */ -@property(nonatomic, readwrite) float value; - -@end - -#pragma mark - GPBInt64Value - -typedef GPB_ENUM(GPBInt64Value_FieldNumber) { - GPBInt64Value_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `int64`. - * - * The JSON representation for `Int64Value` is JSON string. - **/ -GPB_FINAL @interface GPBInt64Value : GPBMessage - -/** The int64 value. */ -@property(nonatomic, readwrite) int64_t value; - -@end - -#pragma mark - GPBUInt64Value - -typedef GPB_ENUM(GPBUInt64Value_FieldNumber) { - GPBUInt64Value_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `uint64`. - * - * The JSON representation for `UInt64Value` is JSON string. - **/ -GPB_FINAL @interface GPBUInt64Value : GPBMessage - -/** The uint64 value. */ -@property(nonatomic, readwrite) uint64_t value; - -@end - -#pragma mark - GPBInt32Value - -typedef GPB_ENUM(GPBInt32Value_FieldNumber) { - GPBInt32Value_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `int32`. - * - * The JSON representation for `Int32Value` is JSON number. - **/ -GPB_FINAL @interface GPBInt32Value : GPBMessage - -/** The int32 value. */ -@property(nonatomic, readwrite) int32_t value; - -@end - -#pragma mark - GPBUInt32Value - -typedef GPB_ENUM(GPBUInt32Value_FieldNumber) { - GPBUInt32Value_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `uint32`. - * - * The JSON representation for `UInt32Value` is JSON number. - **/ -GPB_FINAL @interface GPBUInt32Value : GPBMessage - -/** The uint32 value. */ -@property(nonatomic, readwrite) uint32_t value; - -@end - -#pragma mark - GPBBoolValue - -typedef GPB_ENUM(GPBBoolValue_FieldNumber) { - GPBBoolValue_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `bool`. - * - * The JSON representation for `BoolValue` is JSON `true` and `false`. - **/ -GPB_FINAL @interface GPBBoolValue : GPBMessage - -/** The bool value. */ -@property(nonatomic, readwrite) BOOL value; - -@end - -#pragma mark - GPBStringValue - -typedef GPB_ENUM(GPBStringValue_FieldNumber) { - GPBStringValue_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `string`. - * - * The JSON representation for `StringValue` is JSON string. - **/ -GPB_FINAL @interface GPBStringValue : GPBMessage - -/** The string value. */ -@property(nonatomic, readwrite, copy, null_resettable) NSString *value; - -@end - -#pragma mark - GPBBytesValue - -typedef GPB_ENUM(GPBBytesValue_FieldNumber) { - GPBBytesValue_FieldNumber_Value = 1, -}; - -/** - * Wrapper message for `bytes`. - * - * The JSON representation for `BytesValue` is JSON string. - **/ -GPB_FINAL @interface GPBBytesValue : GPBMessage - -/** The bytes value. */ -@property(nonatomic, readwrite, copy, null_resettable) NSData *value; - -@end - -NS_ASSUME_NONNULL_END - -CF_EXTERN_C_END - -#pragma clang diagnostic pop - -// @@protoc_insertion_point(global_scope) +// Moved to root of objectivec directory, shim to keep anyone's imports working. +#import "GPBWrappers.pbobjc.h" diff --git a/php/composer.json b/php/composer.json index b47065b78b4d..abcc293b2b05 100644 --- a/php/composer.json +++ b/php/composer.json @@ -23,6 +23,7 @@ } }, "scripts": { - "test": "(cd tests && rm -rf generated && mkdir -p generated && ../../src/protoc --php_out=generated -I../../src -I. proto/empty/echo.proto proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_reserved_enum_lower.proto proto/test_reserved_enum_upper.proto proto/test_reserved_enum_value_lower.proto proto/test_reserved_enum_value_upper.proto proto/test_reserved_message_lower.proto proto/test_reserved_message_upper.proto proto/test_service.proto proto/test_service_namespace.proto proto/test_wrapper_type_setters.proto proto/test_descriptors.proto) && (cd ../src && ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto) && vendor/bin/phpunit" + "test": "tests/generate_protos.sh && vendor/bin/phpunit", + "aggregate_metadata_test": "tests/generate_protos.sh --aggregate_metadata && vendor/bin/phpunit" } } diff --git a/php/ext/google/protobuf/arena.c b/php/ext/google/protobuf/arena.c new file mode 100644 index 000000000000..035dfcad760f --- /dev/null +++ b/php/ext/google/protobuf/arena.c @@ -0,0 +1,95 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#include + +#include "php-upb.h" + +// ----------------------------------------------------------------------------- +// Arena +// ----------------------------------------------------------------------------- + +typedef struct Arena { + zend_object std; + upb_arena* arena; +} Arena; + +zend_class_entry *Arena_class_entry; +static zend_object_handlers Arena_object_handlers; + +// PHP Object Handlers ///////////////////////////////////////////////////////// + +static zend_object* Arena_Create(zend_class_entry *class_type) { + Arena *intern = emalloc(sizeof(Arena)); + zend_object_std_init(&intern->std, class_type); + intern->std.handlers = &Arena_object_handlers; + intern->arena = upb_arena_new(); + // Skip object_properties_init(), we don't allow derived classes. + return &intern->std; +} + +static void Arena_Free(zend_object* obj) { + Arena* intern = (Arena*)obj; + upb_arena_free(intern->arena); + zend_object_std_dtor(&intern->std); +} + +// C Functions from arena.h //////////////////////////////////////////////////// + +void Arena_Init(zval* val) { + ZVAL_OBJ(val, Arena_Create(Arena_class_entry)); +} + +upb_arena *Arena_Get(zval *val) { + Arena *a = (Arena*)Z_OBJ_P(val); + return a->arena; +} + +// ----------------------------------------------------------------------------- +// Module init. +// ----------------------------------------------------------------------------- + +// No public methods. +static const zend_function_entry Arena_methods[] = { + ZEND_FE_END +}; + +void Arena_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\Arena", Arena_methods); + Arena_class_entry = zend_register_internal_class(&tmp_ce); + Arena_class_entry->create_object = Arena_Create; + Arena_class_entry->ce_flags |= ZEND_ACC_FINAL; + + memcpy(&Arena_object_handlers, &std_object_handlers, + sizeof(zend_object_handlers)); + Arena_object_handlers.free_obj = Arena_Free; +} diff --git a/php/ext/google/protobuf/arena.h b/php/ext/google/protobuf/arena.h new file mode 100644 index 000000000000..67e165d37d35 --- /dev/null +++ b/php/ext/google/protobuf/arena.h @@ -0,0 +1,47 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#ifndef PHP_PROTOBUF_ARENA_H_ +#define PHP_PROTOBUF_ARENA_H_ + +#include + +#include "php-upb.h" + +// Registers the PHP Arena class. +void Arena_ModuleInit(); + +// Creates and returns a new arena object that wraps a new upb_arena*. +void Arena_Init(zval *val); + +// Gets the underlying upb_arena from this arena object. +upb_arena *Arena_Get(zval *arena); + +#endif // PHP_PROTOBUF_ARENA_H_ diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 5174f4a78bb6..0fa9bf0e5bb3 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -28,389 +28,311 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include "array.h" + #include #include -#include "protobuf.h" +#include -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) - ZEND_ARG_INFO(0, index) -ZEND_END_ARG_INFO() +// This is not self-contained: it must be after other Zend includes. +#include -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) - ZEND_ARG_INFO(0, index) - ZEND_ARG_INFO(0, newval) -ZEND_END_ARG_INFO() +#include "arena.h" +#include "convert.h" +#include "def.h" +#include "message.h" +#include "php-upb.h" +#include "protobuf.h" -ZEND_BEGIN_ARG_INFO(arginfo_void, 0) -ZEND_END_ARG_INFO() +static void RepeatedFieldIter_make(zval *val, zval *repeated_field); -static zend_function_entry repeated_field_methods[] = { - PHP_ME(RepeatedField, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, append, NULL, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, count, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedField, getIterator, arginfo_void, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; +// ----------------------------------------------------------------------------- +// RepeatedField +// ----------------------------------------------------------------------------- -static zend_function_entry repeated_field_iter_methods[] = { - PHP_ME(RepeatedFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(RepeatedFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; +typedef struct { + zend_object std; + zval arena; + upb_array *array; + upb_fieldtype_t type; + const Descriptor* desc; // When values are messages. +} RepeatedField; -// Forward declare static functions. - -static int repeated_field_array_init(zval *array, upb_fieldtype_t type, - uint size ZEND_FILE_LINE_DC); -static void repeated_field_write_dimension(zval *object, zval *offset, - zval *value TSRMLS_DC); -static HashTable *repeated_field_get_gc(zval *object, CACHED_VALUE **table, - int *n TSRMLS_DC); -#if PHP_MAJOR_VERSION < 7 -static zend_object_value repeated_field_create(zend_class_entry *ce TSRMLS_DC); -static zend_object_value repeated_field_iter_create(zend_class_entry *ce TSRMLS_DC); -#else -static zend_object *repeated_field_create(zend_class_entry *ce TSRMLS_DC); -static zend_object *repeated_field_iter_create(zend_class_entry *ce TSRMLS_DC); -#endif +zend_class_entry *RepeatedField_class_entry; +static zend_object_handlers RepeatedField_object_handlers; -// ----------------------------------------------------------------------------- -// RepeatedField creation/destruction -// ----------------------------------------------------------------------------- +// PHP Object Handlers ///////////////////////////////////////////////////////// -zend_class_entry* repeated_field_type; -zend_class_entry* repeated_field_iter_type; -zend_object_handlers* repeated_field_handlers; -zend_object_handlers* repeated_field_iter_handlers; - -// Define object free method. -PHP_PROTO_OBJECT_FREE_START(RepeatedField, repeated_field) -#if PHP_MAJOR_VERSION < 7 -php_proto_zval_ptr_dtor(intern->array); -#else -php_proto_zval_ptr_dtor(&intern->array); -#endif -PHP_PROTO_OBJECT_FREE_END - -PHP_PROTO_OBJECT_EMPTY_DTOR_START(RepeatedField, repeated_field) -PHP_PROTO_OBJECT_DTOR_END - -// Define object create method. -PHP_PROTO_OBJECT_CREATE_START(RepeatedField, repeated_field) -#if PHP_MAJOR_VERSION < 7 -intern->array = NULL; -#endif -intern->type = 0; -intern->msg_ce = NULL; -PHP_PROTO_OBJECT_CREATE_END(RepeatedField, repeated_field) - -// Init class entry. -PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\RepeatedField", - RepeatedField, repeated_field) -zend_class_implements(repeated_field_type TSRMLS_CC, 3, spl_ce_ArrayAccess, - zend_ce_aggregate, spl_ce_Countable); -repeated_field_handlers->write_dimension = repeated_field_write_dimension; -repeated_field_handlers->get_gc = repeated_field_get_gc; -PHP_PROTO_INIT_CLASS_END - -// Define array element free function. -#if PHP_MAJOR_VERSION < 7 -static inline void php_proto_array_string_release(void *value) { - zval_ptr_dtor(value); +/** + * RepeatedField_create() + * + * PHP class entry function to allocate and initialize a new RepeatedField + * object. + */ +static zend_object* RepeatedField_create(zend_class_entry *class_type) { + RepeatedField *intern = emalloc(sizeof(RepeatedField)); + zend_object_std_init(&intern->std, class_type); + intern->std.handlers = &RepeatedField_object_handlers; + Arena_Init(&intern->arena); + intern->array = NULL; + intern->desc = NULL; + // Skip object_properties_init(), we don't allow derived classes. + return &intern->std; } -static inline void php_proto_array_object_release(void *value) { - zval_ptr_dtor(value); -} -static inline void php_proto_array_default_release(void *value) { -} -#else -static inline void php_proto_array_string_release(zval *value) { - void* ptr = Z_PTR_P(value); - zend_string* object = *(zend_string**)ptr; - zend_string_release(object); - efree(ptr); -} -static inline void php_proto_array_object_release(zval *value) { - zval_ptr_dtor(value); -} -static void php_proto_array_default_release(zval* value) { - void* ptr = Z_PTR_P(value); - efree(ptr); +/** + * RepeatedField_dtor() + * + * Object handler to destroy a RepeatedField. This releases all resources + * associated with the message. Note that it is possible to access a destroyed + * object from PHP in rare cases. + */ +static void RepeatedField_destructor(zend_object* obj) { + RepeatedField* intern = (RepeatedField*)obj; + ObjCache_Delete(intern->array); + zval_ptr_dtor(&intern->arena); + zend_object_std_dtor(&intern->std); } -#endif - -static int repeated_field_array_init(zval *array, upb_fieldtype_t type, - uint size ZEND_FILE_LINE_DC) { - PHP_PROTO_ALLOC_ARRAY(array); - - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - zend_hash_init(Z_ARRVAL_P(array), size, NULL, - php_proto_array_string_release, 0); - break; - case UPB_TYPE_MESSAGE: - zend_hash_init(Z_ARRVAL_P(array), size, NULL, - php_proto_array_object_release, 0); - break; - default: - zend_hash_init(Z_ARRVAL_P(array), size, NULL, - php_proto_array_default_release, 0); - } - return SUCCESS; + +/** + * RepeatedField_compare_objects() + * + * Object handler for comparing two repeated field objects. Called whenever PHP + * code does: + * + * $rf1 == $rf2 + */ +static int RepeatedField_compare_objects(zval *rf1, zval *rf2) { + RepeatedField* intern1 = (RepeatedField*)Z_OBJ_P(rf1); + RepeatedField* intern2 = (RepeatedField*)Z_OBJ_P(rf2); + upb_fieldtype_t type = intern1->type; + const upb_msgdef *m = intern1->desc ? intern1->desc->msgdef : NULL; + + if (type != intern2->type) return 1; + if (intern1->desc != intern2->desc) return 1; + + return ArrayEq(intern1->array, intern2->array, type, m) ? 0 : 1; } -// ----------------------------------------------------------------------------- -// RepeatedField Handlers -// ----------------------------------------------------------------------------- +static HashTable *RepeatedField_GetProperties(PROTO_VAL *object) { + return NULL; // We do not have a properties table. +} -static void repeated_field_write_dimension(zval *object, zval *offset, - zval *value TSRMLS_DC) { - uint64_t index; +static zval *RepeatedField_GetPropertyPtrPtr(PROTO_VAL *object, + PROTO_STR *member, + int type, void **cache_slot) { + return NULL; // We don't offer direct references to our properties. +} - RepeatedField *intern = UNBOX(RepeatedField, object); - HashTable *ht = PHP_PROTO_HASH_OF(intern->array); - int size = native_slot_size(intern->type); +// C Functions from array.h //////////////////////////////////////////////////// - unsigned char memory[NATIVE_SLOT_MAX_SIZE]; - memset(memory, 0, NATIVE_SLOT_MAX_SIZE); +// These are documented in the header file. - if (!native_slot_set_by_array(intern->type, intern->msg_ce, memory, - value TSRMLS_CC)) { +void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, + const upb_fielddef *f, zval *arena) { + if (!arr) { + ZVAL_NULL(val); return; } - if (!offset || Z_TYPE_P(offset) == IS_NULL) { - index = zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array)); - } else { - if (protobuf_convert_to_uint64(offset, &index)) { - if (!zend_hash_index_exists(ht, index)) { - zend_error(E_USER_ERROR, "Element at %llu doesn't exist.\n", - (long long unsigned int)index); - return; - } - } else { - return; - } + if (!ObjCache_Get(arr, val)) { + RepeatedField *intern = emalloc(sizeof(RepeatedField)); + zend_object_std_init(&intern->std, RepeatedField_class_entry); + intern->std.handlers = &RepeatedField_object_handlers; + ZVAL_COPY(&intern->arena, arena); + intern->array = arr; + intern->type = upb_fielddef_type(f); + intern->desc = Descriptor_GetFromFieldDef(f); + // Skip object_properties_init(), we don't allow derived classes. + ObjCache_Add(intern->array, &intern->std); + ZVAL_OBJ(val, &intern->std); } +} - if (intern->type == UPB_TYPE_MESSAGE) { - php_proto_zend_hash_index_update_zval(ht, index, *(zval**)memory); - } else { - php_proto_zend_hash_index_update_mem(ht, index, memory, size, NULL); +upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f, + upb_arena *arena) { + if (Z_ISREF_P(val)) { + ZVAL_DEREF(val); } -} -#if PHP_MAJOR_VERSION < 7 -static HashTable *repeated_field_get_gc(zval *object, zval ***table, - int *n TSRMLS_DC) { -#else -static HashTable *repeated_field_get_gc(zval *object, zval **table, int *n) { -#endif - *table = NULL; - *n = 0; - RepeatedField *intern = UNBOX(RepeatedField, object); - return PHP_PROTO_HASH_OF(intern->array); -} + if (Z_TYPE_P(val) == IS_ARRAY) { + // Auto-construct, eg. [1, 2, 3] -> upb_array([1, 2, 3]). + upb_array *arr = upb_array_new(arena, upb_fielddef_type(f)); + HashTable *table = HASH_OF(val); + HashPosition pos; + upb_fieldtype_t type = upb_fielddef_type(f); + const Descriptor *desc = Descriptor_GetFromFieldDef(f); -// ----------------------------------------------------------------------------- -// C RepeatedField Utilities -// ----------------------------------------------------------------------------- + zend_hash_internal_pointer_reset_ex(table, &pos); + + while (true) { + zval *zv = zend_hash_get_current_data_ex(table, &pos); + upb_msgval val; -void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC) { - HashTable *ht = PHP_PROTO_HASH_OF(intern->array); - void *value; + if (!zv) return arr; - if (intern->type == UPB_TYPE_MESSAGE) { - if (php_proto_zend_hash_index_find_zval(ht, index, (void **)&value) == - FAILURE) { - zend_error(E_USER_ERROR, "Element at %d doesn't exist.\n", index); - return NULL; + if (!Convert_PhpToUpbAutoWrap(zv, &val, type, desc, arena)) { + return NULL; + } + + upb_array_append(arr, val, arena); + zend_hash_move_forward_ex(table, &pos); } - } else { - if (php_proto_zend_hash_index_find_mem(ht, index, (void **)&value) == - FAILURE) { - zend_error(E_USER_ERROR, "Element at %d doesn't exist.\n", index); - return NULL; + } else if (Z_TYPE_P(val) == IS_OBJECT && + Z_OBJCE_P(val) == RepeatedField_class_entry) { + // Unwrap existing RepeatedField object to get the upb_array* inside. + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(val); + const Descriptor *desc = Descriptor_GetFromFieldDef(f); + + if (intern->type != upb_fielddef_type(f) || intern->desc != desc) { + php_error_docref(NULL, E_USER_ERROR, + "Wrong type for this repeated field."); } - } - - return value; -} -void repeated_field_push_native(RepeatedField *intern, void *value) { - HashTable *ht = PHP_PROTO_HASH_OF(intern->array); - int size = native_slot_size(intern->type); - if (intern->type == UPB_TYPE_MESSAGE) { - php_proto_zend_hash_next_index_insert_zval(ht, value); + upb_arena_fuse(arena, Arena_Get(&intern->arena)); + return intern->array; } else { - php_proto_zend_hash_next_index_insert_mem(ht, (void **)value, size, NULL); + php_error_docref(NULL, E_USER_ERROR, "Must be a repeated field"); + return NULL; } } -void repeated_field_ensure_created( - const upb_fielddef *field, - CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC) { - if (ZVAL_IS_NULL(CACHED_PTR_TO_ZVAL_PTR(repeated_field))) { - zval_ptr_dtor(repeated_field); -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(CACHED_PTR_TO_ZVAL_PTR(repeated_field)); -#endif - repeated_field_create_with_field(repeated_field_type, field, - repeated_field PHP_PROTO_TSRMLS_CC); - } -} +bool ArrayEq(const upb_array *a1, const upb_array *a2, upb_fieldtype_t type, + const upb_msgdef *m) { + size_t i; + size_t n; -void repeated_field_create_with_field( - zend_class_entry *ce, const upb_fielddef *field, - CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC) { - upb_fieldtype_t type = upb_fielddef_type(field); - const zend_class_entry *msg_ce = field_type_class(field PHP_PROTO_TSRMLS_CC); - repeated_field_create_with_type(ce, type, msg_ce, - repeated_field PHP_PROTO_TSRMLS_CC); -} + if ((a1 == NULL) != (a2 == NULL)) return false; + if (a1 == NULL) return true; -void repeated_field_create_with_type( - zend_class_entry *ce, upb_fieldtype_t type, const zend_class_entry *msg_ce, - CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC) { - CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(CACHED_PTR_TO_ZVAL_PTR(repeated_field), - repeated_field_type); - - RepeatedField *intern = - UNBOX(RepeatedField, CACHED_TO_ZVAL_PTR(*repeated_field)); - intern->type = type; - intern->msg_ce = msg_ce; -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(intern->array); - repeated_field_array_init(intern->array, intern->type, 0 ZEND_FILE_LINE_CC); -#else - repeated_field_array_init(&intern->array, intern->type, 0 ZEND_FILE_LINE_CC); -#endif - - // TODO(teboring): Link class entry for message and enum + n = upb_array_size(a1); + if (n != upb_array_size(a2)) return false; + + for (i = 0; i < n; i++) { + upb_msgval val1 = upb_array_get(a1, i); + upb_msgval val2 = upb_array_get(a2, i); + if (!ValueEq(val1, val2, type, m)) return false; + } + + return true; } -// ----------------------------------------------------------------------------- -// PHP RepeatedField Methods -// ----------------------------------------------------------------------------- +// RepeatedField PHP methods /////////////////////////////////////////////////// /** + * RepeatedField::__construct() + * * Constructs an instance of RepeatedField. * @param long Type of the stored element. - * @param string Message/Enum class name (message/enum fields only). + * @param string Message/Enum class. */ PHP_METHOD(RepeatedField, __construct) { - long type; + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); + zend_long type; zend_class_entry* klass = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|C", &type, &klass) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|C", &type, &klass) != SUCCESS) { return; } - RepeatedField *intern = UNBOX(RepeatedField, getThis()); - intern->type = to_fieldtype(type); - intern->msg_ce = klass; - -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(intern->array); - repeated_field_array_init(intern->array, intern->type, 0 ZEND_FILE_LINE_CC); -#else - repeated_field_array_init(&intern->array, intern->type, 0 ZEND_FILE_LINE_CC); -#endif + intern->type = pbphp_dtype_to_type(type); + intern->desc = Descriptor_GetFromClassEntry(klass); if (intern->type == UPB_TYPE_MESSAGE && klass == NULL) { - zend_error(E_USER_ERROR, "Message type must have concrete class."); + php_error_docref(NULL, E_USER_ERROR, + "Message/enum type must have concrete class."); return; } - // TODO(teboring): Consider enum. + intern->array = upb_array_new(arena, intern->type); + ObjCache_Add(intern->array, &intern->std); } /** + * RepeatedField::append() + * * Append element to the end of the repeated field. * @param object The element to be added. */ PHP_METHOD(RepeatedField, append) { - zval *value; + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); + zval *php_val; + upb_msgval msgval; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &php_val) != SUCCESS || + !Convert_PhpToUpb(php_val, &msgval, intern->type, intern->desc, arena)) { return; } - repeated_field_write_dimension(getThis(), NULL, value TSRMLS_CC); + + upb_array_append(intern->array, msgval, arena); } /** - * Check whether the element at given index exists. + * RepeatedField::offsetExists() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * isset($arr[$idx]); + * empty($arr[$idx]); + * * @param long The index to be checked. * @return bool True if the element at the given index exists. */ PHP_METHOD(RepeatedField, offsetExists) { - long index; + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); + zend_long index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { return; } - RepeatedField *intern = UNBOX(RepeatedField, getThis()); - - RETURN_BOOL(index >= 0 && - index < zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array))); + RETURN_BOOL(index >= 0 && index < upb_array_size(intern->array)); } /** - * Return the element at the given index. - * This will also be called for: $ele = $arr[0] + * RepeatedField::offsetGet() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * $x = $arr[$idx]; + * * @param long The index of the element to be fetched. * @return object The stored element at given index. * @exception Invalid type for index. * @exception Non-existing index. */ PHP_METHOD(RepeatedField, offsetGet) { - long index; - void *memory; + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); + zend_long index; + upb_msgval msgval; + zval ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { return; } - RepeatedField *intern = UNBOX(RepeatedField, getThis()); - HashTable *table = PHP_PROTO_HASH_OF(intern->array); - - if (intern->type == UPB_TYPE_MESSAGE) { - if (php_proto_zend_hash_index_find_zval(table, index, (void **)&memory) == - FAILURE) { - zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); - return; - } - } else { - if (php_proto_zend_hash_index_find_mem(table, index, (void **)&memory) == - FAILURE) { - zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); - return; - } + if (index < 0 || index >= upb_array_size(intern->array)) { + zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); + return; } - native_slot_get_by_array(intern->type, memory, - ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); + + msgval = upb_array_get(intern->array, index); + Convert_UpbToPhp(msgval, &ret, intern->type, intern->desc, &intern->arena); + RETURN_ZVAL(&ret, 0, 1); } /** - * Assign the element at the given index. - * This will also be called for: $arr []= $ele and $arr[0] = ele + * RepeatedField::offsetSet() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * $arr[$idx] = $x; + * $arr []= $x; // Append + * * @param long The index of the element to be assigned. * @param object The element to be assigned. * @exception Invalid type for index. @@ -418,140 +340,316 @@ PHP_METHOD(RepeatedField, offsetGet) { * @exception Incorrect type of the element. */ PHP_METHOD(RepeatedField, offsetSet) { - zval *index, *value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &index, &value) == - FAILURE) { + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); + size_t size = upb_array_size(intern->array); + zval *offset, *val; + int64_t index; + upb_msgval msgval; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &offset, &val) != SUCCESS) { return; } - repeated_field_write_dimension(getThis(), index, value TSRMLS_CC); + + if (Z_TYPE_P(offset) == IS_NULL) { + index = size; + } else if (!Convert_PhpToInt64(offset, &index)) { + return; + } + + if (!Convert_PhpToUpb(val, &msgval, intern->type, intern->desc, arena)) { + return; + } + + if (index > size) { + zend_error(E_USER_ERROR, "Element at index %ld doesn't exist.\n", index); + } else if (index == size) { + upb_array_append(intern->array, msgval, Arena_Get(&intern->arena)); + } else { + upb_array_set(intern->array, index, msgval); + } } /** - * Remove the element at the given index. - * This will also be called for: unset($arr) + * RepeatedField::offsetUnset() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * unset($arr[$idx]); + * * @param long The index of the element to be removed. * @exception Invalid type for index. * @exception The element to be removed is not at the end of the RepeatedField. */ PHP_METHOD(RepeatedField, offsetUnset) { - long index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); + zend_long index; + zend_long size = upb_array_size(intern->array); + + // Only the element at the end of the array can be removed. + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) != SUCCESS) { return; } - RepeatedField *intern = UNBOX(RepeatedField, getThis()); - - // Only the element at the end of the array can be removed. - if (index == -1 || - index != (zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array)) - 1)) { - zend_error(E_USER_ERROR, "Cannot remove element at %ld.\n", index); + if (size == 0 || index != size - 1) { + php_error_docref(NULL, E_USER_ERROR, "Cannot remove element at %ld.\n", + index); return; } - zend_hash_index_del(PHP_PROTO_HASH_OF(intern->array), index); + upb_array_resize(intern->array, size - 1, Arena_Get(&intern->arena)); } /** + * RepeatedField::count() + * + * Implements the Countable interface. Invoked when PHP code calls: + * + * $len = count($arr); * Return the number of stored elements. * This will also be called for: count($arr) * @return long The number of stored elements. */ PHP_METHOD(RepeatedField, count) { - RepeatedField *intern = UNBOX(RepeatedField, getThis()); + RepeatedField *intern = (RepeatedField*)Z_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } - RETURN_LONG(zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array))); + RETURN_LONG(upb_array_size(intern->array)); } /** - * Return the beginning iterator. - * This will also be called for: foreach($arr) + * RepeatedField::getIterator() + * + * Implements the IteratorAggregate interface. Invoked when PHP code calls: + * + * foreach ($arr) {} + * * @return object Beginning iterator. */ PHP_METHOD(RepeatedField, getIterator) { - CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(return_value, - repeated_field_iter_type); - - RepeatedField *intern = UNBOX(RepeatedField, getThis()); - RepeatedFieldIter *iter = UNBOX(RepeatedFieldIter, return_value); - iter->repeated_field = intern; - iter->position = 0; + zval ret; + RepeatedFieldIter_make(&ret, getThis()); + RETURN_ZVAL(&ret, 0, 1); } -// ----------------------------------------------------------------------------- -// RepeatedFieldIter creation/destruction -// ----------------------------------------------------------------------------- +ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 1) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, class) +ZEND_END_ARG_INFO() -// Define object free method. -PHP_PROTO_OBJECT_EMPTY_FREE_START(RepeatedFieldIter, repeated_field_iter) -PHP_PROTO_OBJECT_FREE_END +ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 1) + ZEND_ARG_INFO(0, newval) +ZEND_END_ARG_INFO() -PHP_PROTO_OBJECT_EMPTY_DTOR_START(RepeatedFieldIter, repeated_field_iter) -PHP_PROTO_OBJECT_DTOR_END +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() -// Define object create method. -PHP_PROTO_OBJECT_CREATE_START(RepeatedFieldIter, repeated_field_iter) -intern->repeated_field = NULL; -intern->position = 0; -PHP_PROTO_OBJECT_CREATE_END(RepeatedFieldIter, repeated_field_iter) +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, newval) +ZEND_END_ARG_INFO() -// Init class entry. -PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\RepeatedFieldIter", - RepeatedFieldIter, repeated_field_iter) -zend_class_implements(repeated_field_iter_type TSRMLS_CC, 1, zend_ce_iterator); -PHP_PROTO_INIT_CLASS_END +ZEND_BEGIN_ARG_INFO(arginfo_void, 0) +ZEND_END_ARG_INFO() + +static zend_function_entry repeated_field_methods[] = { + PHP_ME(RepeatedField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, append, arginfo_append, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, count, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, getIterator, arginfo_void, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; // ----------------------------------------------------------------------------- -// PHP RepeatedFieldIter Methods +// PHP RepeatedFieldIter // ----------------------------------------------------------------------------- -PHP_METHOD(RepeatedFieldIter, rewind) { - RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); +typedef struct { + zend_object std; + zval repeated_field; + zend_long position; +} RepeatedFieldIter; + +zend_class_entry *RepeatedFieldIter_class_entry; +static zend_object_handlers repeated_field_iter_object_handlers; + +/** + * RepeatedFieldIter_create() + * + * PHP class entry function to allocate and initialize a new RepeatedFieldIter + * object. + */ +zend_object* RepeatedFieldIter_create(zend_class_entry *class_type) { + RepeatedFieldIter *intern = emalloc(sizeof(RepeatedFieldIter)); + zend_object_std_init(&intern->std, class_type); + intern->std.handlers = &repeated_field_iter_object_handlers; + ZVAL_NULL(&intern->repeated_field); intern->position = 0; + // Skip object_properties_init(), we don't allow derived classes. + return &intern->std; } -PHP_METHOD(RepeatedFieldIter, current) { - RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); - RepeatedField *repeated_field = intern->repeated_field; +/** + * RepeatedFieldIter_dtor() + * + * Object handler to destroy a RepeatedFieldIter. This releases all resources + * associated with the message. Note that it is possible to access a destroyed + * object from PHP in rare cases. + */ +static void RepeatedFieldIter_dtor(zend_object* obj) { + RepeatedFieldIter* intern = (RepeatedFieldIter*)obj; + zval_ptr_dtor(&intern->repeated_field); + zend_object_std_dtor(&intern->std); +} - long index = 0; - void *memory; +/** + * RepeatedFieldIter_make() + * + * C function to create a RepeatedFieldIter. + */ +static void RepeatedFieldIter_make(zval *val, zval *repeated_field) { + RepeatedFieldIter *iter; + ZVAL_OBJ(val, RepeatedFieldIter_class_entry->create_object( + RepeatedFieldIter_class_entry)); + iter = (RepeatedFieldIter*)Z_OBJ_P(val); + ZVAL_COPY(&iter->repeated_field, repeated_field); +} - HashTable *table = PHP_PROTO_HASH_OF(repeated_field->array); +/* + * When a user writes: + * + * foreach($arr as $key => $val) {} + * + * PHP's iterator protocol is: + * + * $iter = $arr->getIterator(); + * for ($iter->rewind(); $iter->valid(); $iter->next()) { + * $key = $iter->key(); + * $val = $iter->current(); + * } + */ - if (repeated_field->type == UPB_TYPE_MESSAGE) { - if (php_proto_zend_hash_index_find_zval(table, intern->position, - (void **)&memory) == FAILURE) { - zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); - return; - } - } else { - if (php_proto_zend_hash_index_find_mem(table, intern->position, - (void **)&memory) == FAILURE) { - zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); - return; - } +/** + * RepeatedFieldIter::rewind() + * + * Implements the Iterator interface. Sets the iterator to the first element. + */ +PHP_METHOD(RepeatedFieldIter, rewind) { + RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis()); + intern->position = 0; +} + +/** + * RepeatedFieldIter::current() + * + * Implements the Iterator interface. Returns the current value. + */ +PHP_METHOD(RepeatedFieldIter, current) { + RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis()); + RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field); + upb_array *array = field->array; + zend_long index = intern->position; + upb_msgval msgval; + zval ret; + + if (index < 0 || index >= upb_array_size(array)) { + zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); } - native_slot_get_by_array(repeated_field->type, memory, - ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); + + msgval = upb_array_get(array, index); + + Convert_UpbToPhp(msgval, &ret, field->type, field->desc, &field->arena); + RETURN_ZVAL(&ret, 0, 1); } +/** + * RepeatedFieldIter::key() + * + * Implements the Iterator interface. Returns the current key. + */ PHP_METHOD(RepeatedFieldIter, key) { - RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); + RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis()); RETURN_LONG(intern->position); } +/** + * RepeatedFieldIter::next() + * + * Implements the Iterator interface. Advances to the next element. + */ PHP_METHOD(RepeatedFieldIter, next) { - RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); + RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis()); ++intern->position; } +/** + * RepeatedFieldIter::valid() + * + * Implements the Iterator interface. Returns true if this is a valid element. + */ PHP_METHOD(RepeatedFieldIter, valid) { - RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); - RETURN_BOOL(zend_hash_num_elements(PHP_PROTO_HASH_OF( - intern->repeated_field->array)) > intern->position); + RepeatedFieldIter *intern = (RepeatedFieldIter*)Z_OBJ_P(getThis()); + RepeatedField *field = (RepeatedField*)Z_OBJ_P(&intern->repeated_field); + RETURN_BOOL(intern->position < upb_array_size(field->array)); +} + +static zend_function_entry repeated_field_iter_methods[] = { + PHP_ME(RepeatedFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +// ----------------------------------------------------------------------------- +// Module init. +// ----------------------------------------------------------------------------- + +/** + * Array_ModuleInit() + * + * Called when the C extension is loaded to register all types. + */ +void Array_ModuleInit() { + zend_class_entry tmp_ce; + zend_object_handlers *h; + + // RepeatedField. + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\RepeatedField", + repeated_field_methods); + + RepeatedField_class_entry = zend_register_internal_class(&tmp_ce); + zend_class_implements(RepeatedField_class_entry, 3, spl_ce_ArrayAccess, + zend_ce_aggregate, spl_ce_Countable); + RepeatedField_class_entry->ce_flags |= ZEND_ACC_FINAL; + RepeatedField_class_entry->create_object = RepeatedField_create; + + h = &RepeatedField_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + h->dtor_obj = RepeatedField_destructor; + h->compare_objects = RepeatedField_compare_objects; + h->get_properties = RepeatedField_GetProperties; + h->get_property_ptr_ptr = RepeatedField_GetPropertyPtrPtr; + + // RepeatedFieldIter + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\RepeatedFieldIter", + repeated_field_iter_methods); + + RepeatedFieldIter_class_entry = zend_register_internal_class(&tmp_ce); + zend_class_implements(RepeatedFieldIter_class_entry, 1, zend_ce_iterator); + RepeatedFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL; + RepeatedFieldIter_class_entry->create_object = RepeatedFieldIter_create; + + h = &repeated_field_iter_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + h->dtor_obj = RepeatedFieldIter_dtor; } diff --git a/php/ext/google/protobuf/array.h b/php/ext/google/protobuf/array.h new file mode 100644 index 000000000000..921e0bf564f4 --- /dev/null +++ b/php/ext/google/protobuf/array.h @@ -0,0 +1,66 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#ifndef PHP_PROTOBUF_ARRAY_H_ +#define PHP_PROTOBUF_ARRAY_H_ + +#include + +#include "php-upb.h" + +// Registers PHP classes for RepeatedField. +void Array_ModuleInit(); + +// Gets a upb_array* for the PHP object |val|: +// * If |val| is a RepeatedField object, we first check its type and verify +// that that the elements have the correct type for |f|. If so, we return the +// wrapped upb_array*. We also make sure that this array's arena is fused to +// |arena|, so the returned upb_array is guaranteed to live as long as +// |arena|. +// * If |val| is a PHP Array, we attempt to create a new upb_array using +// |arena| and add all of the PHP elements to it. +// +// If an error occurs, we raise a PHP error and return NULL. +upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f, upb_arena *arena); + +// Creates a PHP RepeatedField object for the given upb_array* and |f| and +// returns it in |val|. The PHP object will keep a reference to this |arena| to +// ensure the underlying array data stays alive. +// +// If |arr| is NULL, this will return a PHP null object. +void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, + const upb_fielddef *f, zval *arena); + +// Returns true if the given arrays are equal. Both arrays must be of this +// |type| and, if the type is |UPB_TYPE_MESSAGE|, must have the same |m|. +bool ArrayEq(const upb_array *a1, const upb_array *a2, upb_fieldtype_t type, + const upb_msgdef *m); + +#endif // PHP_PROTOBUF_ARRAY_H_ diff --git a/php/ext/google/protobuf/builtin_descriptors.inc b/php/ext/google/protobuf/builtin_descriptors.inc deleted file mode 100644 index 1bb5dbfa85b9..000000000000 --- a/php/ext/google/protobuf/builtin_descriptors.inc +++ /dev/null @@ -1,635 +0,0 @@ -unsigned char descriptor_proto[] = { - 0x0a, 0x9b, 0x3b, 0x0a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x0f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0x4d, 0x0a, 0x11, 0x46, 0x69, - 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x53, 0x65, 0x74, 0x12, 0x38, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x04, 0x66, 0x69, 0x6c, - 0x65, 0x22, 0xe4, 0x04, 0x0a, 0x13, 0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, - 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, - 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, - 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, - 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x05, 0x52, 0x10, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, - 0x65, 0x6e, 0x63, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x65, 0x61, 0x6b, - 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, - 0x0b, 0x20, 0x03, 0x28, 0x05, 0x52, 0x0e, 0x77, 0x65, 0x61, 0x6b, 0x44, - 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x43, 0x0a, - 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, - 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, - 0x75, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x41, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x09, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x49, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x0e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x79, 0x6e, 0x74, - 0x61, 0x78, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x79, - 0x6e, 0x74, 0x61, 0x78, 0x22, 0xb9, 0x06, 0x0a, 0x0f, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x05, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x43, 0x0a, - 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x09, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0b, 0x6e, 0x65, - 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x52, 0x0a, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x41, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x08, - 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x58, 0x0a, 0x0f, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x61, - 0x6e, 0x67, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, - 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0e, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, - 0x64, 0x65, 0x63, 0x6c, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x52, 0x09, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, 0x63, 0x6c, - 0x12, 0x39, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x55, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, - 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, - 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x4e, - 0x61, 0x6d, 0x65, 0x1a, 0x7a, 0x0a, 0x0e, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, - 0x64, 0x12, 0x40, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, - 0x6e, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x37, 0x0a, 0x0d, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, - 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x03, 0x65, 0x6e, 0x64, 0x22, 0x7c, 0x0a, 0x15, 0x45, 0x78, 0x74, 0x65, - 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, - 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2a, - 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x98, - 0x06, 0x0a, 0x14, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x05, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, - 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x6e, - 0x64, 0x65, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x6e, 0x65, 0x6f, - 0x66, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x0a, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, - 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0xb6, 0x02, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, 0x55, - 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, - 0x0a, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, - 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, - 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x05, 0x12, 0x10, - 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, - 0x36, 0x34, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x07, 0x12, 0x0d, - 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, - 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, - 0x52, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x10, 0x0a, 0x12, 0x10, - 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, - 0x47, 0x45, 0x10, 0x0b, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x42, 0x59, 0x54, 0x45, 0x53, 0x10, 0x0c, 0x12, 0x0f, 0x0a, 0x0b, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, - 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, - 0x55, 0x4d, 0x10, 0x0e, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x0f, 0x12, - 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x46, 0x49, 0x58, - 0x45, 0x44, 0x36, 0x34, 0x10, 0x10, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x11, 0x12, - 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x49, 0x4e, 0x54, - 0x36, 0x34, 0x10, 0x12, 0x22, 0x43, 0x0a, 0x05, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x4f, - 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x01, 0x12, 0x12, 0x0a, - 0x0e, 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x49, - 0x52, 0x45, 0x44, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x41, 0x42, - 0x45, 0x4c, 0x5f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, - 0x03, 0x22, 0x63, 0x0a, 0x14, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x37, 0x0a, - 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, - 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe3, 0x02, 0x0a, 0x13, 0x45, - 0x6e, 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, - 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x5d, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, - 0x75, 0x6d, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, - 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x4e, - 0x61, 0x6d, 0x65, 0x1a, 0x3b, 0x0a, 0x11, 0x45, 0x6e, 0x75, 0x6d, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, - 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x03, 0x65, 0x6e, 0x64, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x45, 0x6e, 0x75, - 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x16, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x6d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x39, 0x0a, - 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x89, 0x02, 0x0a, - 0x15, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6e, - 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, - 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x10, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, - 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, - 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x30, - 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, - 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, - 0x22, 0x92, 0x09, 0x0a, 0x0b, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x61, 0x76, 0x61, - 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x6a, 0x61, 0x76, 0x61, 0x50, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6a, 0x61, 0x76, 0x61, 0x5f, - 0x6f, 0x75, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6a, - 0x61, 0x76, 0x61, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x6a, 0x61, 0x76, - 0x61, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, - 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x6a, 0x61, 0x76, 0x61, 0x4d, - 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x12, 0x44, 0x0a, 0x1d, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x73, - 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x14, 0x20, - 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x19, 0x6a, 0x61, 0x76, - 0x61, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x45, 0x71, 0x75, - 0x61, 0x6c, 0x73, 0x41, 0x6e, 0x64, 0x48, 0x61, 0x73, 0x68, 0x12, 0x3a, - 0x0a, 0x16, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x75, 0x74, 0x66, 0x38, - 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, - 0x65, 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x74, 0x66, 0x38, 0x12, 0x53, - 0x0a, 0x0c, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x5f, 0x66, - 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x4d, - 0x6f, 0x64, 0x65, 0x3a, 0x05, 0x53, 0x50, 0x45, 0x45, 0x44, 0x52, 0x0b, - 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x46, 0x6f, 0x72, 0x12, - 0x1d, 0x0a, 0x0a, 0x67, 0x6f, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, - 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x6f, 0x50, - 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x35, 0x0a, 0x13, 0x63, 0x63, - 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x3a, - 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x63, 0x63, 0x47, 0x65, - 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x12, 0x39, 0x0a, 0x15, 0x6a, 0x61, 0x76, 0x61, 0x5f, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x52, 0x13, 0x6a, 0x61, 0x76, 0x61, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x12, 0x35, 0x0a, 0x13, 0x70, 0x79, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, - 0x69, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, - 0x12, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x52, 0x11, 0x70, 0x79, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x14, 0x70, - 0x68, 0x70, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x2a, 0x20, 0x01, 0x28, - 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x12, 0x70, 0x68, - 0x70, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, - 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, - 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, - 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x10, 0x63, - 0x63, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x72, 0x65, - 0x6e, 0x61, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, - 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0e, 0x63, 0x63, 0x45, 0x6e, 0x61, 0x62, - 0x6c, 0x65, 0x41, 0x72, 0x65, 0x6e, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x11, - 0x6f, 0x62, 0x6a, 0x63, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x70, - 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x24, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x6f, 0x62, 0x6a, 0x63, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x50, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x73, 0x68, 0x61, - 0x72, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x73, 0x68, 0x61, - 0x72, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x73, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x70, 0x72, 0x65, - 0x66, 0x69, 0x78, 0x18, 0x27, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, - 0x77, 0x69, 0x66, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x28, - 0x0a, 0x10, 0x70, 0x68, 0x70, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, - 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x70, 0x68, 0x70, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x50, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x68, 0x70, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x29, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x68, 0x70, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x68, 0x70, - 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x2c, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x14, 0x70, 0x68, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x62, 0x79, 0x5f, 0x70, 0x61, 0x63, 0x6b, - 0x61, 0x67, 0x65, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, - 0x75, 0x62, 0x79, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x58, - 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, - 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, - 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, - 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3a, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, - 0x6d, 0x69, 0x7a, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x09, 0x0a, 0x05, - 0x53, 0x50, 0x45, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x43, - 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x02, 0x12, 0x10, - 0x0a, 0x0c, 0x4c, 0x49, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4e, 0x54, 0x49, - 0x4d, 0x45, 0x10, 0x03, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, - 0x80, 0x80, 0x02, 0x4a, 0x04, 0x08, 0x26, 0x10, 0x27, 0x22, 0xd1, 0x02, - 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x17, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x77, 0x69, 0x72, 0x65, - 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x14, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x65, 0x74, 0x57, 0x69, 0x72, 0x65, - 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x4c, 0x0a, 0x1f, 0x6e, 0x6f, - 0x5f, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x5f, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, - 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x1c, 0x6e, 0x6f, 0x53, 0x74, - 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, - 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, - 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, - 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, - 0x6d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x58, 0x0a, 0x14, - 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, - 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, - 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, - 0x02, 0x4a, 0x04, 0x08, 0x08, 0x10, 0x09, 0x4a, 0x04, 0x08, 0x09, 0x10, - 0x0a, 0x22, 0xe2, 0x03, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x05, 0x63, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x43, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x06, - 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x52, 0x05, 0x63, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x65, - 0x64, 0x12, 0x47, 0x0a, 0x06, 0x6a, 0x73, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x4a, 0x53, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x09, 0x4a, 0x53, 0x5f, - 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x52, 0x06, 0x6a, 0x73, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x19, 0x0a, 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, - 0x04, 0x6c, 0x61, 0x7a, 0x79, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, - 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x04, - 0x77, 0x65, 0x61, 0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, - 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x04, 0x77, 0x65, 0x61, 0x6b, 0x12, - 0x58, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, - 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0xe7, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, - 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x05, 0x43, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, - 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x43, 0x4f, 0x52, 0x44, 0x10, 0x01, - 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x50, - 0x49, 0x45, 0x43, 0x45, 0x10, 0x02, 0x22, 0x35, 0x0a, 0x06, 0x4a, 0x53, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, - 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4a, - 0x53, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0d, - 0x0a, 0x09, 0x4a, 0x53, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, - 0x02, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, - 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x73, 0x0a, 0x0c, 0x4f, 0x6e, - 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, - 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, - 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, - 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, - 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, - 0x80, 0x80, 0x02, 0x22, 0xc0, 0x01, 0x0a, 0x0b, 0x45, 0x6e, 0x75, 0x6d, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, - 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, - 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x14, 0x75, - 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, - 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, - 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x9e, 0x01, 0x0a, 0x10, 0x45, - 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, - 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x3a, - 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, - 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, - 0x9c, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, 0x64, 0x65, - 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x21, 0x20, 0x01, - 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x64, - 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x58, 0x0a, - 0x14, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, - 0x65, 0x64, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, - 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, - 0x80, 0x02, 0x22, 0xe0, 0x02, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0a, - 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x21, - 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, - 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, - 0x71, 0x0a, 0x11, 0x69, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, - 0x63, 0x79, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x22, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, - 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x49, - 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x3a, 0x13, 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, - 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x52, 0x10, 0x69, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x63, - 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x58, 0x0a, 0x14, 0x75, 0x6e, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xe7, 0x07, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x75, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x50, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6d, 0x70, 0x6f, 0x74, 0x65, - 0x6e, 0x63, 0x79, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x17, 0x0a, 0x13, - 0x49, 0x44, 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x43, 0x59, 0x5f, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, - 0x0f, 0x4e, 0x4f, 0x5f, 0x53, 0x49, 0x44, 0x45, 0x5f, 0x45, 0x46, 0x46, - 0x45, 0x43, 0x54, 0x53, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x44, - 0x45, 0x4d, 0x50, 0x4f, 0x54, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x2a, 0x09, - 0x08, 0xe8, 0x07, 0x10, 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9a, 0x03, - 0x0a, 0x13, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x65, - 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x2d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x6e, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x65, 0x74, 0x65, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, - 0x65, 0x49, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x0a, - 0x12, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, - 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x10, 0x6e, 0x65, 0x67, 0x61, 0x74, 0x69, 0x76, 0x65, 0x49, - 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, - 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x67, 0x67, 0x72, - 0x65, 0x67, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x4a, - 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x18, - 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x61, 0x6d, 0x65, 0x50, - 0x61, 0x72, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x65, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x02, 0x28, - 0x08, 0x52, 0x0b, 0x69, 0x73, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x22, 0xa7, 0x02, 0x0a, 0x0e, 0x53, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, - 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xce, 0x01, 0x0a, 0x08, - 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, - 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x04, - 0x73, 0x70, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, - 0x10, 0x01, 0x52, 0x04, 0x73, 0x70, 0x61, 0x6e, 0x12, 0x29, 0x0a, 0x10, - 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, - 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x69, 0x6c, - 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x72, 0x61, 0x69, - 0x6c, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x12, 0x3a, 0x0a, 0x19, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x5f, - 0x64, 0x65, 0x74, 0x61, 0x63, 0x68, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x17, 0x6c, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x44, 0x65, 0x74, 0x61, - 0x63, 0x68, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x22, 0xd1, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4d, - 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, - 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x6d, 0x0a, 0x0a, 0x41, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, - 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x46, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x65, 0x67, 0x69, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x62, 0x65, 0x67, - 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x42, 0x8f, 0x01, 0x0a, - 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x42, 0x10, 0x44, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x73, 0x48, 0x01, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0xf8, 0x01, 0x01, 0xa2, - 0x02, 0x03, 0x47, 0x50, 0x42, 0xaa, 0x02, 0x1a, 0x47, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e -}; -unsigned int descriptor_proto_len = 7582; diff --git a/php/ext/google/protobuf/config.m4 b/php/ext/google/protobuf/config.m4 index ab032e466b57..c09c03af0a5b 100644 --- a/php/ext/google/protobuf/config.m4 +++ b/php/ext/google/protobuf/config.m4 @@ -4,7 +4,7 @@ if test "$PHP_PROTOBUF" != "no"; then PHP_NEW_EXTENSION( protobuf, - array.c def.c encode_decode.c map.c message.c protobuf.c storage.c type_check.c upb.c utf8.c, - $ext_shared) + arena.c array.c convert.c def.c map.c message.c names.c php-upb.c protobuf.c, + $ext_shared, , -std=gnu99) fi diff --git a/php/ext/google/protobuf/convert.c b/php/ext/google/protobuf/convert.c new file mode 100644 index 000000000000..1c2f6288b5a9 --- /dev/null +++ b/php/ext/google/protobuf/convert.c @@ -0,0 +1,513 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#include "convert.h" + +#include + +// This is not self-contained: it must be after other Zend includes. +#include + +#include "array.h" +#include "map.h" +#include "message.h" +#include "php-upb.h" +#include "protobuf.h" + +// ----------------------------------------------------------------------------- +// GPBUtil +// ----------------------------------------------------------------------------- + +static zend_class_entry* GPBUtil_class_entry; + +// The implementation of type checking for primitive fields is empty. This is +// because type checking is done when direct assigning message fields (e.g., +// foo->a = 1). Functions defined here are place holders in generated code for +// pure PHP implementation (c extension and pure PHP share the same generated +// code). + +PHP_METHOD(Util, checkInt32) {} +PHP_METHOD(Util, checkUint32) {} +PHP_METHOD(Util, checkInt64) {} +PHP_METHOD(Util, checkUint64) {} +PHP_METHOD(Util, checkEnum) {} +PHP_METHOD(Util, checkFloat) {} +PHP_METHOD(Util, checkDouble) {} +PHP_METHOD(Util, checkBool) {} +PHP_METHOD(Util, checkString) {} +PHP_METHOD(Util, checkBytes) {} +PHP_METHOD(Util, checkMessage) {} + +// The result of checkMapField() is assigned, so we need to return the first +// param: +// $arr = GPBUtil::checkMapField($var, +// \Google\Protobuf\Internal\GPBType::INT64, +// \Google\Protobuf\Internal\GPBType::INT32); +PHP_METHOD(Util, checkMapField) { + zval *val, *key_type, *val_type, *klass; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz|z", &val, &key_type, + &val_type, &klass) == FAILURE) { + return; + } + RETURN_ZVAL(val, 1, 0); +} + +// The result of checkRepeatedField() is assigned, so we need to return the +// first param: +// $arr = GPBUtil::checkRepeatedField( +// $var, \Google\Protobuf\Internal\GPBType::STRING); +PHP_METHOD(Util, checkRepeatedField) { + zval *val, *type, *klass; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz|z", &val, &type, &klass) == + FAILURE) { + return; + } + RETURN_ZVAL(val, 1, 0); +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkPrimitive, 0, 0, 1) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkMessage, 0, 0, 2) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, class) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkMapField, 0, 0, 3) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, key_type) + ZEND_ARG_INFO(0, value_type) + ZEND_ARG_INFO(0, value_class) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_checkRepeatedField, 0, 0, 2) + ZEND_ARG_INFO(0, value) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, class) +ZEND_END_ARG_INFO() + +static zend_function_entry util_methods[] = { + PHP_ME(Util, checkInt32, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkUint32, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkInt64, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkUint64, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkEnum, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkFloat, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkDouble, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkBool, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkString, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkBytes, arginfo_checkPrimitive, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkMessage, arginfo_checkMessage, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkMapField, arginfo_checkMapField, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(Util, checkRepeatedField, arginfo_checkRepeatedField, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_FE_END +}; + +// ----------------------------------------------------------------------------- +// Conversion functions used from C +// ----------------------------------------------------------------------------- + +upb_fieldtype_t pbphp_dtype_to_type(upb_descriptortype_t type) { + switch (type) { +#define CASE(descriptor_type, type) \ + case UPB_DESCRIPTOR_TYPE_##descriptor_type: \ + return UPB_TYPE_##type; + + CASE(FLOAT, FLOAT); + CASE(DOUBLE, DOUBLE); + CASE(BOOL, BOOL); + CASE(STRING, STRING); + CASE(BYTES, BYTES); + CASE(MESSAGE, MESSAGE); + CASE(GROUP, MESSAGE); + CASE(ENUM, ENUM); + CASE(INT32, INT32); + CASE(INT64, INT64); + CASE(UINT32, UINT32); + CASE(UINT64, UINT64); + CASE(SINT32, INT32); + CASE(SINT64, INT64); + CASE(FIXED32, UINT32); + CASE(FIXED64, UINT64); + CASE(SFIXED32, INT32); + CASE(SFIXED64, INT64); + +#undef CASE + + } + + zend_error(E_ERROR, "Unknown field type."); + return 0; +} + +static bool buftouint64(const char *ptr, const char *end, uint64_t *val) { + uint64_t u64 = 0; + while (ptr < end) { + unsigned ch = (unsigned)(*ptr - '0'); + if (ch >= 10) break; + if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) { + return false; + } + u64 *= 10; + u64 += ch; + ptr++; + } + + if (ptr != end) { + // In PHP tradition, we allow truncation: "1.1" -> 1. + // But we don't allow 'e', eg. '1.1e2' or any other non-numeric chars. + if (*ptr++ != '.') return false; + + for (;ptr < end; ptr++) { + if (*ptr < '0' || *ptr > '9') { + return false; + } + } + } + + *val = u64; + return true; +} + +static bool buftoint64(const char *ptr, const char *end, int64_t *val) { + bool neg = false; + uint64_t u64; + + if (ptr != end && *ptr == '-') { + ptr++; + neg = true; + } + + if (!buftouint64(ptr, end, &u64) || + u64 > (uint64_t)INT64_MAX + neg) { + return false; + } + + *val = neg ? -u64 : u64; + return true; +} + +static void throw_conversion_exception(const char *to, const zval *zv) { + zval tmp; + ZVAL_COPY(&tmp, zv); + convert_to_string(&tmp); + + zend_throw_exception_ex(NULL, 0, "Cannot convert '%s' to %s", + Z_STRVAL_P(&tmp), to); + + zval_ptr_dtor(&tmp); +} + +bool Convert_PhpToInt64(const zval *php_val, int64_t *i64) { + switch (Z_TYPE_P(php_val)) { + case IS_LONG: + *i64 = Z_LVAL_P(php_val); + return true; + case IS_DOUBLE: { + double dbl = Z_DVAL_P(php_val); + if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) { + zend_throw_exception_ex(NULL, 0, "Out of range"); + return false; + } + *i64 = dbl; /* must be guarded, overflow here is UB */ + return true; + } + case IS_STRING: { + const char *buf = Z_STRVAL_P(php_val); + // PHP would accept scientific notation here, but we're going to be a + // little more discerning and only accept pure integers. + bool ok = buftoint64(buf, buf + Z_STRLEN_P(php_val), i64); + if (!ok) { + throw_conversion_exception("integer", php_val); + } + return ok; + } + default: + throw_conversion_exception("integer", php_val); + return false; + } +} + +static bool to_double(zval *php_val, double *dbl) { + switch (Z_TYPE_P(php_val)) { + case IS_LONG: + *dbl = Z_LVAL_P(php_val); + return true; + case IS_DOUBLE: + *dbl = Z_DVAL_P(php_val); + return true; + case IS_STRING: { + zend_long lval; + switch (is_numeric_string(Z_STRVAL_P(php_val), Z_STRLEN_P(php_val), &lval, + dbl, false)) { + case IS_LONG: + *dbl = lval; + return true; + case IS_DOUBLE: + return true; + default: + goto fail; + } + } + default: + fail: + throw_conversion_exception("double", php_val); + return false; + } +} + +static bool to_bool(zval* from, bool* to) { + switch (Z_TYPE_P(from)) { + case IS_TRUE: + *to = true; + return true; + case IS_FALSE: + *to = false; + return true; + case IS_LONG: + *to = (Z_LVAL_P(from) != 0); + return true; + case IS_DOUBLE: + *to = (Z_LVAL_P(from) != 0); + return true; + case IS_STRING: + if (Z_STRLEN_P(from) == 0 || + (Z_STRLEN_P(from) == 1 && Z_STRVAL_P(from)[0] == '0')) { + *to = false; + } else { + *to = true; + } + return true; + default: + throw_conversion_exception("bool", from); + return false; + } +} + +static bool to_string(zval* from) { + if (Z_ISREF_P(from)) { + ZVAL_DEREF(from); + } + + switch (Z_TYPE_P(from)) { + case IS_STRING: + return true; + case IS_TRUE: + case IS_FALSE: + case IS_LONG: + case IS_DOUBLE: { + zval tmp; + zend_make_printable_zval(from, &tmp); + ZVAL_COPY_VALUE(from, &tmp); + return true; + } + default: + throw_conversion_exception("string", from); + return false; + } +} + +bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type, + const Descriptor *desc, upb_arena *arena) { + int64_t i64; + + if (Z_ISREF_P(php_val)) { + ZVAL_DEREF(php_val); + } + + switch (type) { + case UPB_TYPE_INT64: + return Convert_PhpToInt64(php_val, &upb_val->int64_val); + case UPB_TYPE_INT32: + case UPB_TYPE_ENUM: + if (!Convert_PhpToInt64(php_val, &i64)) { + return false; + } + upb_val->int32_val = i64; + return true; + case UPB_TYPE_UINT64: + if (!Convert_PhpToInt64(php_val, &i64)) { + return false; + } + upb_val->uint64_val = i64; + return true; + case UPB_TYPE_UINT32: + if (!Convert_PhpToInt64(php_val, &i64)) { + return false; + } + upb_val->uint32_val = i64; + return true; + case UPB_TYPE_DOUBLE: + return to_double(php_val, &upb_val->double_val); + case UPB_TYPE_FLOAT: + if (!to_double(php_val, &upb_val->double_val)) return false; + upb_val->float_val = upb_val->double_val; + return true; + case UPB_TYPE_BOOL: + return to_bool(php_val, &upb_val->bool_val); + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: { + char *ptr; + size_t size; + + if (!to_string(php_val)) return false; + + size = Z_STRLEN_P(php_val); + + // If arena is NULL we reference the input zval. + // The resulting upb_strview will only be value while the zval is alive. + if (arena) { + ptr = upb_arena_malloc(arena, size); + memcpy(ptr, Z_STRVAL_P(php_val), size); + } else { + ptr = Z_STRVAL_P(php_val); + } + + upb_val->str_val = upb_strview_make(ptr, size); + return true; + } + case UPB_TYPE_MESSAGE: + PBPHP_ASSERT(desc); + return Message_GetUpbMessage(php_val, desc, arena, + (upb_msg **)&upb_val->msg_val); + } + + return false; +} + +void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, upb_fieldtype_t type, + const Descriptor *desc, zval *arena) { + switch (type) { + case UPB_TYPE_INT64: +#if SIZEOF_ZEND_LONG == 8 + ZVAL_LONG(php_val, upb_val.int64_val); +#else + { + char buf[20]; + int size = sprintf(buf, "%lld", upb_val.int64_val); + ZVAL_NEW_STR(php_val, zend_string_init(buf, size, 0)); + } +#endif + break; + case UPB_TYPE_UINT64: +#if SIZEOF_ZEND_LONG == 8 + ZVAL_LONG(php_val, upb_val.uint64_val); +#else + { + char buf[20]; + int size = sprintf(buf, "%lld", (int64_t)upb_val.uint64_val); + ZVAL_NEW_STR(php_val, zend_string_init(buf, size, 0)); + } +#endif + break; + case UPB_TYPE_INT32: + case UPB_TYPE_ENUM: + ZVAL_LONG(php_val, upb_val.int32_val); + break; + case UPB_TYPE_UINT32: { + // Sign-extend for consistency between 32/64-bit builds. + zend_long val = (int32_t)upb_val.uint32_val; + ZVAL_LONG(php_val, val); + break; + } + case UPB_TYPE_DOUBLE: + ZVAL_DOUBLE(php_val, upb_val.double_val); + break; + case UPB_TYPE_FLOAT: + ZVAL_DOUBLE(php_val, upb_val.float_val); + break; + case UPB_TYPE_BOOL: + ZVAL_BOOL(php_val, upb_val.bool_val); + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: { + upb_strview str = upb_val.str_val; + ZVAL_NEW_STR(php_val, zend_string_init(str.data, str.size, 0)); + break; + } + case UPB_TYPE_MESSAGE: + PBPHP_ASSERT(desc); + Message_GetPhpWrapper(php_val, desc, (upb_msg*)upb_val.msg_val, arena); + break; + } +} + +bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val, + upb_fieldtype_t type, const Descriptor *desc, + upb_arena *arena) { + const upb_msgdef *subm = desc ? desc->msgdef : NULL; + if (subm && upb_msgdef_iswrapper(subm) && Z_TYPE_P(val) != IS_OBJECT) { + // Assigning a scalar to a wrapper-typed value. We will automatically wrap + // the value, so the user doesn't need to create a FooWrapper(['value': X]) + // message manually. + upb_msg *wrapper = upb_msg_new(subm, arena); + const upb_fielddef *val_f = upb_msgdef_itof(subm, 1); + upb_fieldtype_t type_f = upb_fielddef_type(val_f); + upb_msgval msgval; + if (!Convert_PhpToUpb(val, &msgval, type_f, NULL, arena)) return false; + upb_msg_set(wrapper, val_f, msgval, arena); + upb_val->msg_val = wrapper; + return true; + } else { + // Convert_PhpToUpb doesn't auto-construct messages. This means that we only + // allow: + // ['foo_submsg': new Foo(['a' => 1])] + // not: + // ['foo_submsg': ['a' => 1]] + return Convert_PhpToUpb(val, upb_val, type, desc, arena); + } +} + +void Convert_ModuleInit(void) { + const char *prefix_name = "TYPE_URL_PREFIX"; + zend_class_entry class_type; + + INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\GPBUtil", + util_methods); + GPBUtil_class_entry = zend_register_internal_class(&class_type); + + zend_declare_class_constant_string(GPBUtil_class_entry, prefix_name, + strlen(prefix_name), + "type.googleapis.com/"); +} diff --git a/php/ext/google/protobuf/convert.h b/php/ext/google/protobuf/convert.h new file mode 100644 index 000000000000..06c05c72750c --- /dev/null +++ b/php/ext/google/protobuf/convert.h @@ -0,0 +1,73 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#ifndef PHP_PROTOBUF_CONVERT_H_ +#define PHP_PROTOBUF_CONVERT_H_ + +#include + +#include "php-upb.h" +#include "def.h" + +upb_fieldtype_t pbphp_dtype_to_type(upb_descriptortype_t type); + +// Converts |php_val| to an int64_t. Returns false if the value cannot be +// converted. +bool Convert_PhpToInt64(const zval *php_val, int64_t *i64); + +// Converts |php_val| to a upb_msgval according to |type|. If type is +// UPB_TYPE_MESSAGE, then |desc| must be the Descriptor for this message type. +// If type is string, message, or bytes, then |arena| will be used to copy +// string data or fuse this arena to the given message's arena. +bool Convert_PhpToUpb(zval *php_val, upb_msgval *upb_val, upb_fieldtype_t type, + const Descriptor *desc, upb_arena *arena); + +// Similar to Convert_PhpToUpb, but supports automatically wrapping the wrapper +// types if a primitive is specified: +// +// 5 -> Int64Wrapper(value=5) +// +// We currently allow this implicit conversion in initializers, but not for +// assignment. +bool Convert_PhpToUpbAutoWrap(zval *val, upb_msgval *upb_val, + upb_fieldtype_t type, const Descriptor *desc, + upb_arena *arena); + +// Converts |upb_val| to a PHP zval according to |type|. This may involve +// creating a PHP wrapper object. If type == UPB_TYPE_MESSAGE, then |desc| must +// be the Descriptor for this message type. Any newly created wrapper object +// will reference |arena|. +void Convert_UpbToPhp(upb_msgval upb_val, zval *php_val, upb_fieldtype_t type, + const Descriptor *desc, zval *arena); + +// Registers the GPBUtil class. +void Convert_ModuleInit(void); + +#endif // PHP_PROTOBUF_CONVERT_H_ diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index f10c37cd9bc2..3f7590ca44dc 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -28,325 +28,330 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "def.h" + #include + +// This is not self-contained: it must be after other Zend includes. #include +#include "names.h" +#include "php-upb.h" #include "protobuf.h" -#include "builtin_descriptors.inc" - -// Forward declare. -static void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC); -static void descriptor_free_c(Descriptor* object TSRMLS_DC); - -static void field_descriptor_init_c_instance(FieldDescriptor* intern TSRMLS_DC); -static void field_descriptor_free_c(FieldDescriptor* object TSRMLS_DC); -static void enum_descriptor_init_c_instance(EnumDescriptor* intern TSRMLS_DC); -static void enum_descriptor_free_c(EnumDescriptor* object TSRMLS_DC); - -static void enum_value_descriptor_init_c_instance( - EnumValueDescriptor *intern TSRMLS_DC); -static void enum_value_descriptor_free_c(EnumValueDescriptor *object TSRMLS_DC); +static void CheckUpbStatus(const upb_status* status, const char* msg) { + if (!upb_ok(status)) { + zend_error(E_ERROR, "%s: %s\n", msg, upb_status_errmsg(status)); + } +} -static void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC); -static void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC); +static void FieldDescriptor_FromFieldDef(zval *val, const upb_fielddef *f); -static void internal_descriptor_pool_free_c( - InternalDescriptorPool *object TSRMLS_DC); -static void internal_descriptor_pool_init_c_instance( - InternalDescriptorPool *pool TSRMLS_DC); +// We use this for objects that should not be created directly from PHP. +static zend_object *CreateHandler_ReturnNull(zend_class_entry *class_type) { + return NULL; // Nobody should call this. +} -static void oneof_descriptor_free_c(Oneof* object TSRMLS_DC); -static void oneof_descriptor_init_c_instance(Oneof* pool TSRMLS_DC); // ----------------------------------------------------------------------------- -// Common Utilities +// EnumValueDescriptor // ----------------------------------------------------------------------------- -static void check_upb_status(const upb_status* status, const char* msg) { - if (!upb_ok(status)) { - zend_error(E_ERROR, "%s: %s\n", msg, upb_status_errmsg(status)); - } +typedef struct { + zend_object std; + const char *name; + int32_t number; +} EnumValueDescriptor; + +zend_class_entry *EnumValueDescriptor_class_entry; +static zend_object_handlers EnumValueDescriptor_object_handlers; + +/* + * EnumValueDescriptor_Make() + * + * Function to create an EnumValueDescriptor object from C. + */ +static void EnumValueDescriptor_Make(zval *val, const char *name, + int32_t number) { + EnumValueDescriptor *intern = emalloc(sizeof(EnumValueDescriptor)); + zend_object_std_init(&intern->std, EnumValueDescriptor_class_entry); + intern->std.handlers = &EnumValueDescriptor_object_handlers; + intern->name = name; + intern->number = number; + // Skip object_properties_init(), we don't allow derived classes. + ZVAL_OBJ(val, &intern->std); } -// ----------------------------------------------------------------------------- -// GPBType -// ----------------------------------------------------------------------------- +/* + * EnumValueDescriptor::getName() + * + * Returns the name for this enum value. + */ +PHP_METHOD(EnumValueDescriptor, getName) { + EnumValueDescriptor *intern = (EnumValueDescriptor*)Z_OBJ_P(getThis()); + RETURN_STRING(intern->name); +} -zend_class_entry* gpb_type_type; +/* + * EnumValueDescriptor::getNumber() + * + * Returns the number for this enum value. + */ +PHP_METHOD(EnumValueDescriptor, getNumber) { + EnumValueDescriptor *intern = (EnumValueDescriptor*)Z_OBJ_P(getThis()); + RETURN_LONG(intern->number); +} -static zend_function_entry gpb_type_methods[] = { +static zend_function_entry EnumValueDescriptor_methods[] = { + PHP_ME(EnumValueDescriptor, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(EnumValueDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC) ZEND_FE_END }; -void gpb_type_init(TSRMLS_D) { - zend_class_entry class_type; - INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\GPBType", - gpb_type_methods); - gpb_type_type = zend_register_internal_class(&class_type TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("DOUBLE"), 1 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("FLOAT"), 2 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("INT64"), 3 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("UINT64"), 4 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("INT32"), 5 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("FIXED64"), 6 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("FIXED32"), 7 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("BOOL"), 8 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("STRING"), 9 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("GROUP"), 10 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("MESSAGE"), 11 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("BYTES"), 12 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("UINT32"), 13 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("ENUM"), 14 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("SFIXED32"), - 15 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("SFIXED64"), - 16 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("SINT32"), 17 TSRMLS_CC); - zend_declare_class_constant_long(gpb_type_type, STR("SINT64"), 18 TSRMLS_CC); -} - // ----------------------------------------------------------------------------- -// Descriptor +// EnumDescriptor // ----------------------------------------------------------------------------- -static zend_function_entry descriptor_methods[] = { - PHP_ME(Descriptor, getClass, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Descriptor, getFullName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Descriptor, getField, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Descriptor, getFieldCount, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Descriptor, getOneofDecl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Descriptor, getOneofDeclCount, NULL, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; +typedef struct { + zend_object std; + const upb_enumdef *enumdef; +} EnumDescriptor; -DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Descriptor"); +zend_class_entry *EnumDescriptor_class_entry; +static zend_object_handlers EnumDescriptor_object_handlers; -static void descriptor_free_c(Descriptor *self TSRMLS_DC) { -} +void EnumDescriptor_FromClassEntry(zval *val, zend_class_entry *ce) { + // To differentiate enums from classes, we pointer-tag the class entry. + void* key = (void*)((uintptr_t)ce | 1); + PBPHP_ASSERT(key != ce); -static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) { - desc->intern = NULL; -} + if (ce == NULL) { + ZVAL_NULL(val); + return; + } -PHP_METHOD(Descriptor, getClass) { - Descriptor* desc = UNBOX(Descriptor, getThis()); - DescriptorInternal* intern = desc->intern; -#if PHP_MAJOR_VERSION < 7 - const char* classname = intern->klass->name; -#else - const char* classname = ZSTR_VAL(intern->klass->name); -#endif - PHP_PROTO_RETVAL_STRINGL(classname, strlen(classname), 1); -} + if (!ObjCache_Get(key, val)) { + const upb_enumdef *e = NameMap_GetEnum(ce); + if (!e) { + ZVAL_NULL(val); + return; + } + EnumDescriptor* ret = emalloc(sizeof(EnumDescriptor)); + zend_object_std_init(&ret->std, EnumDescriptor_class_entry); + ret->std.handlers = &EnumDescriptor_object_handlers; + ret->enumdef = e; + ObjCache_Add(key, &ret->std); -PHP_METHOD(Descriptor, getFullName) { - Descriptor* desc = UNBOX(Descriptor, getThis()); - DescriptorInternal* intern = desc->intern; - const char* fullname = upb_msgdef_fullname(intern->msgdef); - PHP_PROTO_RETVAL_STRINGL(fullname, strlen(fullname), 1); -} + // Prevent this from ever being collected (within a request). + GC_ADDREF(&ret->std); -PHP_METHOD(Descriptor, getField) { - long index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { - zend_error(E_USER_ERROR, "Expect integer for index.\n"); - return; + ZVAL_OBJ(val, &ret->std); } +} - Descriptor* desc = UNBOX(Descriptor, getThis()); - DescriptorInternal* intern = desc->intern; - int field_num = upb_msgdef_numfields(intern->msgdef); - if (index < 0 || index >= field_num) { - zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); - return; - } +void EnumDescriptor_FromEnumDef(zval *val, const upb_enumdef *m) { + if (!m) { + ZVAL_NULL(val); + } else { + char *classname = + GetPhpClassname(upb_enumdef_file(m), upb_enumdef_fullname(m)); + zend_string *str = zend_string_init(classname, strlen(classname), 0); + zend_class_entry *ce = zend_lookup_class(str); // May autoload the class. - upb_msg_field_iter iter; - int i; - for(upb_msg_field_begin(&iter, intern->msgdef), i = 0; - !upb_msg_field_done(&iter) && i < index; - upb_msg_field_next(&iter), i++); - const upb_fielddef *field = upb_msg_iter_field(&iter); + zend_string_release (str); - PHP_PROTO_HASHTABLE_VALUE field_hashtable_value = get_def_obj(field); - if (field_hashtable_value == NULL) { -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(field_hashtable_value); - ZVAL_OBJ(field_hashtable_value, field_descriptor_type->create_object( - field_descriptor_type TSRMLS_CC)); - Z_DELREF_P(field_hashtable_value); -#else - field_hashtable_value = - field_descriptor_type->create_object(field_descriptor_type TSRMLS_CC); - GC_DELREF(field_hashtable_value); -#endif - FieldDescriptor *field_php = - UNBOX_HASHTABLE_VALUE(FieldDescriptor, field_hashtable_value); - field_php->fielddef = field; - add_def_obj(field, field_hashtable_value); - } + if (!ce) { + zend_error(E_ERROR, "Couldn't load generated class %s", classname); + } -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(field_hashtable_value, 1, 0); -#else - GC_ADDREF(field_hashtable_value); - RETURN_OBJ(field_hashtable_value); -#endif + free(classname); + EnumDescriptor_FromClassEntry(val, ce); + } } -PHP_METHOD(Descriptor, getFieldCount) { - Descriptor* desc = UNBOX(Descriptor, getThis()); - DescriptorInternal* intern = desc->intern; - RETURN_LONG(upb_msgdef_numfields(intern->msgdef)); -} +/* + * EnumDescriptor::getValue() + * + * Returns an EnumValueDescriptor for this index. Note: we are not looking + * up by numeric enum value, but by the index in the list of enum values. + */ +PHP_METHOD(EnumDescriptor, getValue) { + EnumDescriptor *intern = (EnumDescriptor*)Z_OBJ_P(getThis()); + zend_long index; + zval ret; -PHP_METHOD(Descriptor, getOneofDecl) { - long index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { zend_error(E_USER_ERROR, "Expect integer for index.\n"); return; } - Descriptor* desc = UNBOX(Descriptor, getThis()); - DescriptorInternal* intern = desc->intern; - int field_num = upb_msgdef_numoneofs(intern->msgdef); + int field_num = upb_enumdef_numvals(intern->enumdef); if (index < 0 || index >= field_num) { zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); return; } - upb_msg_oneof_iter iter; + upb_enum_iter iter; int i; - for(upb_msg_oneof_begin(&iter, intern->msgdef), i = 0; - !upb_msg_oneof_done(&iter) && i < index; - upb_msg_oneof_next(&iter), i++); - const upb_oneofdef *oneof = upb_msg_iter_oneof(&iter); + for(upb_enum_begin(&iter, intern->enumdef), i = 0; + !upb_enum_done(&iter) && i < index; + upb_enum_next(&iter), i++); - ZVAL_OBJ(return_value, oneof_descriptor_type->create_object( - oneof_descriptor_type TSRMLS_CC)); - Oneof *oneof_php = UNBOX(Oneof, return_value); - oneof_php->oneofdef = oneof; + EnumValueDescriptor_Make(&ret, upb_enum_iter_name(&iter), + upb_enum_iter_number(&iter)); + RETURN_ZVAL(&ret, 0, 1); } -PHP_METHOD(Descriptor, getOneofDeclCount) { - Descriptor* desc = UNBOX(Descriptor, getThis()); - DescriptorInternal* intern = desc->intern; - RETURN_LONG(upb_msgdef_numoneofs(intern->msgdef)); +/* + * EnumDescriptor::getValueCount() + * + * Returns the number of values in this enum. + */ +PHP_METHOD(EnumDescriptor, getValueCount) { + EnumDescriptor *intern = (EnumDescriptor*)Z_OBJ_P(getThis()); + RETURN_LONG(upb_enumdef_numvals(intern->enumdef)); } -// ----------------------------------------------------------------------------- -// EnumDescriptor -// ----------------------------------------------------------------------------- +/* + * EnumDescriptor::getPublicDescriptor() + * + * Returns this EnumDescriptor. Unlike the pure-PHP descriptor, we do not + * have two separate EnumDescriptor classes. We use a single class for both + * the public and private descriptor. + */ +PHP_METHOD(EnumDescriptor, getPublicDescriptor) { + RETURN_ZVAL(getThis(), 1, 0); +} -static zend_function_entry enum_descriptor_methods[] = { - PHP_ME(EnumDescriptor, getValue, NULL, ZEND_ACC_PUBLIC) +static zend_function_entry EnumDescriptor_methods[] = { + PHP_ME(EnumDescriptor, getPublicDescriptor, NULL, ZEND_ACC_PUBLIC) PHP_ME(EnumDescriptor, getValueCount, NULL, ZEND_ACC_PUBLIC) + PHP_ME(EnumDescriptor, getValue, NULL, ZEND_ACC_PUBLIC) ZEND_FE_END }; -DEFINE_CLASS(EnumDescriptor, enum_descriptor, - "Google\\Protobuf\\EnumDescriptor"); +// ----------------------------------------------------------------------------- +// Oneof +// ----------------------------------------------------------------------------- + +typedef struct { + zend_object std; + const upb_oneofdef *oneofdef; +} OneofDescriptor; + +zend_class_entry *OneofDescriptor_class_entry; +static zend_object_handlers OneofDescriptor_object_handlers; + +static void OneofDescriptor_FromOneofDef(zval *val, const upb_oneofdef *o) { + if (o == NULL) { + ZVAL_NULL(val); + return; + } + + if (!ObjCache_Get(o, val)) { + OneofDescriptor* ret = emalloc(sizeof(OneofDescriptor)); + zend_object_std_init(&ret->std, OneofDescriptor_class_entry); + ret->std.handlers = &OneofDescriptor_object_handlers; + ret->oneofdef = o; + ObjCache_Add(o, &ret->std); -static void enum_descriptor_free_c(EnumDescriptor *self TSRMLS_DC) { + // Prevent this from ever being collected (within a request). + GC_ADDREF(&ret->std); + + ZVAL_OBJ(val, &ret->std); + } } -static void enum_descriptor_init_c_instance(EnumDescriptor *self TSRMLS_DC) { - self->intern = NULL; +/* + * OneofDescriptor::getName() + * + * Returns the name of this oneof. + */ +PHP_METHOD(OneofDescriptor, getName) { + OneofDescriptor *intern = (OneofDescriptor*)Z_OBJ_P(getThis()); + RETURN_STRING(upb_oneofdef_name(intern->oneofdef)); } -PHP_METHOD(EnumDescriptor, getValue) { - long index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { +/* + * OneofDescriptor::getField() + * + * Returns a field from this oneof. The given index must be in the range + * [0, getFieldCount() - 1]. + */ +PHP_METHOD(OneofDescriptor, getField) { + OneofDescriptor *intern = (OneofDescriptor*)Z_OBJ_P(getThis()); + zend_long index; + zval ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { zend_error(E_USER_ERROR, "Expect integer for index.\n"); return; } - EnumDescriptor *desc = UNBOX(EnumDescriptor, getThis()); - EnumDescriptorInternal *intern = desc->intern; - int field_num = upb_enumdef_numvals(intern->enumdef); + int field_num = upb_oneofdef_numfields(intern->oneofdef); if (index < 0 || index >= field_num) { zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); return; } - upb_enum_iter iter; + upb_oneof_iter iter; int i; - for(upb_enum_begin(&iter, intern->enumdef), i = 0; - !upb_enum_done(&iter) && i < index; - upb_enum_next(&iter), i++); + for(upb_oneof_begin(&iter, intern->oneofdef), i = 0; + !upb_oneof_done(&iter) && i < index; + upb_oneof_next(&iter), i++); + const upb_fielddef *field = upb_oneof_iter_field(&iter); - ZVAL_OBJ(return_value, enum_value_descriptor_type->create_object( - enum_value_descriptor_type TSRMLS_CC)); - EnumValueDescriptor *enum_value_php = - UNBOX(EnumValueDescriptor, return_value); - enum_value_php->name = upb_enum_iter_name(&iter); - enum_value_php->number = upb_enum_iter_number(&iter); + FieldDescriptor_FromFieldDef(&ret, field); + RETURN_ZVAL(&ret, 1, 0); } -PHP_METHOD(EnumDescriptor, getValueCount) { - EnumDescriptor *desc = UNBOX(EnumDescriptor, getThis()); - EnumDescriptorInternal *intern = desc->intern; - RETURN_LONG(upb_enumdef_numvals(intern->enumdef)); +/* + * OneofDescriptor::getFieldCount() + * + * Returns the number of fields in this oneof. + */ +PHP_METHOD(OneofDescriptor, getFieldCount) { + OneofDescriptor *intern = (OneofDescriptor*)Z_OBJ_P(getThis()); + RETURN_LONG(upb_oneofdef_numfields(intern->oneofdef)); } -// ----------------------------------------------------------------------------- -// EnumValueDescriptor -// ----------------------------------------------------------------------------- - -static zend_function_entry enum_value_descriptor_methods[] = { - PHP_ME(EnumValueDescriptor, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(EnumValueDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC) +static zend_function_entry OneofDescriptor_methods[] = { + PHP_ME(OneofDescriptor, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(OneofDescriptor, getField, NULL, ZEND_ACC_PUBLIC) + PHP_ME(OneofDescriptor, getFieldCount, NULL, ZEND_ACC_PUBLIC) ZEND_FE_END }; -DEFINE_CLASS(EnumValueDescriptor, enum_value_descriptor, - "Google\\Protobuf\\EnumValueDescriptor"); - -static void enum_value_descriptor_free_c(EnumValueDescriptor *self TSRMLS_DC) { -} - -static void enum_value_descriptor_init_c_instance(EnumValueDescriptor *self TSRMLS_DC) { - self->name = NULL; - self->number = 0; -} - -PHP_METHOD(EnumValueDescriptor, getName) { - EnumValueDescriptor *intern = UNBOX(EnumValueDescriptor, getThis()); - PHP_PROTO_RETVAL_STRINGL(intern->name, strlen(intern->name), 1); -} - -PHP_METHOD(EnumValueDescriptor, getNumber) { - EnumValueDescriptor *intern = UNBOX(EnumValueDescriptor, getThis()); - RETURN_LONG(intern->number); -} - // ----------------------------------------------------------------------------- // FieldDescriptor // ----------------------------------------------------------------------------- -static zend_function_entry field_descriptor_methods[] = { - PHP_ME(FieldDescriptor, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldDescriptor, getLabel, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldDescriptor, getType, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldDescriptor, isMap, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldDescriptor, getEnumType, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldDescriptor, getMessageType, NULL, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; +typedef struct { + zend_object std; + const upb_fielddef *fielddef; +} FieldDescriptor; -DEFINE_CLASS(FieldDescriptor, field_descriptor, - "Google\\Protobuf\\FieldDescriptor"); +zend_class_entry *FieldDescriptor_class_entry; +static zend_object_handlers FieldDescriptor_object_handlers; -static void field_descriptor_free_c(FieldDescriptor *self TSRMLS_DC) { -} +static void FieldDescriptor_FromFieldDef(zval *val, const upb_fielddef *f) { + if (f == NULL) { + ZVAL_NULL(val); + return; + } + + if (!ObjCache_Get(f, val)) { + FieldDescriptor* ret = emalloc(sizeof(FieldDescriptor)); + zend_object_std_init(&ret->std, FieldDescriptor_class_entry); + ret->std.handlers = &FieldDescriptor_object_handlers; + ret->fielddef = f; + ObjCache_Add(f, &ret->std); + + // Prevent this from ever being collected (within a request). + GC_ADDREF(&ret->std); -static void field_descriptor_init_c_instance(FieldDescriptor *self TSRMLS_DC) { - self->fielddef = NULL; + ZVAL_OBJ(val, &ret->std); + } } upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { @@ -382,499 +387,495 @@ upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { return 0; } +/* + * FieldDescriptor::getName() + * + * Returns the name of this field. + */ PHP_METHOD(FieldDescriptor, getName) { - FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); - const char* name = upb_fielddef_name(intern->fielddef); - PHP_PROTO_RETVAL_STRINGL(name, strlen(name), 1); + FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); + RETURN_STRING(upb_fielddef_name(intern->fielddef)); } +/* + * FieldDescriptor::getNumber() + * + * Returns the number of this field. + */ PHP_METHOD(FieldDescriptor, getNumber) { - FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); + FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); RETURN_LONG(upb_fielddef_number(intern->fielddef)); } +/* + * FieldDescriptor::getLabel() + * + * Returns the label of this field as an integer. + */ PHP_METHOD(FieldDescriptor, getLabel) { - FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); + FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); RETURN_LONG(upb_fielddef_label(intern->fielddef)); } +/* + * FieldDescriptor::getType() + * + * Returns the type of this field as an integer. + */ PHP_METHOD(FieldDescriptor, getType) { - FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); + FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); RETURN_LONG(upb_fielddef_descriptortype(intern->fielddef)); } +/* + * FieldDescriptor::isMap() + * + * Returns true if this field is a map. + */ PHP_METHOD(FieldDescriptor, isMap) { - FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); + FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); RETURN_BOOL(upb_fielddef_ismap(intern->fielddef)); } +/* + * FieldDescriptor::getEnumType() + * + * Returns the EnumDescriptor for this field, which must be an enum. + */ PHP_METHOD(FieldDescriptor, getEnumType) { - FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); - if (upb_fielddef_type(intern->fielddef) != UPB_TYPE_ENUM) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, + FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); + const upb_enumdef *e = upb_fielddef_enumsubdef(intern->fielddef); + zval ret; + + if (!e) { + zend_throw_exception_ex(NULL, 0, "Cannot get enum type for non-enum field '%s'", upb_fielddef_name(intern->fielddef)); return; } - const upb_enumdef *enumdef = upb_fielddef_enumsubdef(intern->fielddef); - PHP_PROTO_HASHTABLE_VALUE desc_php = get_def_obj(enumdef); - - if (desc_php == NULL) { - EnumDescriptorInternal* intern = get_enumdef_enumdesc(enumdef); - -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(desc_php); - ZVAL_OBJ(desc_php, enum_descriptor_type->create_object( - enum_descriptor_type TSRMLS_CC)); - Z_DELREF_P(desc_php); -#else - desc_php = - enum_descriptor_type->create_object(enum_descriptor_type TSRMLS_CC); - GC_DELREF(desc_php); -#endif - EnumDescriptor* desc = UNBOX_HASHTABLE_VALUE(EnumDescriptor, desc_php); - desc->intern = intern; - add_def_obj(enumdef, desc_php); - add_ce_obj(intern->klass, desc_php); - } -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(desc_php, 1, 0); -#else - GC_ADDREF(desc_php); - RETURN_OBJ(desc_php); -#endif + EnumDescriptor_FromEnumDef(&ret, e); + RETURN_ZVAL(&ret, 1, 0); } +/* + * FieldDescriptor::getMessageType() + * + * Returns the Descriptor for this field, which must be a message. + */ PHP_METHOD(FieldDescriptor, getMessageType) { - FieldDescriptor *intern = UNBOX(FieldDescriptor, getThis()); - if (upb_fielddef_type(intern->fielddef) != UPB_TYPE_MESSAGE) { + FieldDescriptor *intern = (FieldDescriptor*)Z_OBJ_P(getThis()); + Descriptor* desc = Descriptor_GetFromFieldDef(intern->fielddef); + zval ret; + + if (!desc) { zend_throw_exception_ex( - NULL, 0 TSRMLS_CC, "Cannot get message type for non-message field '%s'", + NULL, 0, "Cannot get message type for non-message field '%s'", upb_fielddef_name(intern->fielddef)); return; } - const upb_msgdef *msgdef = upb_fielddef_msgsubdef(intern->fielddef); - PHP_PROTO_HASHTABLE_VALUE desc_php = get_def_obj(msgdef); - - if (desc_php == NULL) { - DescriptorInternal* intern = get_msgdef_desc(msgdef); - -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(desc_php); - ZVAL_OBJ(desc_php, descriptor_type->create_object( - descriptor_type TSRMLS_CC)); - Z_DELREF_P(desc_php); -#else - desc_php = - descriptor_type->create_object(descriptor_type TSRMLS_CC); - GC_DELREF(desc_php); -#endif - Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, desc_php); - desc->intern = intern; - add_def_obj(msgdef, desc_php); - add_ce_obj(intern->klass, desc_php); - } -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(desc_php, 1, 0); -#else - GC_ADDREF(desc_php); - RETURN_OBJ(desc_php); -#endif + ZVAL_OBJ(&ret, &desc->std); + RETURN_ZVAL(&ret, 1, 0); } +static zend_function_entry FieldDescriptor_methods[] = { + PHP_ME(FieldDescriptor, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(FieldDescriptor, getNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(FieldDescriptor, getLabel, NULL, ZEND_ACC_PUBLIC) + PHP_ME(FieldDescriptor, getType, NULL, ZEND_ACC_PUBLIC) + PHP_ME(FieldDescriptor, isMap, NULL, ZEND_ACC_PUBLIC) + PHP_ME(FieldDescriptor, getEnumType, NULL, ZEND_ACC_PUBLIC) + PHP_ME(FieldDescriptor, getMessageType, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + // ----------------------------------------------------------------------------- -// Oneof +// Descriptor // ----------------------------------------------------------------------------- -static zend_function_entry oneof_descriptor_methods[] = { - PHP_ME(Oneof, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Oneof, getField, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Oneof, getFieldCount, NULL, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; +zend_class_entry *Descriptor_class_entry; +static zend_object_handlers Descriptor_object_handlers; + +static void Descriptor_destructor(zend_object* obj) { + // We don't really need to do anything here, we don't allow this to be + // collected before the end of the request. +} + +// C Functions from def.h ////////////////////////////////////////////////////// + +// These are documented in the header file. + +void Descriptor_FromClassEntry(zval *val, zend_class_entry *ce) { + if (ce == NULL) { + ZVAL_NULL(val); + return; + } + + if (!ObjCache_Get(ce, val)) { + const upb_msgdef *msgdef = NameMap_GetMessage(ce); + if (!msgdef) { + ZVAL_NULL(val); + return; + } + Descriptor* ret = emalloc(sizeof(Descriptor)); + zend_object_std_init(&ret->std, Descriptor_class_entry); + ret->std.handlers = &Descriptor_object_handlers; + ret->class_entry = ce; + ret->msgdef = msgdef; + ObjCache_Add(ce, &ret->std); -DEFINE_CLASS(Oneof, oneof_descriptor, - "Google\\Protobuf\\OneofDescriptor"); + // Prevent this from ever being collected (within a request). + GC_ADDREF(&ret->std); -static void oneof_descriptor_free_c(Oneof *self TSRMLS_DC) { + ZVAL_OBJ(val, &ret->std); + } +} + +Descriptor* Descriptor_GetFromClassEntry(zend_class_entry *ce) { + zval desc; + Descriptor_FromClassEntry(&desc, ce); + if (Z_TYPE_P(&desc) == IS_NULL) { + return NULL; + } else { + return (Descriptor*)Z_OBJ_P(&desc); + } +} + +Descriptor* Descriptor_GetFromMessageDef(const upb_msgdef *m) { + if (m) { + if (upb_msgdef_mapentry(m)) { + // A bit of a hack, since map entries don't have classes. + Descriptor* ret = emalloc(sizeof(Descriptor)); + zend_object_std_init(&ret->std, Descriptor_class_entry); + ret->std.handlers = &Descriptor_object_handlers; + ret->class_entry = NULL; + ret->msgdef = m; + + // Prevent this from ever being collected (within a request). + GC_ADDREF(&ret->std); + + return ret; + } + + char *classname = + GetPhpClassname(upb_msgdef_file(m), upb_msgdef_fullname(m)); + zend_string *str = zend_string_init(classname, strlen(classname), 0); + zend_class_entry *ce = zend_lookup_class(str); // May autoload the class. + + zend_string_release (str); + + if (!ce) { + zend_error(E_ERROR, "Couldn't load generated class %s", classname); + } + + free(classname); + return Descriptor_GetFromClassEntry(ce); + } else { + return NULL; + } } -static void oneof_descriptor_init_c_instance(Oneof *self TSRMLS_DC) { - self->oneofdef = NULL; +Descriptor* Descriptor_GetFromFieldDef(const upb_fielddef *f) { + return Descriptor_GetFromMessageDef(upb_fielddef_msgsubdef(f)); } -PHP_METHOD(Oneof, getName) { - Oneof *intern = UNBOX(Oneof, getThis()); - const char *name = upb_oneofdef_name(intern->oneofdef); - PHP_PROTO_RETVAL_STRINGL(name, strlen(name), 1); +/* + * Descriptor::getPublicDescriptor() + * + * Returns this EnumDescriptor. Unlike the pure-PHP descriptor, we do not + * have two separate EnumDescriptor classes. We use a single class for both + * the public and private descriptor. + */ +PHP_METHOD(Descriptor, getPublicDescriptor) { + RETURN_ZVAL(getThis(), 1, 0); } -PHP_METHOD(Oneof, getField) { - long index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { +/* + * Descriptor::getFullName() + * + * Returns the full name for this message type. + */ +PHP_METHOD(Descriptor, getFullName) { + Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); + RETURN_STRING(upb_msgdef_fullname(intern->msgdef)); +} + +/* + * Descriptor::getField() + * + * Returns a FieldDescriptor for the given index, which must be in the range + * [0, getFieldCount()-1]. + */ +PHP_METHOD(Descriptor, getField) { + Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); + int count = upb_msgdef_numfields(intern->msgdef); + zval ret; + zend_long index; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { zend_error(E_USER_ERROR, "Expect integer for index.\n"); return; } - Oneof *intern = UNBOX(Oneof, getThis()); - int field_num = upb_oneofdef_numfields(intern->oneofdef); - if (index < 0 || index >= field_num) { + if (index < 0 || index >= count) { zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); return; } - upb_oneof_iter iter; + upb_msg_field_iter iter; int i; - for(upb_oneof_begin(&iter, intern->oneofdef), i = 0; - !upb_oneof_done(&iter) && i < index; - upb_oneof_next(&iter), i++); - const upb_fielddef *field = upb_oneof_iter_field(&iter); - - PHP_PROTO_HASHTABLE_VALUE field_hashtable_value = get_def_obj(field); - if (field_hashtable_value == NULL) { -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(field_hashtable_value); - ZVAL_OBJ(field_hashtable_value, field_descriptor_type->create_object( - field_descriptor_type TSRMLS_CC)); -#else - field_hashtable_value = - field_descriptor_type->create_object(field_descriptor_type TSRMLS_CC); -#endif - FieldDescriptor *field_php = - UNBOX_HASHTABLE_VALUE(FieldDescriptor, field_hashtable_value); - field_php->fielddef = field; - add_def_obj(field, field_hashtable_value); - } + for(upb_msg_field_begin(&iter, intern->msgdef), i = 0; + !upb_msg_field_done(&iter) && i < index; + upb_msg_field_next(&iter), i++); + const upb_fielddef *field = upb_msg_iter_field(&iter); -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(field_hashtable_value, 1, 0); -#else - GC_ADDREF(field_hashtable_value); - RETURN_OBJ(field_hashtable_value); -#endif + FieldDescriptor_FromFieldDef(&ret, field); + RETURN_ZVAL(&ret, 1, 0); } -PHP_METHOD(Oneof, getFieldCount) { - Oneof *intern = UNBOX(Oneof, getThis()); - RETURN_LONG(upb_oneofdef_numfields(intern->oneofdef)); +/* + * Descriptor::getFieldCount() + * + * Returns the number of fields in this message. + */ +PHP_METHOD(Descriptor, getFieldCount) { + Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); + RETURN_LONG(upb_msgdef_numfields(intern->msgdef)); } -// ----------------------------------------------------------------------------- -// DescriptorPool -// ----------------------------------------------------------------------------- - -static zend_function_entry descriptor_pool_methods[] = { - PHP_ME(DescriptorPool, getGeneratedPool, NULL, - ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(DescriptorPool, getDescriptorByClassName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(DescriptorPool, getEnumDescriptorByClassName, NULL, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; +/* + * Descriptor::getOneofDecl() + * + * Returns a OneofDescriptor for the given index, which must be in the range + * [0, getOneofDeclCount()]. + */ +PHP_METHOD(Descriptor, getOneofDecl) { + Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); + zend_long index; + zval ret; -static zend_function_entry internal_descriptor_pool_methods[] = { - PHP_ME(InternalDescriptorPool, getGeneratedPool, NULL, - ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(InternalDescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &index) == FAILURE) { + zend_error(E_USER_ERROR, "Expect integer for index.\n"); + return; + } -DEFINE_CLASS(DescriptorPool, descriptor_pool, - "Google\\Protobuf\\DescriptorPool"); -DEFINE_CLASS(InternalDescriptorPool, internal_descriptor_pool, - "Google\\Protobuf\\Internal\\DescriptorPool"); - -// wrapper of generated pool -#if PHP_MAJOR_VERSION < 7 -zval* generated_pool_php; -zval* internal_generated_pool_php; -#else -zend_object *generated_pool_php; -zend_object *internal_generated_pool_php; -#endif -InternalDescriptorPoolImpl *generated_pool; -InternalDescriptorPoolImpl generated_pool_impl; // The actual generated pool - -void init_generated_pool_once(TSRMLS_D) { - if (generated_pool == NULL) { -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(generated_pool_php); - MAKE_STD_ZVAL(internal_generated_pool_php); - ZVAL_OBJ(internal_generated_pool_php, - internal_descriptor_pool_type->create_object( - internal_descriptor_pool_type TSRMLS_CC)); - ZVAL_OBJ(generated_pool_php, descriptor_pool_type->create_object( - descriptor_pool_type TSRMLS_CC)); -#else - internal_generated_pool_php = internal_descriptor_pool_type->create_object( - internal_descriptor_pool_type TSRMLS_CC); - generated_pool_php = - descriptor_pool_type->create_object(descriptor_pool_type TSRMLS_CC); -#endif - generated_pool = &generated_pool_impl; + int field_num = upb_msgdef_numoneofs(intern->msgdef); + if (index < 0 || index >= field_num) { + zend_error(E_USER_ERROR, "Cannot get element at %ld.\n", index); + return; } -} -static void internal_descriptor_pool_init_c_instance( - InternalDescriptorPool *pool TSRMLS_DC) { - pool->intern = &generated_pool_impl; -} + upb_msg_oneof_iter iter; + int i; + for(upb_msg_oneof_begin(&iter, intern->msgdef), i = 0; + !upb_msg_oneof_done(&iter) && i < index; + upb_msg_oneof_next(&iter), i++); + const upb_oneofdef *oneof = upb_msg_iter_oneof(&iter); -static void internal_descriptor_pool_free_c( - InternalDescriptorPool *pool TSRMLS_DC) { + OneofDescriptor_FromOneofDef(&ret, oneof); + RETURN_ZVAL(&ret, 1, 0); } -void internal_descriptor_pool_impl_init( - InternalDescriptorPoolImpl *pool TSRMLS_DC) { - pool->symtab = upb_symtab_new(); - pool->fill_handler_cache = - upb_handlercache_new(add_handlers_for_message, NULL); - pool->pb_serialize_handler_cache = upb_pb_encoder_newcache(); - pool->json_serialize_handler_cache = upb_json_printer_newcache(false); - pool->json_serialize_handler_preserve_cache = upb_json_printer_newcache(true); - pool->fill_method_cache = upb_pbcodecache_new(pool->fill_handler_cache); - pool->json_fill_method_cache = upb_json_codecache_new(); +/* + * Descriptor::getOneofDeclCount() + * + * Returns the number of oneofs in this message. + */ +PHP_METHOD(Descriptor, getOneofDeclCount) { + Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); + RETURN_LONG(upb_msgdef_numoneofs(intern->msgdef)); } -void internal_descriptor_pool_impl_destroy( - InternalDescriptorPoolImpl *pool TSRMLS_DC) { - upb_symtab_free(pool->symtab); - upb_handlercache_free(pool->fill_handler_cache); - upb_handlercache_free(pool->pb_serialize_handler_cache); - upb_handlercache_free(pool->json_serialize_handler_cache); - upb_handlercache_free(pool->json_serialize_handler_preserve_cache); - upb_pbcodecache_free(pool->fill_method_cache); - upb_json_codecache_free(pool->json_fill_method_cache); +/* + * Descriptor::getClass() + * + * Returns the name of the PHP class for this message. + */ +PHP_METHOD(Descriptor, getClass) { + Descriptor *intern = (Descriptor*)Z_OBJ_P(getThis()); + const char* classname = ZSTR_VAL(intern->class_entry->name); + RETURN_STRING(classname); } -static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) { - assert(generated_pool != NULL); - pool->intern = generated_pool; -} -static void descriptor_pool_free_c(DescriptorPool *pool TSRMLS_DC) { -} +static zend_function_entry Descriptor_methods[] = { + PHP_ME(Descriptor, getClass, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Descriptor, getFullName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Descriptor, getField, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Descriptor, getFieldCount, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Descriptor, getOneofDecl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Descriptor, getOneofDeclCount, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Descriptor, getPublicDescriptor, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; -PHP_METHOD(DescriptorPool, getGeneratedPool) { - init_generated_pool_once(TSRMLS_C); -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(generated_pool_php, 1, 0); -#else - GC_ADDREF(generated_pool_php); - RETURN_OBJ(generated_pool_php); -#endif +// ----------------------------------------------------------------------------- +// DescriptorPool +// ----------------------------------------------------------------------------- + +typedef struct DescriptorPool { + zend_object std; + upb_symtab *symtab; +} DescriptorPool; + +zend_class_entry *DescriptorPool_class_entry; +static zend_object_handlers DescriptorPool_object_handlers; + +static DescriptorPool *GetPool(const zval* this_ptr) { + return (DescriptorPool*)Z_OBJ_P(this_ptr); } -PHP_METHOD(InternalDescriptorPool, getGeneratedPool) { - init_generated_pool_once(TSRMLS_C); -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(internal_generated_pool_php, 1, 0); -#else - GC_ADDREF(internal_generated_pool_php); - RETURN_OBJ(internal_generated_pool_php); -#endif +/** + * Object handler to create an DescriptorPool. + */ +static zend_object* DescriptorPool_create(zend_class_entry *class_type) { + DescriptorPool *intern = emalloc(sizeof(DescriptorPool)); + zend_object_std_init(&intern->std, class_type); + intern->std.handlers = &DescriptorPool_object_handlers; + intern->symtab = upb_symtab_new(); + // Skip object_properties_init(), we don't allow derived classes. + return &intern->std; } -static bool is_reserved(const char *segment, int length) { - bool result; - char* lower = ALLOC_N(char, length + 1); - memset(lower, 0, length + 1); - memcpy(lower, segment, length); - int i = 0; - while(lower[i]) { - lower[i] = (char)tolower(lower[i]); - i++; +/** + * Object handler to free an DescriptorPool. + */ +static void DescriptorPool_destructor(zend_object* obj) { + DescriptorPool* intern = (DescriptorPool*)obj; + if (intern->symtab) { + upb_symtab_free(intern->symtab); } - lower[length] = 0; - result = is_reserved_name(lower); - FREE(lower); - return result; + intern->symtab = NULL; + zend_object_std_dtor(&intern->std); } -static void fill_prefix(const char *segment, int length, - const char *prefix_given, - const char *package_name, - stringsink *classname) { - if (prefix_given != NULL && strcmp(prefix_given, "") != 0) { - stringsink_string(classname, NULL, prefix_given, - strlen(prefix_given), NULL); - } else { - if (is_reserved(segment, length)) { - if (package_name != NULL && - strcmp("google.protobuf", package_name) == 0) { - stringsink_string(classname, NULL, "GPB", 3, NULL); - } else { - stringsink_string(classname, NULL, "PB", 2, NULL); - } - } +void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab) { + ZVAL_OBJ(zv, DescriptorPool_create(DescriptorPool_class_entry)); + + if (symtab) { + DescriptorPool *intern = GetPool(zv); + upb_symtab_free(intern->symtab); + intern->symtab = symtab; } } -static void fill_segment(const char *segment, int length, - stringsink *classname, bool use_camel) { - if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) { - char first = segment[0] + ('A' - 'a'); - stringsink_string(classname, NULL, &first, 1, NULL); - stringsink_string(classname, NULL, segment + 1, length - 1, NULL); - } else { - stringsink_string(classname, NULL, segment, length, NULL); - } +upb_symtab *DescriptorPool_Steal(zval *zv) { + DescriptorPool *intern = GetPool(zv); + upb_symtab *ret = intern->symtab; + intern->symtab = NULL; + return ret; } -static void fill_namespace(const char *package, const char *php_namespace, - stringsink *classname) { - if (php_namespace != NULL) { - if (strlen(php_namespace) != 0) { - stringsink_string(classname, NULL, php_namespace, strlen(php_namespace), - NULL); - stringsink_string(classname, NULL, "\\", 1, NULL); - } - } else if (package != NULL) { - int i = 0, j = 0; - size_t package_len = strlen(package); - while (i < package_len) { - j = i; - while (j < package_len && package[j] != '.') { - j++; - } - fill_prefix(package + i, j - i, "", package, classname); - fill_segment(package + i, j - i, classname, true); - stringsink_string(classname, NULL, "\\", 1, NULL); - i = j + 1; - } - } +upb_symtab *DescriptorPool_GetSymbolTable() { + DescriptorPool *intern = GetPool(get_generated_pool()); + return intern->symtab; } -static void fill_classname(const char *fullname, - const char *package, - const char *prefix, - stringsink *classname, - bool use_nested_submsg) { - int classname_start = 0; - if (package != NULL) { - size_t package_len = strlen(package); - classname_start = package_len == 0 ? 0 : package_len + 1; - } - size_t fullname_len = strlen(fullname); - bool is_first_segment = true; - - int i = classname_start, j; - while (i < fullname_len) { - j = i; - while (j < fullname_len && fullname[j] != '.') { - j++; - } - if (use_nested_submsg || (is_first_segment && j == fullname_len)) { - fill_prefix(fullname + i, j - i, prefix, package, classname); - } - is_first_segment = false; - fill_segment(fullname + i, j - i, classname, false); - if (j != fullname_len) { - if (use_nested_submsg) { - stringsink_string(classname, NULL, "\\", 1, NULL); - } else { - stringsink_string(classname, NULL, "_", 1, NULL); - } - } - i = j + 1; - } + +/* + * DescriptorPool::getGeneratedPool() + * + * Returns the generated DescriptorPool. + */ +PHP_METHOD(DescriptorPool, getGeneratedPool) { + zval ret; + ZVAL_COPY(&ret, get_generated_pool()); + RETURN_ZVAL(&ret, 0, 1); } -static void fill_classname_for_desc(void *desc, bool is_enum) { - const upb_filedef *file; - const char *fullname; - bool use_nested_submsg; +/* + * DescriptorPool::getDescriptorByClassName() + * + * Returns a Descriptor object for the given PHP class name. + */ +PHP_METHOD(DescriptorPool, getDescriptorByClassName) { + char *classname = NULL; + zend_long classname_len; + zend_class_entry *ce; + zend_string *str; + zval ret; - if (is_enum) { - EnumDescriptorInternal* enumdesc = desc; - file = upb_enumdef_file(enumdesc->enumdef); - fullname = upb_enumdef_fullname(enumdesc->enumdef); - use_nested_submsg = enumdesc->use_nested_submsg; - } else { - DescriptorInternal* msgdesc = desc; - file = upb_msgdef_file(msgdesc->msgdef); - fullname = upb_msgdef_fullname(msgdesc->msgdef); - use_nested_submsg = msgdesc->use_nested_submsg; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) == + FAILURE) { + return; } - // Prepend '.' to package name to make it absolute. In the 5 additional - // bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if - // given message is google.protobuf.Empty. - const char *package = upb_filedef_package(file); - const char *php_namespace = upb_filedef_phpnamespace(file); - const char *prefix = upb_filedef_phpprefix(file); - stringsink namesink; - stringsink_init(&namesink); - - fill_namespace(package, php_namespace, &namesink); - fill_classname(fullname, package, prefix, &namesink, use_nested_submsg); - stringsink_string(&namesink, NULL, "\0", 1, NULL); - - if (is_enum) { - EnumDescriptorInternal* enumdesc = desc; - enumdesc->classname = strdup(namesink.ptr); - } else { - DescriptorInternal* msgdesc = desc; - msgdesc->classname = strdup(namesink.ptr); + str = zend_string_init(classname, strlen(classname), 0); + ce = zend_lookup_class(str); // May autoload the class. + zend_string_release (str); + + if (!ce) { + RETURN_NULL(); } - stringsink_uninit(&namesink); + Descriptor_FromClassEntry(&ret, ce); + RETURN_ZVAL(&ret, 1, 0); } -void register_class(void *desc, bool is_enum TSRMLS_DC) { - const char *classname; - const char *fullname; - zend_class_entry* ret; +/* + * DescriptorPool::getEnumDescriptorByClassName() + * + * Returns a EnumDescriptor object for the given PHP class name. + */ +PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) { + char *classname = NULL; + zend_long classname_len; + zend_class_entry *ce; + zend_string *str; + zval ret; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &classname, &classname_len) == + FAILURE) { + return; + } - if (is_enum) { - EnumDescriptorInternal* enumdesc = desc; - if (enumdesc->klass) { - return; - } - classname = enumdesc->classname; - fullname = upb_enumdef_fullname(enumdesc->enumdef); - } else { - DescriptorInternal* msgdesc = desc; - if (msgdesc->klass) { - return; - } - if (!msgdesc->classname) { - return; - } - classname = msgdesc->classname; - fullname = upb_msgdef_fullname(msgdesc->msgdef); + str = zend_string_init(classname, strlen(classname), 0); + ce = zend_lookup_class(str); // May autoload the class. + zend_string_release (str); + + if (!ce) { + RETURN_NULL(); } - PHP_PROTO_CE_DECLARE pce; - if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) == + EnumDescriptor_FromClassEntry(&ret, ce); + RETURN_ZVAL(&ret, 1, 0); +} + +/* + * DescriptorPool::getEnumDescriptorByProtoName() + * + * Returns a Descriptor object for the given protobuf message name. + */ +PHP_METHOD(DescriptorPool, getDescriptorByProtoName) { + DescriptorPool *intern = GetPool(getThis()); + char *protoname = NULL; + zend_long protoname_len; + const upb_msgdef *m; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &protoname, &protoname_len) == FAILURE) { - zend_error( - E_ERROR, - "Generated message class %s hasn't been defined (%s)", - classname, fullname); return; } - ret = PHP_PROTO_CE_UNREF(pce); - if (is_enum) { - EnumDescriptorInternal* enumdesc = desc; - add_ce_enumdesc(ret, desc); - enumdesc->klass = ret; + + if (*protoname == '.') protoname++; + + m = upb_symtab_lookupmsg(intern->symtab, protoname); + + if (m) { + zval ret; + ZVAL_OBJ(&ret, &Descriptor_GetFromMessageDef(m)->std); + RETURN_ZVAL(&ret, 1, 0); } else { - DescriptorInternal* msgdesc = desc; - add_ce_desc(ret, desc); - msgdesc->klass = ret; - // Map entries don't have existing php class. - if (!upb_msgdef_mapentry(msgdesc->msgdef)) { - if (msgdesc->layout == NULL) { - MessageLayout* layout = create_layout(msgdesc->msgdef); - msgdesc->layout = layout; - } - } + RETURN_NULL(); } } +/* + * depends_on_descriptor() + * + * Returns true if this FileDescriptorProto depends on descriptor.proto. + */ bool depends_on_descriptor(const google_protobuf_FileDescriptorProto* file) { const upb_strview *deps; upb_strview name = upb_strview_makez("google/protobuf/descriptor.proto"); @@ -890,239 +891,251 @@ bool depends_on_descriptor(const google_protobuf_FileDescriptorProto* file) { return false; } -const upb_filedef *parse_and_add_descriptor(const char *data, - PHP_PROTO_SIZE data_len, - InternalDescriptorPoolImpl *pool, - upb_arena *arena) { - size_t n; - google_protobuf_FileDescriptorSet *set; - const google_protobuf_FileDescriptorProto* const* files; - const upb_filedef* file; - upb_status status; - - set = google_protobuf_FileDescriptorSet_parse( - data, data_len, arena); - - if (!set) { - zend_error(E_ERROR, "Failed to parse binary descriptor\n"); - return NULL; +/* + * add_name_mappings() + * + * Adds the messages and enums in this file to the NameMap. + */ +static void add_name_mappings(const upb_filedef *file) { + size_t i; + for (i = 0; i < upb_filedef_msgcount(file); i++) { + NameMap_AddMessage(upb_filedef_msg(file, i)); } - files = google_protobuf_FileDescriptorSet_file(set, &n); - - if (n != 1) { - zend_error(E_ERROR, "Serialized descriptors should have exactly one file"); - return NULL; + for (i = 0; i < upb_filedef_enumcount(file); i++) { + NameMap_AddEnum(upb_filedef_enum(file, i)); } +} - // Check whether file has already been added. - upb_strview name = google_protobuf_FileDescriptorProto_name(files[0]); - // TODO(teboring): Needs another look up method which takes data and length. - file = upb_symtab_lookupfile2(pool->symtab, name.data, name.size); - if (file != NULL) { - return NULL; +static void add_descriptor(DescriptorPool *pool, + const google_protobuf_FileDescriptorProto *file) { + upb_strview name = google_protobuf_FileDescriptorProto_name(file); + upb_status status; + const upb_filedef *file_def; + upb_status_clear(&status); + + if (upb_symtab_lookupfile2(pool->symtab, name.data, name.size)) { + // Already added. + fprintf(stderr, "WARNING: file was already added\n"); + return; } // The PHP code generator currently special-cases descriptor.proto. It // doesn't add it as a dependency even if the proto file actually does // depend on it. - if (depends_on_descriptor(files[0]) && - upb_symtab_lookupfile(pool->symtab, "google/protobuf/descriptor.proto") == - NULL) { - if (!parse_and_add_descriptor((char *)descriptor_proto, - descriptor_proto_len, pool, arena)) { - return NULL; - } + if (depends_on_descriptor(file)) { + google_protobuf_FileDescriptorProto_getmsgdef(pool->symtab); } - upb_status_clear(&status); - file = upb_symtab_addfile(pool->symtab, files[0], &status); - check_upb_status(&status, "Unable to load descriptor"); - return file; + file_def = upb_symtab_addfile(pool->symtab, file, &status); + CheckUpbStatus(&status, "Unable to load descriptor"); + add_name_mappings(file_def); } -void internal_add_generated_file(const char *data, PHP_PROTO_SIZE data_len, - InternalDescriptorPoolImpl *pool, - bool use_nested_submsg TSRMLS_DC) { - int i; - upb_arena *arena; - const upb_filedef* file; +/* + * add_descriptor() + * + * Adds the given descriptor data to this DescriptorPool. + */ +static void add_descriptor_set(DescriptorPool *pool, const char *data, + int data_len, upb_arena *arena) { + size_t i, n; + google_protobuf_FileDescriptorSet *set; + const google_protobuf_FileDescriptorProto* const* files; - arena = upb_arena_new(); - file = parse_and_add_descriptor(data, data_len, pool, arena); - upb_arena_free(arena); - if (!file) return; + set = google_protobuf_FileDescriptorSet_parse(data, data_len, arena); - // For each enum/message, we need its PHP class, upb descriptor and its PHP - // wrapper. These information are needed later for encoding, decoding and type - // checking. However, sometimes we just have one of them. In order to find - // them quickly, here, we store the mapping for them. + if (!set) { + zend_error(E_ERROR, "Failed to parse binary descriptor\n"); + return; + } - for (i = 0; i < upb_filedef_msgcount(file); i++) { - const upb_msgdef *msgdef = upb_filedef_msg(file, i); - CREATE_HASHTABLE_VALUE(desc, desc_php, Descriptor, descriptor_type); - desc->intern = SYS_MALLOC(DescriptorInternal); - desc->intern->msgdef = msgdef; - desc->intern->pool = pool; - desc->intern->layout = NULL; - desc->intern->klass = NULL; - desc->intern->use_nested_submsg = use_nested_submsg; - desc->intern->classname = NULL; - - add_def_obj(desc->intern->msgdef, desc_php); - add_msgdef_desc(desc->intern->msgdef, desc->intern); - - // Unlike other messages, MapEntry is shared by all map fields and doesn't - // have generated PHP class. - if (upb_msgdef_mapentry(msgdef)) { - continue; - } + files = google_protobuf_FileDescriptorSet_file(set, &n); - fill_classname_for_desc(desc->intern, false); - add_class_desc(desc->intern->classname, desc->intern); - add_proto_desc(upb_msgdef_fullname(desc->intern->msgdef), desc->intern); + for (i = 0; i < n; i++) { + const google_protobuf_FileDescriptorProto* file = files[i]; + add_descriptor(pool, file); } +} - for (i = 0; i < upb_filedef_enumcount(file); i++) { - const upb_enumdef *enumdef = upb_filedef_enum(file, i); - CREATE_HASHTABLE_VALUE(desc, desc_php, EnumDescriptor, enum_descriptor_type); - desc->intern = SYS_MALLOC(EnumDescriptorInternal); - desc->intern->enumdef = enumdef; - desc->intern->klass = NULL; - desc->intern->use_nested_submsg = use_nested_submsg; - desc->intern->classname = NULL; - - add_def_obj(desc->intern->enumdef, desc_php); - add_enumdef_enumdesc(desc->intern->enumdef, desc->intern); - fill_classname_for_desc(desc->intern, true); - add_class_enumdesc(desc->intern->classname, desc->intern); - } +bool DescriptorPool_HasFile(const char *filename) { + DescriptorPool *intern = GetPool(get_generated_pool()); + return upb_symtab_lookupfile(intern->symtab, filename) != NULL; } -PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile) { - char *data = NULL; - PHP_PROTO_SIZE data_len; - zend_bool use_nested_submsg = false; +void DescriptorPool_AddDescriptor(const char *filename, const char *data, + int size) { + upb_arena *arena = upb_arena_new(); + const google_protobuf_FileDescriptorProto *file = + google_protobuf_FileDescriptorProto_parse(data, size, arena); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", - &data, &data_len, &use_nested_submsg) == - FAILURE) { + if (!file) { + zend_error(E_ERROR, "Failed to parse binary descriptor for %s\n", filename); return; } - InternalDescriptorPool *pool = UNBOX(InternalDescriptorPool, getThis()); - internal_add_generated_file(data, data_len, pool->intern, - use_nested_submsg TSRMLS_CC); + add_descriptor(GetPool(get_generated_pool()), file); + upb_arena_free(arena); } -PHP_METHOD(DescriptorPool, getDescriptorByClassName) { - char *classname = NULL; - PHP_PROTO_SIZE classname_len; +/* + * DescriptorPool::internalAddGeneratedFile() + * + * Adds the given descriptor data to this DescriptorPool. + */ +PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { + DescriptorPool *intern = GetPool(getThis()); + char *data = NULL; + zend_long data_len; + zend_bool use_nested_submsg = false; + upb_arena *arena; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname, - &classname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &data, &data_len, + &use_nested_submsg) != SUCCESS) { return; } - PHP_PROTO_CE_DECLARE pce; - if (php_proto_zend_lookup_class(classname, classname_len, &pce) == - FAILURE) { - RETURN_NULL(); - } + arena = upb_arena_new(); + add_descriptor_set(intern, data, data_len, arena); + upb_arena_free(arena); +} - PHP_PROTO_HASHTABLE_VALUE desc_php = get_ce_obj(PHP_PROTO_CE_UNREF(pce)); - if (desc_php == NULL) { - DescriptorInternal* intern = get_ce_desc(PHP_PROTO_CE_UNREF(pce)); - if (intern == NULL) { - RETURN_NULL(); - } +static zend_function_entry DescriptorPool_methods[] = { + PHP_ME(DescriptorPool, getGeneratedPool, NULL, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + PHP_ME(DescriptorPool, getDescriptorByClassName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(DescriptorPool, getDescriptorByProtoName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(DescriptorPool, getEnumDescriptorByClassName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(DescriptorPool, internalAddGeneratedFile, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(desc_php); - ZVAL_OBJ(desc_php, descriptor_type->create_object( - descriptor_type TSRMLS_CC)); - Z_DELREF_P(desc_php); -#else - desc_php = - descriptor_type->create_object(descriptor_type TSRMLS_CC); - GC_DELREF(desc_php); -#endif - Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, desc_php); - desc->intern = intern; - add_def_obj(intern->msgdef, desc_php); - add_ce_obj(PHP_PROTO_CE_UNREF(pce), desc_php); - } +// ----------------------------------------------------------------------------- +// InternalDescriptorPool +// ----------------------------------------------------------------------------- - zend_class_entry* instance_ce = HASHTABLE_VALUE_CE(desc_php); +// For the C extension, Google\Protobuf\Internal\DescriptorPool is not a +// separate instantiable object, it just returns a +// Google\Protobuf\DescriptorPool. - if (!instanceof_function(instance_ce, descriptor_type TSRMLS_CC)) { - RETURN_NULL(); - } +zend_class_entry *InternalDescriptorPool_class_entry; -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(desc_php, 1, 0); -#else - GC_ADDREF(desc_php); - RETURN_OBJ(desc_php); -#endif +/* + * InternalDescriptorPool::getGeneratedPool() + * + * Returns the generated DescriptorPool. Note that this is identical to + * DescriptorPool::getGeneratedPool(), and in fact returns a DescriptorPool + * instance. + */ +PHP_METHOD(InternalDescriptorPool, getGeneratedPool) { + zval ret; + ZVAL_COPY(&ret, get_generated_pool()); + RETURN_ZVAL(&ret, 0, 1); } -PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName) { - char *classname = NULL; - PHP_PROTO_SIZE classname_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &classname, - &classname_len) == FAILURE) { - return; - } - - PHP_PROTO_CE_DECLARE pce; - if (php_proto_zend_lookup_class(classname, classname_len, &pce) == - FAILURE) { - RETURN_NULL(); - } - - zend_class_entry* ce = PHP_PROTO_CE_UNREF(pce); - - PHP_PROTO_HASHTABLE_VALUE desc_php = get_ce_obj(ce); - if (desc_php == NULL) { -#if PHP_MAJOR_VERSION < 7 - EnumDescriptorInternal* intern = get_class_enumdesc(ce->name); -#else - EnumDescriptorInternal* intern = get_class_enumdesc(ZSTR_VAL(ce->name)); -#endif - register_class(intern, true TSRMLS_CC); +static zend_function_entry InternalDescriptorPool_methods[] = { + PHP_ME(InternalDescriptorPool, getGeneratedPool, NULL, + ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) + ZEND_FE_END +}; - if (intern == NULL) { - RETURN_NULL(); - } +// ----------------------------------------------------------------------------- +// GPBType +// ----------------------------------------------------------------------------- -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(desc_php); - ZVAL_OBJ(desc_php, enum_descriptor_type->create_object( - enum_descriptor_type TSRMLS_CC)); - Z_DELREF_P(desc_php); -#else - desc_php = - enum_descriptor_type->create_object(enum_descriptor_type TSRMLS_CC); - GC_DELREF(desc_php); -#endif - EnumDescriptor* desc = UNBOX_HASHTABLE_VALUE(EnumDescriptor, desc_php); - desc->intern = intern; - add_def_obj(intern->enumdef, desc_php); - add_ce_obj(ce, desc_php); - } +zend_class_entry* gpb_type_type; - zend_class_entry* instance_ce = HASHTABLE_VALUE_CE(desc_php); +static zend_function_entry gpb_type_methods[] = { + ZEND_FE_END +}; - if (!instanceof_function(instance_ce, enum_descriptor_type TSRMLS_CC)) { - RETURN_NULL(); - } +// ----------------------------------------------------------------------------- +// Module Init +// ----------------------------------------------------------------------------- -#if PHP_MAJOR_VERSION < 7 - RETURN_ZVAL(desc_php, 1, 0); -#else - GC_ADDREF(desc_php); - RETURN_OBJ(desc_php); -#endif +void Def_ModuleInit() { + zend_class_entry tmp_ce; + zend_object_handlers *h; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\OneofDescriptor", + OneofDescriptor_methods); + OneofDescriptor_class_entry = zend_register_internal_class(&tmp_ce); + OneofDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; + OneofDescriptor_class_entry->create_object = CreateHandler_ReturnNull; + h = &OneofDescriptor_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\EnumValueDescriptor", + EnumValueDescriptor_methods); + EnumValueDescriptor_class_entry = zend_register_internal_class(&tmp_ce); + EnumValueDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; + EnumValueDescriptor_class_entry->create_object = CreateHandler_ReturnNull; + h = &EnumValueDescriptor_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\EnumDescriptor", + EnumDescriptor_methods); + EnumDescriptor_class_entry = zend_register_internal_class(&tmp_ce); + EnumDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; + EnumDescriptor_class_entry->create_object = CreateHandler_ReturnNull; + h = &EnumDescriptor_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Descriptor", + Descriptor_methods); + + Descriptor_class_entry = zend_register_internal_class(&tmp_ce); + Descriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; + Descriptor_class_entry->create_object = CreateHandler_ReturnNull; + h = &Descriptor_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + h->dtor_obj = Descriptor_destructor; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\FieldDescriptor", + FieldDescriptor_methods); + FieldDescriptor_class_entry = zend_register_internal_class(&tmp_ce); + FieldDescriptor_class_entry->ce_flags |= ZEND_ACC_FINAL; + FieldDescriptor_class_entry->create_object = CreateHandler_ReturnNull; + h = &FieldDescriptor_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\DescriptorPool", + DescriptorPool_methods); + DescriptorPool_class_entry = zend_register_internal_class(&tmp_ce); + DescriptorPool_class_entry->ce_flags |= ZEND_ACC_FINAL; + DescriptorPool_class_entry->create_object = DescriptorPool_create; + h = &DescriptorPool_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + h->dtor_obj = DescriptorPool_destructor; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\DescriptorPool", + InternalDescriptorPool_methods); + InternalDescriptorPool_class_entry = zend_register_internal_class(&tmp_ce); + + // GPBType. +#define STR(str) (str), strlen(str) + zend_class_entry class_type; + INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\GPBType", + gpb_type_methods); + gpb_type_type = zend_register_internal_class(&class_type); + zend_declare_class_constant_long(gpb_type_type, STR("DOUBLE"), 1); + zend_declare_class_constant_long(gpb_type_type, STR("FLOAT"), 2); + zend_declare_class_constant_long(gpb_type_type, STR("INT64"), 3); + zend_declare_class_constant_long(gpb_type_type, STR("UINT64"), 4); + zend_declare_class_constant_long(gpb_type_type, STR("INT32"), 5); + zend_declare_class_constant_long(gpb_type_type, STR("FIXED64"), 6); + zend_declare_class_constant_long(gpb_type_type, STR("FIXED32"), 7); + zend_declare_class_constant_long(gpb_type_type, STR("BOOL"), 8); + zend_declare_class_constant_long(gpb_type_type, STR("STRING"), 9); + zend_declare_class_constant_long(gpb_type_type, STR("GROUP"), 10); + zend_declare_class_constant_long(gpb_type_type, STR("MESSAGE"), 11); + zend_declare_class_constant_long(gpb_type_type, STR("BYTES"), 12); + zend_declare_class_constant_long(gpb_type_type, STR("UINT32"), 13); + zend_declare_class_constant_long(gpb_type_type, STR("ENUM"), 14); + zend_declare_class_constant_long(gpb_type_type, STR("SFIXED32"), 15); + zend_declare_class_constant_long(gpb_type_type, STR("SFIXED64"), 16); + zend_declare_class_constant_long(gpb_type_type, STR("SINT32"), 17); + zend_declare_class_constant_long(gpb_type_type, STR("SINT64"), 18); +#undef STR } diff --git a/php/ext/google/protobuf/def.h b/php/ext/google/protobuf/def.h new file mode 100644 index 000000000000..2a89cd0fd4e6 --- /dev/null +++ b/php/ext/google/protobuf/def.h @@ -0,0 +1,75 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#ifndef PHP_PROTOBUF_DEF_H_ +#define PHP_PROTOBUF_DEF_H_ + +#include + +#include "php-upb.h" + +// Initializes the Def module, which defines all of the descriptor classes. +void Def_ModuleInit(); + +// Creates a new DescriptorPool to wrap the given symtab. The DescriptorPool +// takes ownership of the given symtab. If symtab is NULL, the DescriptorPool +// will create an empty symtab instead. +void DescriptorPool_CreateWithSymbolTable(zval *zv, upb_symtab *symtab); + +// Given a zval representing a DescriptorPool, steals and returns its symtab, +// which is now owned by the caller. +upb_symtab *DescriptorPool_Steal(zval *zv); + +upb_symtab *DescriptorPool_GetSymbolTable(); + +// Returns true if the global descriptor pool already has the given filename. +bool DescriptorPool_HasFile(const char *filename); + +// Adds the given descriptor with the given filename to the global pool. +void DescriptorPool_AddDescriptor(const char *filename, const char *data, int size); + +typedef struct Descriptor { + zend_object std; + const upb_msgdef *msgdef; + zend_class_entry *class_entry; +} Descriptor; + +// Gets or creates a PHP Descriptor object for a |ce| and stores it in |val|. +// If this is not a protobuf generated class, |val| will be set to null. +void Descriptor_FromClassEntry(zval *val, zend_class_entry *ce); + +// Gets or creates a Descriptor* for the given class entry, upb_msgdef, or +// upb_fielddef. The returned Descriptor* will live for the entire request, +// so no ref is necessary to keep it alive. +Descriptor* Descriptor_GetFromClassEntry(zend_class_entry *ce); +Descriptor* Descriptor_GetFromMessageDef(const upb_msgdef *m); +Descriptor* Descriptor_GetFromFieldDef(const upb_fielddef *f); + +#endif // PHP_PROTOBUF_DEF_H_ diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c deleted file mode 100644 index 8eaa5d22eed8..000000000000 --- a/php/ext/google/protobuf/encode_decode.c +++ /dev/null @@ -1,2283 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. -// -#include -#include - -#include "protobuf.h" -#include "utf8.h" - -/* stringsink *****************************************************************/ - -static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) { - stringsink *sink = _sink; - sink->len = 0; - return sink; -} - -size_t stringsink_string(void *_sink, const void *hd, const char *ptr, - size_t len, const upb_bufhandle *handle) { - stringsink *sink = _sink; - size_t new_size = sink->size; - - PHP_PROTO_UNUSED(hd); - PHP_PROTO_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 stringsink_init(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); - PHP_PROTO_ASSERT(sink->ptr != NULL); - sink->len = 0; -} - -void stringsink_uninit(stringsink *sink) { free(sink->ptr); } - -void stringsink_uninit_opaque(void *sink) { stringsink_uninit(sink); } - -/* stackenv *****************************************************************/ - -// Stack-allocated context during an encode/decode operation. Contains the upb -// environment and its stack-based allocator, an initial buffer for allocations -// to avoid malloc() when possible, and a template for PHP exception messages -// if any error occurs. -#define STACK_ENV_STACKBYTES 4096 -typedef struct { - upb_arena *arena; - upb_status status; - const char *php_error_template; - char allocbuf[STACK_ENV_STACKBYTES]; -} stackenv; - - -static void stackenv_init(stackenv* se, const char* errmsg); -static void stackenv_uninit(stackenv* se); - -static void stackenv_init(stackenv* se, const char* errmsg) { - se->php_error_template = errmsg; - se->arena = upb_arena_new(); - upb_status_clear(&se->status); -} - -static void stackenv_uninit(stackenv* se) { - upb_arena_free(se->arena); - - if (!upb_ok(&se->status)) { - // TODO(teboring): have a way to verify that this is actually a parse error, - // instead of just throwing "parse error" unconditionally. - TSRMLS_FETCH(); - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, se->php_error_template, - upb_status_errmsg(&se->status)); - } -} - -// ----------------------------------------------------------------------------- -// Parsing. -// ----------------------------------------------------------------------------- - -bool is_wrapper_msg(const upb_msgdef* m) { - switch (upb_msgdef_wellknowntype(m)) { - case UPB_WELLKNOWN_DOUBLEVALUE: - case UPB_WELLKNOWN_FLOATVALUE: - case UPB_WELLKNOWN_INT64VALUE: - case UPB_WELLKNOWN_UINT64VALUE: - case UPB_WELLKNOWN_INT32VALUE: - case UPB_WELLKNOWN_UINT32VALUE: - case UPB_WELLKNOWN_STRINGVALUE: - case UPB_WELLKNOWN_BYTESVALUE: - case UPB_WELLKNOWN_BOOLVALUE: - return true; - default: - return false; - } -} - -typedef struct { - void* closure; - void* submsg; - bool is_msg; -} wrapperfields_parseframe_t; - -#define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs) - -// Creates a handlerdata that simply contains the offset for this field. -static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) { - size_t* hd_ofs = (size_t*)malloc(sizeof(size_t)); - PHP_PROTO_ASSERT(hd_ofs != NULL); - *hd_ofs = ofs; - upb_handlers_addcleanup(h, hd_ofs, free); - return hd_ofs; -} - -static const void* newhandlerfielddata( - upb_handlers* h, const upb_fielddef* field) { - const void** hd_field = malloc(sizeof(void*)); - PHP_PROTO_ASSERT(hd_field != NULL); - *hd_field = field; - upb_handlers_addcleanup(h, hd_field, free); - return hd_field; -} - -typedef struct { - void* closure; - stringsink sink; -} stringfields_parseframe_t; - -typedef size_t (*encodeunknown_handlerfunc)(void* _sink, const void* hd, - const char* ptr, size_t len, - const upb_bufhandle* handle); - -typedef struct { - encodeunknown_handlerfunc handler; -} unknownfields_handlerdata_t; - -// Creates a handlerdata for unknown fields. -static const void *newunknownfieldshandlerdata(upb_handlers* h) { - unknownfields_handlerdata_t* hd = - (unknownfields_handlerdata_t*)malloc(sizeof(unknownfields_handlerdata_t)); - PHP_PROTO_ASSERT(hd != NULL); - hd->handler = stringsink_string; - upb_handlers_addcleanup(h, hd, free); - return hd; -} - -typedef struct { - const upb_fielddef *fd; - size_t ofs; - const upb_msgdef *md; -} submsg_handlerdata_t; - -// Creates a handlerdata that contains field and submessage type information. -static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs, - const upb_fielddef* f) { - submsg_handlerdata_t* hd = - (submsg_handlerdata_t*)malloc(sizeof(submsg_handlerdata_t)); - PHP_PROTO_ASSERT(hd != NULL); - hd->fd = f; - hd->ofs = ofs; - hd->md = upb_fielddef_msgsubdef(f); - upb_handlers_addcleanup(h, hd, free); - return hd; -} - -typedef struct { - size_t ofs; // union data slot - size_t case_ofs; // oneof_case field - int property_ofs; // properties table cache - uint32_t oneof_case_num; // oneof-case number to place in oneof_case field - const upb_msgdef *md; // msgdef, for oneof submessage handler - const upb_msgdef *parent_md; // msgdef, for parent submessage -} oneof_handlerdata_t; - -static const void *newoneofhandlerdata(upb_handlers *h, - uint32_t ofs, - uint32_t case_ofs, - int property_ofs, - const upb_msgdef *m, - const upb_fielddef *f) { - oneof_handlerdata_t* hd = - (oneof_handlerdata_t*)malloc(sizeof(oneof_handlerdata_t)); - PHP_PROTO_ASSERT(hd != NULL); - hd->ofs = ofs; - hd->case_ofs = case_ofs; - hd->property_ofs = property_ofs; - hd->parent_md = m; - // We reuse the field tag number as a oneof union discriminant tag. Note that - // we don't expose these numbers to the user, so the only requirement is that - // we have some unique ID for each union case/possibility. The field tag - // numbers are already present and are easy to use so there's no reason to - // create a separate ID space. In addition, using the field tag number here - // lets us easily look up the field in the oneof accessor. - hd->oneof_case_num = upb_fielddef_number(f); - if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE) { - hd->md = upb_fielddef_msgsubdef(f); - } else { - hd->md = NULL; - } - upb_handlers_addcleanup(h, hd, free); - return hd; -} - -// A handler that starts a repeated field. Gets the Repeated*Field instance for -// this field (such an instance always exists even in an empty message). -static void *startseq_handler(void* closure, const void* hd) { - MessageHeader* msg = closure; - const upb_fielddef** field = (const upb_fielddef**) hd; - CACHED_VALUE* cache = find_zval_property(msg, *field); - TSRMLS_FETCH(); - repeated_field_ensure_created(*field, cache PHP_PROTO_TSRMLS_CC); - return CACHED_PTR_TO_ZVAL_PTR(cache); -} - -// Handlers that append primitive values to a repeated field. -#define DEFINE_APPEND_HANDLER(type, ctype) \ - static bool append##type##_handler(void* closure, const void* hd, \ - ctype val) { \ - zval* array = (zval*)closure; \ - TSRMLS_FETCH(); \ - RepeatedField* intern = UNBOX(RepeatedField, array); \ - repeated_field_push_native(intern, &val); \ - return true; \ - } - -DEFINE_APPEND_HANDLER(bool, bool) -DEFINE_APPEND_HANDLER(int32, int32_t) -DEFINE_APPEND_HANDLER(uint32, uint32_t) -DEFINE_APPEND_HANDLER(float, float) -DEFINE_APPEND_HANDLER(int64, int64_t) -DEFINE_APPEND_HANDLER(uint64, uint64_t) -DEFINE_APPEND_HANDLER(double, double) - -// Appends a string or 'bytes' string to a repeated field. -static void* appendstr_handler(void *closure, - const void *hd, - size_t size_hint) { - PHP_PROTO_UNUSED(hd); - - stringfields_parseframe_t* frame = - (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t)); - PHP_PROTO_ASSERT(frame != NULL); - frame->closure = closure; - stringsink_init(&frame->sink); - - return frame; -} - -static bool appendstr_end_handler(void *closure, const void *hd) { - stringfields_parseframe_t* frame = closure; - - zval* array = (zval*)frame->closure; - TSRMLS_FETCH(); - RepeatedField* intern = UNBOX(RepeatedField, array); - -#if PHP_MAJOR_VERSION < 7 - zval* str; - MAKE_STD_ZVAL(str); - PHP_PROTO_ZVAL_STRINGL(str, frame->sink.ptr, frame->sink.len, 1); - repeated_field_push_native(intern, &str); -#else - zend_string* str = zend_string_init(frame->sink.ptr, frame->sink.len, 1); - repeated_field_push_native(intern, &str); -#endif - - stringsink_uninit(&frame->sink); - free(frame); - - return true; -} - -// Handlers that append primitive values to a repeated field. -#define DEFINE_SINGULAR_HANDLER(type, ctype) \ - static bool type##_handler(void* closure, const void* hd, \ - ctype val) { \ - MessageHeader* msg = (MessageHeader*)closure; \ - const size_t *ofs = hd; \ - DEREF(message_data(msg), *ofs, ctype) = val; \ - return true; \ - } - -DEFINE_SINGULAR_HANDLER(bool, bool) -DEFINE_SINGULAR_HANDLER(int32, int32_t) -DEFINE_SINGULAR_HANDLER(uint32, uint32_t) -DEFINE_SINGULAR_HANDLER(float, float) -DEFINE_SINGULAR_HANDLER(int64, int64_t) -DEFINE_SINGULAR_HANDLER(uint64, uint64_t) -DEFINE_SINGULAR_HANDLER(double, double) - -#undef DEFINE_SINGULAR_HANDLER - -#if PHP_MAJOR_VERSION < 7 -static void new_php_string(zval** value_ptr, const char* str, size_t len) { - SEPARATE_ZVAL_IF_NOT_REF(value_ptr); - if (Z_TYPE_PP(value_ptr) == IS_STRING && - !IS_INTERNED(Z_STRVAL_PP(value_ptr))) { - FREE(Z_STRVAL_PP(value_ptr)); - } - ZVAL_STRINGL(*value_ptr, str, len, 1); -} -#else -static void new_php_string(zval* value_ptr, const char* str, size_t len) { - if (Z_TYPE_P(value_ptr) == IS_STRING) { - zend_string_release(Z_STR_P(value_ptr)); - } - ZVAL_NEW_STR(value_ptr, zend_string_init(str, len, 0)); -} -#endif - -// Sets a non-repeated string/bytes field in a message. -static void* str_handler(void *closure, - const void *hd, - size_t size_hint) { - PHP_PROTO_UNUSED(hd); - - stringfields_parseframe_t* frame = - (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t)); - PHP_PROTO_ASSERT(frame != NULL); - frame->closure = closure; - stringsink_init(&frame->sink); - - return frame; -} - -static bool str_end_handler(void *closure, const void *hd) { - stringfields_parseframe_t* frame = closure; - const upb_fielddef **field = (const upb_fielddef **) hd; - MessageHeader* msg = (MessageHeader*)frame->closure; - - CACHED_VALUE* cached = find_zval_property(msg, *field); - - new_php_string(cached, frame->sink.ptr, frame->sink.len); - - stringsink_uninit(&frame->sink); - free(frame); - - return true; -} - -static bool map_str_end_handler(void *closure, const void *hd) { - stringfields_parseframe_t* frame = closure; - const size_t *ofs = hd; - MessageHeader* msg = (MessageHeader*)frame->closure; - - new_php_string(DEREF(message_data(msg), *ofs, CACHED_VALUE*), - frame->sink.ptr, frame->sink.len); - - stringsink_uninit(&frame->sink); - free(frame); - - return true; -} - -static size_t stringdata_handler(void* closure, const void* hd, - const char* str, size_t len, - const upb_bufhandle* handle) { - stringfields_parseframe_t* frame = closure; - return stringsink_string(&frame->sink, hd, str, len, handle); -} - -// Appends a submessage to a repeated field. -static void *appendsubmsg_handler(void *closure, const void *hd) { - zval* array = (zval*)closure; - TSRMLS_FETCH(); - RepeatedField* intern = UNBOX(RepeatedField, array); - - const submsg_handlerdata_t *submsgdata = hd; - DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; - MessageHeader* submsg; - -#if PHP_MAJOR_VERSION < 7 - zval* val = NULL; - MAKE_STD_ZVAL(val); - ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC)); - repeated_field_push_native(intern, &val); - submsg = UNBOX(MessageHeader, val); -#else - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - repeated_field_push_native(intern, &obj); - submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std)); -#endif - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); - - return submsg; -} - -// Appends a wrapper submessage to a repeated field. -static void *appendwrappersubmsg_handler(void *closure, const void *hd) { - zval* array = (zval*)closure; - TSRMLS_FETCH(); - RepeatedField* intern = UNBOX(RepeatedField, array); - - const submsg_handlerdata_t *submsgdata = hd; - DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; - MessageHeader* submsg; - wrapperfields_parseframe_t* frame = - (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t)); - -#if PHP_MAJOR_VERSION < 7 - zval* val = NULL; - MAKE_STD_ZVAL(val); - ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC)); - repeated_field_push_native(intern, &val); - submsg = UNBOX(MessageHeader, val); -#else - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - repeated_field_push_native(intern, &obj); - submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std)); -#endif - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); - - frame->closure = closure; - frame->submsg = submsg; - frame->is_msg = true; - - return frame; -} - -// Sets a non-repeated submessage field in a message. -static void *submsg_handler(void *closure, const void *hd) { - MessageHeader* msg = closure; - const submsg_handlerdata_t* submsgdata = hd; - TSRMLS_FETCH(); - DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; - zval* submsg_php; - MessageHeader* submsg; - - CACHED_VALUE* cached = find_zval_property(msg, submsgdata->fd); - - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) { -#if PHP_MAJOR_VERSION < 7 - zval val; - ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC)); - MessageHeader* intern = UNBOX(MessageHeader, &val); - custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); - REPLACE_ZVAL_VALUE(cached, &val, 1); - zval_dtor(&val); -#else - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - ZVAL_OBJ(cached, obj); - MessageHeader* intern = UNBOX_HASHTABLE_VALUE(MessageHeader, obj); - custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); -#endif - } - - submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached); - - submsg = UNBOX(MessageHeader, submsg_php); - return submsg; -} - -static void *map_submsg_handler(void *closure, const void *hd) { - MessageHeader* msg = closure; - const submsg_handlerdata_t* submsgdata = hd; - TSRMLS_FETCH(); - DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; - zval* submsg_php; - MessageHeader* submsg; - - CACHED_VALUE* cached = - DEREF(message_data(msg), submsgdata->ofs, CACHED_VALUE*); - - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) { -#if PHP_MAJOR_VERSION < 7 - zval val; - ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC)); - MessageHeader* intern = UNBOX(MessageHeader, &val); - custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); - REPLACE_ZVAL_VALUE(cached, &val, 1); - zval_dtor(&val); -#else - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - ZVAL_OBJ(cached, obj); - MessageHeader* intern = UNBOX_HASHTABLE_VALUE(MessageHeader, obj); - custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); -#endif - } - - submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached); - - submsg = UNBOX(MessageHeader, submsg_php); - return submsg; -} - -static void *map_wrapper_submsg_handler(void *closure, const void *hd) { - MessageHeader* msg = closure; - const submsg_handlerdata_t* submsgdata = hd; - TSRMLS_FETCH(); - DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; - zval* submsg_php; - MessageHeader* submsg; - wrapperfields_parseframe_t* frame = - (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t)); - - CACHED_VALUE* cached = - DEREF(message_data(msg), submsgdata->ofs, CACHED_VALUE*); - - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) { -#if PHP_MAJOR_VERSION < 7 - zval val; - ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC)); - MessageHeader* intern = UNBOX(MessageHeader, &val); - custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); - REPLACE_ZVAL_VALUE(cached, &val, 1); - zval_dtor(&val); -#else - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - ZVAL_OBJ(cached, obj); - MessageHeader* intern = UNBOX_HASHTABLE_VALUE(MessageHeader, obj); - custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); -#endif - } - - submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached); - - submsg = UNBOX(MessageHeader, submsg_php); - frame->closure = closure; - frame->submsg = submsg; - frame->is_msg = true; - return frame; -} - -// Handler data for startmap/endmap handlers. -typedef struct { - const upb_fielddef* fd; - const upb_msgdef* value_md; - upb_fieldtype_t key_field_type; - upb_fieldtype_t value_field_type; -} map_handlerdata_t; - -// Temporary frame for map parsing: at the beginning of a map entry message, a -// submsg handler allocates a frame to hold (i) a reference to the Map object -// into which this message will be inserted and (ii) storage slots to -// temporarily hold the key and value for this map entry until the end of the -// submessage. When the submessage ends, another handler is called to insert the -// value into the map. -typedef struct { - char key_storage[NATIVE_SLOT_MAX_SIZE]; - char value_storage[NATIVE_SLOT_MAX_SIZE]; -} map_parse_frame_data_t; - -PHP_PROTO_WRAP_OBJECT_START(map_parse_frame_t) - map_parse_frame_data_t* data; // Place needs to be consistent with - // MessageHeader. - zval* map; - // In php7, we cannot allocate zval dynamically. So we need to add zval here - // to help decoding. - zval key_zval; - zval value_zval; -PHP_PROTO_WRAP_OBJECT_END -typedef struct map_parse_frame_t map_parse_frame_t; - -static void map_slot_init( - void* memory, upb_fieldtype_t type, zval* cache, - const upb_msgdef* value_msg PHP_PROTO_TSRMLS_DC) { - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { -#if PHP_MAJOR_VERSION < 7 - // Store zval** in memory in order to be consistent with the layout of - // singular fields. - zval** holder = ALLOC(zval*); - *(zval***)memory = holder; - zval* tmp; - MAKE_STD_ZVAL(tmp); - PHP_PROTO_ZVAL_STRINGL(tmp, "", 0, 1); - *holder = tmp; -#else - *(zval**)memory = cache; - PHP_PROTO_ZVAL_STRINGL(*(zval**)memory, "", 0, 1); -#endif - break; - } - case UPB_TYPE_MESSAGE: { - DescriptorInternal* subdesc = get_msgdef_desc(value_msg); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; - MessageHeader* submsg; -#if PHP_MAJOR_VERSION < 7 - zval** holder = ALLOC(zval*); - zval* tmp; - MAKE_STD_ZVAL(tmp); - ZVAL_OBJ(tmp, subklass->create_object(subklass TSRMLS_CC)); - submsg = UNBOX(MessageHeader, tmp); - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); - *holder = tmp; - *(zval***)memory = holder; -#else - *(zval**)memory = cache; - ZVAL_OBJ(*(zval**)memory, subklass->create_object(subklass TSRMLS_CC)); - submsg = UNBOX(MessageHeader, cache); - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); -#endif - break; - } - default: - native_slot_init(type, memory, NULL); - } -} - -static void map_slot_uninit(void* memory, upb_fieldtype_t type) { - switch (type) { - case UPB_TYPE_MESSAGE: - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { -#if PHP_MAJOR_VERSION < 7 - zval** holder = *(zval***)memory; - zval_ptr_dtor(holder); - FREE(holder); -#else - php_proto_zval_ptr_dtor(*(zval**)memory); -#endif - break; - } - default: - break; - } -} - -static void map_slot_key(upb_fieldtype_t type, const void* from, - const char** keyval, - size_t* length) { - if (type == UPB_TYPE_STRING) { -#if PHP_MAJOR_VERSION < 7 - zval* key_php = **(zval***)from; -#else - zval* key_php = *(zval**)from; -#endif - *keyval = Z_STRVAL_P(key_php); - *length = Z_STRLEN_P(key_php); - } else { - *keyval = from; - *length = native_slot_size(type); - } -} - -static void map_slot_value(upb_fieldtype_t type, const void* from, - upb_value* v) { - size_t len; - void* to = upb_value_memory(v); -#ifndef NDEBUG - v->ctype = UPB_CTYPE_UINT64; -#endif - - memset(to, 0, native_slot_size(type)); - - switch (type) { -#if PHP_MAJOR_VERSION < 7 - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - case UPB_TYPE_MESSAGE: { - *(zval**)to = **(zval***)from; - Z_ADDREF_PP((zval**)to); - break; - } -#else - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - *(zend_string**)to = Z_STR_P(*(zval**)from); - zend_string_addref(*(zend_string**)to); - break; - case UPB_TYPE_MESSAGE: - if (!ZVAL_IS_NULL(*(zval**)from)) { - *(zend_object**)to = Z_OBJ_P(*(zval**)from); - GC_ADDREF(*(zend_object**)to); - } - break; -#endif - default: - len = native_slot_size(type); - memcpy(to, from, len); - } -} - -// Handler to begin a map entry: allocates a temporary frame. This is the -// 'startsubmsg' handler on the msgdef that contains the map field. -static void *startmapentry_handler(void *closure, const void *hd) { - MessageHeader* msg = closure; - const map_handlerdata_t* mapdata = hd; - CACHED_VALUE* cache = find_zval_property(msg, mapdata->fd); - TSRMLS_FETCH(); - map_field_ensure_created(mapdata->fd, cache PHP_PROTO_TSRMLS_CC); - zval* map = CACHED_PTR_TO_ZVAL_PTR(cache); - - map_parse_frame_t* frame = ALLOC(map_parse_frame_t); - frame->data = ALLOC(map_parse_frame_data_t); - frame->map = map; - - map_slot_init(&frame->data->key_storage, mapdata->key_field_type, - &frame->key_zval, NULL PHP_PROTO_TSRMLS_CC); - map_slot_init(&frame->data->value_storage, mapdata->value_field_type, - &frame->value_zval, mapdata->value_md PHP_PROTO_TSRMLS_CC); - - return frame; -} - -// Handler to end a map entry: inserts the value defined during the message into -// the map. This is the 'endmsg' handler on the map entry msgdef. -static bool endmap_handler(void* closure, const void* hd, upb_status* s) { - map_parse_frame_t* frame = closure; - const map_handlerdata_t* mapdata = hd; - - TSRMLS_FETCH(); - Map *map = UNBOX(Map, frame->map); - - const char* keyval = NULL; - upb_value v; - size_t length; - - map_slot_key(map->key_type, &frame->data->key_storage, &keyval, &length); - map_slot_value(map->value_type, &frame->data->value_storage, &v); - - map_index_set(map, keyval, length, v); - - map_slot_uninit(&frame->data->key_storage, mapdata->key_field_type); - map_slot_uninit(&frame->data->value_storage, mapdata->value_field_type); - FREE(frame->data); - FREE(frame); - - return true; -} - -// Allocates a new map_handlerdata_t given the map entry message definition. If -// the offset of the field within the parent message is also given, that is -// added to the handler data as well. Note that this is called *twice* per map -// field: once in the parent message handler setup when setting the startsubmsg -// handler and once in the map entry message handler setup when setting the -// key/value and endmsg handlers. The reason is that there is no easy way to -// pass the handlerdata down to the sub-message handler setup. -static map_handlerdata_t* new_map_handlerdata( - const upb_fielddef* field, - const upb_msgdef* mapentry_def) { - const upb_fielddef* key_field; - const upb_fielddef* value_field; - // TODO(teboring): Use emalloc and efree. - map_handlerdata_t* hd = - (map_handlerdata_t*)malloc(sizeof(map_handlerdata_t)); - PHP_PROTO_ASSERT(hd != NULL); - hd->fd = field; - key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD); - PHP_PROTO_ASSERT(key_field != NULL); - hd->key_field_type = upb_fielddef_type(key_field); - value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD); - PHP_PROTO_ASSERT(value_field != NULL); - hd->value_field_type = upb_fielddef_type(value_field); - if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE) { - hd->value_md = upb_fielddef_msgsubdef(value_field); - } else { - hd->value_md = NULL; - } - - return hd; -} - -// Handlers that set primitive values in oneofs. -#define DEFINE_ONEOF_HANDLER(type, ctype) \ - static bool oneof##type##_handler(void* closure, const void* hd, \ - ctype val) { \ - const oneof_handlerdata_t* oneofdata = hd; \ - DEREF(message_data(closure), oneofdata->case_ofs, uint32_t) = \ - oneofdata->oneof_case_num; \ - DEREF(message_data(closure), oneofdata->ofs, ctype) = val; \ - return true; \ - } - -DEFINE_ONEOF_HANDLER(bool, bool) -DEFINE_ONEOF_HANDLER(int32, int32_t) -DEFINE_ONEOF_HANDLER(uint32, uint32_t) -DEFINE_ONEOF_HANDLER(float, float) -DEFINE_ONEOF_HANDLER(int64, int64_t) -DEFINE_ONEOF_HANDLER(uint64, uint64_t) -DEFINE_ONEOF_HANDLER(double, double) - -#undef DEFINE_ONEOF_HANDLER - -static void oneof_cleanup(MessageHeader* msg, - const oneof_handlerdata_t* oneofdata) { - uint32_t old_case_num = - DEREF(message_data(msg), oneofdata->case_ofs, uint32_t); - if (old_case_num == 0) { - return; - } - - const upb_fielddef* old_field = - upb_msgdef_itof(oneofdata->parent_md, old_case_num); - bool need_clean = false; - - switch (upb_fielddef_type(old_field)) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - need_clean = true; - break; - case UPB_TYPE_MESSAGE: - if (oneofdata->oneof_case_num != old_case_num) { - need_clean = true; - } - break; - default: - break; - } - - if (need_clean) { -#if PHP_MAJOR_VERSION < 7 - SEPARATE_ZVAL_IF_NOT_REF( - DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)); - php_proto_zval_ptr_dtor( - *DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)); - MAKE_STD_ZVAL(*DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)); - ZVAL_NULL(*DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)); -#endif - } -} - -// Handlers for string/bytes in a oneof. -static bool oneofstr_end_handler(void *closure, const void *hd) { - stringfields_parseframe_t* frame = closure; - MessageHeader* msg = (MessageHeader*)frame->closure; - const oneof_handlerdata_t *oneofdata = hd; - - oneof_cleanup(msg, oneofdata); - - DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) = - oneofdata->oneof_case_num; - DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) = - OBJ_PROP(&msg->std, oneofdata->property_ofs); - - new_php_string(DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*), - frame->sink.ptr, frame->sink.len); - - stringsink_uninit(&frame->sink); - free(frame); - - return true; -} - -static void *oneofstr_handler(void *closure, - const void *hd, - size_t size_hint) { - PHP_PROTO_UNUSED(hd); - - stringfields_parseframe_t* frame = - (stringfields_parseframe_t*)malloc(sizeof(stringfields_parseframe_t)); - PHP_PROTO_ASSERT(frame != NULL); - frame->closure = closure; - stringsink_init(&frame->sink); - - return frame; -} - -// Handler for a submessage field in a oneof. -static void* oneofsubmsg_handler(void* closure, const void* hd) { - MessageHeader* msg = closure; - const oneof_handlerdata_t *oneofdata = hd; - uint32_t oldcase = DEREF(message_data(msg), oneofdata->case_ofs, uint32_t); - TSRMLS_FETCH(); - DescriptorInternal* subdesc = get_msgdef_desc(oneofdata->md); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; - zval* submsg_php; - MessageHeader* submsg; - - if (oldcase != oneofdata->oneof_case_num) { - oneof_cleanup(msg, oneofdata); - - // Create new message. - DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) = - OBJ_PROP(&msg->std, oneofdata->property_ofs); -#if PHP_MAJOR_VERSION < 7 - zval val; - ZVAL_OBJ(&val, subklass->create_object(subklass TSRMLS_CC)); - REPLACE_ZVAL_VALUE(DEREF(message_data(msg), oneofdata->ofs, zval**), - &val, 1); - zval_dtor(&val); -#else - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - ZVAL_OBJ(DEREF(message_data(msg), oneofdata->ofs, zval*), obj); -#endif - } - - DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) = - oneofdata->oneof_case_num; - - submsg_php = CACHED_PTR_TO_ZVAL_PTR( - DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)); - submsg = UNBOX(MessageHeader, submsg_php); - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); - return submsg; -} - -// Sets a non-repeated wrapper submessage field in a message. -static void* wrapper_submsg_handler(void* closure, const void* hd) { - MessageHeader* msg = closure; - const submsg_handlerdata_t* submsgdata = hd; - TSRMLS_FETCH(); - DescriptorInternal* subdesc = get_msgdef_desc(submsgdata->md); - register_class(subdesc, false TSRMLS_CC); - zval* submsg_php; - MessageHeader* submsg; - wrapperfields_parseframe_t* frame = - (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t)); - - CACHED_VALUE* cached = find_zval_property(msg, submsgdata->fd); - submsg_php = CACHED_PTR_TO_ZVAL_PTR(cached); - frame->closure = closure; - - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_OBJECT) { - submsg = UNBOX(MessageHeader, submsg_php); - frame->submsg = submsg; - frame->is_msg = true; - } else { - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) { - // Needs to initiate the wrapper message - const upb_msgdef* msgdef = subdesc->msgdef; - const upb_fielddef* f = upb_msgdef_itof(msgdef, 1); - native_slot_get_default(upb_fielddef_type(f), cached TSRMLS_CC); - } - // In this case, wrapper message hasn't been created and value will be - // stored in cache directly. - frame->submsg = cached; - frame->is_msg = false; - } - - return frame; -} - -// Handler for a wrapper submessage field in a oneof. -static void* wrapper_oneofsubmsg_handler(void* closure, const void* hd) { - MessageHeader* msg = closure; - const oneof_handlerdata_t *oneofdata = hd; - uint32_t oldcase = DEREF(message_data(msg), oneofdata->case_ofs, uint32_t); - TSRMLS_FETCH(); - DescriptorInternal* subdesc = get_msgdef_desc(oneofdata->md); - register_class(subdesc, false TSRMLS_CC); - wrapperfields_parseframe_t* frame = - (wrapperfields_parseframe_t*)malloc(sizeof(wrapperfields_parseframe_t)); - CACHED_VALUE* cached = OBJ_PROP(&msg->std, oneofdata->property_ofs); - MessageHeader* submsg; - - if (oldcase != oneofdata->oneof_case_num) { - oneof_cleanup(msg, oneofdata); - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_NULL) { - // Needs to initiate the wrapper message - const upb_msgdef* msgdef = subdesc->msgdef; - const upb_fielddef* f = upb_msgdef_itof(msgdef, 1); - native_slot_get_default(upb_fielddef_type(f), cached TSRMLS_CC); - } - frame->submsg = cached; - frame->is_msg = false; - } else if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(cached)) == IS_OBJECT) { - submsg = UNBOX(MessageHeader, CACHED_PTR_TO_ZVAL_PTR(cached)); - frame->submsg = submsg; - frame->is_msg = true; - } else { - // In this case, wrapper message hasn't been created and value will be - // stored in cache directly. - frame->submsg = cached; - frame->is_msg = false; - } - - DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) = - oneofdata->oneof_case_num; - - return frame; -} - -static bool wrapper_submsg_end_handler(void *closure, const void *hd) { - wrapperfields_parseframe_t* frame = closure; - free(frame); - return true; -} - -// Set up handlers for a repeated field. -static void add_handlers_for_repeated_field(upb_handlers *h, - const upb_fielddef *f, - size_t offset) { - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - attr.handler_data = newhandlerfielddata(h, f); - upb_handlers_setstartseq(h, f, startseq_handler, &attr); - - switch (upb_fielddef_type(f)) { - -#define SET_HANDLER(utype, ltype) \ - case utype: \ - upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \ - break; - - SET_HANDLER(UPB_TYPE_BOOL, bool); - SET_HANDLER(UPB_TYPE_INT32, int32); - SET_HANDLER(UPB_TYPE_UINT32, uint32); - SET_HANDLER(UPB_TYPE_ENUM, int32); - SET_HANDLER(UPB_TYPE_FLOAT, float); - SET_HANDLER(UPB_TYPE_INT64, int64); - SET_HANDLER(UPB_TYPE_UINT64, uint64); - SET_HANDLER(UPB_TYPE_DOUBLE, double); - -#undef SET_HANDLER - - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - upb_handlers_setstartstr(h, f, appendstr_handler, NULL); - upb_handlers_setstring(h, f, stringdata_handler, NULL); - upb_handlers_setendstr(h, f, appendstr_end_handler, &attr); - break; - } - case UPB_TYPE_MESSAGE: { - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - attr.handler_data = newsubmsghandlerdata(h, 0, f); - if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) { - upb_handlers_setstartsubmsg(h, f, appendwrappersubmsg_handler, &attr); - upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr); - } else { - upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr); - } - break; - } - } -} - -// Set up handlers for a singular field. -static void add_handlers_for_singular_field(upb_handlers *h, - const upb_fielddef *f, - size_t offset, bool is_map) { - switch (upb_fielddef_type(f)) { -#define SET_HANDLER(utype, ltype) \ - case utype: { \ - upb_handlerattr attr = UPB_HANDLERATTR_INIT; \ - attr.handler_data = newhandlerdata(h, offset); \ - upb_handlers_set##ltype(h, f, ltype##_handler, &attr); \ - break; \ - } - - SET_HANDLER(UPB_TYPE_BOOL, bool); - SET_HANDLER(UPB_TYPE_INT32, int32); - SET_HANDLER(UPB_TYPE_UINT32, uint32); - SET_HANDLER(UPB_TYPE_ENUM, int32); - SET_HANDLER(UPB_TYPE_FLOAT, float); - SET_HANDLER(UPB_TYPE_INT64, int64); - SET_HANDLER(UPB_TYPE_UINT64, uint64); - SET_HANDLER(UPB_TYPE_DOUBLE, double); - -#undef SET_HANDLER - - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - if (is_map) { - attr.handler_data = newhandlerdata(h, offset); - } else { - attr.handler_data = newhandlerfielddata(h, f); - } - upb_handlers_setstartstr(h, f, str_handler, &attr); - upb_handlers_setstring(h, f, stringdata_handler, &attr); - if (is_map) { - upb_handlers_setendstr(h, f, map_str_end_handler, &attr); - } else { - upb_handlers_setendstr(h, f, str_end_handler, &attr); - } - break; - } - case UPB_TYPE_MESSAGE: { - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - if (is_map) { - attr.handler_data = newsubmsghandlerdata(h, offset, f); - if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) { - upb_handlers_setstartsubmsg(h, f, map_wrapper_submsg_handler, &attr); - upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr); - } else { - upb_handlers_setstartsubmsg(h, f, map_submsg_handler, &attr); - } - } else if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) { - attr.handler_data = newsubmsghandlerdata(h, 0, f); - upb_handlers_setstartsubmsg(h, f, wrapper_submsg_handler, &attr); - upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr); - } else { - attr.handler_data = newsubmsghandlerdata(h, 0, f); - upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr); - } - break; - } - } -} - -// Adds handlers to a map field. -static void add_handlers_for_mapfield(upb_handlers* h, - const upb_fielddef* fielddef, - size_t offset) { - const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef); - map_handlerdata_t* hd = new_map_handlerdata(fielddef, map_msgdef); - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - - upb_handlers_addcleanup(h, hd, free); - attr.handler_data = hd; - upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr); -} - -// Adds handlers to a map-entry msgdef. -static void add_handlers_for_mapentry( - const upb_msgdef* msgdef, upb_handlers* h) { - const upb_fielddef* key_field = map_entry_key(msgdef); - const upb_fielddef* value_field = map_entry_value(msgdef); - map_handlerdata_t* hd = new_map_handlerdata(0, msgdef); - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - - upb_handlers_addcleanup(h, hd, free); - attr.handler_data = hd; - upb_handlers_setendmsg(h, endmap_handler, &attr); - - add_handlers_for_singular_field(h, key_field, - offsetof(map_parse_frame_data_t, - key_storage), true); - add_handlers_for_singular_field(h, value_field, - offsetof(map_parse_frame_data_t, - value_storage), true); -} - -// Set up handlers for a oneof field. -static void add_handlers_for_oneof_field(upb_handlers *h, - const upb_msgdef *m, - const upb_fielddef *f, - size_t offset, - size_t oneof_case_offset, - int property_cache_offset) { - - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - attr.handler_data = newoneofhandlerdata(h, offset, oneof_case_offset, - property_cache_offset, m, f); - - switch (upb_fielddef_type(f)) { - -#define SET_HANDLER(utype, ltype) \ - case utype: \ - upb_handlers_set##ltype(h, f, oneof##ltype##_handler, &attr); \ - break; - - SET_HANDLER(UPB_TYPE_BOOL, bool); - SET_HANDLER(UPB_TYPE_INT32, int32); - SET_HANDLER(UPB_TYPE_UINT32, uint32); - SET_HANDLER(UPB_TYPE_ENUM, int32); - SET_HANDLER(UPB_TYPE_FLOAT, float); - SET_HANDLER(UPB_TYPE_INT64, int64); - SET_HANDLER(UPB_TYPE_UINT64, uint64); - SET_HANDLER(UPB_TYPE_DOUBLE, double); - -#undef SET_HANDLER - - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - upb_handlers_setstartstr(h, f, oneofstr_handler, &attr); - upb_handlers_setstring(h, f, stringdata_handler, NULL); - upb_handlers_setendstr(h, f, oneofstr_end_handler, &attr); - break; - } - case UPB_TYPE_MESSAGE: { - if (is_wrapper_msg(upb_fielddef_msgsubdef(f))) { - upb_handlers_setstartsubmsg(h, f, wrapper_oneofsubmsg_handler, &attr); - upb_handlers_setendsubmsg(h, f, wrapper_submsg_end_handler, &attr); - } else { - upb_handlers_setstartsubmsg(h, f, oneofsubmsg_handler, &attr); - } - break; - } - } -} - -#define DEFINE_WRAPPER_HANDLER(utype, type, ctype) \ - static bool type##wrapper_handler( \ - void* closure, const void* hd, ctype val) { \ - wrapperfields_parseframe_t* frame = closure; \ - if (frame->is_msg) { \ - MessageHeader* msg = frame->submsg; \ - const size_t *ofs = hd; \ - DEREF(message_data(msg), *ofs, ctype) = val; \ - } else { \ - TSRMLS_FETCH(); \ - native_slot_get(utype, &val, frame->submsg TSRMLS_CC); \ - } \ - return true; \ - } - -DEFINE_WRAPPER_HANDLER(UPB_TYPE_BOOL, bool, bool) -DEFINE_WRAPPER_HANDLER(UPB_TYPE_INT32, int32, int32_t) -DEFINE_WRAPPER_HANDLER(UPB_TYPE_UINT32, uint32, uint32_t) -DEFINE_WRAPPER_HANDLER(UPB_TYPE_FLOAT, float, float) -DEFINE_WRAPPER_HANDLER(UPB_TYPE_INT64, int64, int64_t) -DEFINE_WRAPPER_HANDLER(UPB_TYPE_UINT64, uint64, uint64_t) -DEFINE_WRAPPER_HANDLER(UPB_TYPE_DOUBLE, double, double) - -#undef DEFINE_WRAPPER_HANDLER - -static bool strwrapper_end_handler(void *closure, const void *hd) { - stringfields_parseframe_t* frame = closure; - const upb_fielddef **field = (const upb_fielddef **) hd; - wrapperfields_parseframe_t* wrapper_frame = frame->closure; - MessageHeader* msg; - CACHED_VALUE* cached; - - if (wrapper_frame->is_msg) { - msg = wrapper_frame->submsg; - cached = find_zval_property(msg, *field); - } else { - cached = wrapper_frame->submsg; - } - - new_php_string(cached, frame->sink.ptr, frame->sink.len); - - stringsink_uninit(&frame->sink); - free(frame); - - return true; -} - -static void add_handlers_for_wrapper(const upb_msgdef* msgdef, - upb_handlers* h) { - const upb_fielddef* f = upb_msgdef_itof(msgdef, 1); - DescriptorInternal* desc; - size_t offset; - - TSRMLS_FETCH(); - desc = get_msgdef_desc(msgdef); - offset = desc->layout->fields[upb_fielddef_index(f)].offset; - - switch (upb_msgdef_wellknowntype(msgdef)) { -#define SET_HANDLER(utype, ltype) \ - case utype: { \ - upb_handlerattr attr = UPB_HANDLERATTR_INIT; \ - attr.handler_data = newhandlerdata(h, offset); \ - upb_handlers_set##ltype(h, f, ltype##wrapper_handler, &attr); \ - break; \ - } - - SET_HANDLER(UPB_WELLKNOWN_BOOLVALUE, bool); - SET_HANDLER(UPB_WELLKNOWN_INT32VALUE, int32); - SET_HANDLER(UPB_WELLKNOWN_UINT32VALUE, uint32); - SET_HANDLER(UPB_WELLKNOWN_FLOATVALUE, float); - SET_HANDLER(UPB_WELLKNOWN_INT64VALUE, int64); - SET_HANDLER(UPB_WELLKNOWN_UINT64VALUE, uint64); - SET_HANDLER(UPB_WELLKNOWN_DOUBLEVALUE, double); - -#undef SET_HANDLER - - case UPB_WELLKNOWN_STRINGVALUE: - case UPB_WELLKNOWN_BYTESVALUE: { - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - attr.handler_data = newhandlerfielddata(h, f); - - upb_handlers_setstartstr(h, f, str_handler, &attr); - upb_handlers_setstring(h, f, stringdata_handler, &attr); - upb_handlers_setendstr(h, f, strwrapper_end_handler, &attr); - break; - } - default: - // Cannot reach here. - break; - } -} - -static bool add_unknown_handler(void* closure, const void* hd, const char* buf, - size_t size) { - encodeunknown_handlerfunc handler = - ((unknownfields_handlerdata_t*)hd)->handler; - - MessageHeader* msg = (MessageHeader*)closure; - stringsink* unknown = DEREF(message_data(msg), 0, stringsink*); - if (unknown == NULL) { - DEREF(message_data(msg), 0, stringsink*) = ALLOC(stringsink); - unknown = DEREF(message_data(msg), 0, stringsink*); - stringsink_init(unknown); - } - - handler(unknown, NULL, buf, size, NULL); - - return true; -} - -void add_handlers_for_message(const void* closure, upb_handlers* h) { - const upb_msgdef* msgdef = upb_handlers_msgdef(h); - TSRMLS_FETCH(); - DescriptorInternal* desc = get_msgdef_desc(msgdef); - register_class(desc, false TSRMLS_CC); - upb_msg_field_iter i; - - // If this is a mapentry message type, set up a special set of handlers and - // bail out of the normal (user-defined) message type handling. - if (upb_msgdef_mapentry(msgdef)) { - add_handlers_for_mapentry(msgdef, h); - return; - } - - // If this is a wrapper message type, set up a special set of handlers and - // bail out of the normal (user-defined) message type handling. - if (is_wrapper_msg(msgdef)) { - add_handlers_for_wrapper(msgdef, h); - return; - } - - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - attr.handler_data = newunknownfieldshandlerdata(h); - upb_handlers_setunknown(h, add_unknown_handler, &attr); - - for (upb_msg_field_begin(&i, desc->msgdef); - !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - const upb_fielddef *f = upb_msg_iter_field(&i); - size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset; - - if (upb_fielddef_containingoneof(f)) { - size_t oneof_case_offset = - desc->layout->fields[upb_fielddef_index(f)].case_offset; - int property_cache_index = - desc->layout->fields[upb_fielddef_index(f)].cache_index; - add_handlers_for_oneof_field(h, desc->msgdef, f, offset, - oneof_case_offset, property_cache_index); - } else if (is_map_field(f)) { - add_handlers_for_mapfield(h, f, offset); - } else if (upb_fielddef_isseq(f)) { - add_handlers_for_repeated_field(h, f, offset); - } else { - add_handlers_for_singular_field(h, f, offset, false); - } - } -} - -// Constructs the handlers for filling a message's data into an in-memory -// object. -const upb_handlers* get_fill_handlers(DescriptorInternal* desc) { - return upb_handlercache_get(desc->pool->fill_handler_cache, desc->msgdef); -} - -static const upb_pbdecodermethod *msgdef_decodermethod(DescriptorInternal* desc) { - return upb_pbcodecache_get(desc->pool->fill_method_cache, desc->msgdef); -} - -static const upb_json_parsermethod *msgdef_jsonparsermethod(DescriptorInternal* desc) { - return upb_json_codecache_get(desc->pool->json_fill_method_cache, desc->msgdef); -} - -// ----------------------------------------------------------------------------- -// Serializing. -// ----------------------------------------------------------------------------- - -static void putmsg(zval* msg, const DescriptorInternal* desc, upb_sink sink, - int depth, bool is_json TSRMLS_DC); -static void putrawmsg(MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth, bool is_json, - bool open_msg TSRMLS_DC); -static void putwrappervalue( - zval* value, const upb_fielddef* f, - upb_sink sink, int depth, bool is_json TSRMLS_DC); -static void putjsonany(MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth TSRMLS_DC); -static void putjsonlistvalue( - MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth TSRMLS_DC); -static void putjsonstruct( - MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth TSRMLS_DC); - -static void putstr(zval* str, const upb_fielddef* f, upb_sink sink, - bool force_default); - -static void putrawstr(const char* str, int len, const upb_fielddef* f, - upb_sink sink, bool force_default); - -static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink sink, - int depth, bool is_json TSRMLS_DC); -static void putrawsubmsg(MessageHeader* submsg, const upb_fielddef* f, - upb_sink sink, int depth, bool is_json TSRMLS_DC); - -static void putarray(zval* array, const upb_fielddef* f, upb_sink sink, - int depth, bool is_json TSRMLS_DC); -static void putmap(zval* map, const upb_fielddef* f, upb_sink sink, - int depth, bool is_json TSRMLS_DC); - -static upb_selector_t getsel(const upb_fielddef* f, upb_handlertype_t type) { - upb_selector_t ret; - bool ok = upb_handlers_getselector(f, type, &ret); - PHP_PROTO_ASSERT(ok); - return ret; -} - -static void put_optional_value(const void* memory, int len, - const upb_fielddef* f, - int depth, upb_sink sink, - bool is_json TSRMLS_DC) { - PHP_PROTO_ASSERT(upb_fielddef_label(f) == UPB_LABEL_OPTIONAL); - - switch (upb_fielddef_type(f)) { -#define T(upbtypeconst, upbtype, ctype, default_value) \ - case upbtypeconst: { \ - ctype value = DEREF(memory, 0, ctype); \ - if (is_json || value != default_value) { \ - upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); \ - upb_sink_put##upbtype(sink, sel, value); \ - } \ - } break; - - T(UPB_TYPE_FLOAT, float, float, 0.0) - T(UPB_TYPE_DOUBLE, double, double, 0.0) - T(UPB_TYPE_BOOL, bool, uint8_t, 0) - T(UPB_TYPE_ENUM, int32, int32_t, 0) - T(UPB_TYPE_INT32, int32, int32_t, 0) - T(UPB_TYPE_UINT32, uint32, uint32_t, 0) - T(UPB_TYPE_INT64, int64, int64_t, 0) - T(UPB_TYPE_UINT64, uint64, uint64_t, 0) - -#undef T - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - putrawstr(memory, len, f, sink, is_json); - break; - case UPB_TYPE_MESSAGE: { -#if PHP_MAJOR_VERSION < 7 - MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory); -#else - MessageHeader *submsg = - (MessageHeader*)((char*)(*(zend_object**)memory) - - XtOffsetOf(MessageHeader, std)); -#endif - putrawsubmsg(submsg, f, sink, depth, is_json TSRMLS_CC); - break; - } - default: - PHP_PROTO_ASSERT(false); - } -} - -// Only string/bytes fields are stored as zval. -static const char* raw_value(void* memory, const upb_fielddef* f) { - switch (upb_fielddef_type(f)) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: -#if PHP_MAJOR_VERSION < 7 - return Z_STRVAL_PP((zval**)memory); -#else - return ZSTR_VAL(*(zend_string**)memory); -#endif - break; - default: - return memory; - } -} - -static int raw_value_len(void* memory, int len, const upb_fielddef* f) { - switch (upb_fielddef_type(f)) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: -#if PHP_MAJOR_VERSION < 7 - return Z_STRLEN_PP((zval**)memory); -#else - return ZSTR_LEN(*(zend_string**)memory); -#endif - default: - return len; - } -} - -static void putmap(zval* map, const upb_fielddef* f, upb_sink sink, - int depth, bool is_json TSRMLS_DC) { - upb_sink subsink; - const upb_fielddef* key_field; - const upb_fielddef* value_field; - MapIter it; - int len, size; - - PHP_PROTO_ASSERT(map != NULL); - Map* intern = UNBOX(Map, map); - size = upb_strtable_count(&intern->table); - if (size == 0) return; - - upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); - - PHP_PROTO_ASSERT(upb_fielddef_type(f) == UPB_TYPE_MESSAGE); - key_field = map_field_key(f); - value_field = map_field_value(f); - - for (map_begin(map, &it TSRMLS_CC); !map_done(&it); map_next(&it)) { - upb_status status; - - upb_sink entry_sink; - upb_sink_startsubmsg(subsink, getsel(f, UPB_HANDLER_STARTSUBMSG), - &entry_sink); - upb_sink_startmsg(entry_sink); - - // Serialize key. - const char *key = map_iter_key(&it, &len); - put_optional_value(key, len, key_field, depth + 1, - entry_sink, is_json TSRMLS_CC); - - // Serialize value. - upb_value value = map_iter_value(&it, &len); - put_optional_value(raw_value(upb_value_memory(&value), value_field), - raw_value_len(upb_value_memory(&value), len, value_field), - value_field, depth + 1, entry_sink, is_json TSRMLS_CC); - - upb_sink_endmsg(entry_sink, &status); - upb_sink_endsubmsg(subsink, entry_sink, getsel(f, UPB_HANDLER_ENDSUBMSG)); - } - - upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); -} - -static void putmsg(zval* msg_php, const DescriptorInternal* desc, upb_sink sink, - int depth, bool is_json TSRMLS_DC) { - MessageHeader* msg = UNBOX(MessageHeader, msg_php); - putrawmsg(msg, desc, sink, depth, is_json, true TSRMLS_CC); -} - -static const upb_handlers* msgdef_json_serialize_handlers( - DescriptorInternal* desc, bool preserve_proto_fieldnames); - -static void putjsonany(MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth TSRMLS_DC) { - upb_status status; - const upb_fielddef* type_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_TYPE); - const upb_fielddef* value_field = upb_msgdef_itof(desc->msgdef, UPB_ANY_VALUE); - - zval* type_url_php_str; - const upb_msgdef *payload_type = NULL; - - upb_sink_startmsg(sink); - - /* Handle type url */ - type_url_php_str = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, type_field)); - if (Z_STRLEN_P(type_url_php_str) > 0) { - putstr(type_url_php_str, type_field, sink, false); - } - - { - const char* type_url_str = Z_STRVAL_P(type_url_php_str); - size_t type_url_len = Z_STRLEN_P(type_url_php_str); - if (type_url_len <= 20 || - strncmp(type_url_str, "type.googleapis.com/", 20) != 0) { - zend_error(E_ERROR, "Invalid type url: %s", type_url_str); - } - - /* Resolve type url */ - type_url_str += 20; - type_url_len -= 20; - - payload_type = upb_symtab_lookupmsg2( - generated_pool->symtab, type_url_str, type_url_len); - if (payload_type == NULL) { - zend_error(E_ERROR, "Unknown type: %s", type_url_str); - return; - } - } - - { - zval* value_php_str; - const char* value_str; - size_t value_len; - - value_php_str = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, value_field)); - value_str = Z_STRVAL_P(value_php_str); - value_len = Z_STRLEN_P(value_php_str); - - if (value_len > 0) { - DescriptorInternal* payload_desc = get_msgdef_desc(payload_type); - register_class(payload_desc, false TSRMLS_CC); - zend_class_entry* payload_klass = payload_desc->klass; - zval val; - upb_sink subsink; - bool is_wellknown; - - /* Create message of the payload type. */ - ZVAL_OBJ(&val, payload_klass->create_object(payload_klass TSRMLS_CC)); - MessageHeader* intern = UNBOX(MessageHeader, &val); - custom_data_init(payload_klass, intern PHP_PROTO_TSRMLS_CC); - - merge_from_string(value_str, value_len, payload_desc, intern); - - is_wellknown = - upb_msgdef_wellknowntype(payload_desc->msgdef) != - UPB_WELLKNOWN_UNSPECIFIED; - if (is_wellknown) { - upb_sink_startstr(sink, getsel(value_field, UPB_HANDLER_STARTSTR), 0, - &subsink); - } - - subsink.handlers = - msgdef_json_serialize_handlers(payload_desc, true); - subsink.closure = sink.closure; - putrawmsg(intern, payload_desc, subsink, depth, true, - is_wellknown TSRMLS_CC); - - zval_dtor(&val); - } - } - - upb_sink_endmsg(sink, &status); -} - -static void putjsonlistvalue( - MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth TSRMLS_DC) { - upb_status status; - upb_sink subsink; - const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1); - zval* array; - RepeatedField* intern; - HashTable *ht; - int size; - - upb_sink_startmsg(sink); - - array = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (ZVAL_IS_NULL(array)) { - upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); - upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); - } else { - intern = UNBOX(RepeatedField, array); - ht = PHP_PROTO_HASH_OF(intern->array); - size = zend_hash_num_elements(ht); - - if (size == 0) { - upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); - upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); - } else { - putarray(array, f, sink, depth, true TSRMLS_CC); - } - } - - upb_sink_endmsg(sink, &status); -} - -static void putjsonstruct( - MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth TSRMLS_DC) { - upb_status status; - upb_sink subsink; - const upb_fielddef* f = upb_msgdef_itof(desc->msgdef, 1); - zval* map; - Map* intern; - int size; - - upb_sink_startmsg(sink); - - map = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (ZVAL_IS_NULL(map)) { - upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); - upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); - } else { - intern = UNBOX(Map, map); - size = upb_strtable_count(&intern->table); - - if (size == 0) { - upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); - upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); - } else { - putmap(map, f, sink, depth, true TSRMLS_CC); - } - } - - upb_sink_endmsg(sink, &status); -} - -static void putrawmsg(MessageHeader* msg, const DescriptorInternal* desc, - upb_sink sink, int depth, bool is_json, - bool open_msg TSRMLS_DC) { - upb_msg_field_iter i; - upb_status status; - - if (is_json && - upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) { - putjsonany(msg, desc, sink, depth TSRMLS_CC); - return; - } - - if (is_json && - upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_LISTVALUE) { - putjsonlistvalue(msg, desc, sink, depth TSRMLS_CC); - return; - } - - if (is_json && - upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_STRUCT) { - putjsonstruct(msg, desc, sink, depth TSRMLS_CC); - return; - } - - if (open_msg) { - upb_sink_startmsg(sink); - } - - // Protect against cycles (possible because users may freely reassign message - // and repeated fields) by imposing a maximum recursion depth. - if (depth > ENCODE_MAX_NESTING) { - zend_error(E_ERROR, - "Maximum recursion depth exceeded during encoding."); - } - - for (upb_msg_field_begin(&i, desc->msgdef); !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - upb_fielddef* f = upb_msg_iter_field(&i); - uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset; - bool containing_oneof = false; - - if (upb_fielddef_containingoneof(f)) { - uint32_t oneof_case_offset = - desc->layout->fields[upb_fielddef_index(f)].case_offset; - // For a oneof, check that this field is actually present -- skip all the - // below if not. - if (DEREF(message_data(msg), oneof_case_offset, uint32_t) != - upb_fielddef_number(f)) { - continue; - } - // Otherwise, fall through to the appropriate singular-field handler - // below. - containing_oneof = true; - } - - if (is_map_field(f)) { - zval* map = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (!ZVAL_IS_NULL(map)) { - putmap(map, f, sink, depth, is_json TSRMLS_CC); - } - } else if (upb_fielddef_isseq(f)) { - zval* array = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (!ZVAL_IS_NULL(array)) { - putarray(array, f, sink, depth, is_json TSRMLS_CC); - } - } else if (upb_fielddef_isstring(f)) { - zval* str = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (containing_oneof || (is_json && is_wrapper_msg(desc->msgdef)) || - Z_STRLEN_P(str) > 0) { - putstr(str, f, sink, is_json && is_wrapper_msg(desc->msgdef)); - } - } else if (upb_fielddef_issubmsg(f)) { - zval* submsg = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (is_wrapper_msg(upb_fielddef_msgsubdef(f)) && - Z_TYPE_P(submsg) != IS_NULL && Z_TYPE_P(submsg) != IS_OBJECT) { - putwrappervalue(submsg, f, sink, depth, is_json TSRMLS_CC); - } else { - putsubmsg(submsg, f, sink, depth, is_json TSRMLS_CC); - } - } else { - upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); - -#define T(upbtypeconst, upbtype, ctype, default_value) \ - case upbtypeconst: { \ - ctype value = DEREF(message_data(msg), offset, ctype); \ - if (containing_oneof || \ - (is_json && is_wrapper_msg(desc->msgdef)) || \ - value != default_value) { \ - upb_sink_put##upbtype(sink, sel, value); \ - } \ - } break; - - switch (upb_fielddef_type(f)) { - T(UPB_TYPE_FLOAT, float, float, 0.0) - T(UPB_TYPE_DOUBLE, double, double, 0.0) - T(UPB_TYPE_BOOL, bool, uint8_t, 0) - case UPB_TYPE_ENUM: - T(UPB_TYPE_INT32, int32, int32_t, 0) - T(UPB_TYPE_UINT32, uint32, uint32_t, 0) - T(UPB_TYPE_INT64, int64, int64_t, 0) - T(UPB_TYPE_UINT64, uint64, uint64_t, 0) - - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - case UPB_TYPE_MESSAGE: - zend_error(E_ERROR, "Internal error."); - } - -#undef T - } - } - - stringsink* unknown = DEREF(message_data(msg), 0, stringsink*); - if (unknown != NULL) { - upb_sink_putunknown(sink, unknown->ptr, unknown->len); - } - - if (open_msg) { - upb_sink_endmsg(sink, &status); - } -} - -static void putstr(zval* str, const upb_fielddef *f, - upb_sink sink, bool force_default) { - upb_sink subsink; - - if (ZVAL_IS_NULL(str)) return; - - PHP_PROTO_ASSERT(Z_TYPE_P(str) == IS_STRING); - - upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), Z_STRLEN_P(str), - &subsink); - - // For oneof string field, we may get here with string length is zero. - if (Z_STRLEN_P(str) > 0 || force_default) { - // Ensure that the string has the correct encoding. We also check at - // field-set time, but the user may have mutated the string object since - // then. - if (upb_fielddef_type(f) == UPB_TYPE_STRING && - !is_structurally_valid_utf8(Z_STRVAL_P(str), Z_STRLEN_P(str))) { - zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); - return; - } - upb_sink_putstring(subsink, getsel(f, UPB_HANDLER_STRING), Z_STRVAL_P(str), - Z_STRLEN_P(str), NULL); - } - - upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR)); -} - -static void putrawstr(const char* str, int len, const upb_fielddef* f, - upb_sink sink, bool force_default) { - upb_sink subsink; - - if (len == 0 && !force_default) return; - - // Ensure that the string has the correct encoding. We also check at field-set - // time, but the user may have mutated the string object since then. - if (upb_fielddef_type(f) == UPB_TYPE_STRING && - !is_structurally_valid_utf8(str, len)) { - zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); - return; - } - - upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), len, &subsink); - upb_sink_putstring(subsink, getsel(f, UPB_HANDLER_STRING), str, len, NULL); - upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR)); -} - -static void putsubmsg(zval* submsg_php, const upb_fielddef* f, upb_sink sink, - int depth, bool is_json TSRMLS_DC) { - if (Z_TYPE_P(submsg_php) == IS_NULL) return; - - MessageHeader *submsg = UNBOX(MessageHeader, submsg_php); - putrawsubmsg(submsg, f, sink, depth, is_json TSRMLS_CC); -} - -static void putwrappervalue( - zval* value, const upb_fielddef* f, - upb_sink sink, int depth, bool is_json TSRMLS_DC) { - upb_sink subsink; - const upb_msgdef* msgdef = upb_fielddef_msgsubdef(f); - const upb_fielddef* value_field = upb_msgdef_itof(msgdef, 1); - upb_selector_t sel = - getsel(value_field, upb_handlers_getprimitivehandlertype(value_field)); - - upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink); - -#define T(upbtypeconst, upbtype, ctype, default_value) \ - case upbtypeconst: { \ - ctype value_raw; \ - native_slot_set(upb_fielddef_type(value_field), NULL, \ - &value_raw, value PHP_PROTO_TSRMLS_CC); \ - if ((is_json && is_wrapper_msg(msgdef)) || \ - value_raw != default_value) { \ - upb_sink_put##upbtype(subsink, sel, value_raw); \ - } \ - } break; - - switch (upb_fielddef_type(value_field)) { - T(UPB_TYPE_FLOAT, float, float, 0.0) - T(UPB_TYPE_DOUBLE, double, double, 0.0) - T(UPB_TYPE_BOOL, bool, uint8_t, 0) - T(UPB_TYPE_INT32, int32, int32_t, 0) - T(UPB_TYPE_UINT32, uint32, uint32_t, 0) - T(UPB_TYPE_INT64, int64, int64_t, 0) - T(UPB_TYPE_UINT64, uint64, uint64_t, 0) - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - if ((is_json && is_wrapper_msg(msgdef)) || - Z_STRLEN_P(value) > 0) { - putstr(value, value_field, subsink, is_json && is_wrapper_msg(msgdef)); - } - break; - } - case UPB_TYPE_ENUM: - case UPB_TYPE_MESSAGE: - zend_error(E_ERROR, "Internal error."); - } - -#undef T - - upb_sink_endsubmsg(sink, subsink, getsel(f, UPB_HANDLER_ENDSUBMSG)); -} - -static void putrawsubmsg(MessageHeader* submsg, const upb_fielddef* f, - upb_sink sink, int depth, bool is_json TSRMLS_DC) { - upb_sink subsink; - - const upb_msgdef* m = upb_fielddef_msgsubdef(f); - DescriptorInternal* subdesc = get_msgdef_desc(m); - - upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink); - putrawmsg(submsg, subdesc, subsink, depth + 1, is_json, true TSRMLS_CC); - upb_sink_endsubmsg(sink, subsink, getsel(f, UPB_HANDLER_ENDSUBMSG)); -} - -static void putarray(zval* array, const upb_fielddef* f, upb_sink sink, - int depth, bool is_json TSRMLS_DC) { - upb_sink subsink; - upb_fieldtype_t type = upb_fielddef_type(f); - upb_selector_t sel = 0; - int size, i; - - PHP_PROTO_ASSERT(array != NULL); - RepeatedField* intern = UNBOX(RepeatedField, array); - HashTable *ht = PHP_PROTO_HASH_OF(intern->array); - size = zend_hash_num_elements(ht); - if (size == 0) return; - - upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); - - if (upb_fielddef_isprimitive(f)) { - sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); - } - - for (i = 0; i < size; i++) { - void* memory = repeated_field_index_native(intern, i TSRMLS_CC); - switch (type) { -#define T(upbtypeconst, upbtype, ctype) \ - case upbtypeconst: \ - upb_sink_put##upbtype(subsink, sel, *((ctype*)memory)); \ - break; - - T(UPB_TYPE_FLOAT, float, float) - T(UPB_TYPE_DOUBLE, double, double) - T(UPB_TYPE_BOOL, bool, int8_t) - case UPB_TYPE_ENUM: - T(UPB_TYPE_INT32, int32, int32_t) - T(UPB_TYPE_UINT32, uint32, uint32_t) - T(UPB_TYPE_INT64, int64, int64_t) - T(UPB_TYPE_UINT64, uint64, uint64_t) - - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { -#if PHP_MAJOR_VERSION < 7 - const char* rawstr = Z_STRVAL_P(*(zval**)memory); - int len = Z_STRLEN_P(*(zval**)memory); -#else - const char* rawstr = ZSTR_VAL(*(zend_string**)memory); - int len = ZSTR_LEN(*(zend_string**)memory); -#endif - putrawstr(rawstr, len, f, subsink, - is_json && is_wrapper_msg(upb_fielddef_containingtype(f))); - break; - } - case UPB_TYPE_MESSAGE: { -#if PHP_MAJOR_VERSION < 7 - MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory); -#else - MessageHeader *submsg = - (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) - - XtOffsetOf(MessageHeader, std)); -#endif - putrawsubmsg(submsg, f, subsink, depth, is_json TSRMLS_CC); - break; - } - -#undef T - } - } - upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); -} - -static const upb_handlers* msgdef_pb_serialize_handlers(DescriptorInternal* desc) { - return upb_handlercache_get(desc->pool->pb_serialize_handler_cache, - desc->msgdef); -} - -static const upb_handlers* msgdef_json_serialize_handlers( - DescriptorInternal* desc, bool preserve_proto_fieldnames) { - if (preserve_proto_fieldnames) { - return upb_handlercache_get( - desc->pool->json_serialize_handler_preserve_cache, desc->msgdef); - } else { - return upb_handlercache_get(desc->pool->json_serialize_handler_cache, - desc->msgdef); - } -} - -// ----------------------------------------------------------------------------- -// PHP encode/decode methods -// ----------------------------------------------------------------------------- - -void serialize_to_string(zval* val, zval* return_value TSRMLS_DC) { - DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(val)); - - stringsink sink; - stringsink_init(&sink); - - { - const upb_handlers* serialize_handlers = msgdef_pb_serialize_handlers(desc); - - stackenv se; - upb_pb_encoder* encoder; - - stackenv_init(&se, "Error occurred during encoding: %s"); - encoder = upb_pb_encoder_create(se.arena, serialize_handlers, sink.sink); - - putmsg(val, desc, upb_pb_encoder_input(encoder), 0, false TSRMLS_CC); - - PHP_PROTO_RETVAL_STRINGL(sink.ptr, sink.len, 1); - - stackenv_uninit(&se); - stringsink_uninit(&sink); - } -} - -PHP_METHOD(Message, serializeToString) { - serialize_to_string(getThis(), return_value TSRMLS_CC); -} - -void merge_from_string(const char* data, int data_len, DescriptorInternal* desc, - MessageHeader* msg) { - const upb_pbdecodermethod* method = msgdef_decodermethod(desc); - const upb_handlers* h = upb_pbdecodermethod_desthandlers(method); - stackenv se; - upb_sink sink; - upb_pbdecoder* decoder; - void* closure; - stackenv_init(&se, "Error occurred during parsing: %s"); - - if (is_wrapper_msg(desc->msgdef)) { - wrapperfields_parseframe_t* frame = - (wrapperfields_parseframe_t*)malloc( - sizeof(wrapperfields_parseframe_t)); - frame->submsg = msg; - frame->is_msg = true; - closure = frame; - } else { - closure = msg; - } - - upb_sink_reset(&sink, h, closure); - decoder = upb_pbdecoder_create(se.arena, method, sink, &se.status); - upb_bufsrc_putbuf(data, data_len, upb_pbdecoder_input(decoder)); - - if (is_wrapper_msg(desc->msgdef)) { - free((wrapperfields_parseframe_t*)closure); - } - - stackenv_uninit(&se); -} - -PHP_METHOD(Message, mergeFromString) { - DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(getThis())); - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - - char *data = NULL; - PHP_PROTO_SIZE data_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == - FAILURE) { - return; - } - - merge_from_string(data, data_len, desc, msg); -} - -PHP_METHOD(Message, serializeToJsonString) { - DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(getThis())); - - zend_bool preserve_proto_fieldnames = false; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", - &preserve_proto_fieldnames) == FAILURE) { - return; - } - - stringsink sink; - stringsink_init(&sink); - - { - const upb_handlers* serialize_handlers = - msgdef_json_serialize_handlers(desc, preserve_proto_fieldnames); - upb_json_printer* printer; - stackenv se; - - stackenv_init(&se, "Error occurred during encoding: %s"); - printer = upb_json_printer_create(se.arena, serialize_handlers, sink.sink); - - putmsg(getThis(), desc, upb_json_printer_input(printer), 0, true TSRMLS_CC); - - PHP_PROTO_RETVAL_STRINGL(sink.ptr, sink.len, 1); - - stackenv_uninit(&se); - stringsink_uninit(&sink); - } -} - -PHP_METHOD(Message, mergeFromJsonString) { - DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(getThis())); - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - - char *data = NULL; - PHP_PROTO_SIZE data_len; - zend_bool ignore_json_unknown = false; - - if (zend_parse_parameters( - ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &data, &data_len, - &ignore_json_unknown) == - FAILURE) { - return; - } - - // TODO(teboring): Check and respect string encoding. If not UTF-8, we need to - // convert, because string handlers pass data directly to message string - // fields. - - // TODO(teboring): Clear message. - - { - const upb_json_parsermethod* method = msgdef_jsonparsermethod(desc); - stackenv se; - upb_sink sink; - upb_json_parser* parser; - void* closure; - stackenv_init(&se, "Error occurred during parsing: %s"); - - if (is_wrapper_msg(desc->msgdef)) { - wrapperfields_parseframe_t* frame = - (wrapperfields_parseframe_t*)malloc( - sizeof(wrapperfields_parseframe_t)); - frame->submsg = msg; - frame->is_msg = true; - closure = frame; - } else { - closure = msg; - } - - upb_sink_reset(&sink, get_fill_handlers(desc), closure); - parser = upb_json_parser_create(se.arena, method, generated_pool->symtab, - sink, &se.status, ignore_json_unknown); - upb_bufsrc_putbuf(data, data_len, upb_json_parser_input(parser)); - - if (is_wrapper_msg(desc->msgdef)) { - free((wrapperfields_parseframe_t*)closure); - } - stackenv_uninit(&se); - } -} - -// TODO(teboring): refactoring with putrawmsg -static void discard_unknown_fields(MessageHeader* msg) { - upb_msg_field_iter it; - - stringsink* unknown = DEREF(message_data(msg), 0, stringsink*); - if (unknown != NULL) { - stringsink_uninit(unknown); - FREE(unknown); - DEREF(message_data(msg), 0, stringsink*) = NULL; - } - - // Recursively discard unknown fields of submessages. - DescriptorInternal* desc = msg->descriptor; - TSRMLS_FETCH(); - for (upb_msg_field_begin(&it, desc->msgdef); - !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - upb_fielddef* f = upb_msg_iter_field(&it); - - if (upb_fielddef_containingoneof(f)) { - uint32_t oneof_case_offset = - desc->layout->fields[upb_fielddef_index(f)].case_offset; - // For a oneof, check that this field is actually present -- skip all the - // below if not. - if (DEREF(message_data(msg), oneof_case_offset, uint32_t) != - upb_fielddef_number(f)) { - continue; - } - // Otherwise, fall through to the appropriate singular-field handler - // below. - } - - if (is_map_field(f)) { - MapIter map_it; - int len; - const upb_fielddef* value_field; - - value_field = map_field_value(f); - if (!upb_fielddef_issubmsg(value_field)) continue; - - zval* map_php = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (ZVAL_IS_NULL(map_php)) continue; - - for (map_begin(map_php, &map_it TSRMLS_CC); - !map_done(&map_it); map_next(&map_it)) { - upb_value value = map_iter_value(&map_it, &len); - const void* memory = raw_value(upb_value_memory(&value), value_field); -#if PHP_MAJOR_VERSION < 7 - MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory); -#else - MessageHeader *submsg = - (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) - - XtOffsetOf(MessageHeader, std)); -#endif - discard_unknown_fields(submsg); - } - } else if (upb_fielddef_isseq(f)) { - if (!upb_fielddef_issubmsg(f)) continue; - - zval* array_php = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (ZVAL_IS_NULL(array_php)) continue; - - int size, i; - RepeatedField* intern = UNBOX(RepeatedField, array_php); - HashTable *ht = PHP_PROTO_HASH_OF(intern->array); - size = zend_hash_num_elements(ht); - if (size == 0) continue; - - for (i = 0; i < size; i++) { - void* memory = repeated_field_index_native(intern, i TSRMLS_CC); -#if PHP_MAJOR_VERSION < 7 - MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory); -#else - MessageHeader *submsg = - (MessageHeader*)((char*)(Z_OBJ_P((zval*)memory)) - - XtOffsetOf(MessageHeader, std)); -#endif - discard_unknown_fields(submsg); - } - } else if (upb_fielddef_issubmsg(f)) { - zval* submsg_php = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, f)); - if (Z_TYPE_P(submsg_php) == IS_NULL) continue; - MessageHeader* submsg = UNBOX(MessageHeader, submsg_php); - discard_unknown_fields(submsg); - } - } -} - -PHP_METHOD(Message, discardUnknownFields) { - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - discard_unknown_fields(msg); -} diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index 1878a0ae6779..426d56a4f9b4 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -28,390 +28,231 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include "map.h" + #include #include -#include "protobuf.h" -#include "utf8.h" - -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) - ZEND_ARG_INFO(0, index) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) - ZEND_ARG_INFO(0, index) - ZEND_ARG_INFO(0, newval) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_void, 0) -ZEND_END_ARG_INFO() +#include -// Utilities +#include "arena.h" +#include "convert.h" +#include "message.h" +#include "php-upb.h" +#include "protobuf.h" -void* upb_value_memory(upb_value* v) { - return (void*)(&v->val); -} +static void MapFieldIter_make(zval *val, zval *map_field); // ----------------------------------------------------------------------------- -// Basic map operations on top of upb's strtable. -// -// Note that we roll our own `Map` container here because, as for -// `RepeatedField`, we want a strongly-typed container. This is so that any user -// errors due to incorrect map key or value types are raised as close as -// possible to the error site, rather than at some deferred point (e.g., -// serialization). -// -// We build our `Map` on top of upb_strtable so that we're able to take -// advantage of the native_slot storage abstraction, as RepeatedField does. -// (This is not quite a perfect mapping -- see the key conversions below -- but -// gives us full support and error-checking for all value types for free.) +// MapField // ----------------------------------------------------------------------------- -// Map values are stored using the native_slot abstraction (as with repeated -// field values), but keys are a bit special. Since we use a strtable, we need -// to store keys as sequences of bytes such that equality of those bytes maps -// one-to-one to equality of keys. We store strings directly (i.e., they map to -// their own bytes) and integers as native integers (using the native_slot -// abstraction). - -// Note that there is another tradeoff here in keeping string keys as native -// strings rather than PHP strings: traversing the Map requires conversion to -// PHP string values on every traversal, potentially creating more garbage. We -// should consider ways to cache a PHP version of the key if this becomes an -// issue later. - -// Forms a key to use with the underlying strtable from a PHP key value. |buf| -// must point to TABLE_KEY_BUF_LENGTH bytes of temporary space, used to -// construct a key byte sequence if needed. |out_key| and |out_length| provide -// the resulting key data/length. -#define TABLE_KEY_BUF_LENGTH 8 // sizeof(uint64_t) -static bool table_key(Map* self, zval* key, - char* buf, - const char** out_key, - size_t* out_length TSRMLS_DC) { - switch (self->key_type) { - case UPB_TYPE_STRING: - if (!protobuf_convert_to_string(key)) { - return false; - } - if (!is_structurally_valid_utf8(Z_STRVAL_P(key), Z_STRLEN_P(key))) { - zend_error(E_USER_ERROR, "Given key is not UTF8 encoded."); - return false; - } - *out_key = Z_STRVAL_P(key); - *out_length = Z_STRLEN_P(key); - break; - -#define CASE_TYPE(upb_type, type, c_type, php_type) \ - case UPB_TYPE_##upb_type: { \ - c_type type##_value; \ - if (!protobuf_convert_to_##type(key, &type##_value)) { \ - return false; \ - } \ - native_slot_set_by_array(self->key_type, NULL, buf, key TSRMLS_CC); \ - *out_key = buf; \ - *out_length = native_slot_size(self->key_type); \ - break; \ +typedef struct { + zend_object std; + zval arena; + upb_map *map; + upb_fieldtype_t key_type; + upb_fieldtype_t val_type; + const Descriptor* desc; // When values are messages. +} MapField; + +zend_class_entry *MapField_class_entry; +static zend_object_handlers MapField_object_handlers; + +// PHP Object Handlers ///////////////////////////////////////////////////////// + +/** + * MapField_create() + * + * PHP class entry function to allocate and initialize a new MapField + * object. + */ +static zend_object* MapField_create(zend_class_entry *class_type) { + MapField *intern = emalloc(sizeof(MapField)); + zend_object_std_init(&intern->std, class_type); + intern->std.handlers = &MapField_object_handlers; + Arena_Init(&intern->arena); + intern->map = NULL; + // Skip object_properties_init(), we don't allow derived classes. + return &intern->std; +} + +/** + * MapField_dtor() + * + * Object handler to destroy a MapField. This releases all resources + * associated with the message. Note that it is possible to access a destroyed + * object from PHP in rare cases. + */ +static void MapField_destructor(zend_object* obj) { + MapField* intern = (MapField*)obj; + ObjCache_Delete(intern->map); + zval_ptr_dtor(&intern->arena); + zend_object_std_dtor(&intern->std); +} + +/** + * MapField_compare_objects() + * + * Object handler for comparing two repeated field objects. Called whenever PHP + * code does: + * + * $map1 == $map2 + */ +static int MapField_compare_objects(zval *map1, zval *map2) { + MapField* intern1 = (MapField*)Z_OBJ_P(map1); + MapField* intern2 = (MapField*)Z_OBJ_P(map2); + const upb_msgdef *m = intern1->desc ? intern1->desc->msgdef : NULL; + upb_fieldtype_t key_type = intern1->key_type; + upb_fieldtype_t val_type = intern1->val_type; + + if (key_type != intern2->key_type) return 1; + if (val_type != intern2->val_type) return 1; + if (intern1->desc != intern2->desc) return 1; + + return MapEq(intern1->map, intern2->map, key_type, val_type, m) ? 0 : 1; +} + +static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member, + int type, void **cache_slot) { + return NULL; // We don't offer direct references to our properties. +} + +static HashTable *Map_GetProperties(PROTO_VAL *object) { + return NULL; // We do not have a properties table. +} + +// C Functions from map.h ////////////////////////////////////////////////////// + +// These are documented in the header file. + +void MapField_GetPhpWrapper(zval *val, upb_map *map, const upb_fielddef *f, + zval *arena) { + if (!map) { + ZVAL_NULL(val); + return; } - CASE_TYPE(BOOL, bool, int8_t, BOOL) - CASE_TYPE(INT32, int32, int32_t, LONG) - CASE_TYPE(INT64, int64, int64_t, LONG) - CASE_TYPE(UINT32, uint32, uint32_t, LONG) - CASE_TYPE(UINT64, uint64, uint64_t, LONG) - -#undef CASE_TYPE - default: - // Map constructor should not allow a Map with another key type to be - // constructed. - assert(false); - break; + if (!ObjCache_Get(map, val)) { + const upb_msgdef *ent = upb_fielddef_msgsubdef(f); + const upb_fielddef *key_f = upb_msgdef_itof(ent, 1); + const upb_fielddef *val_f = upb_msgdef_itof(ent, 2); + MapField *intern = emalloc(sizeof(MapField)); + zend_object_std_init(&intern->std, MapField_class_entry); + intern->std.handlers = &MapField_object_handlers; + ZVAL_COPY(&intern->arena, arena); + intern->map = map; + intern->key_type = upb_fielddef_type(key_f); + intern->val_type = upb_fielddef_type(val_f); + intern->desc = Descriptor_GetFromFieldDef(val_f); + // Skip object_properties_init(), we don't allow derived classes. + ObjCache_Add(intern->map, &intern->std); + ZVAL_OBJ(val, &intern->std); } - - return true; -} - -// ----------------------------------------------------------------------------- -// MapField methods -// ----------------------------------------------------------------------------- - -static zend_function_entry map_field_methods[] = { - PHP_ME(MapField, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC) - PHP_ME(MapField, count, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapField, getIterator, arginfo_void, ZEND_ACC_PUBLIC) - ZEND_FE_END -}; - -// Forward declare static functions. - -static void map_field_write_dimension(zval *object, zval *key, - zval *value TSRMLS_DC); - -// ----------------------------------------------------------------------------- -// MapField creation/destruction -// ----------------------------------------------------------------------------- - -zend_class_entry* map_field_type; -zend_class_entry* map_field_iter_type; - -zend_object_handlers* map_field_handlers; -zend_object_handlers* map_field_iter_handlers; - -static void map_begin_internal(Map *map, MapIter *iter) { - iter->self = map; - upb_strtable_begin(&iter->it, &map->table); } -static HashTable *map_field_get_gc(zval *object, CACHED_VALUE **table, - int *n TSRMLS_DC) { - // TODO(teboring): Unfortunately, zend engine does not support garbage - // collection for custom array. We have to use zend engine's native array - // instead. - *table = NULL; - *n = 0; - return NULL; -} - -// Define map value element free function. -#if PHP_MAJOR_VERSION < 7 -static inline void php_proto_map_string_release(void *value) { - zval_ptr_dtor(value); -} +upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena) { + const upb_msgdef *ent = upb_fielddef_msgsubdef(f); + const upb_fielddef *key_f = upb_msgdef_itof(ent, 1); + const upb_fielddef *val_f = upb_msgdef_itof(ent, 2); + upb_fieldtype_t key_type = upb_fielddef_type(key_f); + upb_fieldtype_t val_type = upb_fielddef_type(val_f); + const Descriptor *desc = Descriptor_GetFromFieldDef(val_f); -static inline void php_proto_map_object_release(void *value) { - zval_ptr_dtor(value); -} -#else -static inline void php_proto_map_string_release(void *value) { - zend_string* object = *(zend_string**)value; - zend_string_release(object); -} -static inline void php_proto_map_object_release(void *value) { - zend_object* object = *(zend_object**)value; - GC_DELREF(object); - if(GC_REFCOUNT(object) == 0) { - zend_objects_store_del(object); - } -} -#endif - -// Define object free method. -PHP_PROTO_OBJECT_FREE_START(Map, map_field) -MapIter it; -int len; -for (map_begin_internal(intern, &it); !map_done(&it); map_next(&it)) { - upb_value value = map_iter_value(&it, &len); - void *mem = upb_value_memory(&value); - switch (intern->value_type) { - case UPB_TYPE_MESSAGE: - php_proto_map_object_release(mem); - break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - php_proto_map_string_release(mem); - break; - default: - break; - } -} -upb_strtable_uninit(&intern->table); -PHP_PROTO_OBJECT_FREE_END - -PHP_PROTO_OBJECT_EMPTY_DTOR_START(Map, map_field) -PHP_PROTO_OBJECT_DTOR_END - -// Define object create method. -PHP_PROTO_OBJECT_CREATE_START(Map, map_field) -// Table value type is always UINT64: this ensures enough space to store the -// native_slot value. -if (!upb_strtable_init(&intern->table, UPB_CTYPE_UINT64)) { - zend_error(E_USER_ERROR, "Could not allocate table."); -} -PHP_PROTO_OBJECT_CREATE_END(Map, map_field) - -// Init class entry. -PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\MapField", Map, - map_field) -zend_class_implements(map_field_type TSRMLS_CC, 3, spl_ce_ArrayAccess, - zend_ce_aggregate, spl_ce_Countable); -map_field_handlers->write_dimension = map_field_write_dimension; -map_field_handlers->get_gc = map_field_get_gc; -PHP_PROTO_INIT_CLASS_END - -void map_field_ensure_created(const upb_fielddef *field, - CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC) { - if (ZVAL_IS_NULL(CACHED_PTR_TO_ZVAL_PTR(map_field))) { - zval_ptr_dtor(map_field); -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(CACHED_PTR_TO_ZVAL_PTR(map_field)); -#endif - map_field_create_with_field(map_field_type, field, - map_field PHP_PROTO_TSRMLS_CC); + if (Z_ISREF_P(val)) { + ZVAL_DEREF(val); } -} -void map_field_create_with_field(const zend_class_entry *ce, - const upb_fielddef *field, - CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC) { - const upb_fielddef *key_field = map_field_key(field); - const upb_fielddef *value_field = map_field_value(field); - map_field_create_with_type( - ce, upb_fielddef_type(key_field), upb_fielddef_type(value_field), - field_type_class(value_field TSRMLS_CC), map_field PHP_PROTO_TSRMLS_CC); -} + if (Z_TYPE_P(val) == IS_ARRAY) { + upb_map *map = upb_map_new(arena, key_type, val_type); + HashTable *table = HASH_OF(val); + HashPosition pos; -void map_field_create_with_type(const zend_class_entry *ce, - upb_fieldtype_t key_type, - upb_fieldtype_t value_type, - const zend_class_entry *msg_ce, - CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC) { - CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(CACHED_PTR_TO_ZVAL_PTR(map_field), - map_field_type); - Map *intern = UNBOX(Map, CACHED_TO_ZVAL_PTR(*map_field)); - intern->key_type = key_type; - intern->value_type = value_type; - intern->msg_ce = msg_ce; -} + zend_hash_internal_pointer_reset_ex(table, &pos); -// ----------------------------------------------------------------------------- -// MapField Handlers -// ----------------------------------------------------------------------------- + while (true) { + zval php_key; + zval *php_val; + upb_msgval upb_key; + upb_msgval upb_val; -static bool map_field_read_dimension(zval *object, zval *key, int type, - CACHED_VALUE *retval TSRMLS_DC) { - Map *intern = UNBOX(Map, object); - - char keybuf[TABLE_KEY_BUF_LENGTH]; - const char* keyval = NULL; - size_t length = 0; - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_UINT64; -#endif - if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { - return false; - } + zend_hash_get_current_key_zval_ex(table, &php_key, &pos); + php_val = zend_hash_get_current_data_ex(table, &pos); - if (upb_strtable_lookup2(&intern->table, keyval, length, &v)) { - void* mem = upb_value_memory(&v); - native_slot_get_by_map_value(intern->value_type, mem, retval TSRMLS_CC); - return true; - } else { - zend_error(E_USER_ERROR, "Given key doesn't exist."); - return false; - } -} + if (!php_val) return map; -static void map_index_unset(Map *intern, const char* keyval, int length) { - upb_value old_value; - if (upb_strtable_remove2(&intern->table, keyval, length, &old_value)) { - switch (intern->value_type) { - case UPB_TYPE_MESSAGE: { -#if PHP_MAJOR_VERSION < 7 - zval_ptr_dtor(upb_value_memory(&old_value)); -#else - zend_object* object = *(zend_object**)upb_value_memory(&old_value); - GC_DELREF(object); - if(GC_REFCOUNT(object) == 0) { - zend_objects_store_del(object); - } -#endif - break; - } - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { -#if PHP_MAJOR_VERSION < 7 - zval_ptr_dtor(upb_value_memory(&old_value)); -#else - zend_string* object = *(zend_string**)upb_value_memory(&old_value); - zend_string_release(object); -#endif - break; + if (!Convert_PhpToUpb(&php_key, &upb_key, key_type, NULL, arena) || + !Convert_PhpToUpbAutoWrap(php_val, &upb_val, val_type, desc, arena)) { + return NULL; } - default: - break; - } - } -} -bool map_index_set(Map *intern, const char* keyval, int length, upb_value v) { - // Replace any existing value by issuing a 'remove' operation first. - map_index_unset(intern, keyval, length); + upb_map_set(map, upb_key, upb_val, arena); + zend_hash_move_forward_ex(table, &pos); + zval_dtor(&php_key); + } + } else if (Z_TYPE_P(val) == IS_OBJECT && + Z_OBJCE_P(val) == MapField_class_entry) { + MapField *intern = (MapField*)Z_OBJ_P(val); + + if (intern->key_type != key_type || intern->val_type != val_type || + intern->desc != desc) { + php_error_docref(NULL, E_USER_ERROR, "Wrong type for this map field."); + return NULL; + } - if (!upb_strtable_insert2(&intern->table, keyval, length, v)) { - zend_error(E_USER_ERROR, "Could not insert into table"); - return false; + upb_arena_fuse(arena, Arena_Get(&intern->arena)); + return intern->map; + } else { + php_error_docref(NULL, E_USER_ERROR, "Must be a map"); + return NULL; } - - return true; } -static void map_field_write_dimension(zval *object, zval *key, - zval *value TSRMLS_DC) { - Map *intern = UNBOX(Map, object); - - char keybuf[TABLE_KEY_BUF_LENGTH]; - const char* keyval = NULL; - size_t length = 0; - upb_value v; - void* mem; - if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { - return; - } - - mem = upb_value_memory(&v); - memset(mem, 0, native_slot_size(intern->value_type)); - if (!native_slot_set_by_map(intern->value_type, intern->msg_ce, mem, - value TSRMLS_CC)) { - return; - } -#ifndef NDEBUG - v.ctype = UPB_CTYPE_UINT64; -#endif +bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type, + upb_fieldtype_t val_type, const upb_msgdef *m) { + size_t iter = UPB_MAP_BEGIN; - map_index_set(intern, keyval, length, v); -} + if ((m1 == NULL) != (m2 == NULL)) return false; + if (m1 == NULL) return true; + if (upb_map_size(m1) != upb_map_size(m2)) return false; -static bool map_field_unset_dimension(zval *object, zval *key TSRMLS_DC) { - Map *intern = UNBOX(Map, object); + while (upb_mapiter_next(m1, &iter)) { + upb_msgval key = upb_mapiter_key(m1, iter); + upb_msgval val1 = upb_mapiter_value(m1, iter); + upb_msgval val2; - char keybuf[TABLE_KEY_BUF_LENGTH]; - const char* keyval = NULL; - size_t length = 0; - if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { - return false; + if (!upb_map_get(m2, key, &val2)) return false; + if (!ValueEq(val1, val2, val_type, m)) return false; } -#ifndef NDEBUG - v.ctype = UPB_CTYPE_UINT64; -#endif - - map_index_unset(intern, keyval, length); return true; } -// ----------------------------------------------------------------------------- -// PHP MapField Methods -// ----------------------------------------------------------------------------- +// MapField PHP methods //////////////////////////////////////////////////////// + +/** + * MapField::__construct() + * + * Constructs an instance of MapField. + * @param long Key type. + * @param long Value type. + * @param string Message/Enum class (message/enum value types only). + */ PHP_METHOD(MapField, __construct) { - long key_type, value_type; + MapField *intern = (MapField*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); + zend_long key_type, val_type; zend_class_entry* klass = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|C", &key_type, - &value_type, &klass) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|C", &key_type, &val_type, + &klass) != SUCCESS) { return; } - Map *intern = UNBOX(Map, getThis()); - intern->key_type = to_fieldtype(key_type); - intern->value_type = to_fieldtype(value_type); - intern->msg_ce = klass; + intern->key_type = pbphp_dtype_to_type(key_type); + intern->val_type = pbphp_dtype_to_type(val_type); + intern->desc = Descriptor_GetFromClassEntry(klass); // Check that the key type is an allowed type. switch (intern->key_type) { @@ -427,176 +268,374 @@ PHP_METHOD(MapField, __construct) { default: zend_error(E_USER_ERROR, "Invalid key type for map."); } -} + if (intern->val_type == UPB_TYPE_MESSAGE && klass == NULL) { + php_error_docref(NULL, E_USER_ERROR, + "Message/enum type must have concrete class."); + return; + } + + intern->map = upb_map_new(arena, intern->key_type, intern->val_type); + ObjCache_Add(intern->map, &intern->std); +} + +/** + * MapField::offsetExists() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * isset($map[$idx]); + * empty($map[$idx]); + * + * @param long The index to be checked. + * @return bool True if the element at the given index exists. + */ PHP_METHOD(MapField, offsetExists) { + MapField *intern = (MapField*)Z_OBJ_P(getThis()); zval *key; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &key) == - FAILURE) { + upb_msgval upb_key; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS || + !Convert_PhpToUpb(key, &upb_key, intern->key_type, intern->desc, NULL)) { return; } - Map *intern = UNBOX(Map, getThis()); - - char keybuf[TABLE_KEY_BUF_LENGTH]; - const char* keyval = NULL; - size_t length = 0; - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_UINT64; -#endif - if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { - RETURN_BOOL(false); - } + RETURN_BOOL(upb_map_get(intern->map, upb_key, NULL)); +} + +/** + * MapField::offsetGet() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * $x = $map[$idx]; + * + * @param long The index of the element to be fetched. + * @return object The stored element at given index. + * @exception Invalid type for index. + * @exception Non-existing index. + */ +PHP_METHOD(MapField, offsetGet) { + MapField *intern = (MapField*)Z_OBJ_P(getThis()); + zval *key; + zval ret; + upb_msgval upb_key, upb_val; - RETURN_BOOL(upb_strtable_lookup2(&intern->table, keyval, length, &v)); -} + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS || + !Convert_PhpToUpb(key, &upb_key, intern->key_type, intern->desc, NULL)) { + return; + } -PHP_METHOD(MapField, offsetGet) { - zval *index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &index) == - FAILURE) { + if (!upb_map_get(intern->map, upb_key, &upb_val)) { + zend_error(E_USER_ERROR, "Given key doesn't exist."); return; } - map_field_read_dimension(getThis(), index, BP_VAR_R, - ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); -} + Convert_UpbToPhp(upb_val, &ret, intern->val_type, intern->desc, &intern->arena); + RETURN_ZVAL(&ret, 0, 1); +} + +/** + * MapField::offsetSet() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * $map[$idx] = $x; + * + * @param long The index of the element to be assigned. + * @param object The element to be assigned. + * @exception Invalid type for index. + * @exception Non-existing index. + * @exception Incorrect type of the element. + */ PHP_METHOD(MapField, offsetSet) { - zval *index, *value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &index, &value) == - FAILURE) { + MapField *intern = (MapField*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); + zval *key, *val; + upb_msgval upb_key, upb_val; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &key, &val) != SUCCESS || + !Convert_PhpToUpb(key, &upb_key, intern->key_type, NULL, NULL) || + !Convert_PhpToUpb(val, &upb_val, intern->val_type, intern->desc, arena)) { return; } - map_field_write_dimension(getThis(), index, value TSRMLS_CC); + + upb_map_set(intern->map, upb_key, upb_val, arena); } +/** + * MapField::offsetUnset() + * + * Implements the ArrayAccess interface. Invoked when PHP code calls: + * + * unset($map[$idx]); + * + * @param long The index of the element to be removed. + * @exception Invalid type for index. + * @exception The element to be removed is not at the end of the MapField. + */ PHP_METHOD(MapField, offsetUnset) { - zval *index; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &index) == - FAILURE) { + MapField *intern = (MapField*)Z_OBJ_P(getThis()); + zval *key; + upb_msgval upb_key; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &key) != SUCCESS || + !Convert_PhpToUpb(key, &upb_key, intern->key_type, NULL, NULL)) { return; } - map_field_unset_dimension(getThis(), index TSRMLS_CC); + + upb_map_delete(intern->map, upb_key); } +/** + * MapField::count() + * + * Implements the Countable interface. Invoked when PHP code calls: + * + * $len = count($map); + * Return the number of stored elements. + * This will also be called for: count($map) + * @return long The number of stored elements. + */ PHP_METHOD(MapField, count) { - Map *intern = UNBOX(Map, getThis()); + MapField *intern = (MapField*)Z_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } - RETURN_LONG(upb_strtable_count(&intern->table)); + RETURN_LONG(upb_map_size(intern->map)); } +/** + * MapField::getIterator() + * + * Implements the IteratorAggregate interface. Invoked when PHP code calls: + * + * foreach ($arr) {} + * + * @return object Beginning iterator. + */ PHP_METHOD(MapField, getIterator) { - CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(return_value, - map_field_iter_type); - - MapIter *iter = UNBOX(MapIter, return_value); - map_begin(getThis(), iter TSRMLS_CC); -} - -// ----------------------------------------------------------------------------- -// Map Iterator -// ----------------------------------------------------------------------------- - -void map_begin(zval *map_php, MapIter *iter TSRMLS_DC) { - Map *self = UNBOX(Map, map_php); - map_begin_internal(self, iter); + zval ret; + MapFieldIter_make(&ret, getThis()); + RETURN_ZVAL(&ret, 0, 1); } -void map_next(MapIter *iter) { - upb_strtable_next(&iter->it); -} +ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2) + ZEND_ARG_INFO(0, key_type) + ZEND_ARG_INFO(0, value_type) + ZEND_ARG_INFO(0, value_class) +ZEND_END_ARG_INFO() -bool map_done(MapIter *iter) { - return upb_strtable_done(&iter->it); -} +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() -const char *map_iter_key(MapIter *iter, int *len) { - *len = upb_strtable_iter_keylength(&iter->it); - return upb_strtable_iter_key(&iter->it); -} +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, newval) +ZEND_END_ARG_INFO() -upb_value map_iter_value(MapIter *iter, int *len) { - *len = native_slot_size(iter->self->value_type); - return upb_strtable_iter_value(&iter->it); -} +ZEND_BEGIN_ARG_INFO(arginfo_void, 0) +ZEND_END_ARG_INFO() -// ----------------------------------------------------------------------------- -// MapFieldIter methods -// ----------------------------------------------------------------------------- -static zend_function_entry map_field_iter_methods[] = { - PHP_ME(MapFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC) - PHP_ME(MapFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC) +static zend_function_entry MapField_methods[] = { + PHP_ME(MapField, __construct, arginfo_construct, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetExists, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetGet, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) + PHP_ME(MapField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC) + PHP_ME(MapField, count, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(MapField, getIterator, arginfo_void, ZEND_ACC_PUBLIC) ZEND_FE_END }; // ----------------------------------------------------------------------------- -// MapFieldIter creation/destruction +// MapFieldIter // ----------------------------------------------------------------------------- -// Define object free method. -PHP_PROTO_OBJECT_EMPTY_FREE_START(MapIter, map_field_iter) -PHP_PROTO_OBJECT_FREE_END - -PHP_PROTO_OBJECT_EMPTY_DTOR_START(MapIter, map_field_iter) -PHP_PROTO_OBJECT_DTOR_END - -// Define object create method. -PHP_PROTO_OBJECT_CREATE_START(MapIter, map_field_iter) -intern->self = NULL; -PHP_PROTO_OBJECT_CREATE_END(MapIter, map_field_iter) - -// Init class entry. -PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\MapFieldIter", - MapIter, map_field_iter) -zend_class_implements(map_field_iter_type TSRMLS_CC, 1, zend_ce_iterator); -PHP_PROTO_INIT_CLASS_END +typedef struct { + zend_object std; + zval map_field; + size_t position; +} MapFieldIter; + +zend_class_entry *MapFieldIter_class_entry; +static zend_object_handlers MapFieldIter_object_handlers; + +/** + * MapFieldIter_create() + * + * PHP class entry function to allocate and initialize a new MapFieldIter + * object. + */ +zend_object* MapFieldIter_create(zend_class_entry *class_type) { + MapFieldIter *intern = emalloc(sizeof(MapFieldIter)); + zend_object_std_init(&intern->std, class_type); + intern->std.handlers = &MapFieldIter_object_handlers; + ZVAL_NULL(&intern->map_field); + intern->position = 0; + // Skip object_properties_init(), we don't allow derived classes. + return &intern->std; +} + +/** + * MapFieldIter_dtor() + * + * Object handler to destroy a MapFieldIter. This releases all resources + * associated with the message. Note that it is possible to access a destroyed + * object from PHP in rare cases. + */ +static void map_field_iter_dtor(zend_object* obj) { + MapFieldIter* intern = (MapFieldIter*)obj; + zval_ptr_dtor(&intern->map_field); + zend_object_std_dtor(&intern->std); +} + +/** + * MapFieldIter_make() + * + * Function to create a MapFieldIter directly from C. + */ +static void MapFieldIter_make(zval *val, zval *map_field) { + MapFieldIter *iter; + ZVAL_OBJ(val, + MapFieldIter_class_entry->create_object(MapFieldIter_class_entry)); + iter = (MapFieldIter*)Z_OBJ_P(val); + ZVAL_COPY(&iter->map_field, map_field); +} // ----------------------------------------------------------------------------- // PHP MapFieldIter Methods // ----------------------------------------------------------------------------- +/* + * When a user writes: + * + * foreach($arr as $key => $val) {} + * + * PHP translates this into: + * + * $iter = $arr->getIterator(); + * for ($iter->rewind(); $iter->valid(); $iter->next()) { + * $key = $iter->key(); + * $val = $iter->current(); + * } + */ + +/** + * MapFieldIter::rewind() + * + * Implements the Iterator interface. Sets the iterator to the first element. + */ PHP_METHOD(MapFieldIter, rewind) { - MapIter *intern = UNBOX(MapIter, getThis()); - map_begin_internal(intern->self, intern); + MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); + MapField *map_field = (MapField*)Z_OBJ_P(&intern->map_field); + intern->position = UPB_MAP_BEGIN; + upb_mapiter_next(map_field->map, &intern->position); } +/** + * MapFieldIter::current() + * + * Implements the Iterator interface. Returns the current value. + */ PHP_METHOD(MapFieldIter, current) { - MapIter *intern = UNBOX(MapIter, getThis()); - Map *map_field = intern->self; - - int value_length = 0; - upb_value value = map_iter_value(intern, &value_length); - - void* mem = upb_value_memory(&value); - native_slot_get_by_map_value(map_field->value_type, mem, - ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); -} - + MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); + MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); + upb_msgval upb_val = upb_mapiter_value(field->map, intern->position); + zval ret; + Convert_UpbToPhp(upb_val, &ret, field->val_type, field->desc, &field->arena); + RETURN_ZVAL(&ret, 0, 1); +} + +/** + * MapFieldIter::key() + * + * Implements the Iterator interface. Returns the current key. + */ PHP_METHOD(MapFieldIter, key) { - MapIter *intern = UNBOX(MapIter, getThis()); - Map *map_field = intern->self; - - int key_length = 0; - const char* key = map_iter_key(intern, &key_length); - - native_slot_get_by_map_key(map_field->key_type, key, key_length, - ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); -} - + MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); + MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); + upb_msgval upb_key = upb_mapiter_key(field->map, intern->position); + zval ret; + Convert_UpbToPhp(upb_key, &ret, field->key_type, NULL, NULL); + RETURN_ZVAL(&ret, 0, 1); +} + +/** + * MapFieldIter::next() + * + * Implements the Iterator interface. Advances to the next element. + */ PHP_METHOD(MapFieldIter, next) { - MapIter *intern = UNBOX(MapIter, getThis()); - map_next(intern); + MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); + MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); + upb_mapiter_next(field->map, &intern->position); } +/** + * MapFieldIter::valid() + * + * Implements the Iterator interface. Returns true if this is a valid element. + */ PHP_METHOD(MapFieldIter, valid) { - MapIter *intern = UNBOX(MapIter, getThis()); - RETURN_BOOL(!map_done(intern)); + MapFieldIter *intern = (MapFieldIter*)Z_OBJ_P(getThis()); + MapField *field = (MapField*)Z_OBJ_P(&intern->map_field); + bool done = upb_mapiter_done(field->map, intern->position); + RETURN_BOOL(!done); +} + +static zend_function_entry map_field_iter_methods[] = { + PHP_ME(MapFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(MapFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +// ----------------------------------------------------------------------------- +// Module init. +// ----------------------------------------------------------------------------- + +/** + * Map_ModuleInit() + * + * Called when the C extension is loaded to register all types. + */ + +void Map_ModuleInit() { + zend_class_entry tmp_ce; + zend_object_handlers *h; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapField", + MapField_methods); + + MapField_class_entry = zend_register_internal_class(&tmp_ce); + zend_class_implements(MapField_class_entry, 3, spl_ce_ArrayAccess, + zend_ce_aggregate, spl_ce_Countable); + MapField_class_entry->ce_flags |= ZEND_ACC_FINAL; + MapField_class_entry->create_object = MapField_create; + + h = &MapField_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + h->dtor_obj = MapField_destructor; + h->compare_objects = MapField_compare_objects; + h->get_properties = Map_GetProperties; + h->get_property_ptr_ptr = Map_GetPropertyPtrPtr; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\MapFieldIter", + map_field_iter_methods); + + MapFieldIter_class_entry = zend_register_internal_class(&tmp_ce); + zend_class_implements(MapFieldIter_class_entry, 1, zend_ce_iterator); + MapFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL; + MapFieldIter_class_entry->ce_flags |= ZEND_ACC_FINAL; + MapFieldIter_class_entry->create_object = MapFieldIter_create; + + h = &MapFieldIter_object_handlers; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + h->dtor_obj = map_field_iter_dtor; } diff --git a/php/ext/google/protobuf/map.h b/php/ext/google/protobuf/map.h new file mode 100644 index 000000000000..6eb0620c2e06 --- /dev/null +++ b/php/ext/google/protobuf/map.h @@ -0,0 +1,63 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#ifndef PHP_PROTOBUF_MAP_H_ +#define PHP_PROTOBUF_MAP_H_ + +#include + +#include "php-upb.h" + +void Map_ModuleInit(); + +// Gets a upb_map* for the PHP object |val|: +// * If |val| is a RepeatedField object, we first check its type and verify +// that that the elements have the correct type for |f|. If so, we return the +// wrapped upb_map*. We also make sure that this map's arena is fused to +// |arena|, so the returned upb_map is guaranteed to live as long as +// |arena|. +// * If |val| is a PHP Map, we attempt to create a new upb_map using +// |arena| and add all of the PHP elements to it. +// +// If an error occurs, we raise a PHP error and return NULL. +upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena); + +// Creates a PHP MapField object for the given upb_map* and |f| and returns it +// in |val|. The PHP object will keep a reference to this |arena| to ensure the +// underlying array data stays alive. +// +// If |map| is NULL, this will return a PHP null object. +void MapField_GetPhpWrapper(zval *val, upb_map *arr, const upb_fielddef *f, + zval *arena); + +bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type, + upb_fieldtype_t val_type, const upb_msgdef *m); + +#endif // PHP_PROTOBUF_MAP_H_ diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index e8d4c6ff1d74..f15b8ac1b466 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -28,1820 +28,1256 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "message.h" + +#include #include -#include #include -#include -#if PHP_MAJOR_VERSION < 7 -#include -#else +// This is not self-contained: it must be after other Zend includes. +#include #include -#endif +#include "arena.h" +#include "array.h" +#include "convert.h" +#include "def.h" +#include "map.h" +#include "php-upb.h" #include "protobuf.h" -#include "utf8.h" - -zend_class_entry* message_type; -zend_object_handlers* message_handlers; -static const char TYPE_URL_PREFIX[] = "type.googleapis.com/"; -static void hex_to_binary(const char* hex, char** binary, int* binary_len); - -static zend_function_entry message_methods[] = { - PHP_ME(Message, clear, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, discardUnknownFields, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, serializeToString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, mergeFromString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, serializeToJsonString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, mergeFromJsonString, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, mergeFrom, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Message, readWrapperValue, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, writeWrapperValue, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, readOneof, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, writeOneof, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, whichOneof, NULL, ZEND_ACC_PROTECTED) - PHP_ME(Message, __construct, NULL, ZEND_ACC_PROTECTED) - {NULL, NULL, NULL} -}; -// Forward declare static functions. +// ----------------------------------------------------------------------------- +// Message +// ----------------------------------------------------------------------------- + +typedef struct { + zend_object std; + zval arena; + const Descriptor* desc; + upb_msg *msg; +} Message; + +zend_class_entry *message_ce; +static zend_object_handlers message_object_handlers; + +// PHP Object Handlers ///////////////////////////////////////////////////////// + +/** + * Message_create() + * + * PHP class entry function to allocate and initialize a new Message object. + */ +static zend_object* Message_create(zend_class_entry *class_type) { + Message *intern = emalloc(sizeof(Message)); + // XXX(haberman): verify whether we actually want to take this route. + class_type->default_properties_count = 0; + zend_object_std_init(&intern->std, class_type); + intern->std.handlers = &message_object_handlers; + Arena_Init(&intern->arena); + return &intern->std; +} + +/** + * Message_dtor() + * + * Object handler to destroy a Message. This releases all resources associated + * with the message. Note that it is possible to access a destroyed object from + * PHP in rare cases. + */ +static void Message_dtor(zend_object* obj) { + Message* intern = (Message*)obj; + ObjCache_Delete(intern->msg); + zval_dtor(&intern->arena); + zend_object_std_dtor(&intern->std); +} + +/** + * get_field() + * + * Helper function to look up a field given a member name (as a string). + */ +static const upb_fielddef *get_field(Message *msg, PROTO_STR *member) { + const upb_msgdef *m = msg->desc->msgdef; + const upb_fielddef *f = + upb_msgdef_ntof(m, PROTO_STRVAL_P(member), PROTO_STRLEN_P(member)); + + if (!f) { + zend_throw_exception_ex(NULL, 0, "No such property %s.", + ZSTR_VAL(msg->desc->class_entry->name)); + } -#if PHP_MAJOR_VERSION < 7 -static void message_set_property(zval* object, zval* member, zval* value, - php_proto_zend_literal key TSRMLS_DC); -static zval* message_get_property(zval* object, zval* member, int type, - const zend_literal* key TSRMLS_DC); -static zval** message_get_property_ptr_ptr(zval* object, zval* member, int type, - php_proto_zend_literal key TSRMLS_DC); -static HashTable* message_get_gc(zval* object, zval*** table, int* n TSRMLS_DC); -#else -#if PHP_VERSION_ID < 70400 -static void message_set_property(zval* object, zval* member, zval* value, - void** cache_slot); -#else -static zval* message_set_property(zval* object, zval* member, zval* value, - void** cache_slot); -#endif -static zval* message_get_property(zval* object, zval* member, int type, - void** cache_slot, zval* rv); -static zval* message_get_property_ptr_ptr(zval* object, zval* member, int type, - void** cache_slot); -static HashTable* message_get_gc(zval* object, zval** table, int* n); -#endif -static HashTable* message_get_properties(zval* object TSRMLS_DC); + return f; +} -// ----------------------------------------------------------------------------- -// PHP Message Handlers -// ----------------------------------------------------------------------------- +static void Message_get(Message *intern, const upb_fielddef *f, zval *rv) { + upb_arena *arena = Arena_Get(&intern->arena); -// Define object free method. -PHP_PROTO_OBJECT_FREE_START(MessageHeader, message) - if (intern->data) { - if (*(void**)intern->data != NULL) { - stringsink_uninit_opaque(*(void**)intern->data); - FREE(*(void**)intern->data); - } - FREE(intern->data); + if (upb_fielddef_ismap(f)) { + upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); + MapField_GetPhpWrapper(rv, msgval.map, f, &intern->arena); + } else if (upb_fielddef_isseq(f)) { + upb_mutmsgval msgval = upb_msg_mutable(intern->msg, f, arena); + RepeatedField_GetPhpWrapper(rv, msgval.array, f, &intern->arena); + } else { + upb_msgval msgval = upb_msg_get(intern->msg, f); + const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); + Convert_UpbToPhp(msgval, rv, upb_fielddef_type(f), subdesc, &intern->arena); } -PHP_PROTO_OBJECT_FREE_END - -PHP_PROTO_OBJECT_EMPTY_DTOR_START(MessageHeader, message) -PHP_PROTO_OBJECT_DTOR_END - -// Define object create method. -PHP_PROTO_OBJECT_CREATE_START(MessageHeader, message) -// Because php call this create func before calling the sub-message's -// constructor defined in PHP, it's possible that the descriptor of this class -// hasn't been added to descriptor pool (when the class is first -// instantiated). In that case, we will defer the initialization of the custom -// data to the parent Message's constructor, which will be called by -// sub-message's constructors after the descriptor has been added. -PHP_PROTO_OBJECT_CREATE_END(MessageHeader, message) - -// Init class entry. -PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\Message", - MessageHeader, message) - message_handlers->write_property = message_set_property; - message_handlers->read_property = message_get_property; - message_handlers->get_property_ptr_ptr = message_get_property_ptr_ptr; - message_handlers->get_properties = message_get_properties; - message_handlers->get_gc = message_get_gc; -PHP_PROTO_INIT_CLASS_END - -static void message_set_property_internal(zval* object, zval* member, - zval* value TSRMLS_DC) { - const upb_fielddef* field; +} - MessageHeader* self = UNBOX(MessageHeader, object); +static bool Message_set(Message *intern, const upb_fielddef *f, zval *val) { + upb_arena *arena = Arena_Get(&intern->arena); + upb_msgval msgval; - field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member)); - if (field == NULL) { - zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(member)); + if (upb_fielddef_ismap(f)) { + msgval.map_val = MapField_GetUpbMap(val, f, arena); + if (!msgval.map_val) return false; + } else if (upb_fielddef_isseq(f)) { + msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); + if (!msgval.array_val) return false; + } else { + upb_fieldtype_t type = upb_fielddef_type(f); + const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); + bool ok = Convert_PhpToUpb(val, &msgval, type, subdesc, arena); + if (!ok) return false; } - layout_set(self->descriptor->layout, self, field, value TSRMLS_CC); + upb_msg_set(intern->msg, f, msgval, arena); + return true; +} + +static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m); + +/** + * ValueEq()() + */ +bool ValueEq(upb_msgval val1, upb_msgval val2, upb_fieldtype_t type, + const upb_msgdef *m) { + switch (type) { + case UPB_TYPE_BOOL: + return val1.bool_val == val2.bool_val; + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_ENUM: + return val1.int32_val == val2.int32_val; + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + return val1.int64_val == val2.int64_val; + case UPB_TYPE_FLOAT: + return val1.float_val == val2.float_val; + case UPB_TYPE_DOUBLE: + return val1.double_val == val2.double_val; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + return val1.str_val.size == val2.str_val.size && + memcmp(val1.str_val.data, val2.str_val.data, val1.str_val.size) == 0; + case UPB_TYPE_MESSAGE: + return MessageEq(val1.msg_val, val2.msg_val, m); + default: + return false; + } } -#if PHP_MAJOR_VERSION < 7 -static void message_set_property(zval* object, zval* member, zval* value, - php_proto_zend_literal key TSRMLS_DC) { -#elif PHP_VERSION_ID < 70400 -static void message_set_property(zval* object, zval* member, zval* value, - void** cache_slot) { -#else -static zval* message_set_property(zval* object, zval* member, zval* value, - void** cache_slot) { -#endif - if (Z_TYPE_P(member) != IS_STRING) { - zend_error(E_USER_ERROR, "Unexpected type for field name"); -#if PHP_VERSION_ID < 70400 +/** + * MessageEq() + */ +static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) { + upb_msg_field_iter i; + + for(upb_msg_field_begin(&i, m); + !upb_msg_field_done(&i); + upb_msg_field_next(&i)) { + const upb_fielddef *f = upb_msg_iter_field(&i); + upb_msgval val1 = upb_msg_get(m1, f); + upb_msgval val2 = upb_msg_get(m2, f); + upb_fieldtype_t type = upb_fielddef_type(f); + const upb_msgdef *sub_m = upb_fielddef_msgsubdef(f); + + if (upb_fielddef_haspresence(f)) { + if (upb_msg_has(m1, f) != upb_msg_has(m2, f)) { + return false; + } + if (!upb_msg_has(m1, f)) continue; + } + + if (upb_fielddef_ismap(f)) { + const upb_fielddef *key_f = upb_msgdef_itof(sub_m, 1); + const upb_fielddef *val_f = upb_msgdef_itof(sub_m, 2); + upb_fieldtype_t key_type = upb_fielddef_type(key_f); + upb_fieldtype_t val_type = upb_fielddef_type(val_f); + const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f); + if (!MapEq(val1.map_val, val2.map_val, key_type, val_type, val_m)) { + return false; + } + } else if (upb_fielddef_isseq(f)) { + if (!ArrayEq(val1.array_val, val2.array_val, type, sub_m)) return false; + } else { + if (!ValueEq(val1, val2, type, sub_m)) return false; + } + } + + return true; +} + +/** + * Message_compare_objects() + * + * Object handler for comparing two message objects. Called whenever PHP code + * does: + * + * $m1 == $m2 + */ +static int Message_compare_objects(zval *m1, zval *m2) { + Message* intern1 = (Message*)Z_OBJ_P(m1); + Message* intern2 = (Message*)Z_OBJ_P(m2); + const upb_msgdef *m = intern1->desc->msgdef; + + if (intern2->desc->msgdef != m) return 1; + + return MessageEq(intern1->msg, intern2->msg, m) ? 0 : 1; +} + +/** + * Message_has_property() + * + * Object handler for testing whether a property exists. Called when PHP code + * does any of: + * + * isset($message->foobar); + * property_exists($message->foobar); + * + * Note that all properties of generated messages are private, so this should + * only be possible to invoke from generated code, which has accessors like this + * (if the field has presence): + * + * public function hasOptionalInt32() + * { + * return isset($this->optional_int32); + * } + */ +static int Message_has_property(PROTO_VAL *obj, PROTO_STR *member, + int has_set_exists, + void **cache_slot) { + Message* intern = PROTO_MSG_P(obj); + const upb_fielddef *f = get_field(intern, member); + + if (!f) return 0; + + if (!upb_fielddef_haspresence(f)) { + zend_throw_exception_ex( + NULL, 0, + "Cannot call isset() on field %s which does not have presence.", + ZSTR_VAL(intern->desc->class_entry->name)); + return 0; + } + + return upb_msg_has(intern->msg, f); +} + +/** + * Message_unset_property() + * + * Object handler for unsetting a property. Called when PHP code calls: + * does any of: + * + * unset($message->foobar); + * + * Note that all properties of generated messages are private, so this should + * only be possible to invoke from generated code, which has accessors like this + * (if the field has presence): + * + * public function clearOptionalInt32() + * { + * unset($this->optional_int32); + * } + */ +static void Message_unset_property(PROTO_VAL *obj, PROTO_STR *member, + void **cache_slot) { + Message* intern = PROTO_MSG_P(obj); + const upb_fielddef *f = get_field(intern, member); + + if (!f) return; + + if (!upb_fielddef_haspresence(f)) { + zend_throw_exception_ex( + NULL, 0, + "Cannot call unset() on field %s which does not have presence.", + ZSTR_VAL(intern->desc->class_entry->name)); return; -#else - return value; -#endif } -#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0) - if (Z_OBJCE_P(object) != EG(scope)) { + upb_msg_clearfield(intern->msg, f); +} + + +/** + * Message_read_property() + * + * Object handler for reading a property in PHP. Called when PHP code does: + * + * $x = $message->foobar; + * + * Note that all properties of generated messages are private, so this should + * only be possible to invoke from generated code, which has accessors like: + * + * public function getOptionalInt32() + * { + * return $this->optional_int32; + * } + * + * We lookup the field and return the scalar, RepeatedField, or MapField for + * this field. + */ +static zval *Message_read_property(PROTO_VAL *obj, PROTO_STR *member, + int type, void **cache_slot, zval *rv) { + Message* intern = PROTO_MSG_P(obj); + const upb_fielddef *f = get_field(intern, member); + + if (!f) return NULL; + Message_get(intern, f, rv); + return rv; +} + +/** + * Message_write_property() + * + * Object handler for writing a property in PHP. Called when PHP code does: + * + * $message->foobar = $x; + * + * Note that all properties of generated messages are private, so this should + * only be possible to invoke from generated code, which has accessors like: + * + * public function setOptionalInt32($var) + * { + * GPBUtil::checkInt32($var); + * $this->optional_int32 = $var; + * + * return $this; + * } + * + * The C extension version of checkInt32() doesn't actually check anything, so + * we perform all checking and conversion in this function. + */ +static PROTO_RETURN_VAL Message_write_property( + PROTO_VAL *obj, PROTO_STR *member, zval *val, void **cache_slot) { + Message* intern = PROTO_MSG_P(obj); + const upb_fielddef *f = get_field(intern, member); + + if (f && Message_set(intern, f, val)) { +#if PHP_VERSION_ID < 70400 + return; #else - if (Z_OBJCE_P(object) != zend_get_executed_scope()) { + return val; #endif - // User cannot set property directly (e.g., $m->a = 1) - zend_error(E_USER_ERROR, "Cannot access private property."); + } else { #if PHP_VERSION_ID < 70400 return; #else - return value; + return &EG(error_zval); #endif } - - message_set_property_internal(object, member, value TSRMLS_CC); -#if PHP_VERSION_ID >= 70400 - return value; -#endif } -static zval* message_get_property_internal(zval* object, - zval* member TSRMLS_DC) { - MessageHeader* self = UNBOX(MessageHeader, object); - const upb_fielddef* field; - field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member)); - if (field == NULL) { - return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL; - } +/** + * Message_get_property_ptr_ptr() + * + * Object handler for the get_property_ptr_ptr event in PHP. This returns a + * reference to our internal properties. We don't support this, so we return + * NULL. + */ +static zval *Message_get_property_ptr_ptr(PROTO_VAL *object, PROTO_STR *member, + int type, + void **cache_slot) { + return NULL; // We do not have a properties table. +} - zend_property_info* property_info; -#if PHP_MAJOR_VERSION < 7 - property_info = - zend_get_property_info(Z_OBJCE_P(object), member, true TSRMLS_CC); -#else - property_info = - zend_get_property_info(Z_OBJCE_P(object), Z_STR_P(member), true); -#endif - return layout_get( - self->descriptor->layout, self, field, - OBJ_PROP(Z_OBJ_P(object), property_info->offset) TSRMLS_CC); +/** + * Message_get_properties() + * + * Object handler for the get_properties event in PHP. This returns a HashTable + * of our internal properties. We don't support this, so we return NULL. + */ +static HashTable *Message_get_properties(PROTO_VAL *object) { + return NULL; // We don't offer direct references to our properties. } -static void message_get_oneof_property_internal(zval* object, zval* member, - zval* return_value TSRMLS_DC) { - MessageHeader* self = UNBOX(MessageHeader, object); - const upb_fielddef* field; - field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member)); - if (field == NULL) { +// C Functions from message.h. ///////////////////////////////////////////////// + +// These are documented in the header file. + +void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg, + zval *arena) { + if (!msg) { + ZVAL_NULL(val); return; } - layout_get(self->descriptor->layout, self, field, - ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); + if (!ObjCache_Get(msg, val)) { + Message *intern = emalloc(sizeof(Message)); + // XXX(haberman): verify whether we actually want to take this route. + desc->class_entry->default_properties_count = 0; + zend_object_std_init(&intern->std, desc->class_entry); + intern->std.handlers = &message_object_handlers; + ZVAL_COPY(&intern->arena, arena); + intern->desc = desc; + intern->msg = msg; + ZVAL_OBJ(val, &intern->std); + ObjCache_Add(intern->msg, &intern->std); + } } -#if PHP_MAJOR_VERSION < 7 -static zval* message_get_property(zval* object, zval* member, int type, - const zend_literal* key TSRMLS_DC) { -#else -static zval* message_get_property(zval* object, zval* member, int type, - void** cache_slot, zval* rv) { -#endif - if (Z_TYPE_P(member) != IS_STRING) { - zend_error(E_USER_ERROR, "Property name has to be a string."); - return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL; +bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena, + upb_msg **msg) { + PBPHP_ASSERT(desc); + + if (Z_ISREF_P(val)) { + ZVAL_DEREF(val); } -#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0) - if (Z_OBJCE_P(object) != EG(scope)) { -#else - if (Z_OBJCE_P(object) != zend_get_executed_scope()) { -#endif - // User cannot get property directly (e.g., $a = $m->a) - zend_error(E_USER_ERROR, "Cannot access private property."); - return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL; + if (Z_TYPE_P(val) == IS_NULL) { + *msg = NULL; + return true; } - return message_get_property_internal(object, member TSRMLS_CC); + if (Z_TYPE_P(val) == IS_OBJECT && + instanceof_function(Z_OBJCE_P(val), desc->class_entry)) { + Message *intern = (Message*)Z_OBJ_P(val); + upb_arena_fuse(arena, Arena_Get(&intern->arena)); + *msg = intern->msg; + return true; + } else { + zend_throw_exception_ex(NULL, 0, "Given value is not an instance of %s.", + ZSTR_VAL(desc->class_entry->name)); + return false; + } } -#if PHP_MAJOR_VERSION < 7 -static zval** message_get_property_ptr_ptr(zval* object, zval* member, int type, - php_proto_zend_literal key - TSRMLS_DC) { -#else -static zval* message_get_property_ptr_ptr(zval* object, zval* member, int type, - void** cache_slot) { -#endif - return NULL; -} +// Message PHP methods ///////////////////////////////////////////////////////// + +/** + * Message_InitFromPhp() + * + * Helper method to handle the initialization of a message from a PHP value, eg. + * + * $m = new TestMessage([ + * 'optional_int32' => -42, + * 'optional_bool' => true, + * 'optional_string' => 'a', + * 'optional_enum' => TestEnum::ONE, + * 'optional_message' => new Sub([ + * 'a' => 33 + * ]), + * 'repeated_int32' => [-42, -52], + * 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], + * 'repeated_message' => [new Sub(['a' => 34]), + * new Sub(['a' => 35])], + * 'map_int32_int32' => [-62 => -62], + * 'map_int32_enum' => [1 => TestEnum::ONE], + * 'map_int32_message' => [1 => new Sub(['a' => 36])], + * ]); + * + * The initializer must be an array. + */ +bool Message_InitFromPhp(upb_msg *msg, const upb_msgdef *m, zval *init, + upb_arena *arena) { + HashTable* table = HASH_OF(init); + HashPosition pos; + + if (Z_ISREF_P(init)) { + ZVAL_DEREF(init); + } -static HashTable* message_get_properties(zval* object TSRMLS_DC) { - return NULL; -} + if (Z_TYPE_P(init) != IS_ARRAY) { + zend_throw_exception_ex(NULL, 0, + "Initializer for a message %s must be an array.", + upb_msgdef_fullname(m)); + return false; + } -static HashTable* message_get_gc(zval* object, CACHED_VALUE** table, - int* n TSRMLS_DC) { - zend_object* zobj = Z_OBJ_P(object); - *table = zobj->properties_table; - *n = zobj->ce->default_properties_count; - return NULL; -} + zend_hash_internal_pointer_reset_ex(table, &pos); -// ----------------------------------------------------------------------------- -// C Message Utilities -// ----------------------------------------------------------------------------- + while (true) { // Iterate over key/value pairs. + zval key; + zval *val; + const upb_fielddef *f; + upb_msgval msgval; + + zend_hash_get_current_key_zval_ex(table, &key, &pos); + val = zend_hash_get_current_data_ex(table, &pos); + + if (!val) return true; // Finished iteration. + + if (Z_ISREF_P(val)) { + ZVAL_DEREF(val); + } + + f = upb_msgdef_ntof(m, Z_STRVAL_P(&key), Z_STRLEN_P(&key)); + + if (!f) { + zend_throw_exception_ex(NULL, 0, + "No such field %s", Z_STRVAL_P(&key)); + return false; + } + + if (upb_fielddef_ismap(f)) { + msgval.map_val = MapField_GetUpbMap(val, f, arena); + if (!msgval.map_val) return false; + } else if (upb_fielddef_isseq(f)) { + msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); + if (!msgval.array_val) return false; + } else { + const Descriptor *desc = Descriptor_GetFromFieldDef(f); + upb_fieldtype_t type = upb_fielddef_type(f); + if (!Convert_PhpToUpbAutoWrap(val, &msgval, type, desc, arena)) { + return false; + } + } -void* message_data(MessageHeader* msg) { - return msg->data; + upb_msg_set(msg, f, msgval, arena); + zend_hash_move_forward_ex(table, &pos); + zval_dtor(&key); + } } -void custom_data_init(const zend_class_entry* ce, - MessageHeader* intern PHP_PROTO_TSRMLS_DC) { - DescriptorInternal* desc = get_ce_desc(ce); - intern->data = ALLOC_N(uint8_t, desc->layout->size); - // We wrap first so that everything in the message object is GC-rooted in - // case a collection happens during object creation in layout_init(). - intern->descriptor = desc; - layout_init(desc->layout, message_data(intern), - &intern->std PHP_PROTO_TSRMLS_CC); +static void Message_Initialize(Message *intern, const Descriptor *desc) { + intern->desc = desc; + intern->msg = upb_msg_new(desc->msgdef, Arena_Get(&intern->arena)); + ObjCache_Add(intern->msg, &intern->std); } -#define INIT_MESSAGE_WITH_ARRAY \ - { \ - zval* array_wrapper = NULL; \ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \ - "|a!", &array_wrapper) == FAILURE) { \ - return; \ - } \ - Message_construct(getThis(), array_wrapper); \ - } +/** + * Message::__construct() + * + * Constructor for Message. + * @param array Map of initial values ['k' = val] + */ +PHP_METHOD(Message, __construct) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const Descriptor* desc = Descriptor_GetFromClassEntry(Z_OBJCE_P(getThis())); + upb_arena *arena = Arena_Get(&intern->arena); + zval *init_arr = NULL; -// ----------------------------------------------------------------------------- -// PHP Methods -// ----------------------------------------------------------------------------- + Message_Initialize(intern, desc); -static void append_wrapper_message( - zend_class_entry* subklass, RepeatedField* intern, zval* value TSRMLS_DC) { - MessageHeader* submsg; - const upb_fielddef* field; -#if PHP_MAJOR_VERSION < 7 - zval* val = NULL; - MAKE_STD_ZVAL(val); - ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC)); - repeated_field_push_native(intern, &val); - submsg = UNBOX(MessageHeader, val); -#else - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - repeated_field_push_native(intern, &obj); - submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std)); -#endif - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|a!", &init_arr) == FAILURE) { + return; + } - field = upb_msgdef_itof(submsg->descriptor->msgdef, 1); - layout_set(submsg->descriptor->layout, submsg, field, value TSRMLS_CC); + if (init_arr) { + Message_InitFromPhp(intern->msg, desc->msgdef, init_arr, arena); + } } -static void set_wrapper_message_as_map_value( - zend_class_entry* subklass, zval* map, zval* key, zval* value TSRMLS_DC) { - MessageHeader* submsg; - const upb_fielddef* field; -#if PHP_MAJOR_VERSION < 7 - zval* val = NULL; - MAKE_STD_ZVAL(val); - ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC)); - map_field_handlers->write_dimension( - map, key, val TSRMLS_CC); - submsg = UNBOX(MessageHeader, val); -#else - zval val; - zend_object* obj = subklass->create_object(subklass TSRMLS_CC); - ZVAL_OBJ(&val, obj); - map_field_handlers->write_dimension(map, key, &val TSRMLS_CC); - submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std)); -#endif - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); +/** + * Message::discardUnknownFields() + * + * Discards any unknown fields for this message or any submessages. + */ +PHP_METHOD(Message, discardUnknownFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_msg_discardunknown(intern->msg, intern->desc->msgdef, 64); +} - field = upb_msgdef_itof(submsg->descriptor->msgdef, 1); - layout_set(submsg->descriptor->layout, submsg, field, value TSRMLS_CC); +/** + * Message::clear() + * + * Clears all fields of this message. + */ +PHP_METHOD(Message, clear) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_msg_clear(intern->msg, intern->desc->msgdef); } -void Message_construct(zval* msg, zval* array_wrapper) { - TSRMLS_FETCH(); - zend_class_entry* ce = Z_OBJCE_P(msg); - MessageHeader* intern = NULL; +/** + * Message::mergeFrom() + * + * Merges from the given message, which must be of the same class as us. + * @param object Message to merge from. + */ +PHP_METHOD(Message, mergeFrom) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + Message* from; + upb_arena *arena = Arena_Get(&intern->arena); + const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef); + zval* value; + char *pb; + size_t size; + bool ok; - if (!class_added(ce)) { -#if PHP_MAJOR_VERSION < 7 - DescriptorInternal* desc = get_class_desc(ce->name); -#else - DescriptorInternal* desc = get_class_desc(ZSTR_VAL(ce->name)); -#endif - register_class(desc, false TSRMLS_CC); + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &value, + intern->desc->class_entry) == FAILURE) { + return; } - intern = UNBOX(MessageHeader, msg); - custom_data_init(ce, intern PHP_PROTO_TSRMLS_CC); + from = (Message*)Z_OBJ_P(value); + + // Should be guaranteed since we passed the class type to + // zend_parse_parameters(). + PBPHP_ASSERT(from->desc == intern->desc); - if (array_wrapper == NULL) { + // TODO(haberman): use a temp arena for this once we can make upb_decode() + // copy strings. + pb = upb_encode(from->msg, l, arena, &size); + + if (!pb) { + zend_throw_exception_ex(NULL, 0, "Max nesting exceeded"); return; } - HashTable* array = Z_ARRVAL_P(array_wrapper); - HashPosition pointer; - zval key; - void* value; - const upb_fielddef* field; - - for (zend_hash_internal_pointer_reset_ex(array, &pointer); - php_proto_zend_hash_get_current_data_ex(array, (void**)&value, - &pointer) == SUCCESS; - zend_hash_move_forward_ex(array, &pointer)) { - zend_hash_get_current_key_zval_ex(array, &key, &pointer); - field = upb_msgdef_ntofz(intern->descriptor->msgdef, Z_STRVAL_P(&key)); -#if PHP_MAJOR_VERSION >= 7 - if (Z_ISREF_P((CACHED_VALUE*)value)) { - value = Z_REFVAL_P((CACHED_VALUE*)value); - } -#endif - if (field == NULL) { - zend_error(E_USER_ERROR, "Unknown field: %s", Z_STRVAL_P(&key)); - } - if (upb_fielddef_ismap(field)) { - PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg)); - zval* submap = message_get_property_internal(msg, &key TSRMLS_CC); - PHP_PROTO_FAKE_SCOPE_END; - HashTable* subtable = HASH_OF( - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)); - HashPosition subpointer; - zval subkey; - void* memory; - bool is_wrapper = false; - zend_class_entry* subklass = NULL; - const upb_msgdef* mapentry = upb_fielddef_msgsubdef(field); - const upb_fielddef *value_field = upb_msgdef_itof(mapentry, 2); - - if (upb_fielddef_issubmsg(value_field)) { - const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(value_field); - is_wrapper = is_wrapper_msg(submsgdef); - - if (is_wrapper) { - DescriptorInternal* subdesc = get_msgdef_desc(submsgdef); - register_class(subdesc, false TSRMLS_CC); - subklass = subdesc->klass; - } - } + ok = upb_decode(pb, size, intern->msg, l, arena); + PBPHP_ASSERT(ok); +} + +/** + * Message::mergeFromString() + * + * Merges from the given string. + * @param string Binary protobuf data to merge. + */ +PHP_METHOD(Message, mergeFromString) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + char *data = NULL; + char *data_copy = NULL; + zend_long data_len; + const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef); + upb_arena *arena = Arena_Get(&intern->arena); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &data, &data_len) == + FAILURE) { + return; + } - for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer); - php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory, - &subpointer) == SUCCESS; - zend_hash_move_forward_ex(subtable, &subpointer)) { - zend_hash_get_current_key_zval_ex(subtable, &subkey, &subpointer); - if (is_wrapper && - Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory)) != IS_OBJECT) { - set_wrapper_message_as_map_value( - subklass, submap, &subkey, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); - } else { - map_field_handlers->write_dimension( - submap, &subkey, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); - } - zval_dtor(&subkey); - } - } else if (upb_fielddef_isseq(field)) { - PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg)); - zval* subarray = message_get_property_internal(msg, &key TSRMLS_CC); - PHP_PROTO_FAKE_SCOPE_END; - HashTable* subtable = HASH_OF( - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)); - HashPosition subpointer; - void* memory; - bool is_wrapper = false; - zend_class_entry* subklass = NULL; - - if (upb_fielddef_issubmsg(field)) { - const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field); - is_wrapper = is_wrapper_msg(submsgdef); - - if (is_wrapper) { - DescriptorInternal* subdesc = get_msgdef_desc(submsgdef); - register_class(subdesc, false TSRMLS_CC); - subklass = subdesc->klass; - } - } + // TODO(haberman): avoid this copy when we can make the decoder copy. + data_copy = upb_arena_malloc(arena, data_len); + memcpy(data_copy, data, data_len); - for (zend_hash_internal_pointer_reset_ex(subtable, &subpointer); - php_proto_zend_hash_get_current_data_ex(subtable, (void**)&memory, - &subpointer) == SUCCESS; - zend_hash_move_forward_ex(subtable, &subpointer)) { - if (is_wrapper && - Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory)) != IS_OBJECT) { - RepeatedField* intern = UNBOX(RepeatedField, subarray); - append_wrapper_message( - subklass, intern, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); - } else { - repeated_field_handlers->write_dimension( - subarray, NULL, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); - } - } - } else if (upb_fielddef_issubmsg(field)) { - const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field); - DescriptorInternal* desc = get_msgdef_desc(submsgdef); - register_class(desc, false TSRMLS_CC); - - CACHED_VALUE* cached = NULL; - if (upb_fielddef_containingoneof(field)) { - void* memory = slot_memory(intern->descriptor->layout, - message_data(intern), field); - uint32_t* oneof_case = slot_oneof_case(intern->descriptor->layout, - message_data(intern), field); - int property_cache_index = - intern->descriptor->layout->fields[upb_fielddef_index(field)] - .cache_index; - cached = OBJ_PROP(Z_OBJ_P(msg), property_cache_index); - *(CACHED_VALUE**)(memory) = cached; - *oneof_case = upb_fielddef_number(field); - } else { - zend_property_info* property_info; - PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg)); -#if PHP_MAJOR_VERSION < 7 - property_info = - zend_get_property_info(Z_OBJCE_P(msg), &key, true TSRMLS_CC); -#else - property_info = - zend_get_property_info(Z_OBJCE_P(msg), Z_STR_P(&key), true); -#endif - PHP_PROTO_FAKE_SCOPE_END; - cached = OBJ_PROP(Z_OBJ_P(msg), property_info->offset); - } -#if PHP_MAJOR_VERSION < 7 - SEPARATE_ZVAL_IF_NOT_REF(cached); -#endif - zval* submsg = CACHED_PTR_TO_ZVAL_PTR(cached); - ZVAL_OBJ(submsg, desc->klass->create_object(desc->klass TSRMLS_CC)); - Message_construct(submsg, NULL); - MessageHeader* to = UNBOX(MessageHeader, submsg); - const upb_filedef *file = upb_msgdef_file(submsgdef); - if (!strcmp(upb_filedef_name(file), "google/protobuf/wrappers.proto") && - Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)) != IS_OBJECT) { - const upb_fielddef *value_field = upb_msgdef_itof(submsgdef, 1); - layout_set(to->descriptor->layout, to, - value_field, CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value) - TSRMLS_CC); - } else { - MessageHeader* from = - UNBOX(MessageHeader, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)); - if(from->descriptor != to->descriptor) { - zend_error(E_USER_ERROR, - "Cannot merge messages with different class."); - return; - } - - layout_merge(from->descriptor->layout, from, to TSRMLS_CC); - } - } else { - message_set_property_internal(msg, &key, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value) TSRMLS_CC); - } - zval_dtor(&key); + if (!upb_decode(data_copy, data_len, intern->msg, l, arena)) { + zend_throw_exception_ex(NULL, 0, "Error occurred during parsing"); + return; } } -// At the first time the message is created, the class entry hasn't been -// modified. As a result, the first created instance will be a normal zend -// object. Here, we manually modify it to our message in such a case. -PHP_METHOD(Message, __construct) { - INIT_MESSAGE_WITH_ARRAY; -} +/** + * Message::serializeToString() + * + * Serializes this message instance to protobuf data. + * @return string Serialized protobuf data. + */ +PHP_METHOD(Message, serializeToString) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_msglayout *l = upb_msgdef_layout(intern->desc->msgdef); + upb_arena *tmp_arena = upb_arena_new(); + char *data; + size_t size; + + data = upb_encode(intern->msg, l, tmp_arena, &size); + + if (!data) { + zend_throw_exception_ex(NULL, 0, "Error occurred during serialization"); + upb_arena_free(tmp_arena); + return; + } -PHP_METHOD(Message, clear) { - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - DescriptorInternal* desc = msg->descriptor; - register_class(desc, false TSRMLS_CC); - zend_class_entry* ce = desc->klass; + RETVAL_STRINGL(data, size); + upb_arena_free(tmp_arena); +} + +/** + * Message::mergeFromJsonString() + * + * Merges the JSON data parsed from the given string. + * @param string Serialized JSON data. + */ +PHP_METHOD(Message, mergeFromJsonString) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + char *data = NULL; + char *data_copy = NULL; + zend_long data_len; + upb_arena *arena = Arena_Get(&intern->arena); + upb_status status; + zend_bool ignore_json_unknown = false; + int options = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &data, &data_len, + &ignore_json_unknown) == FAILURE) { + return; + } + + // TODO(haberman): avoid this copy when we can make the decoder copy. + data_copy = upb_arena_malloc(arena, data_len + 1); + memcpy(data_copy, data, data_len); + data_copy[data_len] = '\0'; - zend_object_std_dtor(&msg->std TSRMLS_CC); - object_properties_init(&msg->std, ce); + if (ignore_json_unknown) { + options |= UPB_JSONDEC_IGNOREUNKNOWN; + } - layout_init(desc->layout, message_data(msg), &msg->std TSRMLS_CC); + upb_status_clear(&status); + if (!upb_json_decode(data_copy, data_len, intern->msg, intern->desc->msgdef, + DescriptorPool_GetSymbolTable(), options, arena, + &status)) { + zend_throw_exception_ex(NULL, 0, "Error occurred during parsing: %s", + upb_status_errmsg(&status)); + return; + } } -PHP_METHOD(Message, mergeFrom) { - zval* value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &value, - message_type) == FAILURE) { +/** + * Message::serializeToJsonString() + * + * Serializes this object to JSON. + * @return string Serialized JSON data. + */ +PHP_METHOD(Message, serializeToJsonString) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + size_t size; + int options = 0; + char buf[1024]; + zend_bool preserve_proto_fieldnames = false; + upb_status status; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", + &preserve_proto_fieldnames) == FAILURE) { return; } - MessageHeader* from = UNBOX(MessageHeader, value); - MessageHeader* to = UNBOX(MessageHeader, getThis()); + if (preserve_proto_fieldnames) { + options |= UPB_JSONENC_PROTONAMES; + } + + upb_status_clear(&status); + size = upb_json_encode(intern->msg, intern->desc->msgdef, + DescriptorPool_GetSymbolTable(), options, buf, + sizeof(buf), &status); - if(from->descriptor != to->descriptor) { - zend_error(E_USER_ERROR, "Cannot merge messages with different class."); + if (!upb_ok(&status)) { + zend_throw_exception_ex(NULL, 0, + "Error occurred during JSON serialization: %s", + upb_status_errmsg(&status)); return; } - layout_merge(from->descriptor->layout, from, to TSRMLS_CC); + if (size >= sizeof(buf)) { + char *buf2 = malloc(size + 1); + upb_json_encode(intern->msg, intern->desc->msgdef, + DescriptorPool_GetSymbolTable(), options, buf2, size + 1, + &status); + RETVAL_STRINGL(buf2, size); + free(buf2); + } else { + RETVAL_STRINGL(buf, size); + } } +/** + * Message::readWrapperValue() + * + * Returns an unboxed value for the given field. This is called from generated + * methods for wrapper fields, eg. + * + * public function getDoubleValueUnwrapped() + * { + * return $this->readWrapperValue("double_value"); + * } + * + * @return Unwrapped field value or null. + */ PHP_METHOD(Message, readWrapperValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); char* member; - PHP_PROTO_SIZE length; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &member, - &length) == FAILURE) { - return; - } - - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - const upb_fielddef* field = - upb_msgdef_ntofz(msg->descriptor->msgdef, member); + const upb_fielddef *f; + zend_long size; - if (upb_fielddef_containingoneof(field)) { - uint32_t* oneof_case = - slot_oneof_case(msg->descriptor->layout, message_data(msg), field); - if (*oneof_case != upb_fielddef_number(field)) { - RETURN_NULL(); - } + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &member, &size) == FAILURE) { + return; } - zval* cached_zval = - CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, field)); + f = upb_msgdef_ntof(intern->desc->msgdef, member, size); - if (Z_TYPE_P(cached_zval) == IS_NULL) { - RETURN_NULL(); + if (!f || !upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f))) { + zend_throw_exception_ex(NULL, 0, "Message %s has no field %s", + upb_msgdef_fullname(intern->desc->msgdef), member); + return; } - if (Z_TYPE_P(cached_zval) == IS_OBJECT) { - const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field); - const upb_fielddef* value_field = upb_msgdef_itof(submsgdef, 1); - MessageHeader* submsg = UNBOX(MessageHeader, cached_zval); - CACHED_VALUE* cached_value = find_zval_property(submsg, value_field); - layout_get(submsg->descriptor->layout, submsg, value_field, - cached_value TSRMLS_CC); - RETURN_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cached_value), 1, 0); + if (upb_msg_has(intern->msg, f)) { + const upb_msg *wrapper = upb_msg_get(intern->msg, f).msg_val; + const upb_msgdef *m = upb_fielddef_msgsubdef(f); + const upb_fielddef *val_f = upb_msgdef_itof(m, 1); + const upb_fieldtype_t val_type = upb_fielddef_type(val_f); + upb_msgval msgval = upb_msg_get(wrapper, val_f); + zval ret; + Convert_UpbToPhp(msgval, &ret, val_type, NULL, &intern->arena); + RETURN_ZVAL(&ret, 1, 0); } else { - RETURN_ZVAL(cached_zval, 1, 0); + RETURN_NULL(); } } +/** + * Message::writeWrapperValue() + * + * Sets the given wrapper field to the given unboxed value. This is called from + * generated methods for wrapper fields, eg. + * + * + * public function setDoubleValueUnwrapped($var) + * { + * $this->writeWrapperValue("double_value", $var); + * return $this; + * } + * + * @param Unwrapped field value or null. + */ PHP_METHOD(Message, writeWrapperValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); char* member; - PHP_PROTO_SIZE length; - zval* value; - if (zend_parse_parameters( - ZEND_NUM_ARGS() TSRMLS_CC, "sz", &member, &length, &value) == + const upb_fielddef *f; + upb_msgval msgval; + zend_long size; + zval* val; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &member, &size, &val) == FAILURE) { return; } - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - const upb_fielddef* field = upb_msgdef_ntofz(msg->descriptor->msgdef, member); + f = upb_msgdef_ntof(intern->desc->msgdef, member, size); - zval* cached_zval = - CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, field)); - - if (Z_TYPE_P(value) == IS_NULL) { - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - layout_set(msg->descriptor->layout, msg, - field, value TSRMLS_CC); + if (!f || !upb_msgdef_iswrapper(upb_fielddef_msgsubdef(f))) { + zend_throw_exception_ex(NULL, 0, "Message %s has no field %s", + upb_msgdef_fullname(intern->desc->msgdef), member); return; } - { - // Type Checking - const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field); - const upb_fielddef* value_field = upb_msgdef_itof(submsgdef, 1); - upb_fieldtype_t type = upb_fielddef_type(value_field); - switch(type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - if (!protobuf_convert_to_string(value)) { - return; - } - if (type == UPB_TYPE_STRING && - !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) { - zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); - return; - } - } - break; -#define CASE_TYPE(upb_type, type, c_type) \ - case UPB_TYPE_##upb_type: { \ - c_type type##_value; \ - if (!protobuf_convert_to_##type(value, &type##_value)) { \ - return; \ - } \ - break; \ - } - CASE_TYPE(INT32, int32, int32_t) - CASE_TYPE(UINT32, uint32, uint32_t) - CASE_TYPE(ENUM, int32, int32_t) - CASE_TYPE(INT64, int64, int64_t) - CASE_TYPE(UINT64, uint64, uint64_t) - CASE_TYPE(FLOAT, float, float) - CASE_TYPE(DOUBLE, double, double) - CASE_TYPE(BOOL, bool, int8_t) - -#undef CASE_TYPE - case UPB_TYPE_MESSAGE: - zend_error(E_ERROR, "No wrapper for message."); - break; - } + if (Z_ISREF_P(val)) { + ZVAL_DEREF(val); } - if (upb_fielddef_containingoneof(field)) { - uint32_t* oneof_case = - slot_oneof_case(msg->descriptor->layout, message_data(msg), field); - if (*oneof_case != upb_fielddef_number(field)) { - zval null_value; - ZVAL_NULL(&null_value); - layout_set(msg->descriptor->layout, msg, field, &null_value TSRMLS_CC); - cached_zval = CACHED_PTR_TO_ZVAL_PTR(find_zval_property(msg, field)); - ZVAL_ZVAL(cached_zval, value, 1, 0); - return; + if (Z_TYPE_P(val) == IS_NULL) { + upb_msg_clearfield(intern->msg, f); + } else { + const upb_msgdef *m = upb_fielddef_msgsubdef(f); + const upb_fielddef *val_f = upb_msgdef_itof(m, 1); + upb_fieldtype_t val_type = upb_fielddef_type(val_f); + upb_msg *wrapper; + + if (!Convert_PhpToUpb(val, &msgval, val_type, NULL, arena)) { + return; // Error is already set. } - } - if (Z_TYPE_P(cached_zval) == IS_OBJECT) { - const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field); - const upb_fielddef* value_field = upb_msgdef_itof(submsgdef, 1); - MessageHeader* submsg = UNBOX(MessageHeader, cached_zval); - layout_set(submsg->descriptor->layout, submsg, - value_field, value TSRMLS_CC); - } else { - ZVAL_ZVAL(cached_zval, value, 1, 0); + wrapper = upb_msg_mutable(intern->msg, f, arena).msg; + upb_msg_set(wrapper, val_f, msgval, arena); } } -PHP_METHOD(Message, readOneof) { - PHP_PROTO_LONG index; +/** + * Message::whichOneof() + * + * Given a oneof name, returns the name of the field that is set for this oneof, + * or otherwise the empty string. + * + * @return string The field name in this oneof that is currently set. + */ +PHP_METHOD(Message, whichOneof) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_oneofdef* oneof; + const upb_fielddef* field; + char* name; + zend_long len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &len) == FAILURE) { return; } - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - - const upb_fielddef* field = upb_msgdef_itof(msg->descriptor->msgdef, index); - - // Unlike singular fields, oneof fields share cached property. So we cannot - // let layout_get modify the cached property. Instead, we pass in the return - // value directly. - layout_get(msg->descriptor->layout, msg, field, - ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); -} + oneof = upb_msgdef_ntoo(intern->desc->msgdef, name, len); -PHP_METHOD(Message, writeOneof) { - PHP_PROTO_LONG index; - zval* value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &index, &value) == - FAILURE) { + if (!oneof) { + zend_throw_exception_ex(NULL, 0, "Message %s has no oneof %s", + upb_msgdef_fullname(intern->desc->msgdef), name); return; } - MessageHeader* msg = UNBOX(MessageHeader, getThis()); + field = upb_msg_whichoneof(intern->msg, oneof); + RETURN_STRING(field ? upb_fielddef_name(field) : ""); +} + +/** + * Message::hasOneof() + * + * Returns the presence of the given oneof field, given a field number. Called + * from generated code methods such as: + * + * public function hasDoubleValueOneof() + * { + * return $this->hasOneof(10); + * } + * + * @return boolean + */ +PHP_METHOD(Message, hasOneof) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + zend_long field_num; + const upb_fielddef* f; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &field_num) == FAILURE) { + return; + } - const upb_fielddef* field = upb_msgdef_itof(msg->descriptor->msgdef, index); + f = upb_msgdef_itof(intern->desc->msgdef, field_num); - layout_set(msg->descriptor->layout, msg, field, value TSRMLS_CC); -} + if (!f || !upb_fielddef_realcontainingoneof(f)) { + php_error_docref(NULL, E_USER_ERROR, + "Internal error, no such oneof field %d\n", + (int)field_num); + } -PHP_METHOD(Message, whichOneof) { - char* oneof_name; - PHP_PROTO_SIZE length; + RETVAL_BOOL(upb_msg_has(intern->msg, f)); +} + +/** + * Message::readOneof() + * + * Returns the contents of the given oneof field, given a field number. Called + * from generated code methods such as: + * + * public function getDoubleValueOneof() + * { + * return $this->readOneof(10); + * } + * + * @return object The oneof's field value. + */ +PHP_METHOD(Message, readOneof) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + zend_long field_num; + const upb_fielddef* f; + zval ret; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &oneof_name, - &length) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &field_num) == FAILURE) { return; } - MessageHeader* msg = UNBOX(MessageHeader, getThis()); - - const upb_oneofdef* oneof = - upb_msgdef_ntoo(msg->descriptor->msgdef, oneof_name, length); - const char* oneof_case_name = layout_get_oneof_case( - msg->descriptor->layout, message_data(msg), oneof TSRMLS_CC); - PHP_PROTO_RETURN_STRING(oneof_case_name, 1); -} - -// ----------------------------------------------------------------------------- -// Well Known Types Support -// ----------------------------------------------------------------------------- + f = upb_msgdef_itof(intern->desc->msgdef, field_num); -#define PHP_PROTO_FIELD_ACCESSORS(UPPER_CLASS, LOWER_CLASS, UPPER_FIELD, \ - LOWER_FIELD) \ - PHP_METHOD(UPPER_CLASS, get##UPPER_FIELD) { \ - zval member; \ - PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \ - PHP_PROTO_FAKE_SCOPE_BEGIN(LOWER_CLASS##_type); \ - zval* value = message_get_property_internal(getThis(), &member TSRMLS_CC); \ - PHP_PROTO_FAKE_SCOPE_END; \ - zval_dtor(&member); \ - PHP_PROTO_RETVAL_ZVAL(value); \ - } \ - PHP_METHOD(UPPER_CLASS, set##UPPER_FIELD) { \ - zval* value = NULL; \ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == \ - FAILURE) { \ - return; \ - } \ - zval member; \ - PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \ - message_set_property_internal(getThis(), &member, value TSRMLS_CC); \ - zval_dtor(&member); \ - PHP_PROTO_RETVAL_ZVAL(getThis()); \ + if (!f || !upb_fielddef_realcontainingoneof(f)) { + php_error_docref(NULL, E_USER_ERROR, + "Internal error, no such oneof field %d\n", + (int)field_num); } -#define PHP_PROTO_ONEOF_FIELD_ACCESSORS(UPPER_CLASS, LOWER_CLASS, UPPER_FIELD, \ - LOWER_FIELD) \ - PHP_METHOD(UPPER_CLASS, get##UPPER_FIELD) { \ - zval member; \ - PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \ - PHP_PROTO_FAKE_SCOPE_BEGIN(LOWER_CLASS##_type); \ - message_get_oneof_property_internal(getThis(), &member, \ - return_value TSRMLS_CC); \ - PHP_PROTO_FAKE_SCOPE_END; \ - zval_dtor(&member); \ - } \ - PHP_METHOD(UPPER_CLASS, set##UPPER_FIELD) { \ - zval* value = NULL; \ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == \ - FAILURE) { \ - return; \ - } \ - zval member; \ - PHP_PROTO_ZVAL_STRING(&member, LOWER_FIELD, 1); \ - message_set_property_internal(getThis(), &member, value TSRMLS_CC); \ - zval_dtor(&member); \ - PHP_PROTO_RETVAL_ZVAL(getThis()); \ + { + upb_msgval msgval = upb_msg_get(intern->msg, f); + const Descriptor *subdesc = Descriptor_GetFromFieldDef(f); + Convert_UpbToPhp(msgval, &ret, upb_fielddef_type(f), subdesc, + &intern->arena); } -#define PHP_PROTO_ONEOF_ACCESSORS(UPPER_CLASS, LOWER_CLASS, UPPER_FIELD, \ - LOWER_FIELD) \ - PHP_METHOD(UPPER_CLASS, get##UPPER_FIELD) { \ - MessageHeader* msg = UNBOX(MessageHeader, getThis()); \ - PHP_PROTO_FAKE_SCOPE_BEGIN(LOWER_CLASS##_type); \ - const upb_oneofdef* oneof = upb_msgdef_ntoo( \ - msg->descriptor->msgdef, LOWER_FIELD, strlen(LOWER_FIELD)); \ - const char* oneof_case_name = layout_get_oneof_case( \ - msg->descriptor->layout, message_data(msg), oneof TSRMLS_CC); \ - PHP_PROTO_FAKE_SCOPE_END; \ - PHP_PROTO_RETURN_STRING(oneof_case_name, 1); \ + RETURN_ZVAL(&ret, 1, 0); +} + +/** + * Message::writeOneof() + * + * Sets the contents of the given oneof field, given a field number. Called + * from generated code methods such as: + * + * public function setDoubleValueOneof($var) + * { + * GPBUtil::checkMessage($var, \Google\Protobuf\DoubleValue::class); + * $this->writeOneof(10, $var); + * + * return $this; + * } + * + * The C extension version of GPBUtil::check*() does nothing, so we perform + * all type checking and conversion here. + * + * @param integer The field number we are setting. + * @param object The field value we want to set. + */ +PHP_METHOD(Message, writeOneof) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + zend_long field_num; + const upb_fielddef* f; + upb_arena *arena = Arena_Get(&intern->arena); + upb_msgval msgval; + zval* val; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz", &field_num, &val) == + FAILURE) { + return; } -// Forward declare file init functions -static void init_file_any(TSRMLS_D); -static void init_file_api(TSRMLS_D); -static void init_file_duration(TSRMLS_D); -static void init_file_field_mask(TSRMLS_D); -static void init_file_empty(TSRMLS_D); -static void init_file_source_context(TSRMLS_D); -static void init_file_struct(TSRMLS_D); -static void init_file_timestamp(TSRMLS_D); -static void init_file_type(TSRMLS_D); -static void init_file_wrappers(TSRMLS_D); - -// Define file init functions -static void init_file_any(TSRMLS_D) { - if (is_inited_file_any) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0acd010a19676f6f676c652f70726f746f6275662f616e792e70726f746f" - "120f676f6f676c652e70726f746f62756622260a03416e7912100a087479" - "70655f75726c180120012809120d0a0576616c756518022001280c426f0a" - "13636f6d2e676f6f676c652e70726f746f6275664208416e7950726f746f" - "50015a256769746875622e636f6d2f676f6c616e672f70726f746f627566" - "2f7074797065732f616e79a20203475042aa021e476f6f676c652e50726f" - "746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_any = true; -} + f = upb_msgdef_itof(intern->desc->msgdef, field_num); -static void init_file_api(TSRMLS_D) { - if (is_inited_file_api) return; - init_file_source_context(TSRMLS_C); - init_file_type(TSRMLS_C); - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0aee050a19676f6f676c652f70726f746f6275662f6170692e70726f746f" - "120f676f6f676c652e70726f746f6275661a24676f6f676c652f70726f74" - "6f6275662f736f757263655f636f6e746578742e70726f746f1a1a676f6f" - "676c652f70726f746f6275662f747970652e70726f746f2281020a034170" - "69120c0a046e616d6518012001280912280a076d6574686f647318022003" - "280b32172e676f6f676c652e70726f746f6275662e4d6574686f6412280a" - "076f7074696f6e7318032003280b32172e676f6f676c652e70726f746f62" - "75662e4f7074696f6e120f0a0776657273696f6e18042001280912360a0e" - "736f757263655f636f6e7465787418052001280b321e2e676f6f676c652e" - "70726f746f6275662e536f75726365436f6e7465787412260a066d697869" - "6e7318062003280b32162e676f6f676c652e70726f746f6275662e4d6978" - "696e12270a0673796e74617818072001280e32172e676f6f676c652e7072" - "6f746f6275662e53796e74617822d5010a064d6574686f64120c0a046e61" - "6d6518012001280912180a10726571756573745f747970655f75726c1802" - "2001280912190a11726571756573745f73747265616d696e671803200128" - "0812190a11726573706f6e73655f747970655f75726c180420012809121a" - "0a12726573706f6e73655f73747265616d696e6718052001280812280a07" - "6f7074696f6e7318062003280b32172e676f6f676c652e70726f746f6275" - "662e4f7074696f6e12270a0673796e74617818072001280e32172e676f6f" - "676c652e70726f746f6275662e53796e74617822230a054d6978696e120c" - "0a046e616d65180120012809120c0a04726f6f7418022001280942750a13" - "636f6d2e676f6f676c652e70726f746f627566420841706950726f746f50" - "015a2b676f6f676c652e676f6c616e672e6f72672f67656e70726f746f2f" - "70726f746f6275662f6170693b617069a20203475042aa021e476f6f676c" - "652e50726f746f6275662e57656c6c4b6e6f776e5479706573620670726f" - "746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_api = true; -} + if (!Convert_PhpToUpb(val, &msgval, upb_fielddef_type(f), + Descriptor_GetFromFieldDef(f), arena)) { + return; + } -static void init_file_duration(TSRMLS_D) { - if (is_inited_file_duration) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0ae3010a1e676f6f676c652f70726f746f6275662f6475726174696f6e2e" - "70726f746f120f676f6f676c652e70726f746f627566222a0a0844757261" - "74696f6e120f0a077365636f6e6473180120012803120d0a056e616e6f73" - "180220012805427c0a13636f6d2e676f6f676c652e70726f746f62756642" - "0d4475726174696f6e50726f746f50015a2a6769746875622e636f6d2f67" - "6f6c616e672f70726f746f6275662f7074797065732f6475726174696f6e" - "f80101a20203475042aa021e476f6f676c652e50726f746f6275662e5765" - "6c6c4b6e6f776e5479706573620670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_duration = true; -} + upb_msg_set(intern->msg, f, msgval, arena); +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_mergeFrom, 0, 0, 1) + ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_read, 0, 0, 1) + ZEND_ARG_INFO(0, field) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_write, 0, 0, 2) + ZEND_ARG_INFO(0, field) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +static zend_function_entry Message_methods[] = { + PHP_ME(Message, clear, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, discardUnknownFields, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, serializeToString, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, mergeFromString, arginfo_mergeFrom, ZEND_ACC_PUBLIC) + PHP_ME(Message, serializeToJsonString, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(Message, mergeFromJsonString, arginfo_mergeFrom, ZEND_ACC_PUBLIC) + PHP_ME(Message, mergeFrom, arginfo_mergeFrom, ZEND_ACC_PUBLIC) + PHP_ME(Message, readWrapperValue, arginfo_read, ZEND_ACC_PROTECTED) + PHP_ME(Message, writeWrapperValue, arginfo_write, ZEND_ACC_PROTECTED) + PHP_ME(Message, hasOneof, arginfo_read, ZEND_ACC_PROTECTED) + PHP_ME(Message, readOneof, arginfo_read, ZEND_ACC_PROTECTED) + PHP_ME(Message, writeOneof, arginfo_write, ZEND_ACC_PROTECTED) + PHP_ME(Message, whichOneof, arginfo_read, ZEND_ACC_PROTECTED) + PHP_ME(Message, __construct, arginfo_void, ZEND_ACC_PROTECTED) + ZEND_FE_END +}; -static void init_file_field_mask(TSRMLS_D) { - if (is_inited_file_field_mask) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0ae3010a20676f6f676c652f70726f746f6275662f6669656c645f6d6173" - "6b2e70726f746f120f676f6f676c652e70726f746f627566221a0a094669" - "656c644d61736b120d0a0570617468731801200328094289010a13636f6d" - "2e676f6f676c652e70726f746f627566420e4669656c644d61736b50726f" - "746f50015a39676f6f676c652e676f6c616e672e6f72672f67656e70726f" - "746f2f70726f746f6275662f6669656c645f6d61736b3b6669656c645f6d" - "61736ba20203475042aa021e476f6f676c652e50726f746f6275662e5765" - "6c6c4b6e6f776e5479706573620670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_field_mask = true; -} +// Well-known types //////////////////////////////////////////////////////////// -static void init_file_empty(TSRMLS_D) { - if (is_inited_file_empty) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f" - "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276" - "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072" - "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f" - "6275662f7074797065732f656d707479f80101a20203475042aa021e476f" - "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206" - "70726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_empty = true; -} +static const char TYPE_URL_PREFIX[] = "type.googleapis.com/"; -static void init_file_source_context(TSRMLS_D) { - if (is_inited_file_source_context) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0afb010a24676f6f676c652f70726f746f6275662f736f757263655f636f" - "6e746578742e70726f746f120f676f6f676c652e70726f746f6275662222" - "0a0d536f75726365436f6e7465787412110a0966696c655f6e616d651801" - "200128094295010a13636f6d2e676f6f676c652e70726f746f6275664212" - "536f75726365436f6e7465787450726f746f50015a41676f6f676c652e67" - "6f6c616e672e6f72672f67656e70726f746f2f70726f746f6275662f736f" - "757263655f636f6e746578743b736f757263655f636f6e74657874a20203" - "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77" - "6e5479706573620670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_source_context = true; +static upb_msgval Message_getval(Message *intern, const char *field_name) { + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, field_name); + PBPHP_ASSERT(f); + return upb_msg_get(intern->msg, f); } -static void init_file_struct(TSRMLS_D) { - if (is_inited_file_struct) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0a81050a1c676f6f676c652f70726f746f6275662f7374727563742e7072" - "6f746f120f676f6f676c652e70726f746f6275662284010a065374727563" - "7412330a066669656c647318012003280b32232e676f6f676c652e70726f" - "746f6275662e5374727563742e4669656c6473456e7472791a450a0b4669" - "656c6473456e747279120b0a036b657918012001280912250a0576616c75" - "6518022001280b32162e676f6f676c652e70726f746f6275662e56616c75" - "653a02380122ea010a0556616c756512300a0a6e756c6c5f76616c756518" - "012001280e321a2e676f6f676c652e70726f746f6275662e4e756c6c5661" - "6c7565480012160a0c6e756d6265725f76616c7565180220012801480012" - "160a0c737472696e675f76616c7565180320012809480012140a0a626f6f" - "6c5f76616c75651804200128084800122f0a0c7374727563745f76616c75" - "6518052001280b32172e676f6f676c652e70726f746f6275662e53747275" - "6374480012300a0a6c6973745f76616c756518062001280b321a2e676f6f" - "676c652e70726f746f6275662e4c69737456616c7565480042060a046b69" - "6e6422330a094c69737456616c756512260a0676616c7565731801200328" - "0b32162e676f6f676c652e70726f746f6275662e56616c75652a1b0a094e" - "756c6c56616c7565120e0a0a4e554c4c5f56414c554510004281010a1363" - "6f6d2e676f6f676c652e70726f746f627566420b53747275637450726f74" - "6f50015a316769746875622e636f6d2f676f6c616e672f70726f746f6275" - "662f7074797065732f7374727563743b7374727563747062f80101a20203" - "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77" - "6e5479706573620670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_struct = true; +static void Message_setval(Message *intern, const char *field_name, + upb_msgval val) { + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, field_name); + PBPHP_ASSERT(f); + return upb_msg_set(intern->msg, f, val, Arena_Get(&intern->arena)); } -static void init_file_timestamp(TSRMLS_D) { - if (is_inited_file_timestamp) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0ae7010a1f676f6f676c652f70726f746f6275662f74696d657374616d70" - "2e70726f746f120f676f6f676c652e70726f746f627566222b0a0954696d" - "657374616d70120f0a077365636f6e6473180120012803120d0a056e616e" - "6f73180220012805427e0a13636f6d2e676f6f676c652e70726f746f6275" - "66420e54696d657374616d7050726f746f50015a2b6769746875622e636f" - "6d2f676f6c616e672f70726f746f6275662f7074797065732f74696d6573" - "74616d70f80101a20203475042aa021e476f6f676c652e50726f746f6275" - "662e57656c6c4b6e6f776e5479706573620670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_timestamp = true; +static upb_msgval StringVal(upb_strview view) { + upb_msgval ret; + ret.str_val = view; + return ret; } -static void init_file_type(TSRMLS_D) { - if (is_inited_file_type) return; - init_file_any(TSRMLS_C); - init_file_source_context(TSRMLS_C); - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0aba0c0a1a676f6f676c652f70726f746f6275662f747970652e70726f74" - "6f120f676f6f676c652e70726f746f6275661a19676f6f676c652f70726f" - "746f6275662f616e792e70726f746f1a24676f6f676c652f70726f746f62" - "75662f736f757263655f636f6e746578742e70726f746f22d7010a045479" - "7065120c0a046e616d6518012001280912260a066669656c647318022003" - "280b32162e676f6f676c652e70726f746f6275662e4669656c64120e0a06" - "6f6e656f667318032003280912280a076f7074696f6e7318042003280b32" - "172e676f6f676c652e70726f746f6275662e4f7074696f6e12360a0e736f" - "757263655f636f6e7465787418052001280b321e2e676f6f676c652e7072" - "6f746f6275662e536f75726365436f6e7465787412270a0673796e746178" - "18062001280e32172e676f6f676c652e70726f746f6275662e53796e7461" - "7822d5050a054669656c6412290a046b696e6418012001280e321b2e676f" - "6f676c652e70726f746f6275662e4669656c642e4b696e6412370a0b6361" - "7264696e616c69747918022001280e32222e676f6f676c652e70726f746f" - "6275662e4669656c642e43617264696e616c697479120e0a066e756d6265" - "72180320012805120c0a046e616d6518042001280912100a08747970655f" - "75726c18062001280912130a0b6f6e656f665f696e646578180720012805" - "120e0a067061636b656418082001280812280a076f7074696f6e73180920" - "03280b32172e676f6f676c652e70726f746f6275662e4f7074696f6e1211" - "0a096a736f6e5f6e616d65180a2001280912150a0d64656661756c745f76" - "616c7565180b2001280922c8020a044b696e6412100a0c545950455f554e" - "4b4e4f574e1000120f0a0b545950455f444f55424c451001120e0a0a5459" - "50455f464c4f41541002120e0a0a545950455f494e5436341003120f0a0b" - "545950455f55494e5436341004120e0a0a545950455f494e543332100512" - "100a0c545950455f46495845443634100612100a0c545950455f46495845" - "4433321007120d0a09545950455f424f4f4c1008120f0a0b545950455f53" - "5452494e471009120e0a0a545950455f47524f5550100a12100a0c545950" - "455f4d455353414745100b120e0a0a545950455f4259544553100c120f0a" - "0b545950455f55494e543332100d120d0a09545950455f454e554d100e12" - "110a0d545950455f5346495845443332100f12110a0d545950455f534649" - "58454436341010120f0a0b545950455f53494e5433321011120f0a0b5459" - "50455f53494e543634101222740a0b43617264696e616c69747912170a13" - "43415244494e414c4954595f554e4b4e4f574e100012180a144341524449" - "4e414c4954595f4f5054494f4e414c100112180a1443415244494e414c49" - "54595f5245515549524544100212180a1443415244494e414c4954595f52" - "45504541544544100322ce010a04456e756d120c0a046e616d6518012001" - "2809122d0a09656e756d76616c756518022003280b321a2e676f6f676c65" - "2e70726f746f6275662e456e756d56616c756512280a076f7074696f6e73" - "18032003280b32172e676f6f676c652e70726f746f6275662e4f7074696f" - "6e12360a0e736f757263655f636f6e7465787418042001280b321e2e676f" - "6f676c652e70726f746f6275662e536f75726365436f6e7465787412270a" - "0673796e74617818052001280e32172e676f6f676c652e70726f746f6275" - "662e53796e74617822530a09456e756d56616c7565120c0a046e616d6518" - "0120012809120e0a066e756d62657218022001280512280a076f7074696f" - "6e7318032003280b32172e676f6f676c652e70726f746f6275662e4f7074" - "696f6e223b0a064f7074696f6e120c0a046e616d6518012001280912230a" - "0576616c756518022001280b32142e676f6f676c652e70726f746f627566" - "2e416e792a2e0a0653796e74617812110a0d53594e5441585f50524f544f" - "32100012110a0d53594e5441585f50524f544f331001427d0a13636f6d2e" - "676f6f676c652e70726f746f62756642095479706550726f746f50015a2f" - "676f6f676c652e676f6c616e672e6f72672f67656e70726f746f2f70726f" - "746f6275662f70747970653b7074797065f80101a20203475042aa021e47" - "6f6f676c652e50726f746f6275662e57656c6c4b6e6f776e547970657362" - "0670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_type = true; +static bool TryStripUrlPrefix(upb_strview *str) { + size_t size = strlen(TYPE_URL_PREFIX); + if (str->size < size || memcmp(TYPE_URL_PREFIX, str->data, size) != 0) { + return false; + } + str->data += size; + str->size -= size; + return true; } -static void init_file_wrappers(TSRMLS_D) { - if (is_inited_file_wrappers) return; - init_generated_pool_once(TSRMLS_C); - const char* generated_file = - "0abf030a1e676f6f676c652f70726f746f6275662f77726170706572732e" - "70726f746f120f676f6f676c652e70726f746f627566221c0a0b446f7562" - "6c6556616c7565120d0a0576616c7565180120012801221b0a0a466c6f61" - "7456616c7565120d0a0576616c7565180120012802221b0a0a496e743634" - "56616c7565120d0a0576616c7565180120012803221c0a0b55496e743634" - "56616c7565120d0a0576616c7565180120012804221b0a0a496e74333256" - "616c7565120d0a0576616c7565180120012805221c0a0b55496e74333256" - "616c7565120d0a0576616c756518012001280d221a0a09426f6f6c56616c" - "7565120d0a0576616c7565180120012808221c0a0b537472696e6756616c" - "7565120d0a0576616c7565180120012809221b0a0a427974657356616c75" - "65120d0a0576616c756518012001280c427c0a13636f6d2e676f6f676c65" - "2e70726f746f627566420d577261707065727350726f746f50015a2a6769" - "746875622e636f6d2f676f6c616e672f70726f746f6275662f7074797065" - "732f7772617070657273f80101a20203475042aa021e476f6f676c652e50" - "726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33"; - char* binary; - int binary_len; - hex_to_binary(generated_file, &binary, &binary_len); - internal_add_generated_file(binary, binary_len, - generated_pool, true TSRMLS_CC); - FREE(binary); - is_inited_file_wrappers = true; +static bool StrViewEq(upb_strview view, const char *str) { + size_t size = strlen(str); + return view.size == size && memcmp(view.data, str, size) == 0; } -// ----------------------------------------------------------------------------- -// Define enum -// ----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------------- -// Field_Cardinality -// ----------------------------------------------------------------------------- +PHP_METHOD(google_protobuf_Any, unpack) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_strview type_url = Message_getval(intern, "type_url").str_val; + upb_strview value = Message_getval(intern, "value").str_val; + upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_msgdef *m; + Descriptor *desc; + zval ret; -static zend_function_entry field_cardinality_methods[] = { - PHP_ME(Field_Cardinality, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Field_Cardinality, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - {NULL, NULL, NULL} -}; + // Ensure that type_url has TYPE_URL_PREFIX as a prefix. + if (!TryStripUrlPrefix(&type_url)) { + zend_throw_exception( + NULL, "Type url needs to be type.googleapis.com/fully-qualified", + 0 TSRMLS_CC); + return; + } -zend_class_entry* field_cardinality_type; - -// Init class entry. -PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Cardinality", - Field_Cardinality, field_cardinality) - zend_declare_class_constant_long(field_cardinality_type, - "CARDINALITY_UNKNOWN", 19, 0 TSRMLS_CC); - zend_declare_class_constant_long(field_cardinality_type, - "CARDINALITY_OPTIONAL", 20, 1 TSRMLS_CC); - zend_declare_class_constant_long(field_cardinality_type, - "CARDINALITY_REQUIRED", 20, 2 TSRMLS_CC); - zend_declare_class_constant_long(field_cardinality_type, - "CARDINALITY_REPEATED", 20, 3 TSRMLS_CC); - const char *alias = "Google\\Protobuf\\Field_Cardinality"; -#if PHP_VERSION_ID < 70300 - zend_register_class_alias_ex(alias, strlen(alias), field_cardinality_type TSRMLS_CC); -#else - zend_register_class_alias_ex(alias, strlen(alias), field_cardinality_type, 1); -#endif -PHP_PROTO_INIT_ENUMCLASS_END + m = upb_symtab_lookupmsg2(symtab, type_url.data, type_url.size); -PHP_METHOD(Field_Cardinality, name) { - PHP_PROTO_LONG value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == - FAILURE) { + if (m == NULL) { + zend_throw_exception( + NULL, "Specified message in any hasn't been added to descriptor pool", + 0 TSRMLS_CC); return; } - switch (value) { - case 0: - PHP_PROTO_RETURN_STRING("CARDINALITY_UNKNOWN", 1); - case 1: - PHP_PROTO_RETURN_STRING("CARDINALITY_OPTIONAL", 1); - case 2: - PHP_PROTO_RETURN_STRING("CARDINALITY_REQUIRED", 1); - case 3: - PHP_PROTO_RETURN_STRING("CARDINALITY_REPEATED", 1); - default: - zend_throw_exception_ex( - NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\Field_Cardinality has no name " -#if PHP_MAJOR_VERSION < 7 - "defined for value %d.", -#else - "defined for value " ZEND_LONG_FMT ".", -#endif - value); - } -} -PHP_METHOD(Field_Cardinality, value) { - char *name = NULL; - PHP_PROTO_SIZE name_len; + desc = Descriptor_GetFromMessageDef(m); + PBPHP_ASSERT(desc->class_entry->create_object == Message_create); + zend_object *obj = Message_create(desc->class_entry); + Message *msg = (Message*)obj; + Message_Initialize(msg, desc); + ZVAL_OBJ(&ret, obj); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == - FAILURE) { + // Get value. + if (!upb_decode(value.data, value.size, msg->msg, + upb_msgdef_layout(desc->msgdef), Arena_Get(&msg->arena))) { + zend_throw_exception_ex(NULL, 0, "Error occurred during parsing"); return; } - if (strncmp(name, "CARDINALITY_UNKNOWN", name_len) == 0) RETURN_LONG(0); - if (strncmp(name, "CARDINALITY_OPTIONAL", name_len) == 0) RETURN_LONG(1); - if (strncmp(name, "CARDINALITY_REQUIRED", name_len) == 0) RETURN_LONG(2); - if (strncmp(name, "CARDINALITY_REPEATED", name_len) == 0) RETURN_LONG(3); + // Fuse since the parsed message could alias "value". + upb_arena_fuse(Arena_Get(&intern->arena), Arena_Get(&msg->arena)); - zend_throw_exception_ex( - NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\Field_Cardinality has no value " - "defined for name %s.", - name); + RETURN_ZVAL(&ret, 1, 0); } -// ----------------------------------------------------------------------------- -// Field_Kind -// ----------------------------------------------------------------------------- - -static zend_function_entry field_kind_methods[] = { - PHP_ME(Field_Kind, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Field_Kind, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* field_kind_type; - -// Init class entry. -PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Kind", - Field_Kind, field_kind) - zend_declare_class_constant_long(field_kind_type, - "TYPE_UNKNOWN", 12, 0 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_DOUBLE", 11, 1 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_FLOAT", 10, 2 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_INT64", 10, 3 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_UINT64", 11, 4 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_INT32", 10, 5 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_FIXED64", 12, 6 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_FIXED32", 12, 7 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_BOOL", 9, 8 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_STRING", 11, 9 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_GROUP", 10, 10 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_MESSAGE", 12, 11 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_BYTES", 10, 12 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_UINT32", 11, 13 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_ENUM", 9, 14 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_SFIXED32", 13, 15 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_SFIXED64", 13, 16 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_SINT32", 11, 17 TSRMLS_CC); - zend_declare_class_constant_long(field_kind_type, - "TYPE_SINT64", 11, 18 TSRMLS_CC); - const char *alias = "Google\\Protobuf\\Field_Kind"; -#if PHP_VERSION_ID < 70300 - zend_register_class_alias_ex(alias, strlen(alias), field_kind_type TSRMLS_CC); -#else - zend_register_class_alias_ex(alias, strlen(alias), field_kind_type, 1); -#endif -PHP_PROTO_INIT_ENUMCLASS_END +PHP_METHOD(google_protobuf_Any, pack) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_arena *arena = Arena_Get(&intern->arena); + zval *val; + Message *msg; + upb_strview value; + upb_strview type_url; + const char *full_name; + char *buf; -PHP_METHOD(Field_Kind, name) { - PHP_PROTO_LONG value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &val) == FAILURE) { return; } - switch (value) { - case 0: - PHP_PROTO_RETURN_STRING("TYPE_UNKNOWN", 1); - case 1: - PHP_PROTO_RETURN_STRING("TYPE_DOUBLE", 1); - case 2: - PHP_PROTO_RETURN_STRING("TYPE_FLOAT", 1); - case 3: - PHP_PROTO_RETURN_STRING("TYPE_INT64", 1); - case 4: - PHP_PROTO_RETURN_STRING("TYPE_UINT64", 1); - case 5: - PHP_PROTO_RETURN_STRING("TYPE_INT32", 1); - case 6: - PHP_PROTO_RETURN_STRING("TYPE_FIXED64", 1); - case 7: - PHP_PROTO_RETURN_STRING("TYPE_FIXED32", 1); - case 8: - PHP_PROTO_RETURN_STRING("TYPE_BOOL", 1); - case 9: - PHP_PROTO_RETURN_STRING("TYPE_STRING", 1); - case 10: - PHP_PROTO_RETURN_STRING("TYPE_GROUP", 1); - case 11: - PHP_PROTO_RETURN_STRING("TYPE_MESSAGE", 1); - case 12: - PHP_PROTO_RETURN_STRING("TYPE_BYTES", 1); - case 13: - PHP_PROTO_RETURN_STRING("TYPE_UINT32", 1); - case 14: - PHP_PROTO_RETURN_STRING("TYPE_ENUM", 1); - case 15: - PHP_PROTO_RETURN_STRING("TYPE_SFIXED32", 1); - case 16: - PHP_PROTO_RETURN_STRING("TYPE_SFIXED64", 1); - case 17: - PHP_PROTO_RETURN_STRING("TYPE_SINT32", 1); - case 18: - PHP_PROTO_RETURN_STRING("TYPE_SINT64", 1); - default: - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\Field_Kind has no name " -#if PHP_MAJOR_VERSION < 7 - "defined for value %d.", -#else - "defined for value " ZEND_LONG_FMT ".", -#endif - value); - } -} -PHP_METHOD(Field_Kind, value) { - char *name = NULL; - PHP_PROTO_SIZE name_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == - FAILURE) { + if (!instanceof_function(Z_OBJCE_P(val), message_ce)) { + zend_error(E_USER_ERROR, "Given value is not an instance of Message."); return; } - if (strncmp(name, "TYPE_UNKNOWN", name_len) == 0) RETURN_LONG(0); - if (strncmp(name, "TYPE_DOUBLE", name_len) == 0) RETURN_LONG(1); - if (strncmp(name, "TYPE_FLOAT", name_len) == 0) RETURN_LONG(2); - if (strncmp(name, "TYPE_INT64", name_len) == 0) RETURN_LONG(3); - if (strncmp(name, "TYPE_UINT64", name_len) == 0) RETURN_LONG(4); - if (strncmp(name, "TYPE_INT32", name_len) == 0) RETURN_LONG(5); - if (strncmp(name, "TYPE_FIXED64", name_len) == 0) RETURN_LONG(6); - if (strncmp(name, "TYPE_FIXED32", name_len) == 0) RETURN_LONG(7); - if (strncmp(name, "TYPE_BOOL", name_len) == 0) RETURN_LONG(8); - if (strncmp(name, "TYPE_STRING", name_len) == 0) RETURN_LONG(9); - if (strncmp(name, "TYPE_GROUP", name_len) == 0) RETURN_LONG(10); - if (strncmp(name, "TYPE_MESSAGE", name_len) == 0) RETURN_LONG(11); - if (strncmp(name, "TYPE_BYTES", name_len) == 0) RETURN_LONG(12); - if (strncmp(name, "TYPE_UINT32", name_len) == 0) RETURN_LONG(13); - if (strncmp(name, "TYPE_ENUM", name_len) == 0) RETURN_LONG(14); - if (strncmp(name, "TYPE_SFIXED32", name_len) == 0) RETURN_LONG(15); - if (strncmp(name, "TYPE_SFIXED64", name_len) == 0) RETURN_LONG(16); - if (strncmp(name, "TYPE_SINT32", name_len) == 0) RETURN_LONG(17); - if (strncmp(name, "TYPE_SINT64", name_len) == 0) RETURN_LONG(18); - - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\Field_Kind has no value " - "defined for name %s.", - name); -} - -// ----------------------------------------------------------------------------- -// NullValue -// ----------------------------------------------------------------------------- + msg = (Message*)Z_OBJ_P(val); -static zend_function_entry null_value_methods[] = { - PHP_ME(NullValue, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(NullValue, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - {NULL, NULL, NULL} -}; + // Serialize and set value. + value.data = upb_encode(msg->msg, upb_msgdef_layout(msg->desc->msgdef), arena, + &value.size); + Message_setval(intern, "value", StringVal(value)); -zend_class_entry* null_value_type; + // Set type url: type_url_prefix + fully_qualified_name + full_name = upb_msgdef_fullname(msg->desc->msgdef); + type_url.size = strlen(TYPE_URL_PREFIX) + strlen(full_name); + buf = upb_arena_malloc(arena, type_url.size + 1); + memcpy(buf, TYPE_URL_PREFIX, strlen(TYPE_URL_PREFIX)); + memcpy(buf + strlen(TYPE_URL_PREFIX), full_name, strlen(full_name)); + type_url.data = buf; + Message_setval(intern, "type_url", StringVal(type_url)); +} -// Init class entry. -PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\NullValue", - NullValue, null_value) - zend_declare_class_constant_long(null_value_type, - "NULL_VALUE", 10, 0 TSRMLS_CC); -PHP_PROTO_INIT_ENUMCLASS_END +PHP_METHOD(google_protobuf_Any, is) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_strview type_url = Message_getval(intern, "type_url").str_val; + zend_class_entry *klass = NULL; + const upb_msgdef *m; -PHP_METHOD(NullValue, name) { - PHP_PROTO_LONG value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "C", &klass) == FAILURE) { return; } - switch (value) { - case 0: - PHP_PROTO_RETURN_STRING("NULL_VALUE", 1); - default: - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\NullValue has no name " -#if PHP_MAJOR_VERSION < 7 - "defined for value %d.", -#else - "defined for value " ZEND_LONG_FMT ".", -#endif - value); - } -} -PHP_METHOD(NullValue, value) { - char *name = NULL; - PHP_PROTO_SIZE name_len; + m = NameMap_GetMessage(klass); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == - FAILURE) { - return; - } - - if (strncmp(name, "NULL_VALUE", name_len) == 0) RETURN_LONG(0); - - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\NullValue has no value " - "defined for name %s.", - name); -} - -// ----------------------------------------------------------------------------- -// Syntax -// ----------------------------------------------------------------------------- - -static zend_function_entry syntax_methods[] = { - PHP_ME(Syntax, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Syntax, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* syntax_type; - -// Init class entry. -PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Syntax", - Syntax, syntax) - zend_declare_class_constant_long(syntax_type, - "SYNTAX_PROTO2", 13, 0 TSRMLS_CC); - zend_declare_class_constant_long(syntax_type, - "SYNTAX_PROTO3", 13, 1 TSRMLS_CC); -PHP_PROTO_INIT_ENUMCLASS_END - -PHP_METHOD(Syntax, name) { - PHP_PROTO_LONG value; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == - FAILURE) { - return; - } - switch (value) { - case 0: - PHP_PROTO_RETURN_STRING("SYNTAX_PROTO2", 1); - case 1: - PHP_PROTO_RETURN_STRING("SYNTAX_PROTO3", 1); - default: - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\Syntax has no name " -#if PHP_MAJOR_VERSION < 7 - "defined for value %d.", -#else - "defined for value " ZEND_LONG_FMT ".", -#endif - value); - } -} - -PHP_METHOD(Syntax, value) { - char *name = NULL; - PHP_PROTO_SIZE name_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == - FAILURE) { - return; - } - - if (strncmp(name, "SYNTAX_PROTO2", name_len) == 0) RETURN_LONG(0); - if (strncmp(name, "SYNTAX_PROTO3", name_len) == 0) RETURN_LONG(1); - - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Enum Google\\Protobuf\\Syntax has no value " - "defined for name %s.", - name); -} - -// ----------------------------------------------------------------------------- -// Define message -// ----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------------- -// Any -// ----------------------------------------------------------------------------- - -static zend_function_entry any_methods[] = { - PHP_ME(Any, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Any, getTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Any, setTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Any, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Any, setValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Any, pack, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Any, unpack, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Any, is, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* any_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Any", Any, any) - zend_declare_property_string(any_type, "type_url", strlen("type_url"), - "" ,ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(any_type, "value", strlen("value"), - "" ,ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -static void hex_to_binary(const char* hex, char** binary, int* binary_len) { - int i; - int hex_len = strlen(hex); - *binary_len = hex_len / 2; - *binary = ALLOC_N(char, *binary_len); - for (i = 0; i < *binary_len; i++) { - char value = 0; - if (hex[i * 2] >= '0' && hex[i * 2] <= '9') { - value += (hex[i * 2] - '0') * 16; - } else { - value += (hex[i * 2] - 'a' + 10) * 16; - } - if (hex[i * 2 + 1] >= '0' && hex[i * 2 + 1] <= '9') { - value += hex[i * 2 + 1] - '0'; - } else { - value += hex[i * 2 + 1] - 'a' + 10; - } - (*binary)[i] = value; - } -} - -PHP_METHOD(Any, __construct) { - init_file_any(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Any, any, TypeUrl, "type_url") -PHP_PROTO_FIELD_ACCESSORS(Any, any, Value, "value") - -PHP_METHOD(Any, unpack) { - // Get type url. - zval type_url_member; - PHP_PROTO_ZVAL_STRING(&type_url_member, "type_url", 1); - PHP_PROTO_FAKE_SCOPE_BEGIN(any_type); - zval* type_url_php = php_proto_message_read_property( - getThis(), &type_url_member PHP_PROTO_TSRMLS_CC); - zval_dtor(&type_url_member); - PHP_PROTO_FAKE_SCOPE_END; - - // Get fully-qualified name from type url. - size_t url_prefix_len = strlen(TYPE_URL_PREFIX); - const char* type_url = Z_STRVAL_P(type_url_php); - size_t type_url_len = Z_STRLEN_P(type_url_php); - - if (url_prefix_len > type_url_len || - strncmp(TYPE_URL_PREFIX, type_url, url_prefix_len) != 0) { - zend_throw_exception( - NULL, "Type url needs to be type.googleapis.com/fully-qualified", - 0 TSRMLS_CC); - return; - } - - const char* fully_qualified_name = type_url + url_prefix_len; - DescriptorInternal* desc = get_proto_desc(fully_qualified_name); - if (desc == NULL) { - zend_throw_exception( - NULL, "Specified message in any hasn't been added to descriptor pool", - 0 TSRMLS_CC); - return; - } - register_class(desc, false TSRMLS_CC); - zend_class_entry* klass = desc->klass; - ZVAL_OBJ(return_value, klass->create_object(klass TSRMLS_CC)); - MessageHeader* msg = UNBOX(MessageHeader, return_value); - custom_data_init(klass, msg PHP_PROTO_TSRMLS_CC); - - // Get value. - zval value_member; - PHP_PROTO_ZVAL_STRING(&value_member, "value", 1); - PHP_PROTO_FAKE_SCOPE_RESTART(any_type); - zval* value = php_proto_message_read_property( - getThis(), &value_member PHP_PROTO_TSRMLS_CC); - zval_dtor(&value_member); - PHP_PROTO_FAKE_SCOPE_END; - - merge_from_string(Z_STRVAL_P(value), Z_STRLEN_P(value), desc, msg); -} - -PHP_METHOD(Any, pack) { - zval* val; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &val) == - FAILURE) { - return; - } - - if (!instanceof_function(Z_OBJCE_P(val), message_type TSRMLS_CC)) { - zend_error(E_USER_ERROR, "Given value is not an instance of Message."); - return; - } - - // Set value by serialized data. - zval data; - serialize_to_string(val, &data TSRMLS_CC); - - zval member; - PHP_PROTO_ZVAL_STRING(&member, "value", 1); - - PHP_PROTO_FAKE_SCOPE_BEGIN(any_type); - message_handlers->write_property(getThis(), &member, &data, - NULL PHP_PROTO_TSRMLS_CC); - zval_dtor(&data); - zval_dtor(&member); - PHP_PROTO_FAKE_SCOPE_END; - - // Set type url. - DescriptorInternal* desc = get_ce_desc(Z_OBJCE_P(val)); - const char* fully_qualified_name = upb_msgdef_fullname(desc->msgdef); - size_t type_url_len = - strlen(TYPE_URL_PREFIX) + strlen(fully_qualified_name) + 1; - char* type_url = ALLOC_N(char, type_url_len); - sprintf(type_url, "%s%s", TYPE_URL_PREFIX, fully_qualified_name); - zval type_url_php; - PHP_PROTO_ZVAL_STRING(&type_url_php, type_url, 1); - PHP_PROTO_ZVAL_STRING(&member, "type_url", 1); - - PHP_PROTO_FAKE_SCOPE_RESTART(any_type); - message_handlers->write_property(getThis(), &member, &type_url_php, - NULL PHP_PROTO_TSRMLS_CC); - zval_dtor(&type_url_php); - zval_dtor(&member); - PHP_PROTO_FAKE_SCOPE_END; - FREE(type_url); -} - -PHP_METHOD(Any, is) { - zend_class_entry *klass = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "C", &klass) == - FAILURE) { - return; - } - - DescriptorInternal* desc = get_ce_desc(klass); - if (desc == NULL) { + if (m == NULL) { RETURN_BOOL(false); } - // Create corresponded type url. - const char* fully_qualified_name = upb_msgdef_fullname(desc->msgdef); - size_t type_url_len = - strlen(TYPE_URL_PREFIX) + strlen(fully_qualified_name) + 1; - char* type_url = ALLOC_N(char, type_url_len); - sprintf(type_url, "%s%s", TYPE_URL_PREFIX, fully_qualified_name); - - // Fetch stored type url. - zval member; - PHP_PROTO_ZVAL_STRING(&member, "type_url", 1); - PHP_PROTO_FAKE_SCOPE_BEGIN(any_type); - zval* value = - php_proto_message_read_property(getThis(), &member PHP_PROTO_TSRMLS_CC); - zval_dtor(&member); - PHP_PROTO_FAKE_SCOPE_END; - - // Compare two type url. - bool is = strcmp(type_url, Z_STRVAL_P(value)) == 0; - FREE(type_url); - - RETURN_BOOL(is); + RETURN_BOOL(TryStripUrlPrefix(&type_url) && + StrViewEq(type_url, upb_msgdef_fullname(m))); } -// ----------------------------------------------------------------------------- -// Duration -// ----------------------------------------------------------------------------- - -static zend_function_entry duration_methods[] = { - PHP_ME(Duration, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Duration, getSeconds, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Duration, setSeconds, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Duration, getNanos, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Duration, setNanos, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* duration_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Duration", - Duration, duration) - zend_declare_property_long(duration_type, "seconds", strlen("seconds"), - 0 ,ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(duration_type, "nanos", strlen("nanos"), - 0 ,ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Duration, __construct) { - init_file_duration(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Duration, duration, Seconds, "seconds") -PHP_PROTO_FIELD_ACCESSORS(Duration, duration, Nanos, "nanos") - -// ----------------------------------------------------------------------------- -// Timestamp -// ----------------------------------------------------------------------------- - -static zend_function_entry timestamp_methods[] = { - PHP_ME(Timestamp, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timestamp, fromDateTime, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timestamp, toDateTime, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timestamp, getSeconds, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timestamp, setSeconds, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timestamp, getNanos, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timestamp, setNanos, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* timestamp_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Timestamp", - Timestamp, timestamp) - zend_declare_property_long(timestamp_type, "seconds", strlen("seconds"), - 0 ,ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(timestamp_type, "nanos", strlen("nanos"), - 0 ,ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Timestamp, __construct) { - init_file_timestamp(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Timestamp, timestamp, Seconds, "seconds") -PHP_PROTO_FIELD_ACCESSORS(Timestamp, timestamp, Nanos, "nanos") - -PHP_METHOD(Timestamp, fromDateTime) { +PHP_METHOD(google_protobuf_Timestamp, fromDateTime) { + Message* intern = (Message*)Z_OBJ_P(getThis()); zval* datetime; + const char *classname = "\\DatetimeInterface"; + zend_string *classname_str = zend_string_init(classname, strlen(classname), 0); + zend_class_entry *date_interface_ce = zend_lookup_class(classname_str); - PHP_PROTO_CE_DECLARE date_interface_ce; - if (php_proto_zend_lookup_class("\\DatetimeInterface", 18, - &date_interface_ce) == FAILURE) { + if (date_interface_ce == NULL) { zend_error(E_ERROR, "Make sure date extension is enabled."); return; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &datetime, - PHP_PROTO_CE_UNREF(date_interface_ce)) == FAILURE) { + date_interface_ce) == FAILURE) { zend_error(E_USER_ERROR, "Expect DatetimeInterface."); return; } - int64_t timestamp_seconds; + upb_msgval timestamp_seconds; { zval retval; zval function_name; -#if PHP_MAJOR_VERSION < 7 - INIT_ZVAL(retval); - INIT_ZVAL(function_name); -#endif - - PHP_PROTO_ZVAL_STRING(&function_name, "date_timestamp_get", 1); + ZVAL_STRING(&function_name, "date_timestamp_get"); if (call_user_function(EG(function_table), NULL, &function_name, &retval, 1, - ZVAL_PTR_TO_CACHED_PTR(datetime) TSRMLS_CC) == FAILURE) { + datetime) == FAILURE || + !Convert_PhpToUpb(&retval, ×tamp_seconds, UPB_TYPE_INT64, NULL, + NULL)) { zend_error(E_ERROR, "Cannot get timestamp from DateTime."); return; } - protobuf_convert_to_int64(&retval, ×tamp_seconds); - zval_dtor(&retval); zval_dtor(&function_name); } - int64_t timestamp_micros; + upb_msgval timestamp_nanos; { zval retval; zval function_name; zval format_string; -#if PHP_MAJOR_VERSION < 7 - INIT_ZVAL(retval); - INIT_ZVAL(function_name); - INIT_ZVAL(format_string); -#endif - - PHP_PROTO_ZVAL_STRING(&function_name, "date_format", 1); - PHP_PROTO_ZVAL_STRING(&format_string, "u", 1); + ZVAL_STRING(&function_name, "date_format"); + ZVAL_STRING(&format_string, "u"); - CACHED_VALUE params[2] = { - ZVAL_PTR_TO_CACHED_VALUE(datetime), - ZVAL_TO_CACHED_VALUE(format_string), + zval params[2] = { + *datetime, + format_string, }; - if (call_user_function(EG(function_table), NULL, &function_name, &retval, - ARRAY_SIZE(params), params TSRMLS_CC) == FAILURE) { + if (call_user_function(EG(function_table), NULL, &function_name, &retval, 2, + params) == FAILURE || + !Convert_PhpToUpb(&retval, ×tamp_nanos, UPB_TYPE_INT32, NULL, + NULL)) { zend_error(E_ERROR, "Cannot format DateTime."); return; } - protobuf_convert_to_int64(&retval, ×tamp_micros); + timestamp_nanos.int32_val *= 1000; zval_dtor(&retval); zval_dtor(&function_name); zval_dtor(&format_string); } - // Set seconds - MessageHeader* self = UNBOX(MessageHeader, getThis()); - const upb_fielddef* field = - upb_msgdef_ntofz(self->descriptor->msgdef, "seconds"); - void* storage = message_data(self); - void* memory = slot_memory(self->descriptor->layout, storage, field); - *(int64_t*)memory = timestamp_seconds; - - // Set nanos - field = upb_msgdef_ntofz(self->descriptor->msgdef, "nanos"); - storage = message_data(self); - memory = slot_memory(self->descriptor->layout, storage, field); - *(int32_t*)memory = timestamp_micros * 1000; + Message_setval(intern, "seconds", timestamp_seconds); + Message_setval(intern, "nanos", timestamp_nanos); RETURN_NULL(); } -PHP_METHOD(Timestamp, toDateTime) { - // Get seconds - MessageHeader* self = UNBOX(MessageHeader, getThis()); - const upb_fielddef* field = - upb_msgdef_ntofz(self->descriptor->msgdef, "seconds"); - void* storage = message_data(self); - void* memory = slot_memory(self->descriptor->layout, storage, field); - int64_t seconds = *(int64_t*)memory; - - // Get nanos - field = upb_msgdef_ntofz(self->descriptor->msgdef, "nanos"); - memory = slot_memory(self->descriptor->layout, storage, field); - int32_t nanos = *(int32_t*)memory; +PHP_METHOD(google_protobuf_Timestamp, toDateTime) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + upb_msgval seconds = Message_getval(intern, "seconds"); + upb_msgval nanos = Message_getval(intern, "nanos"); // Get formatted time string. char formatted_time[32]; snprintf(formatted_time, sizeof(formatted_time), "%" PRId64 ".%06" PRId32, - seconds, nanos / 1000); + seconds.int64_val, nanos.int32_val / 1000); // Create Datetime object. zval datetime; @@ -1849,23 +1285,17 @@ PHP_METHOD(Timestamp, toDateTime) { zval format_string; zval formatted_time_php; -#if PHP_MAJOR_VERSION < 7 - INIT_ZVAL(function_name); - INIT_ZVAL(format_string); - INIT_ZVAL(formatted_time_php); -#endif - - PHP_PROTO_ZVAL_STRING(&function_name, "date_create_from_format", 1); - PHP_PROTO_ZVAL_STRING(&format_string, "U.u", 1); - PHP_PROTO_ZVAL_STRING(&formatted_time_php, formatted_time, 1); + ZVAL_STRING(&function_name, "date_create_from_format"); + ZVAL_STRING(&format_string, "U.u"); + ZVAL_STRING(&formatted_time_php, formatted_time); - CACHED_VALUE params[2] = { - ZVAL_TO_CACHED_VALUE(format_string), - ZVAL_TO_CACHED_VALUE(formatted_time_php), + zval params[2] = { + format_string, + formatted_time_php, }; - if (call_user_function(EG(function_table), NULL, &function_name, &datetime, - ARRAY_SIZE(params), params TSRMLS_CC) == FAILURE) { + if (call_user_function(EG(function_table), NULL, &function_name, &datetime, 2, + params) == FAILURE) { zend_error(E_ERROR, "Cannot create DateTime."); return; } @@ -1874,861 +1304,35 @@ PHP_METHOD(Timestamp, toDateTime) { zval_dtor(&format_string); zval_dtor(&formatted_time_php); -#if PHP_MAJOR_VERSION < 7 - zval* datetime_ptr = &datetime; - PHP_PROTO_RETVAL_ZVAL(datetime_ptr); -#else ZVAL_OBJ(return_value, Z_OBJ(datetime)); -#endif } -// ----------------------------------------------------------------------------- -// Api -// ----------------------------------------------------------------------------- - -static zend_function_entry api_methods[] = { - PHP_ME(Api, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, getMethods, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, setMethods, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, getOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, setOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, getVersion, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, setVersion, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, getSourceContext, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, setSourceContext, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, getMixins, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, setMixins, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, getSyntax, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Api, setSyntax, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* api_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Api", - Api, api) - zend_declare_property_string(api_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(api_type, "methods", strlen("methods"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(api_type, "options", strlen("options"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(api_type, "version", strlen("version"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(api_type, "source_context", strlen("source_context"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(api_type, "mixins", strlen("mixins"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(api_type, "syntax", strlen("syntax"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Api, __construct) { - init_file_api(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} +#include "wkt.inc" -PHP_PROTO_FIELD_ACCESSORS(Api, api, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(Api, api, Methods, "methods") -PHP_PROTO_FIELD_ACCESSORS(Api, api, Options, "options") -PHP_PROTO_FIELD_ACCESSORS(Api, api, Version, "version") -PHP_PROTO_FIELD_ACCESSORS(Api, api, SourceContext, "source_context") -PHP_PROTO_FIELD_ACCESSORS(Api, api, Mixins, "mixins") -PHP_PROTO_FIELD_ACCESSORS(Api, api, Syntax, "syntax") +/** + * Message_ModuleInit() + * + * Called when the C extension is loaded to register all types. + */ +void Message_ModuleInit() { + zend_class_entry tmp_ce; + zend_object_handlers *h = &message_object_handlers; -// ----------------------------------------------------------------------------- -// BoolValue -// ----------------------------------------------------------------------------- + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Internal\\Message", + Message_methods); -static zend_function_entry bool_value_methods[] = { - PHP_ME(BoolValue, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(BoolValue, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(BoolValue, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; + message_ce = zend_register_internal_class(&tmp_ce); + message_ce->create_object = Message_create; -zend_class_entry* bool_value_type; + memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); + h->dtor_obj = Message_dtor; + h->compare_objects = Message_compare_objects; + h->read_property = Message_read_property; + h->write_property = Message_write_property; + h->has_property = Message_has_property; + h->unset_property = Message_unset_property; + h->get_properties = Message_get_properties; + h->get_property_ptr_ptr = Message_get_property_ptr_ptr; -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BoolValue", - BoolValue, bool_value) - zend_declare_property_bool(bool_value_type, "value", strlen("value"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(BoolValue, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; + WellKnownTypes_ModuleInit(); /* From wkt.inc. */ } - -PHP_PROTO_FIELD_ACCESSORS(BoolValue, bool_value, Value, "value") - -// ----------------------------------------------------------------------------- -// BytesValue -// ----------------------------------------------------------------------------- - -static zend_function_entry bytes_value_methods[] = { - PHP_ME(BytesValue, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(BytesValue, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(BytesValue, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* bytes_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\BytesValue", - BytesValue, bytes_value) - zend_declare_property_string(bytes_value_type, "value", strlen("value"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(BytesValue, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(BytesValue, bytes_value, Value, "value") - -// ----------------------------------------------------------------------------- -// DoubleValue -// ----------------------------------------------------------------------------- - -static zend_function_entry double_value_methods[] = { - PHP_ME(DoubleValue, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(DoubleValue, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(DoubleValue, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* double_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\DoubleValue", - DoubleValue, double_value) - zend_declare_property_double(double_value_type, "value", strlen("value"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(DoubleValue, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(DoubleValue, double_value, Value, "value") - -// ----------------------------------------------------------------------------- -// Enum -// ----------------------------------------------------------------------------- - -static zend_function_entry enum_methods[] = { - PHP_ME(Enum, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, getEnumvalue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, setEnumvalue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, getOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, setOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, getSourceContext, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, setSourceContext, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, getSyntax, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Enum, setSyntax, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* enum_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Enum", - Enum, enum) - zend_declare_property_string(enum_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(enum_type, "enumvalue", strlen("enumvalue"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(enum_type, "options", strlen("options"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(enum_type, "source_context", strlen("source_context"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(enum_type, "syntax", strlen("syntax"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Enum, __construct) { - init_file_type(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Enumvalue, "enumvalue") -PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Options, "options") -PHP_PROTO_FIELD_ACCESSORS(Enum, enum, SourceContext, "source_context") -PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Syntax, "syntax") - -// ----------------------------------------------------------------------------- -// EnumValue -// ----------------------------------------------------------------------------- - -static zend_function_entry enum_value_methods[] = { - PHP_ME(EnumValue, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(EnumValue, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(EnumValue, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(EnumValue, getNumber, NULL, ZEND_ACC_PUBLIC) - PHP_ME(EnumValue, setNumber, NULL, ZEND_ACC_PUBLIC) - PHP_ME(EnumValue, getOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(EnumValue, setOptions, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* enum_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\EnumValue", - EnumValue, enum_value) - zend_declare_property_string(enum_value_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(enum_value_type, "number", strlen("number"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(enum_value_type, "options", strlen("options"), - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(EnumValue, __construct) { - init_file_type(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(EnumValue, enum_value, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(EnumValue, enum_value, Number, "number") -PHP_PROTO_FIELD_ACCESSORS(EnumValue, enum_value, Options, "options") - -// ----------------------------------------------------------------------------- -// FieldMask -// ----------------------------------------------------------------------------- - -static zend_function_entry field_mask_methods[] = { - PHP_ME(FieldMask, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldMask, getPaths, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FieldMask, setPaths, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* field_mask_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FieldMask", - FieldMask, field_mask) - zend_declare_property_null(field_mask_type, "paths", strlen("paths"), - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(FieldMask, __construct) { - init_file_field_mask(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(FieldMask, field_mask, Paths, "paths") - -// ----------------------------------------------------------------------------- -// Field -// ----------------------------------------------------------------------------- - -static zend_function_entry field_methods[] = { - PHP_ME(Field, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getKind, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setKind, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getCardinality, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setCardinality, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getNumber, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setNumber, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getOneofIndex, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setOneofIndex, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getPacked, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setPacked, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getJsonName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setJsonName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, getDefaultValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Field, setDefaultValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* field_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Field", - Field, field) - zend_declare_property_long(field_type, "kind", strlen("kind"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(field_type, "cardinality", strlen("cardinality"), - 0, ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(field_type, "number", strlen("number"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(field_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(field_type, "type_url", strlen("type_url"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(field_type, "oneof_index", strlen("oneof_index"), - 0, ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_bool(field_type, "packed", strlen("packed"), false, - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(field_type, "options", strlen("options"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(field_type, "json_name", strlen("json_name"), - "", ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(field_type, "default_value", - strlen("default_value"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Field, __construct) { - init_file_type(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Field, field, Kind, "kind") -PHP_PROTO_FIELD_ACCESSORS(Field, field, Cardinality, "cardinality") -PHP_PROTO_FIELD_ACCESSORS(Field, field, Number, "number") -PHP_PROTO_FIELD_ACCESSORS(Field, field, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(Field, field, TypeUrl, "type_url") -PHP_PROTO_FIELD_ACCESSORS(Field, field, OneofIndex, "oneof_index") -PHP_PROTO_FIELD_ACCESSORS(Field, field, Packed, "packed") -PHP_PROTO_FIELD_ACCESSORS(Field, field, Options, "options") -PHP_PROTO_FIELD_ACCESSORS(Field, field, JsonName, "json_name") -PHP_PROTO_FIELD_ACCESSORS(Field, field, DefaultValue, "default_value") - -// ----------------------------------------------------------------------------- -// FloatValue -// ----------------------------------------------------------------------------- - -static zend_function_entry float_value_methods[] = { - PHP_ME(FloatValue, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FloatValue, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(FloatValue, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* float_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\FloatValue", - FloatValue, float_value) - zend_declare_property_double(float_value_type, "value", strlen("value"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(FloatValue, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(FloatValue, float_value, Value, "value") - -// ----------------------------------------------------------------------------- -// GPBEmpty -// ----------------------------------------------------------------------------- - -static zend_function_entry empty_methods[] = { - PHP_ME(GPBEmpty, __construct, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* empty_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\GPBEmpty", - GPBEmpty, empty) -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(GPBEmpty, __construct) { - init_file_empty(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - - -// ----------------------------------------------------------------------------- -// Int32Value -// ----------------------------------------------------------------------------- - -static zend_function_entry int32_value_methods[] = { - PHP_ME(Int32Value, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Int32Value, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Int32Value, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* int32_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int32Value", - Int32Value, int32_value) - zend_declare_property_long(int32_value_type, "value", strlen("value"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Int32Value, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Int32Value, int32_value, Value, "value") - -// ----------------------------------------------------------------------------- -// Int64Value -// ----------------------------------------------------------------------------- - -static zend_function_entry int64_value_methods[] = { - PHP_ME(Int64Value, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Int64Value, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Int64Value, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* int64_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Int64Value", - Int64Value, int64_value) - zend_declare_property_long(int64_value_type, "value", strlen("value"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Int64Value, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Int64Value, int64_value, Value, "value") - -// ----------------------------------------------------------------------------- -// ListValue -// ----------------------------------------------------------------------------- - -static zend_function_entry list_value_methods[] = { - PHP_ME(ListValue, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(ListValue, getValues, NULL, ZEND_ACC_PUBLIC) - PHP_ME(ListValue, setValues, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* list_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\ListValue", - ListValue, list_value) - zend_declare_property_null(list_value_type, "values", strlen("values"), - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(ListValue, __construct) { - init_file_struct(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(ListValue, list_value, Values, "values") - -// ----------------------------------------------------------------------------- -// Method -// ----------------------------------------------------------------------------- - -static zend_function_entry method_methods[] = { - PHP_ME(Method, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, getRequestTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, setRequestTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, getRequestStreaming, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, setRequestStreaming, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, getResponseTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, setResponseTypeUrl, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, getResponseStreaming, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, setResponseStreaming, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, getOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, setOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, getSyntax, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Method, setSyntax, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* method_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Method", - Method, method) - zend_declare_property_string(method_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(method_type, "request_type_url", - strlen("request_type_url"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_bool(method_type, "request_streaming", - strlen("request_streaming"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(method_type, "response_type_url", - strlen("response_type_url"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_bool(method_type, "response_streaming", - strlen("response_streaming"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(method_type, "options", strlen("options"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(method_type, "syntax", strlen("syntax"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Method, __construct) { - init_file_api(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Method, method, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(Method, method, RequestTypeUrl, "request_type_url") -PHP_PROTO_FIELD_ACCESSORS(Method, method, RequestStreaming, "request_streaming") -PHP_PROTO_FIELD_ACCESSORS(Method, method, ResponseTypeUrl, "response_type_url") -PHP_PROTO_FIELD_ACCESSORS(Method, method, ResponseStreaming, "response_streaming") -PHP_PROTO_FIELD_ACCESSORS(Method, method, Options, "options") -PHP_PROTO_FIELD_ACCESSORS(Method, method, Syntax, "syntax") - -// ----------------------------------------------------------------------------- -// Mixin -// ----------------------------------------------------------------------------- - -static zend_function_entry mixin_methods[] = { - PHP_ME(Mixin, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Mixin, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Mixin, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Mixin, getRoot, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Mixin, setRoot, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* mixin_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Mixin", - Mixin, mixin) - zend_declare_property_string(mixin_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(mixin_type, "root", strlen("root"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Mixin, __construct) { - init_file_api(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Mixin, mixin, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(Mixin, mixin, Root, "root") - -// ----------------------------------------------------------------------------- -// Option -// ----------------------------------------------------------------------------- - -static zend_function_entry option_methods[] = { - PHP_ME(Option, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Option, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Option, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Option, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Option, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* option_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Option", - Option, option) - zend_declare_property_string(option_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(option_type, "value", strlen("value"), - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Option, __construct) { - init_file_type(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Option, option, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(Option, option, Value, "value") - -// ----------------------------------------------------------------------------- -// SourceContext -// ----------------------------------------------------------------------------- - -static zend_function_entry source_context_methods[] = { - PHP_ME(SourceContext, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(SourceContext, getFileName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(SourceContext, setFileName, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* source_context_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\SourceContext", - SourceContext, source_context) - zend_declare_property_string(source_context_type, "file_name", - strlen("file_name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(SourceContext, __construct) { - init_file_source_context(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(SourceContext, source_context, FileName, "file_name") - -// ----------------------------------------------------------------------------- -// StringValue -// ----------------------------------------------------------------------------- - -static zend_function_entry string_value_methods[] = { - PHP_ME(StringValue, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(StringValue, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(StringValue, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* string_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\StringValue", - StringValue, string_value) - zend_declare_property_string(string_value_type, "value", strlen("value"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(StringValue, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(StringValue, string_value, Value, "value") - -// ----------------------------------------------------------------------------- -// Struct -// ----------------------------------------------------------------------------- - -static zend_function_entry struct_methods[] = { - PHP_ME(Struct, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Struct, getFields, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Struct, setFields, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* struct_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Struct", - Struct, struct) - zend_declare_property_null(struct_type, "fields", strlen("fields"), - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Struct, __construct) { - init_file_struct(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Struct, struct, Fields, "fields") - -// ----------------------------------------------------------------------------- -// Type -// ----------------------------------------------------------------------------- - -static zend_function_entry type_methods[] = { - PHP_ME(Type, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, setName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, getFields, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, setFields, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, getOneofs, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, setOneofs, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, getOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, setOptions, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, getSourceContext, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, setSourceContext, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, getSyntax, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Type, setSyntax, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* type_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Type", - Type, type) - zend_declare_property_string(type_type, "name", strlen("name"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(type_type, "fields", strlen("fields"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_string(type_type, "oneofs", strlen("oneofs"), "", - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(type_type, "options", strlen("options"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(type_type, "source_context", strlen("source_context"), - ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_long(type_type, "syntax", strlen("syntax"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Type, __construct) { - init_file_type(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(Type, type, Name, "name") -PHP_PROTO_FIELD_ACCESSORS(Type, type, Fields, "fields") -PHP_PROTO_FIELD_ACCESSORS(Type, type, Oneofs, "oneofs") -PHP_PROTO_FIELD_ACCESSORS(Type, type, Options, "options") -PHP_PROTO_FIELD_ACCESSORS(Type, type, SourceContext, "source_context") -PHP_PROTO_FIELD_ACCESSORS(Type, type, Syntax, "syntax") - -// ----------------------------------------------------------------------------- -// UInt32Value -// ----------------------------------------------------------------------------- - -static zend_function_entry u_int32_value_methods[] = { - PHP_ME(UInt32Value, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(UInt32Value, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(UInt32Value, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* u_int32_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt32Value", - UInt32Value, u_int32_value) - zend_declare_property_long(u_int32_value_type, "value", strlen("value"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(UInt32Value, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(UInt32Value, u_int32_value, Value, "value") - -// ----------------------------------------------------------------------------- -// UInt64Value -// ----------------------------------------------------------------------------- - -static zend_function_entry u_int64_value_methods[] = { - PHP_ME(UInt64Value, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(UInt64Value, getValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(UInt64Value, setValue, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* u_int64_value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\UInt64Value", - UInt64Value, u_int64_value) - zend_declare_property_long(u_int64_value_type, "value", strlen("value"), 0, - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(UInt64Value, __construct) { - init_file_wrappers(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_FIELD_ACCESSORS(UInt64Value, u_int64_value, Value, "value") - -// ----------------------------------------------------------------------------- -// Value -// ----------------------------------------------------------------------------- - -static zend_function_entry value_methods[] = { - PHP_ME(Value, __construct, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, getNullValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, setNullValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, getNumberValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, setNumberValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, getStringValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, setStringValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, getBoolValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, setBoolValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, getStructValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, setStructValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, getListValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, setListValue, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Value, getKind, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -zend_class_entry* value_type; - -// Init class entry. -PHP_PROTO_INIT_SUBMSGCLASS_START("Google\\Protobuf\\Value", - Value, value) - zend_declare_property_null(value_type, "kind", strlen("kind"), - ZEND_ACC_PRIVATE TSRMLS_CC); -PHP_PROTO_INIT_SUBMSGCLASS_END - -PHP_METHOD(Value, __construct) { - init_file_struct(TSRMLS_C); - INIT_MESSAGE_WITH_ARRAY; -} - -PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, NullValue, "null_value") -PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, NumberValue, "number_value") -PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, StringValue, "string_value") -PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, BoolValue, "bool_value") -PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, StructValue, "struct_value") -PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, ListValue, "list_value") -PHP_PROTO_ONEOF_ACCESSORS(Value, value, Kind, "kind") - -// ----------------------------------------------------------------------------- -// GPBMetadata files for well known types -// ----------------------------------------------------------------------------- - -#define DEFINE_GPBMETADATA_FILE(LOWERNAME, CAMELNAME, CLASSNAME) \ - zend_class_entry* gpb_metadata_##LOWERNAME##_type; \ - static zend_function_entry gpb_metadata_##LOWERNAME##_methods[] = { \ - PHP_ME(GPBMetadata_##CAMELNAME, initOnce, NULL, \ - ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) \ - ZEND_FE_END \ - }; \ - void gpb_metadata_##LOWERNAME##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY(class_type, CLASSNAME, \ - gpb_metadata_##LOWERNAME##_methods); \ - gpb_metadata_##LOWERNAME##_type = \ - zend_register_internal_class(&class_type TSRMLS_CC); \ - } \ - PHP_METHOD(GPBMetadata_##CAMELNAME, initOnce) { \ - init_file_##LOWERNAME(TSRMLS_C); \ - } - -DEFINE_GPBMETADATA_FILE(any, Any, "GPBMetadata\\Google\\Protobuf\\Any"); -DEFINE_GPBMETADATA_FILE(api, Api, "GPBMetadata\\Google\\Protobuf\\Api"); -DEFINE_GPBMETADATA_FILE(duration, Duration, - "GPBMetadata\\Google\\Protobuf\\Duration"); -DEFINE_GPBMETADATA_FILE(field_mask, FieldMask, - "GPBMetadata\\Google\\Protobuf\\FieldMask"); -DEFINE_GPBMETADATA_FILE(empty, Empty, - "GPBMetadata\\Google\\Protobuf\\GPBEmpty"); -DEFINE_GPBMETADATA_FILE(source_context, SourceContext, - "GPBMetadata\\Google\\Protobuf\\SourceContext"); -DEFINE_GPBMETADATA_FILE(struct, Struct, - "GPBMetadata\\Google\\Protobuf\\Struct"); -DEFINE_GPBMETADATA_FILE(timestamp, Timestamp, - "GPBMetadata\\Google\\Protobuf\\Timestamp"); -DEFINE_GPBMETADATA_FILE(type, Type, "GPBMetadata\\Google\\Protobuf\\Type"); -DEFINE_GPBMETADATA_FILE(wrappers, Wrappers, - "GPBMetadata\\Google\\Protobuf\\Wrappers"); - -#undef DEFINE_GPBMETADATA_FILE diff --git a/php/ext/google/protobuf/utf8.c b/php/ext/google/protobuf/message.h similarity index 56% rename from php/ext/google/protobuf/utf8.c rename to php/ext/google/protobuf/message.h index 2752a08b0593..0e6fb5a4fcbe 100644 --- a/php/ext/google/protobuf/utf8.c +++ b/php/ext/google/protobuf/message.h @@ -28,41 +28,35 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#ifndef PHP_PROTOBUF_MESSAGE_H_ +#define PHP_PROTOBUF_MESSAGE_H_ + #include -#include -#include "utf8.h" +#include "def.h" + +// Registers the PHP Message class. +void Message_ModuleInit(); -static const uint8_t utf8_offset[] = { - 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, 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, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, -}; +// Gets a upb_msg* for the PHP object |val|, which must either be a Message +// object or 'null'. Returns true and stores the message in |msg| if the +// conversion succeeded (we can't return upb_msg* because null->NULL is a valid +// conversion). Returns false and raises a PHP error if this isn't a Message +// object or null, or if the Message object doesn't match this Descriptor. +// +// The given |arena| will be fused to this message's arena. +bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena, + upb_msg **msg); + +// Gets or creates a PHP Message object to wrap the given upb_msg* and |desc| +// and returns it in |val|. The PHP object will keep a reference to this |arena| +// to ensure the underlying message data stays alive. +// +// If |msg| is NULL, this will return a PHP null. +void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg, + zval *arena); -bool is_structurally_valid_utf8(const char* buf, int len) { - int i, j; - uint8_t offset; +bool ValueEq(upb_msgval val1, upb_msgval val2, upb_fieldtype_t type, + const upb_msgdef *m); - i = 0; - while (i < len) { - offset = utf8_offset[(uint8_t)buf[i]]; - if (offset == 0 || i + offset > len) { - return false; - } - for (j = i + 1; j < i + offset; j++) { - if ((buf[j] & 0xc0) != 0x80) { - return false; - } - } - i += offset; - } - return i == len; -} +#endif // PHP_PROTOBUF_MESSAGE_H_ diff --git a/php/ext/google/protobuf/names.c b/php/ext/google/protobuf/names.c new file mode 100644 index 000000000000..ff04b3cbc35b --- /dev/null +++ b/php/ext/google/protobuf/names.c @@ -0,0 +1,226 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#include "names.h" + +#include + +#include "protobuf.h" + +/* stringsink *****************************************************************/ + +typedef struct { + char *ptr; + size_t len, size; +} stringsink; + +static size_t stringsink_string(stringsink *sink, const char *ptr, size_t len) { + size_t new_size = sink->size; + + 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; +} + +static void stringsink_init(stringsink *sink) { + sink->size = 32; + sink->ptr = malloc(sink->size); + PBPHP_ASSERT(sink->ptr != NULL); + sink->len = 0; +} + +static void stringsink_uninit(stringsink *sink) { free(sink->ptr); } + +/* def name -> classname ******************************************************/ + +const char *const kReservedNames[] = { + "abstract", "and", "array", "as", "break", + "callable", "case", "catch", "class", "clone", + "const", "continue", "declare", "default", "die", + "do", "echo", "else", "elseif", "empty", + "enddeclare", "endfor", "endforeach", "endif", "endswitch", + "endwhile", "eval", "exit", "extends", "final", + "for", "foreach", "function", "global", "goto", + "if", "implements", "include", "include_once", "instanceof", + "insteadof", "interface", "isset", "list", "namespace", + "new", "or", "print", "private", "protected", + "public", "require", "require_once", "return", "static", + "switch", "throw", "trait", "try", "unset", + "use", "var", "while", "xor", "int", + "float", "bool", "string", "true", "false", + "null", "void", "iterable", NULL}; + +bool is_reserved_name(const char* name) { + int i; + for (i = 0; kReservedNames[i]; i++) { + if (strcmp(kReservedNames[i], name) == 0) { + return true; + } + } + return false; +} + +static char nolocale_tolower(char ch) { + if (ch >= 'A' && ch <= 'Z') { + return ch - ('A' - 'a'); + } else { + return ch; + } +} + +static char nolocale_toupper(char ch) { + if (ch >= 'a' && ch <= 'z') { + return ch - ('a' - 'A'); + } else { + return ch; + } +} + +static bool is_reserved(const char *segment, int length) { + bool result; + char* lower = calloc(1, length + 1); + memcpy(lower, segment, length); + int i = 0; + while(lower[i]) { + lower[i] = nolocale_tolower(lower[i]); + i++; + } + lower[length] = 0; + result = is_reserved_name(lower); + free(lower); + return result; +} + +static void fill_prefix(const char *segment, int length, + const char *prefix_given, + const char *package_name, + stringsink *classname) { + if (prefix_given != NULL && strcmp(prefix_given, "") != 0) { + stringsink_string(classname, prefix_given, strlen(prefix_given)); + } else { + if (is_reserved(segment, length)) { + if (package_name != NULL && + strcmp("google.protobuf", package_name) == 0) { + stringsink_string(classname, "GPB", 3); + } else { + stringsink_string(classname, "PB", 2); + } + } + } +} + +static void fill_segment(const char *segment, int length, + stringsink *classname, bool use_camel) { + if (use_camel && (segment[0] < 'A' || segment[0] > 'Z')) { + char first = nolocale_toupper(segment[0]); + stringsink_string(classname, &first, 1); + stringsink_string(classname, segment + 1, length - 1); + } else { + stringsink_string(classname, segment, length); + } +} + +static void fill_namespace(const char *package, const char *php_namespace, + stringsink *classname) { + if (php_namespace != NULL) { + if (strlen(php_namespace) != 0) { + stringsink_string(classname, php_namespace, strlen(php_namespace)); + stringsink_string(classname, "\\", 1); + } + } else if (package != NULL) { + int i = 0, j = 0; + size_t package_len = strlen(package); + while (i < package_len) { + j = i; + while (j < package_len && package[j] != '.') { + j++; + } + fill_prefix(package + i, j - i, "", package, classname); + fill_segment(package + i, j - i, classname, true); + stringsink_string(classname, "\\", 1); + i = j + 1; + } + } +} + +static void fill_classname(const char *fullname, + const char *package, + const char *prefix, + stringsink *classname) { + int classname_start = 0; + if (package != NULL) { + size_t package_len = strlen(package); + classname_start = package_len == 0 ? 0 : package_len + 1; + } + size_t fullname_len = strlen(fullname); + + int i = classname_start, j; + while (i < fullname_len) { + j = i; + while (j < fullname_len && fullname[j] != '.') { + j++; + } + fill_prefix(fullname + i, j - i, prefix, package, classname); + fill_segment(fullname + i, j - i, classname, false); + if (j != fullname_len) { + stringsink_string(classname, "\\", 1); + } + i = j + 1; + } +} + +char *GetPhpClassname(const upb_filedef *file, const char *fullname) { + // Prepend '.' to package name to make it absolute. In the 5 additional + // bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if + // given message is google.protobuf.Empty. + const char *package = upb_filedef_package(file); + const char *php_namespace = upb_filedef_phpnamespace(file); + const char *prefix = upb_filedef_phpprefix(file); + char *ret; + stringsink namesink; + stringsink_init(&namesink); + + fill_namespace(package, php_namespace, &namesink); + fill_classname(fullname, package, prefix, &namesink); + stringsink_string(&namesink, "\0", 1); + ret = strdup(namesink.ptr); + stringsink_uninit(&namesink); + return ret; +} diff --git a/src/google/protobuf/unittest_no_arena_lite.proto b/php/ext/google/protobuf/names.h similarity index 81% rename from src/google/protobuf/unittest_no_arena_lite.proto rename to php/ext/google/protobuf/names.h index 34c7b7ce99a9..75101c5a78c3 100644 --- a/src/google/protobuf/unittest_no_arena_lite.proto +++ b/php/ext/google/protobuf/names.h @@ -28,15 +28,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -syntax = "proto2"; +#ifndef PHP_PROTOBUF_NAMES_H_ +#define PHP_PROTOBUF_NAMES_H_ -option optimize_for = LITE_RUNTIME; +#include "php-upb.h" -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest_no_arena; +// Translates a protobuf symbol name (eg. foo.bar.Baz) into a PHP class name +// (eg. \Foo\Bar\Baz). +char *GetPhpClassname(const upb_filedef *file, const char *fullname); -message ForeignMessageLite { - optional int32 c = 1; -} +#endif // PHP_PROTOBUF_NAMES_H_ diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index 99080b750fa4..557f8ffc23a7 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -10,42 +10,49 @@ protobuf-opensource@google.com yes - 2019-12-10 - + 2020-11-12 + - 3.11.2 - 3.11.2 + 3.14.0 + 3.14.0 stable stable 3-Clause BSD License - GA release. + PHP protobuf

    + + - + + + - + + + + + + + - - - - - - + + + - 5.5.9 + 7.0.0 1.4.0 @@ -501,5 +508,247 @@ G A release. 3-Clause BSD License GA release. + + + 3.11.3 + 3.11.3 + + + stable + stable + + 2020-01-28 + + 3-Clause BSD License + GA release. + + + + 3.11.4 + 3.11.4 + + + stable + stable + + 2020-02-12 + + 3-Clause BSD License + GA release. + + + + 3.12.0RC1 + 3.12.0 + + + beta + beta + + 2020-04-30 + + 3-Clause BSD License + GA release. + + + + 3.12.0RC2 + 3.12.0 + + + beta + beta + + 2020-05-12 + + 3-Clause BSD License + GA release. + + + + 3.12.0 + 3.12.0 + + + stable + stable + + 2020-05-15 + + 3-Clause BSD License + GA release. + + + + 3.12.1 + 3.12.1 + + + stable + stable + + 2020-05-20 + + 3-Clause BSD License + GA release. + + + + 3.12.2 + 3.12.2 + + + stable + stable + + 2020-05-26 + + 3-Clause BSD License + GA release. + + + + 3.12.3 + 3.12.3 + + + stable + stable + + 2020-06-01 + + 3-Clause BSD License + GA release. + + + + 3.13.0RC1 + 3.13.0 + + + beta + beta + + 2020-08-05 + + 3-Clause BSD License + GA release. + + + + 3.13.0RC2 + 3.13.0 + + + beta + beta + + 2020-08-05 + + 3-Clause BSD License + GA release. + + + + 3.13.0RC3 + 3.13.0 + + + beta + beta + + 2020-08-12 + + 3-Clause BSD License + GA release. + + + + 3.13.0 + 3.13.0 + + + stable + stable + + 2020-08-14 + + 3-Clause BSD License + GA release. + + + + 3.13.0.1 + 3.13.0.1 + + + stable + stable + + 2020-10-08 + + 3-Clause BSD License + GA release. + + + + 3.14.0RC1 + 3.14.0 + + + beta + beta + + 2020-11-05 + + 3-Clause BSD License + + + + + + 3.14.0RC2 + 3.14.0 + + + beta + beta + + 2020-11-10 + + 3-Clause BSD License + + + + + + 3.14.0RC3 + 3.14.0 + + + beta + beta + + 2020-11-11 + + 3-Clause BSD License + + + + + + 3.14.0 + 3.14.0 + + + stable + stable + + 2020-11-12 + + 3-Clause BSD License + + + diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c new file mode 100644 index 000000000000..738386890bb1 --- /dev/null +++ b/php/ext/google/protobuf/php-upb.c @@ -0,0 +1,8031 @@ +/* Amalgamated source file */ +#include "php-upb.h" +/* +* This is where we define macros used across upb. +* +* All of these macros are undef'd in port_undef.inc to avoid leaking them to +* users. +* +* The correct usage is: +* +* #include "upb/foobar.h" +* #include "upb/baz.h" +* +* // MUST be last included header. +* #include "upb/port_def.inc" +* +* // Code for this file. +* // <...> +* +* // Can be omitted for .c files, required for .h. +* #include "upb/port_undef.inc" +* +* This file is private and must not be included by users! +*/ + +#if !(__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L) +#error upb requires C99 or C++11 +#endif + +#if (defined(_MSC_VER) && _MSC_VER < 1900) +#error upb requires MSVC >= 2015. +#endif + +#include +#include + +#if UINTPTR_MAX == 0xffffffff +#define UPB_SIZE(size32, size64) size32 +#else +#define UPB_SIZE(size32, size64) size64 +#endif + +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) + +#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ + *UPB_PTR_AT(msg, case_offset, int) == case_val \ + ? *UPB_PTR_AT(msg, offset, fieldtype) \ + : default + +#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ + *UPB_PTR_AT(msg, case_offset, int) = case_val; \ + *UPB_PTR_AT(msg, offset, fieldtype) = value; + +#define UPB_MAPTYPE_STRING 0 + +/* UPB_INLINE: inline if possible, emit standalone code if required. */ +#ifdef __cplusplus +#define UPB_INLINE inline +#elif defined (__GNUC__) || defined(__clang__) +#define UPB_INLINE static __inline__ +#else +#define UPB_INLINE static +#endif + +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16) +#define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member) + +/* Hints to the compiler about likely/unlikely branches. */ +#if defined (__GNUC__) || defined(__clang__) +#define UPB_LIKELY(x) __builtin_expect((x),1) +#define UPB_UNLIKELY(x) __builtin_expect((x),0) +#else +#define UPB_LIKELY(x) (x) +#define UPB_UNLIKELY(x) (x) +#endif + +/* Macros for function attributes on compilers that support them. */ +#ifdef __GNUC__ +#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) +#define UPB_NOINLINE __attribute__((noinline)) +#define UPB_NORETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE +#define UPB_NORETURN __declspec(noreturn) +#else /* !defined(__GNUC__) */ +#define UPB_FORCEINLINE +#define UPB_NOINLINE +#define UPB_NORETURN +#endif + +#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define UPB_UNUSED(var) (void)var + +/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. + */ +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable() +#elif defined _MSC_VER +#define UPB_ASSUME(expr) if (!(expr)) __assume(0) +#else +#define UPB_ASSUME(expr) do {} while (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + +/* UPB_ASSERT(): in release mode, we use the expression without letting it be + * evaluated. This prevents "unused variable" warnings. */ +#ifdef NDEBUG +#define UPB_ASSERT(expr) do {} while (false && (expr)) +#else +#define UPB_ASSERT(expr) assert(expr) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0) +#else +#define UPB_UNREACHABLE() do { assert(0); } while(0) +#endif + +#if defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#ifdef __cplusplus +extern "C" { +#endif +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#ifdef __cplusplus +} /* extern "C" */ +#endif +#define UPB_POISON_MEMORY_REGION(addr, size) \ + __asan_poison_memory_region((addr), (size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) +#else +#define UPB_ASAN 0 +#define UPB_POISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#endif + + +#include +#include + + +/* Must be last. */ + +/* Maps descriptor type -> elem_size_lg2. */ +static const uint8_t desctype_to_elem_size_lg2[] = { + -1, /* invalid descriptor type */ + 3, /* DOUBLE */ + 2, /* FLOAT */ + 3, /* INT64 */ + 3, /* UINT64 */ + 2, /* INT32 */ + 3, /* FIXED64 */ + 2, /* FIXED32 */ + 0, /* BOOL */ + UPB_SIZE(3, 4), /* STRING */ + UPB_SIZE(2, 3), /* GROUP */ + UPB_SIZE(2, 3), /* MESSAGE */ + UPB_SIZE(3, 4), /* BYTES */ + 2, /* UINT32 */ + 2, /* ENUM */ + 2, /* SFIXED32 */ + 3, /* SFIXED64 */ + 2, /* SINT32 */ + 3, /* SINT64 */ +}; + +/* Maps descriptor type -> upb map size. */ +static const uint8_t desctype_to_mapsize[] = { + -1, /* invalid descriptor type */ + 8, /* DOUBLE */ + 4, /* FLOAT */ + 8, /* INT64 */ + 8, /* UINT64 */ + 4, /* INT32 */ + 8, /* FIXED64 */ + 4, /* FIXED32 */ + 1, /* BOOL */ + UPB_MAPTYPE_STRING, /* STRING */ + sizeof(void *), /* GROUP */ + sizeof(void *), /* MESSAGE */ + UPB_MAPTYPE_STRING, /* BYTES */ + 4, /* UINT32 */ + 4, /* ENUM */ + 4, /* SFIXED32 */ + 8, /* SFIXED64 */ + 4, /* SINT32 */ + 8, /* SINT64 */ +}; + +static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) | + (1 << UPB_DTYPE_FIXED32) | + (1 << UPB_DTYPE_SFIXED32); + +static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) | + (1 << UPB_DTYPE_FIXED64) | + (1 << UPB_DTYPE_SFIXED64); + +/* Op: an action to be performed for a wire-type/field-type combination. */ +#define OP_SCALAR_LG2(n) (n) /* n in [0, 2, 3] => op in [0, 2, 3] */ +#define OP_STRING 4 +#define OP_BYTES 5 +#define OP_SUBMSG 6 +/* Ops above are scalar-only. Repeated fields can use any op. */ +#define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */ +#define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */ + +static const int8_t varint_ops[19] = { + -1, /* field not found */ + -1, /* DOUBLE */ + -1, /* FLOAT */ + OP_SCALAR_LG2(3), /* INT64 */ + OP_SCALAR_LG2(3), /* UINT64 */ + OP_SCALAR_LG2(2), /* INT32 */ + -1, /* FIXED64 */ + -1, /* FIXED32 */ + OP_SCALAR_LG2(0), /* BOOL */ + -1, /* STRING */ + -1, /* GROUP */ + -1, /* MESSAGE */ + -1, /* BYTES */ + OP_SCALAR_LG2(2), /* UINT32 */ + OP_SCALAR_LG2(2), /* ENUM */ + -1, /* SFIXED32 */ + -1, /* SFIXED64 */ + OP_SCALAR_LG2(2), /* SINT32 */ + OP_SCALAR_LG2(3), /* SINT64 */ +}; + +static const int8_t delim_ops[37] = { + /* For non-repeated field type. */ + -1, /* field not found */ + -1, /* DOUBLE */ + -1, /* FLOAT */ + -1, /* INT64 */ + -1, /* UINT64 */ + -1, /* INT32 */ + -1, /* FIXED64 */ + -1, /* FIXED32 */ + -1, /* BOOL */ + OP_STRING, /* STRING */ + -1, /* GROUP */ + OP_SUBMSG, /* MESSAGE */ + OP_BYTES, /* BYTES */ + -1, /* UINT32 */ + -1, /* ENUM */ + -1, /* SFIXED32 */ + -1, /* SFIXED64 */ + -1, /* SINT32 */ + -1, /* SINT64 */ + /* For repeated field type. */ + OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */ + OP_FIXPCK_LG2(2), /* REPEATED FLOAT */ + OP_VARPCK_LG2(3), /* REPEATED INT64 */ + OP_VARPCK_LG2(3), /* REPEATED UINT64 */ + OP_VARPCK_LG2(2), /* REPEATED INT32 */ + OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */ + OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */ + OP_VARPCK_LG2(0), /* REPEATED BOOL */ + OP_STRING, /* REPEATED STRING */ + OP_SUBMSG, /* REPEATED GROUP */ + OP_SUBMSG, /* REPEATED MESSAGE */ + OP_BYTES, /* REPEATED BYTES */ + OP_VARPCK_LG2(2), /* REPEATED UINT32 */ + OP_VARPCK_LG2(2), /* REPEATED ENUM */ + OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */ + OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */ + OP_VARPCK_LG2(2), /* REPEATED SINT32 */ + OP_VARPCK_LG2(3), /* REPEATED SINT64 */ +}; + +/* Data pertaining to the parse. */ +typedef struct { + const char *end; /* Can read up to 16 bytes slop beyond this. */ + const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */ + int limit; /* Submessage limit relative to end. */ + int depth; + uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ + bool alias; + char patch[32]; + upb_arena arena; + jmp_buf err; +} upb_decstate; + +typedef union { + bool bool_val; + uint32_t uint32_val; + uint64_t uint64_val; + uint32_t size; +} wireval; + +static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout); + +UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); } + +void decode_verifyutf8(upb_decstate *d, const char *buf, int len) { + static const uint8_t utf8_offset[] = { + 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, 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, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + int i, j; + uint8_t offset; + + i = 0; + while (i < len) { + offset = utf8_offset[(uint8_t)buf[i]]; + if (offset == 0 || i + offset > len) { + decode_err(d); + } + for (j = i + 1; j < i + offset; j++) { + if ((buf[j] & 0xc0) != 0x80) { + decode_err(d); + } + } + i += offset; + } + if (i != len) decode_err(d); +} + +static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) { + bool need_realloc = arr->size - arr->len < elem; + if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) { + decode_err(d); + } + return need_realloc; +} + +typedef struct { + const char *ptr; + uint64_t val; +} decode_vret; + +UPB_NOINLINE +static decode_vret decode_longvarint64(const char *ptr, uint64_t val) { + decode_vret ret = {NULL, 0}; + uint64_t byte; + int i; + for (i = 1; i < 10; i++) { + byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + ret.ptr = ptr + i + 1; + ret.val = val; + return ret; + } + } + return ret; +} + +UPB_FORCEINLINE +static const char *decode_varint64(upb_decstate *d, const char *ptr, + uint64_t *val) { + uint64_t byte = (uint8_t)*ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; + return ptr + 1; + } else { + decode_vret res = decode_longvarint64(ptr, byte); + if (!res.ptr) decode_err(d); + *val = res.val; + return res.ptr; + } +} + +UPB_FORCEINLINE +static const char *decode_varint32(upb_decstate *d, const char *ptr, + uint32_t *val) { + uint64_t u64; + ptr = decode_varint64(d, ptr, &u64); + if (u64 > UINT32_MAX) decode_err(d); + *val = (uint32_t)u64; + return ptr; +} + +static void decode_munge(int type, wireval *val) { + switch (type) { + case UPB_DESCRIPTOR_TYPE_BOOL: + val->bool_val = val->uint64_val != 0; + break; + case UPB_DESCRIPTOR_TYPE_SINT32: { + uint32_t n = val->uint32_val; + val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1); + break; + } + case UPB_DESCRIPTOR_TYPE_SINT64: { + uint64_t n = val->uint64_val; + val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1); + break; + } + case UPB_DESCRIPTOR_TYPE_INT32: + case UPB_DESCRIPTOR_TYPE_UINT32: + if (!_upb_isle()) { + /* The next stage will memcpy(dst, &val, 4) */ + val->uint32_val = val->uint64_val; + } + break; + } +} + +static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, + uint32_t field_number) { + static upb_msglayout_field none = {0, 0, 0, 0, 0, 0}; + + /* Lots of optimization opportunities here. */ + int i; + if (l == NULL) return &none; + for (i = 0; i < l->field_count; i++) { + if (l->fields[i].number == field_number) { + return &l->fields[i]; + } + } + + return &none; /* Unknown field. */ +} + +static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout, + const upb_msglayout_field *field) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + return _upb_msg_new_inl(subl, &d->arena); +} + +static int decode_pushlimit(upb_decstate *d, const char *ptr, int size) { + int limit = size + (int)(ptr - d->end); + int delta = d->limit - limit; + d->limit = limit; + d->limit_ptr = d->end + UPB_MIN(0, limit); + return delta; +} + +static void decode_poplimit(upb_decstate *d, int saved_delta) { + d->limit += saved_delta; + d->limit_ptr = d->end + UPB_MIN(0, d->limit); +} + +typedef struct { + bool ok; + const char *ptr; +} decode_doneret; + +UPB_NOINLINE +static const char *decode_isdonefallback(upb_decstate *d, const char *ptr, + int overrun) { + if (overrun < d->limit) { + /* Need to copy remaining data into patch buffer. */ + UPB_ASSERT(overrun < 16); + memset(d->patch + 16, 0, 16); + memcpy(d->patch, d->end, 16); + ptr = &d->patch[0] + overrun; + d->end = &d->patch[16]; + d->limit -= 16; + d->limit_ptr = d->end + d->limit; + d->alias = false; + UPB_ASSERT(ptr < d->limit_ptr); + return ptr; + } else { + decode_err(d); + } +} + +UPB_FORCEINLINE +static bool decode_isdone(upb_decstate *d, const char **ptr) { + int overrun = *ptr - d->end; + if (UPB_LIKELY(*ptr < d->limit_ptr)) { + return false; + } else if (UPB_LIKELY(overrun == d->limit)) { + return true; + } else { + *ptr = decode_isdonefallback(d, *ptr, overrun); + return false; + } +} + +static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, + upb_strview *str) { + if (d->alias) { + str->data = ptr; + } else { + char *data = upb_arena_malloc(&d->arena, size); + if (!data) decode_err(d); + memcpy(data, ptr, size); + str->data = data; + } + str->size = size; + return ptr + size; +} + +static const char *decode_tosubmsg(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *layout, + const upb_msglayout_field *field, int size) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + int saved_delta = decode_pushlimit(d, ptr, size); + if (--d->depth < 0) decode_err(d); + ptr = decode_msg(d, ptr, submsg, subl); + decode_poplimit(d, saved_delta); + if (d->end_group != 0) decode_err(d); + d->depth++; + return ptr; +} + +static const char *decode_group(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *subl, + uint32_t number) { + if (--d->depth < 0) decode_err(d); + ptr = decode_msg(d, ptr, submsg, subl); + if (d->end_group != number) decode_err(d); + d->end_group = 0; + d->depth++; + return ptr; +} + +static const char *decode_togroup(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *layout, + const upb_msglayout_field *field) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + return decode_group(d, ptr, submsg, subl, field->number); +} + +static const char *decode_toarray(upb_decstate *d, const char *ptr, + upb_msg *msg, const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val, + int op) { + upb_array **arrp = UPB_PTR_AT(msg, field->offset, void); + upb_array *arr = *arrp; + void *mem; + + if (arr) { + decode_reserve(d, arr, 1); + } else { + size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype]; + arr = _upb_array_new(&d->arena, 4, lg2); + if (!arr) decode_err(d); + *arrp = arr; + } + + switch (op) { + case OP_SCALAR_LG2(0): + case OP_SCALAR_LG2(2): + case OP_SCALAR_LG2(3): + /* Append scalar value. */ + mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void); + arr->len++; + memcpy(mem, &val, 1 << op); + return ptr; + case OP_STRING: + decode_verifyutf8(d, ptr, val.size); + /* Fallthrough. */ + case OP_BYTES: { + /* Append bytes. */ + upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len; + arr->len++; + return decode_readstr(d, ptr, val.size, str); + } + case OP_SUBMSG: { + /* Append submessage / group. */ + upb_msg *submsg = decode_newsubmsg(d, layout, field); + *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) = + submsg; + arr->len++; + if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) { + return decode_togroup(d, ptr, submsg, layout, field); + } else { + return decode_tosubmsg(d, ptr, submsg, layout, field, val.size); + } + } + case OP_FIXPCK_LG2(2): + case OP_FIXPCK_LG2(3): { + /* Fixed packed. */ + int lg2 = op - OP_FIXPCK_LG2(0); + int mask = (1 << lg2) - 1; + size_t count = val.size >> lg2; + if ((val.size & mask) != 0) { + decode_err(d); /* Length isn't a round multiple of elem size. */ + } + decode_reserve(d, arr, count); + mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + arr->len += count; + memcpy(mem, ptr, val.size); /* XXX: ptr boundary. */ + return ptr + val.size; + } + case OP_VARPCK_LG2(0): + case OP_VARPCK_LG2(2): + case OP_VARPCK_LG2(3): { + /* Varint packed. */ + int lg2 = op - OP_VARPCK_LG2(0); + int scale = 1 << lg2; + int saved_limit = decode_pushlimit(d, ptr, val.size); + char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + while (!decode_isdone(d, &ptr)) { + wireval elem; + ptr = decode_varint64(d, ptr, &elem.uint64_val); + decode_munge(field->descriptortype, &elem); + if (decode_reserve(d, arr, 1)) { + out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + } + arr->len++; + memcpy(out, &elem, scale); + out += scale; + } + decode_poplimit(d, saved_limit); + return ptr; + } + default: + UPB_UNREACHABLE(); + } +} + +static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val) { + upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *); + upb_map *map = *map_p; + upb_map_entry ent; + const upb_msglayout *entry = layout->submsgs[field->submsg_index]; + + if (!map) { + /* Lazily create map. */ + const upb_msglayout *entry = layout->submsgs[field->submsg_index]; + const upb_msglayout_field *key_field = &entry->fields[0]; + const upb_msglayout_field *val_field = &entry->fields[1]; + char key_size = desctype_to_mapsize[key_field->descriptortype]; + char val_size = desctype_to_mapsize[val_field->descriptortype]; + UPB_ASSERT(key_field->offset == 0); + UPB_ASSERT(val_field->offset == sizeof(upb_strview)); + map = _upb_map_new(&d->arena, key_size, val_size); + *map_p = map; + } + + /* Parse map entry. */ + memset(&ent, 0, sizeof(ent)); + + if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || + entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) { + /* Create proactively to handle the case where it doesn't appear. */ + ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena)); + } + + ptr = decode_tosubmsg(d, ptr, &ent.k, layout, field, val.size); + _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena); + return ptr; +} + +static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val, + int op) { + void *mem = UPB_PTR_AT(msg, field->offset, void); + int type = field->descriptortype; + + /* Set presence if necessary. */ + if (field->presence < 0) { + /* Oneof case */ + uint32_t *oneof_case = _upb_oneofcase_field(msg, field); + if (op == OP_SUBMSG && *oneof_case != field->number) { + memset(mem, 0, sizeof(void*)); + } + *oneof_case = field->number; + } else if (field->presence > 0) { + _upb_sethas_field(msg, field); + } + + /* Store into message. */ + switch (op) { + case OP_SUBMSG: { + upb_msg **submsgp = mem; + upb_msg *submsg = *submsgp; + if (!submsg) { + submsg = decode_newsubmsg(d, layout, field); + *submsgp = submsg; + } + if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) { + ptr = decode_togroup(d, ptr, submsg, layout, field); + } else { + ptr = decode_tosubmsg(d, ptr, submsg, layout, field, val.size); + } + break; + } + case OP_STRING: + decode_verifyutf8(d, ptr, val.size); + /* Fallthrough. */ + case OP_BYTES: + return decode_readstr(d, ptr, val.size, mem); + case OP_SCALAR_LG2(3): + memcpy(mem, &val, 8); + break; + case OP_SCALAR_LG2(2): + memcpy(mem, &val, 4); + break; + case OP_SCALAR_LG2(0): + memcpy(mem, &val, 1); + break; + default: + UPB_UNREACHABLE(); + } + + return ptr; +} + +static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout) { + while (!decode_isdone(d, &ptr)) { + uint32_t tag; + const upb_msglayout_field *field; + int field_number; + int wire_type; + const char *field_start = ptr; + wireval val; + int op; + + ptr = decode_varint32(d, ptr, &tag); + field_number = tag >> 3; + wire_type = tag & 7; + + field = upb_find_field(layout, field_number); + + switch (wire_type) { + case UPB_WIRE_TYPE_VARINT: + ptr = decode_varint64(d, ptr, &val.uint64_val); + op = varint_ops[field->descriptortype]; + decode_munge(field->descriptortype, &val); + break; + case UPB_WIRE_TYPE_32BIT: + memcpy(&val.uint32_val, ptr, 4); + val.uint32_val = _upb_be_swap32(val.uint32_val); + ptr += 4; + op = OP_SCALAR_LG2(2); + if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown; + break; + case UPB_WIRE_TYPE_64BIT: + memcpy(&val.uint64_val, ptr, 8); + val.uint64_val = _upb_be_swap64(val.uint64_val); + ptr += 8; + op = OP_SCALAR_LG2(3); + if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown; + break; + case UPB_WIRE_TYPE_DELIMITED: { + int ndx = field->descriptortype; + if (_upb_isrepeated(field)) ndx += 18; + ptr = decode_varint32(d, ptr, &val.size); + if (val.size >= INT32_MAX || + ptr - d->end + (int32_t)val.size > d->limit) { + decode_err(d); /* Length overflow. */ + } + op = delim_ops[ndx]; + break; + } + case UPB_WIRE_TYPE_START_GROUP: + val.uint32_val = field_number; + op = OP_SUBMSG; + if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown; + break; + case UPB_WIRE_TYPE_END_GROUP: + d->end_group = field_number; + return ptr; + default: + decode_err(d); + } + + if (op >= 0) { + /* Parse, using op for dispatch. */ + switch (field->label) { + case UPB_LABEL_REPEATED: + case _UPB_LABEL_PACKED: + ptr = decode_toarray(d, ptr, msg, layout, field, val, op); + break; + case _UPB_LABEL_MAP: + ptr = decode_tomap(d, ptr, msg, layout, field, val); + break; + default: + ptr = decode_tomsg(d, ptr, msg, layout, field, val, op); + break; + } + } else { + unknown: + /* Skip unknown field. */ + if (field_number == 0) decode_err(d); + if (wire_type == UPB_WIRE_TYPE_START_GROUP) { + ptr = decode_group(d, ptr, NULL, NULL, field_number); + } + if (msg) { + if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size; + if (!_upb_msg_addunknown(msg, field_start, ptr - field_start, + &d->arena)) { + decode_err(d); + } + } + } + } + + return ptr; +} + +bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, + upb_arena *arena) { + bool ok; + upb_decstate state; + + if (size == 0) { + return true; + } else if (size < 16) { + memset(&state.patch, 0, 32); + memcpy(&state.patch, buf, size); + buf = state.patch; + state.end = buf + size; + state.limit = 0; + state.alias = false; + } else { + state.end = buf + size - 16; + state.limit = 16; + state.alias = true; + } + + state.limit_ptr = state.end; + state.depth = 64; + state.end_group = 0; + state.arena.head = arena->head; + state.arena.last_size = arena->last_size; + state.arena.parent = arena; + + if (UPB_UNLIKELY(setjmp(state.err))) { + ok = false; + } else { + decode_msg(&state, buf, msg, l); + ok = state.end_group == 0; + } + + arena->head.ptr = state.arena.head.ptr; + arena->head.end = state.arena.head.end; + return ok; +} + +#undef OP_SCALAR_LG2 +#undef OP_FIXPCK_LG2 +#undef OP_VARPCK_LG2 +#undef OP_STRING +#undef OP_SUBMSG +/* We encode backwards, to avoid pre-computing lengths (one-pass encode). */ + + +#include +#include + + + +#define UPB_PB_VARINT_MAX_LEN 10 + +UPB_NOINLINE +static size_t encode_varint64(uint64_t val, char *buf) { + size_t i = 0; + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + buf[i++] = byte; + } while (val); + return i; +} + +static uint32_t encode_zz32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); } +static uint64_t encode_zz64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); } + +typedef struct { + jmp_buf err; + upb_alloc *alloc; + char *buf, *ptr, *limit; +} upb_encstate; + +static size_t upb_roundup_pow2(size_t bytes) { + size_t ret = 128; + while (ret < bytes) { + ret *= 2; + } + return ret; +} + +UPB_NORETURN static void encode_err(upb_encstate *e) { longjmp(e->err, 1); } + +UPB_NOINLINE +static void encode_growbuffer(upb_encstate *e, size_t bytes) { + size_t old_size = e->limit - e->buf; + size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr)); + char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size); + + if (!new_buf) encode_err(e); + + /* We want previous data at the end, realloc() put it at the beginning. */ + if (old_size > 0) { + memmove(new_buf + new_size - old_size, e->buf, old_size); + } + + e->ptr = new_buf + new_size - (e->limit - e->ptr); + e->limit = new_buf + new_size; + e->buf = new_buf; + + e->ptr -= bytes; +} + +/* Call to ensure that at least "bytes" bytes are available for writing at + * e->ptr. Returns false if the bytes could not be allocated. */ +UPB_FORCEINLINE +static void encode_reserve(upb_encstate *e, size_t bytes) { + if ((size_t)(e->ptr - e->buf) < bytes) { + encode_growbuffer(e, bytes); + return; + } + + e->ptr -= bytes; +} + +/* Writes the given bytes to the buffer, handling reserve/advance. */ +static void encode_bytes(upb_encstate *e, const void *data, size_t len) { + if (len == 0) return; /* memcpy() with zero size is UB */ + encode_reserve(e, len); + memcpy(e->ptr, data, len); +} + +static void encode_fixed64(upb_encstate *e, uint64_t val) { + val = _upb_be_swap64(val); + encode_bytes(e, &val, sizeof(uint64_t)); +} + +static void encode_fixed32(upb_encstate *e, uint32_t val) { + val = _upb_be_swap32(val); + encode_bytes(e, &val, sizeof(uint32_t)); +} + +UPB_NOINLINE +static void encode_longvarint(upb_encstate *e, uint64_t val) { + size_t len; + char *start; + + encode_reserve(e, UPB_PB_VARINT_MAX_LEN); + len = encode_varint64(val, e->ptr); + start = e->ptr + UPB_PB_VARINT_MAX_LEN - len; + memmove(start, e->ptr, len); + e->ptr = start; +} + +UPB_FORCEINLINE +static void encode_varint(upb_encstate *e, uint64_t val) { + if (val < 128 && e->ptr != e->buf) { + --e->ptr; + *e->ptr = val; + } else { + encode_longvarint(e, val); + } +} + +static void encode_double(upb_encstate *e, double d) { + uint64_t u64; + UPB_ASSERT(sizeof(double) == sizeof(uint64_t)); + memcpy(&u64, &d, sizeof(uint64_t)); + encode_fixed64(e, u64); +} + +static void encode_float(upb_encstate *e, float d) { + uint32_t u32; + UPB_ASSERT(sizeof(float) == sizeof(uint32_t)); + memcpy(&u32, &d, sizeof(uint32_t)); + encode_fixed32(e, u32); +} + +static void encode_tag(upb_encstate *e, int field_number, int wire_type) { + encode_varint(e, (field_number << 3) | wire_type); +} + +static void encode_fixedarray(upb_encstate *e, const upb_array *arr, + size_t elem_size, uint32_t tag) { + size_t bytes = arr->len * elem_size; + const char* data = _upb_array_constptr(arr); + const char* ptr = data + bytes - elem_size; + if (tag) { + while (true) { + encode_bytes(e, ptr, elem_size); + encode_varint(e, tag); + if (ptr == data) break; + ptr -= elem_size; + } + } else { + encode_bytes(e, data, bytes); + } +} + +static void encode_message(upb_encstate *e, const char *msg, + const upb_msglayout *m, size_t *size); + +static void encode_scalar(upb_encstate *e, const void *_field_mem, + const upb_msglayout *m, const upb_msglayout_field *f, + bool skip_zero_value) { + const char *field_mem = _field_mem; + int wire_type; + +#define CASE(ctype, type, wtype, encodeval) \ + { \ + ctype val = *(ctype *)field_mem; \ + if (skip_zero_value && val == 0) { \ + return; \ + } \ + encode_##type(e, encodeval); \ + wire_type = wtype; \ + break; \ + } + + switch (f->descriptortype) { + case UPB_DESCRIPTOR_TYPE_DOUBLE: + CASE(double, double, UPB_WIRE_TYPE_64BIT, val); + case UPB_DESCRIPTOR_TYPE_FLOAT: + CASE(float, float, UPB_WIRE_TYPE_32BIT, val); + case UPB_DESCRIPTOR_TYPE_INT64: + case UPB_DESCRIPTOR_TYPE_UINT64: + CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val); + case UPB_DESCRIPTOR_TYPE_UINT32: + CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val); + case UPB_DESCRIPTOR_TYPE_INT32: + case UPB_DESCRIPTOR_TYPE_ENUM: + CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val); + case UPB_DESCRIPTOR_TYPE_SFIXED64: + case UPB_DESCRIPTOR_TYPE_FIXED64: + CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val); + case UPB_DESCRIPTOR_TYPE_FIXED32: + case UPB_DESCRIPTOR_TYPE_SFIXED32: + CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val); + case UPB_DESCRIPTOR_TYPE_BOOL: + CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val); + case UPB_DESCRIPTOR_TYPE_SINT32: + CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz32(val)); + case UPB_DESCRIPTOR_TYPE_SINT64: + CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, encode_zz64(val)); + case UPB_DESCRIPTOR_TYPE_STRING: + case UPB_DESCRIPTOR_TYPE_BYTES: { + upb_strview view = *(upb_strview*)field_mem; + if (skip_zero_value && view.size == 0) { + return; + } + encode_bytes(e, view.data, view.size); + encode_varint(e, view.size); + wire_type = UPB_WIRE_TYPE_DELIMITED; + break; + } + case UPB_DESCRIPTOR_TYPE_GROUP: { + size_t size; + void *submsg = *(void **)field_mem; + const upb_msglayout *subm = m->submsgs[f->submsg_index]; + if (submsg == NULL) { + return; + } + encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_message(e, submsg, subm, &size); + wire_type = UPB_WIRE_TYPE_START_GROUP; + break; + } + case UPB_DESCRIPTOR_TYPE_MESSAGE: { + size_t size; + void *submsg = *(void **)field_mem; + const upb_msglayout *subm = m->submsgs[f->submsg_index]; + if (submsg == NULL) { + return; + } + encode_message(e, submsg, subm, &size); + encode_varint(e, size); + wire_type = UPB_WIRE_TYPE_DELIMITED; + break; + } + default: + UPB_UNREACHABLE(); + } +#undef CASE + + encode_tag(e, f->number, wire_type); +} + +static void encode_array(upb_encstate *e, const char *field_mem, + const upb_msglayout *m, const upb_msglayout_field *f) { + const upb_array *arr = *(const upb_array**)field_mem; + bool packed = f->label == _UPB_LABEL_PACKED; + size_t pre_len = e->limit - e->ptr; + + if (arr == NULL || arr->len == 0) { + return; + } + +#define VARINT_CASE(ctype, encode) \ + { \ + const ctype *start = _upb_array_constptr(arr); \ + const ctype *ptr = start + arr->len; \ + uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \ + do { \ + ptr--; \ + encode_varint(e, encode); \ + if (tag) encode_varint(e, tag); \ + } while (ptr != start); \ + } \ + break; + +#define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type)) + + switch (f->descriptortype) { + case UPB_DESCRIPTOR_TYPE_DOUBLE: + encode_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT)); + break; + case UPB_DESCRIPTOR_TYPE_FLOAT: + encode_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT)); + break; + case UPB_DESCRIPTOR_TYPE_SFIXED64: + case UPB_DESCRIPTOR_TYPE_FIXED64: + encode_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT)); + break; + case UPB_DESCRIPTOR_TYPE_FIXED32: + case UPB_DESCRIPTOR_TYPE_SFIXED32: + encode_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT)); + break; + case UPB_DESCRIPTOR_TYPE_INT64: + case UPB_DESCRIPTOR_TYPE_UINT64: + VARINT_CASE(uint64_t, *ptr); + case UPB_DESCRIPTOR_TYPE_UINT32: + VARINT_CASE(uint32_t, *ptr); + case UPB_DESCRIPTOR_TYPE_INT32: + case UPB_DESCRIPTOR_TYPE_ENUM: + VARINT_CASE(int32_t, (int64_t)*ptr); + case UPB_DESCRIPTOR_TYPE_BOOL: + VARINT_CASE(bool, *ptr); + case UPB_DESCRIPTOR_TYPE_SINT32: + VARINT_CASE(int32_t, encode_zz32(*ptr)); + case UPB_DESCRIPTOR_TYPE_SINT64: + VARINT_CASE(int64_t, encode_zz64(*ptr)); + case UPB_DESCRIPTOR_TYPE_STRING: + case UPB_DESCRIPTOR_TYPE_BYTES: { + const upb_strview *start = _upb_array_constptr(arr); + const upb_strview *ptr = start + arr->len; + do { + ptr--; + encode_bytes(e, ptr->data, ptr->size); + encode_varint(e, ptr->size); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + } while (ptr != start); + return; + } + case UPB_DESCRIPTOR_TYPE_GROUP: { + const void *const*start = _upb_array_constptr(arr); + const void *const*ptr = start + arr->len; + const upb_msglayout *subm = m->submsgs[f->submsg_index]; + do { + size_t size; + ptr--; + encode_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP); + encode_message(e, *ptr, subm, &size); + encode_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); + } while (ptr != start); + return; + } + case UPB_DESCRIPTOR_TYPE_MESSAGE: { + const void *const*start = _upb_array_constptr(arr); + const void *const*ptr = start + arr->len; + const upb_msglayout *subm = m->submsgs[f->submsg_index]; + do { + size_t size; + ptr--; + encode_message(e, *ptr, subm, &size); + encode_varint(e, size); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + } while (ptr != start); + return; + } + } +#undef VARINT_CASE + + if (packed) { + encode_varint(e, e->limit - e->ptr - pre_len); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + } +} + +static void encode_map(upb_encstate *e, const char *field_mem, + const upb_msglayout *m, const upb_msglayout_field *f) { + const upb_map *map = *(const upb_map**)field_mem; + const upb_msglayout *entry = m->submsgs[f->submsg_index]; + const upb_msglayout_field *key_field = &entry->fields[0]; + const upb_msglayout_field *val_field = &entry->fields[1]; + upb_strtable_iter i; + if (map == NULL) { + return; + } + + upb_strtable_begin(&i, &map->table); + for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { + size_t pre_len = e->limit - e->ptr; + size_t size; + upb_strview key = upb_strtable_iter_key(&i); + const upb_value val = upb_strtable_iter_value(&i); + upb_map_entry ent; + _upb_map_fromkey(key, &ent.k, map->key_size); + _upb_map_fromvalue(val, &ent.v, map->val_size); + encode_scalar(e, &ent.v, entry, val_field, false); + encode_scalar(e, &ent.k, entry, key_field, false); + size = (e->limit - e->ptr) - pre_len; + encode_varint(e, size); + encode_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + } +} + +static void encode_scalarfield(upb_encstate *e, const char *msg, + const upb_msglayout *m, + const upb_msglayout_field *f) { + bool skip_empty = false; + if (f->presence == 0) { + /* Proto3 presence. */ + skip_empty = true; + } else if (f->presence > 0) { + /* Proto2 presence: hasbit. */ + if (!_upb_hasbit_field(msg, f)) return; + } else { + /* Field is in a oneof. */ + if (_upb_getoneofcase_field(msg, f) != f->number) return; + } + encode_scalar(e, msg + f->offset, m, f, skip_empty); +} + +static void encode_message(upb_encstate *e, const char *msg, + const upb_msglayout *m, size_t *size) { + size_t pre_len = e->limit - e->ptr; + const char *unknown; + size_t unknown_size; + const upb_msglayout_field *f = &m->fields[m->field_count]; + const upb_msglayout_field *first = &m->fields[0]; + + unknown = upb_msg_getunknown(msg, &unknown_size); + + if (unknown) { + encode_bytes(e, unknown, unknown_size); + } + + while (f != first) { + f--; + if (_upb_isrepeated(f)) { + encode_array(e, msg + f->offset, m, f); + } else if (f->label == _UPB_LABEL_MAP) { + encode_map(e, msg + f->offset, m, f); + } else { + encode_scalarfield(e, msg, m, f); + } + } + + *size = (e->limit - e->ptr) - pre_len; +} + +char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, + size_t *size) { + upb_encstate e; + e.alloc = upb_arena_alloc(arena); + e.buf = NULL; + e.limit = NULL; + e.ptr = NULL; + + if (setjmp(e.err)) { + *size = 0; + return NULL; + } + + encode_message(&e, msg, m, size); + + *size = e.limit - e.ptr; + + if (*size == 0) { + static char ch; + return &ch; + } else { + UPB_ASSERT(e.ptr); + return e.ptr; + } +} + + + + +/** upb_msg *******************************************************************/ + +static const size_t overhead = sizeof(upb_msg_internal); + +static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) { + ptrdiff_t size = sizeof(upb_msg_internal); + return (upb_msg_internal*)((char*)msg - size); +} + +upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) { + return _upb_msg_new_inl(l, a); +} + +void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) { + void *mem = UPB_PTR_AT(msg, -sizeof(upb_msg_internal), char); + memset(mem, 0, upb_msg_sizeof(l)); +} + +bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena) { + + upb_msg_internal *in = upb_msg_getinternal(msg); + if (!in->unknown) { + size_t size = 128; + while (size < len) size *= 2; + in->unknown = upb_arena_malloc(arena, size + overhead); + if (!in->unknown) return false; + in->unknown->size = size; + in->unknown->len = 0; + } else if (in->unknown->size - in->unknown->len < len) { + size_t need = in->unknown->len + len; + size_t size = in->unknown->size; + while (size < need) size *= 2; + in->unknown = upb_arena_realloc( + arena, in->unknown, in->unknown->size + overhead, size + overhead); + if (!in->unknown) return false; + in->unknown->size = size; + } + memcpy(UPB_PTR_AT(in->unknown + 1, in->unknown->len, char), data, len); + in->unknown->len += len; + return true; +} + +void _upb_msg_discardunknown_shallow(upb_msg *msg) { + upb_msg_internal *in = upb_msg_getinternal(msg); + if (in->unknown) { + in->unknown->len = 0; + } +} + +const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { + const upb_msg_internal *in = upb_msg_getinternal_const(msg); + if (in->unknown) { + *len = in->unknown->len; + return (char*)(in->unknown + 1); + } else { + *len = 0; + return NULL; + } +} + +/** upb_array *****************************************************************/ + +bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { + size_t new_size = UPB_MAX(arr->size, 4); + int elem_size_lg2 = arr->data & 7; + size_t old_bytes = arr->size << elem_size_lg2; + size_t new_bytes; + void* ptr = _upb_array_ptr(arr); + + /* Log2 ceiling of size. */ + while (new_size < min_size) new_size *= 2; + + new_bytes = new_size << elem_size_lg2; + ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes); + + if (!ptr) { + return false; + } + + arr->data = _upb_tag_arrptr(ptr, elem_size_lg2); + arr->size = new_size; + return true; +} + +static upb_array *getorcreate_array(upb_array **arr_ptr, int elem_size_lg2, + upb_arena *arena) { + upb_array *arr = *arr_ptr; + if (!arr) { + arr = _upb_array_new(arena, 4, elem_size_lg2); + if (!arr) return NULL; + *arr_ptr = arr; + } + return arr; +} + +void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, + int elem_size_lg2, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena); + return arr && _upb_array_resize(arr, size, arena) ? _upb_array_ptr(arr) + : NULL; +} + +bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, + int elem_size_lg2, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, elem_size_lg2, arena); + if (!arr) return false; + + size_t elems = arr->len; + + if (!_upb_array_resize(arr, elems + 1, arena)) { + return false; + } + + char *data = _upb_array_ptr(arr); + memcpy(data + (elems << elem_size_lg2), value, 1 << elem_size_lg2); + return true; +} + +/** upb_map *******************************************************************/ + +upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { + upb_map *map = upb_arena_malloc(a, sizeof(upb_map)); + + if (!map) { + return NULL; + } + + upb_strtable_init2(&map->table, UPB_CTYPE_INT32, 4, upb_arena_alloc(a)); + map->key_size = key_size; + map->val_size = value_size; + + return map; +} +/* +** upb_table Implementation +** +** Implementation is heavily inspired by Lua's ltable.c. +*/ + +#include + +#include "third_party/wyhash/wyhash.h" + +/* Must be last. */ + +#define UPB_MAXARRSIZE 16 /* 64k. */ + +/* From Chromium. */ +#define ARRAY_SIZE(x) \ + ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + +static const double MAX_LOAD = 0.85; + +/* The minimum utilization of the array part of a mixed hash/array table. This + * is a speed/memory-usage tradeoff (though it's not straightforward because of + * cache effects). The lower this is, the more memory we'll use. */ +static const double MIN_DENSITY = 0.1; + +bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; } + +int log2ceil(uint64_t v) { + int ret = 0; + bool pow2 = is_pow2(v); + while (v >>= 1) ret++; + ret = pow2 ? ret : ret + 1; /* Ceiling. */ + return UPB_MIN(UPB_MAXARRSIZE, ret); +} + +char *upb_strdup(const char *s, upb_alloc *a) { + return upb_strdup2(s, strlen(s), a); +} + +char *upb_strdup2(const char *s, size_t len, upb_alloc *a) { + size_t n; + char *p; + + /* Prevent overflow errors. */ + if (len == SIZE_MAX) return NULL; + /* Always null-terminate, even if binary data; but don't rely on the input to + * have a null-terminating byte since it may be a raw binary buffer. */ + n = len + 1; + p = upb_malloc(a, n); + if (p) { + memcpy(p, s, len); + p[len] = 0; + } + return p; +} + +/* A type to represent the lookup key of either a strtable or an inttable. */ +typedef union { + uintptr_t num; + struct { + const char *str; + size_t len; + } str; +} lookupkey_t; + +static lookupkey_t strkey2(const char *str, size_t len) { + lookupkey_t k; + k.str.str = str; + k.str.len = len; + return k; +} + +static lookupkey_t intkey(uintptr_t key) { + lookupkey_t k; + k.num = key; + return k; +} + +typedef uint32_t hashfunc_t(upb_tabkey key); +typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2); + +/* Base table (shared code) ***************************************************/ + +/* For when we need to cast away const. */ +static upb_tabent *mutable_entries(upb_table *t) { + return (upb_tabent*)t->entries; +} + +static bool isfull(upb_table *t) { + return t->count == t->max_count; +} + +static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) { + size_t bytes; + + t->count = 0; + t->size_lg2 = size_lg2; + t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0; + t->max_count = upb_table_size(t) * MAX_LOAD; + bytes = upb_table_size(t) * sizeof(upb_tabent); + if (bytes > 0) { + t->entries = upb_malloc(a, bytes); + if (!t->entries) return false; + memset(mutable_entries(t), 0, bytes); + } else { + t->entries = NULL; + } + return true; +} + +static void uninit(upb_table *t, upb_alloc *a) { + upb_free(a, mutable_entries(t)); +} + +static upb_tabent *emptyent(upb_table *t, upb_tabent *e) { + upb_tabent *begin = mutable_entries(t); + upb_tabent *end = begin + upb_table_size(t); + for (e = e + 1; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + for (e = begin; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + UPB_ASSERT(false); + return NULL; +} + +static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) { + return (upb_tabent*)upb_getentry(t, hash); +} + +static const upb_tabent *findentry(const upb_table *t, lookupkey_t key, + uint32_t hash, eqlfunc_t *eql) { + const upb_tabent *e; + + if (t->size_lg2 == 0) return NULL; + e = upb_getentry(t, hash); + if (upb_tabent_isempty(e)) return NULL; + while (1) { + if (eql(e->key, key)) return e; + if ((e = e->next) == NULL) return NULL; + } +} + +static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key, + uint32_t hash, eqlfunc_t *eql) { + return (upb_tabent*)findentry(t, key, hash, eql); +} + +static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, + uint32_t hash, eqlfunc_t *eql) { + const upb_tabent *e = findentry(t, key, hash, eql); + if (e) { + if (v) { + _upb_value_setval(v, e->val.val); + } + return true; + } else { + return false; + } +} + +/* The given key must not already exist in the table. */ +static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, + upb_value val, uint32_t hash, + hashfunc_t *hashfunc, eqlfunc_t *eql) { + upb_tabent *mainpos_e; + upb_tabent *our_e; + + UPB_ASSERT(findentry(t, key, hash, eql) == NULL); + + t->count++; + mainpos_e = getentry_mutable(t, hash); + our_e = mainpos_e; + + if (upb_tabent_isempty(mainpos_e)) { + /* Our main position is empty; use it. */ + our_e->next = NULL; + } else { + /* Collision. */ + upb_tabent *new_e = emptyent(t, mainpos_e); + /* Head of collider's chain. */ + upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key)); + if (chain == mainpos_e) { + /* Existing ent is in its main posisiton (it has the same hash as us, and + * is the head of our chain). Insert to new ent and append to this chain. */ + new_e->next = mainpos_e->next; + mainpos_e->next = new_e; + our_e = new_e; + } else { + /* Existing ent is not in its main position (it is a node in some other + * chain). This implies that no existing ent in the table has our hash. + * Evict it (updating its chain) and use its ent for head of our chain. */ + *new_e = *mainpos_e; /* copies next. */ + while (chain->next != mainpos_e) { + chain = (upb_tabent*)chain->next; + UPB_ASSERT(chain); + } + chain->next = new_e; + our_e = mainpos_e; + our_e->next = NULL; + } + } + our_e->key = tabkey; + our_e->val.val = val.val; + UPB_ASSERT(findentry(t, key, hash, eql) == our_e); +} + +static bool rm(upb_table *t, lookupkey_t key, upb_value *val, + upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) { + upb_tabent *chain = getentry_mutable(t, hash); + if (upb_tabent_isempty(chain)) return false; + if (eql(chain->key, key)) { + /* Element to remove is at the head of its chain. */ + t->count--; + if (val) _upb_value_setval(val, chain->val.val); + if (removed) *removed = chain->key; + if (chain->next) { + upb_tabent *move = (upb_tabent*)chain->next; + *chain = *move; + move->key = 0; /* Make the slot empty. */ + } else { + chain->key = 0; /* Make the slot empty. */ + } + return true; + } else { + /* Element to remove is either in a non-head position or not in the + * table. */ + while (chain->next && !eql(chain->next->key, key)) { + chain = (upb_tabent*)chain->next; + } + if (chain->next) { + /* Found element to remove. */ + upb_tabent *rm = (upb_tabent*)chain->next; + t->count--; + if (val) _upb_value_setval(val, chain->next->val.val); + if (removed) *removed = rm->key; + rm->key = 0; /* Make the slot empty. */ + chain->next = rm->next; + return true; + } else { + /* Element to remove is not in the table. */ + return false; + } + } +} + +static size_t next(const upb_table *t, size_t i) { + do { + if (++i >= upb_table_size(t)) + return SIZE_MAX - 1; /* Distinct from -1. */ + } while(upb_tabent_isempty(&t->entries[i])); + + return i; +} + +static size_t begin(const upb_table *t) { + return next(t, -1); +} + + +/* upb_strtable ***************************************************************/ + +/* A simple "subclass" of upb_table that only adds a hash function for strings. */ + +static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) { + uint32_t len = (uint32_t) k2.str.len; + char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1); + if (str == NULL) return 0; + memcpy(str, &len, sizeof(uint32_t)); + if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len); + str[sizeof(uint32_t) + k2.str.len] = '\0'; + return (uintptr_t)str; +} + +static uint32_t table_hash(const char *p, size_t n) { + return wyhash(p, n, 0, _wyp); +} + +static uint32_t strhash(upb_tabkey key) { + uint32_t len; + char *str = upb_tabstr(key, &len); + return table_hash(str, len); +} + +static bool streql(upb_tabkey k1, lookupkey_t k2) { + uint32_t len; + char *str = upb_tabstr(k1, &len); + return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0); +} + +bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, + size_t expected_size, upb_alloc *a) { + UPB_UNUSED(ctype); /* TODO(haberman): rm */ + // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator. + size_t need_entries = (expected_size + 1) * 1204 / 1024; + UPB_ASSERT(need_entries >= expected_size * 0.85); + int size_lg2 = _upb_lg2ceil(need_entries); + return init(&t->t, size_lg2, a); +} + +void upb_strtable_clear(upb_strtable *t) { + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); +} + +void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) { + size_t i; + for (i = 0; i < upb_table_size(&t->t); i++) + upb_free(a, (void*)t->t.entries[i].key); + uninit(&t->t, a); +} + +bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) { + upb_strtable new_table; + upb_strtable_iter i; + + if (!init(&new_table.t, size_lg2, a)) + return false; + upb_strtable_begin(&i, t); + for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) { + upb_strview key = upb_strtable_iter_key(&i); + upb_strtable_insert3( + &new_table, key.data, key.size, + upb_strtable_iter_value(&i), a); + } + upb_strtable_uninit2(t, a); + *t = new_table; + return true; +} + +bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len, + upb_value v, upb_alloc *a) { + lookupkey_t key; + upb_tabkey tabkey; + uint32_t hash; + + if (isfull(&t->t)) { + /* Need to resize. New table of double the size, add old elements to it. */ + if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) { + return false; + } + } + + key = strkey2(k, len); + tabkey = strcopy(key, a); + if (tabkey == 0) return false; + + hash = table_hash(key.str.str, key.str.len); + insert(&t->t, key, tabkey, v, hash, &strhash, &streql); + return true; +} + +bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, + upb_value *v) { + uint32_t hash = table_hash(key, len); + return lookup(&t->t, strkey2(key, len), v, hash, &streql); +} + +bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, + upb_value *val, upb_alloc *alloc) { + uint32_t hash = table_hash(key, len); + upb_tabkey tabkey; + if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) { + if (alloc) { + /* Arena-based allocs don't need to free and won't pass this. */ + upb_free(alloc, (void*)tabkey); + } + return true; + } else { + return false; + } +} + +/* Iteration */ + +void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) { + i->t = t; + i->index = begin(&t->t); +} + +void upb_strtable_next(upb_strtable_iter *i) { + i->index = next(&i->t->t, i->index); +} + +bool upb_strtable_done(const upb_strtable_iter *i) { + if (!i->t) return true; + return i->index >= upb_table_size(&i->t->t) || + upb_tabent_isempty(str_tabent(i)); +} + +upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) { + upb_strview key; + uint32_t len; + UPB_ASSERT(!upb_strtable_done(i)); + key.data = upb_tabstr(str_tabent(i)->key, &len); + key.size = len; + return key; +} + +upb_value upb_strtable_iter_value(const upb_strtable_iter *i) { + UPB_ASSERT(!upb_strtable_done(i)); + return _upb_value_val(str_tabent(i)->val.val); +} + +void upb_strtable_iter_setdone(upb_strtable_iter *i) { + i->t = NULL; + i->index = SIZE_MAX; +} + +bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, + const upb_strtable_iter *i2) { + if (upb_strtable_done(i1) && upb_strtable_done(i2)) + return true; + return i1->t == i2->t && i1->index == i2->index; +} + + +/* upb_inttable ***************************************************************/ + +/* For inttables we use a hybrid structure where small keys are kept in an + * array and large keys are put in the hash table. */ + +static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); } + +static bool inteql(upb_tabkey k1, lookupkey_t k2) { + return k1 == k2.num; +} + +static upb_tabval *mutable_array(upb_inttable *t) { + return (upb_tabval*)t->array; +} + +static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) { + if (key < t->array_size) { + return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL; + } else { + upb_tabent *e = + findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql); + return e ? &e->val : NULL; + } +} + +static const upb_tabval *inttable_val_const(const upb_inttable *t, + uintptr_t key) { + return inttable_val((upb_inttable*)t, key); +} + +size_t upb_inttable_count(const upb_inttable *t) { + return t->t.count + t->array_count; +} + +static void check(upb_inttable *t) { + UPB_UNUSED(t); +#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG) + { + /* This check is very expensive (makes inserts/deletes O(N)). */ + size_t count = 0; + upb_inttable_iter i; + upb_inttable_begin(&i, t); + for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) { + UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL)); + } + UPB_ASSERT(count == upb_inttable_count(t)); + } +#endif +} + +bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, + upb_alloc *a) { + size_t array_bytes; + + if (!init(&t->t, hsize_lg2, a)) return false; + /* Always make the array part at least 1 long, so that we know key 0 + * won't be in the hash part, which simplifies things. */ + t->array_size = UPB_MAX(1, asize); + t->array_count = 0; + array_bytes = t->array_size * sizeof(upb_value); + t->array = upb_malloc(a, array_bytes); + if (!t->array) { + uninit(&t->t, a); + return false; + } + memset(mutable_array(t), 0xff, array_bytes); + check(t); + return true; +} + +bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) { + UPB_UNUSED(ctype); /* TODO(haberman): rm */ + return upb_inttable_sizedinit(t, 0, 4, a); +} + +void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) { + uninit(&t->t, a); + upb_free(a, mutable_array(t)); +} + +bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, + upb_alloc *a) { + upb_tabval tabval; + tabval.val = val.val; + UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */ + + if (key < t->array_size) { + UPB_ASSERT(!upb_arrhas(t->array[key])); + t->array_count++; + mutable_array(t)[key].val = val.val; + } else { + if (isfull(&t->t)) { + /* Need to resize the hash part, but we re-use the array part. */ + size_t i; + upb_table new_table; + + if (!init(&new_table, t->t.size_lg2 + 1, a)) { + return false; + } + + for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { + const upb_tabent *e = &t->t.entries[i]; + uint32_t hash; + upb_value v; + + _upb_value_setval(&v, e->val.val); + hash = upb_inthash(e->key); + insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql); + } + + UPB_ASSERT(t->t.count == new_table.count); + + uninit(&t->t, a); + t->t = new_table; + } + insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql); + } + check(t); + return true; +} + +bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) { + const upb_tabval *table_v = inttable_val_const(t, key); + if (!table_v) return false; + if (v) _upb_value_setval(v, table_v->val); + return true; +} + +bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) { + upb_tabval *table_v = inttable_val(t, key); + if (!table_v) return false; + table_v->val = val.val; + return true; +} + +bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { + bool success; + if (key < t->array_size) { + if (upb_arrhas(t->array[key])) { + upb_tabval empty = UPB_TABVALUE_EMPTY_INIT; + t->array_count--; + if (val) { + _upb_value_setval(val, t->array[key].val); + } + mutable_array(t)[key] = empty; + success = true; + } else { + success = false; + } + } else { + success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql); + } + check(t); + return success; +} + +bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, + upb_alloc *a) { + return upb_inttable_insert2(t, (uintptr_t)key, val, a); +} + +bool upb_inttable_lookupptr(const upb_inttable *t, const void *key, + upb_value *v) { + return upb_inttable_lookup(t, (uintptr_t)key, v); +} + +bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) { + return upb_inttable_remove(t, (uintptr_t)key, val); +} + +void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) { + /* A power-of-two histogram of the table keys. */ + size_t counts[UPB_MAXARRSIZE + 1] = {0}; + + /* The max key in each bucket. */ + uintptr_t max[UPB_MAXARRSIZE + 1] = {0}; + + upb_inttable_iter i; + size_t arr_count; + int size_lg2; + upb_inttable new_t; + + upb_inttable_begin(&i, t); + for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { + uintptr_t key = upb_inttable_iter_key(&i); + int bucket = log2ceil(key); + max[bucket] = UPB_MAX(max[bucket], key); + counts[bucket]++; + } + + /* Find the largest power of two that satisfies the MIN_DENSITY + * definition (while actually having some keys). */ + arr_count = upb_inttable_count(t); + + for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) { + if (counts[size_lg2] == 0) { + /* We can halve again without losing any entries. */ + continue; + } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) { + break; + } + + arr_count -= counts[size_lg2]; + } + + UPB_ASSERT(arr_count <= upb_inttable_count(t)); + + { + /* Insert all elements into new, perfectly-sized table. */ + size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */ + size_t hash_count = upb_inttable_count(t) - arr_count; + size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0; + int hashsize_lg2 = log2ceil(hash_size); + + upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a); + upb_inttable_begin(&i, t); + for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { + uintptr_t k = upb_inttable_iter_key(&i); + upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a); + } + UPB_ASSERT(new_t.array_size == arr_size); + UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2); + } + upb_inttable_uninit2(t, a); + *t = new_t; +} + +/* Iteration. */ + +static const upb_tabent *int_tabent(const upb_inttable_iter *i) { + UPB_ASSERT(!i->array_part); + return &i->t->t.entries[i->index]; +} + +static upb_tabval int_arrent(const upb_inttable_iter *i) { + UPB_ASSERT(i->array_part); + return i->t->array[i->index]; +} + +void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) { + i->t = t; + i->index = -1; + i->array_part = true; + upb_inttable_next(i); +} + +void upb_inttable_next(upb_inttable_iter *iter) { + const upb_inttable *t = iter->t; + if (iter->array_part) { + while (++iter->index < t->array_size) { + if (upb_arrhas(int_arrent(iter))) { + return; + } + } + iter->array_part = false; + iter->index = begin(&t->t); + } else { + iter->index = next(&t->t, iter->index); + } +} + +bool upb_inttable_done(const upb_inttable_iter *i) { + if (!i->t) return true; + if (i->array_part) { + return i->index >= i->t->array_size || + !upb_arrhas(int_arrent(i)); + } else { + return i->index >= upb_table_size(&i->t->t) || + upb_tabent_isempty(int_tabent(i)); + } +} + +uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) { + UPB_ASSERT(!upb_inttable_done(i)); + return i->array_part ? i->index : int_tabent(i)->key; +} + +upb_value upb_inttable_iter_value(const upb_inttable_iter *i) { + UPB_ASSERT(!upb_inttable_done(i)); + return _upb_value_val( + i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val); +} + +void upb_inttable_iter_setdone(upb_inttable_iter *i) { + i->t = NULL; + i->index = SIZE_MAX; + i->array_part = false; +} + +bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, + const upb_inttable_iter *i2) { + if (upb_inttable_done(i1) && upb_inttable_done(i2)) + return true; + return i1->t == i2->t && i1->index == i2->index && + i1->array_part == i2->array_part; +} + + +#include +#include +#include +#include +#include +#include +#include + + +/* upb_status *****************************************************************/ + +void upb_status_clear(upb_status *status) { + if (!status) return; + status->ok = true; + status->msg[0] = '\0'; +} + +bool upb_ok(const upb_status *status) { return status->ok; } + +const char *upb_status_errmsg(const upb_status *status) { return status->msg; } + +void upb_status_seterrmsg(upb_status *status, const char *msg) { + if (!status) return; + status->ok = false; + strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; +} + +void upb_status_seterrf(upb_status *status, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + upb_status_vseterrf(status, fmt, args); + va_end(args); +} + +void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { + if (!status) return; + status->ok = false; + vsnprintf(status->msg, sizeof(status->msg), fmt, args); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; +} + +void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args) { + size_t len; + if (!status) return; + status->ok = false; + len = strlen(status->msg); + vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; +} + +/* upb_alloc ******************************************************************/ + +static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, + size_t size) { + UPB_UNUSED(alloc); + UPB_UNUSED(oldsize); + if (size == 0) { + free(ptr); + return NULL; + } else { + return realloc(ptr, size); + } +} + +upb_alloc upb_alloc_global = {&upb_global_allocfunc}; + +/* upb_arena ******************************************************************/ + +/* Be conservative and choose 16 in case anyone is using SSE. */ + +struct mem_block { + struct mem_block *next; + uint32_t size; + uint32_t cleanups; + /* Data follows. */ +}; + +typedef struct cleanup_ent { + upb_cleanup_func *cleanup; + void *ud; +} cleanup_ent; + +static const size_t memblock_reserve = UPB_ALIGN_UP(sizeof(mem_block), 16); + +static upb_arena *arena_findroot(upb_arena *a) { + /* Path splitting keeps time complexity down, see: + * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */ + while (a->parent != a) { + upb_arena *next = a->parent; + a->parent = next->parent; + a = next; + } + return a; +} + +static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr, + size_t size) { + mem_block *block = ptr; + + /* The block is for arena |a|, but should appear in the freelist of |root|. */ + block->next = root->freelist; + block->size = (uint32_t)size; + block->cleanups = 0; + root->freelist = block; + a->last_size = block->size; + if (!root->freelist_tail) root->freelist_tail = block; + + a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char); + a->head.end = UPB_PTR_AT(block, size, char); + a->cleanups = &block->cleanups; + + UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr); +} + +static bool upb_arena_allocblock(upb_arena *a, size_t size) { + upb_arena *root = arena_findroot(a); + size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve; + mem_block *block = upb_malloc(root->block_alloc, block_size); + + if (!block) return false; + upb_arena_addblock(a, root, block, block_size); + return true; +} + +void *_upb_arena_slowmalloc(upb_arena *a, size_t size) { + if (!upb_arena_allocblock(a, size)) return NULL; /* Out of memory. */ + UPB_ASSERT(_upb_arenahas(a, size)); + return upb_arena_malloc(a, size); +} + +static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, + size_t size) { + upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */ + return upb_arena_realloc(a, ptr, oldsize, size); +} + +/* Public Arena API ***********************************************************/ + +upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) { + const size_t first_block_overhead = sizeof(upb_arena) + memblock_reserve; + upb_arena *a; + + /* We need to malloc the initial block. */ + n = first_block_overhead + 256; + if (!alloc || !(mem = upb_malloc(alloc, n))) { + return NULL; + } + + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); + n -= sizeof(*a); + + a->head.alloc.func = &upb_arena_doalloc; + a->block_alloc = alloc; + a->parent = a; + a->refcount = 1; + a->freelist = NULL; + a->freelist_tail = NULL; + + upb_arena_addblock(a, a, mem, n); + + return a; +} + +upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { + upb_arena *a; + + /* Round block size down to alignof(*a) since we will allocate the arena + * itself at the end. */ + n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_arena)); + + if (UPB_UNLIKELY(n < sizeof(upb_arena))) { + return arena_initslow(mem, n, alloc); + } + + a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); + n -= sizeof(*a); + + a->head.alloc.func = &upb_arena_doalloc; + a->block_alloc = alloc; + a->parent = a; + a->refcount = 1; + a->last_size = 128; + a->head.ptr = mem; + a->head.end = UPB_PTR_AT(mem, n, char); + a->freelist = NULL; + a->cleanups = NULL; + + return a; +} + +static void arena_dofree(upb_arena *a) { + mem_block *block = a->freelist; + UPB_ASSERT(a->parent == a); + UPB_ASSERT(a->refcount == 0); + + while (block) { + /* Load first since we are deleting block. */ + mem_block *next = block->next; + + if (block->cleanups > 0) { + cleanup_ent *end = UPB_PTR_AT(block, block->size, void); + cleanup_ent *ptr = end - block->cleanups; + + for (; ptr < end; ptr++) { + ptr->cleanup(ptr->ud); + } + } + + upb_free(a->block_alloc, block); + block = next; + } +} + +void upb_arena_free(upb_arena *a) { + a = arena_findroot(a); + if (--a->refcount == 0) arena_dofree(a); +} + +bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { + cleanup_ent *ent; + + if (!a->cleanups || !_upb_arenahas(a, sizeof(cleanup_ent))) { + if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */ + UPB_ASSERT(_upb_arenahas(a, sizeof(cleanup_ent))); + } + + a->head.end -= sizeof(cleanup_ent); + ent = (cleanup_ent*)a->head.end; + (*a->cleanups)++; + UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent)); + + ent->cleanup = func; + ent->ud = ud; + + return true; +} + +void upb_arena_fuse(upb_arena *a1, upb_arena *a2) { + upb_arena *r1 = arena_findroot(a1); + upb_arena *r2 = arena_findroot(a2); + + if (r1 == r2) return; /* Already fused. */ + + /* We want to join the smaller tree to the larger tree. + * So swap first if they are backwards. */ + if (r1->refcount < r2->refcount) { + upb_arena *tmp = r1; + r1 = r2; + r2 = tmp; + } + + /* r1 takes over r2's freelist and refcount. */ + r1->refcount += r2->refcount; + if (r2->freelist_tail) { + UPB_ASSERT(r2->freelist_tail->next == NULL); + r2->freelist_tail->next = r1->freelist; + r1->freelist = r2->freelist; + } + r2->parent = r1; +} +/* 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 + + +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, 12, 1}, + {2, UPB_SIZE(12, 24), 2, 0, 12, 1}, + {3, UPB_SIZE(36, 72), 0, 0, 12, 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, 12, 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[7] = { + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_DescriptorProto_ExtensionRange_msginit, + &google_protobuf_DescriptorProto_ReservedRange_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_MessageOptions_msginit, + &google_protobuf_OneofDescriptorProto_msginit, +}; + +static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { + {1, UPB_SIZE(4, 8), 1, 0, 12, 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, 12, 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[11] = { + {1, UPB_SIZE(24, 24), 6, 0, 12, 1}, + {2, UPB_SIZE(32, 40), 7, 0, 12, 1}, + {3, UPB_SIZE(12, 12), 3, 0, 5, 1}, + {4, UPB_SIZE(4, 4), 1, 0, 14, 1}, + {5, UPB_SIZE(8, 8), 2, 0, 14, 1}, + {6, UPB_SIZE(40, 56), 8, 0, 12, 1}, + {7, UPB_SIZE(48, 72), 9, 0, 12, 1}, + {8, UPB_SIZE(64, 104), 11, 0, 11, 1}, + {9, UPB_SIZE(16, 16), 4, 0, 5, 1}, + {10, UPB_SIZE(56, 88), 10, 0, 12, 1}, + {17, UPB_SIZE(20, 20), 5, 0, 8, 1}, +}; + +const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { + &google_protobuf_FieldDescriptorProto_submsgs[0], + &google_protobuf_FieldDescriptorProto__fields[0], + UPB_SIZE(72, 112), 11, 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, 12, 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, 12, 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, 12, 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, 12, 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, 12, 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, 12, 1}, + {2, UPB_SIZE(12, 24), 4, 0, 12, 1}, + {3, UPB_SIZE(20, 40), 5, 0, 12, 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(20, 24), 11, 0, 12, 1}, + {8, UPB_SIZE(28, 40), 12, 0, 12, 1}, + {9, UPB_SIZE(4, 4), 1, 0, 14, 1}, + {10, UPB_SIZE(8, 8), 2, 0, 8, 1}, + {11, UPB_SIZE(36, 56), 13, 0, 12, 1}, + {16, UPB_SIZE(9, 9), 3, 0, 8, 1}, + {17, UPB_SIZE(10, 10), 4, 0, 8, 1}, + {18, UPB_SIZE(11, 11), 5, 0, 8, 1}, + {20, UPB_SIZE(12, 12), 6, 0, 8, 1}, + {23, UPB_SIZE(13, 13), 7, 0, 8, 1}, + {27, UPB_SIZE(14, 14), 8, 0, 8, 1}, + {31, UPB_SIZE(15, 15), 9, 0, 8, 1}, + {36, UPB_SIZE(44, 72), 14, 0, 12, 1}, + {37, UPB_SIZE(52, 88), 15, 0, 12, 1}, + {39, UPB_SIZE(60, 104), 16, 0, 12, 1}, + {40, UPB_SIZE(68, 120), 17, 0, 12, 1}, + {41, UPB_SIZE(76, 136), 18, 0, 12, 1}, + {42, UPB_SIZE(16, 16), 10, 0, 8, 1}, + {44, UPB_SIZE(84, 152), 19, 0, 12, 1}, + {45, UPB_SIZE(92, 168), 20, 0, 12, 1}, + {999, UPB_SIZE(100, 184), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FileOptions_msginit = { + &google_protobuf_FileOptions_submsgs[0], + &google_protobuf_FileOptions__fields[0], + UPB_SIZE(104, 192), 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(4, 4), 1, 0, 14, 1}, + {2, UPB_SIZE(12, 12), 3, 0, 8, 1}, + {3, UPB_SIZE(13, 13), 4, 0, 8, 1}, + {5, UPB_SIZE(14, 14), 5, 0, 8, 1}, + {6, UPB_SIZE(8, 8), 2, 0, 14, 1}, + {10, UPB_SIZE(15, 15), 6, 0, 8, 1}, + {999, UPB_SIZE(16, 16), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_FieldOptions_msginit = { + &google_protobuf_FieldOptions_submsgs[0], + &google_protobuf_FieldOptions__fields[0], + UPB_SIZE(20, 24), 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(8, 8), 2, 0, 8, 1}, + {34, UPB_SIZE(4, 4), 1, 0, 14, 1}, + {999, UPB_SIZE(12, 16), 0, 0, 11, 3}, +}; + +const upb_msglayout google_protobuf_MethodOptions_msginit = { + &google_protobuf_MethodOptions_submsgs[0], + &google_protobuf_MethodOptions__fields[0], + UPB_SIZE(16, 24), 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, 12, 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, 12, 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, 12, 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, _UPB_LABEL_PACKED}, + {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED}, + {3, UPB_SIZE(4, 8), 1, 0, 12, 1}, + {4, UPB_SIZE(12, 24), 2, 0, 12, 1}, + {6, UPB_SIZE(28, 56), 0, 0, 12, 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, _UPB_LABEL_PACKED}, + {2, UPB_SIZE(12, 16), 3, 0, 12, 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, +}; + + +/* 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. */ + + +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; + +static const upb_msglayout *layouts[27] = { + &google_protobuf_FileDescriptorSet_msginit, + &google_protobuf_FileDescriptorProto_msginit, + &google_protobuf_DescriptorProto_msginit, + &google_protobuf_DescriptorProto_ExtensionRange_msginit, + &google_protobuf_DescriptorProto_ReservedRange_msginit, + &google_protobuf_ExtensionRangeOptions_msginit, + &google_protobuf_FieldDescriptorProto_msginit, + &google_protobuf_OneofDescriptorProto_msginit, + &google_protobuf_EnumDescriptorProto_msginit, + &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, + &google_protobuf_EnumValueDescriptorProto_msginit, + &google_protobuf_ServiceDescriptorProto_msginit, + &google_protobuf_MethodDescriptorProto_msginit, + &google_protobuf_FileOptions_msginit, + &google_protobuf_MessageOptions_msginit, + &google_protobuf_FieldOptions_msginit, + &google_protobuf_OneofOptions_msginit, + &google_protobuf_EnumOptions_msginit, + &google_protobuf_EnumValueOptions_msginit, + &google_protobuf_ServiceOptions_msginit, + &google_protobuf_MethodOptions_msginit, + &google_protobuf_UninterpretedOption_msginit, + &google_protobuf_UninterpretedOption_NamePart_msginit, + &google_protobuf_SourceCodeInfo_msginit, + &google_protobuf_SourceCodeInfo_Location_msginit, + &google_protobuf_GeneratedCodeInfo_msginit, + &google_protobuf_GeneratedCodeInfo_Annotation_msginit, +}; + +static const char descriptor[7601] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', +'t', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', +'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n', +'\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', +'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', +'\004', 'f', 'i', 'l', 'e', '\"', '\344', '\004', '\n', '\023', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', +'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', +'\030', '\n', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\007', 'p', 'a', 'c', 'k', 'a', 'g', 'e', +'\022', '\036', '\n', '\n', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\003', ' ', '\003', '(', '\t', 'R', '\n', 'd', 'e', 'p', +'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', '+', '\n', '\021', 'p', 'u', 'b', 'l', 'i', 'c', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e', +'n', 'c', 'y', '\030', '\n', ' ', '\003', '(', '\005', 'R', '\020', 'p', 'u', 'b', 'l', 'i', 'c', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n', +'c', 'y', '\022', '\'', '\n', '\017', 'w', 'e', 'a', 'k', '_', 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\030', '\013', ' ', '\003', +'(', '\005', 'R', '\016', 'w', 'e', 'a', 'k', 'D', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'y', '\022', 'C', '\n', '\014', 'm', 'e', 's', +'s', 'a', 'g', 'e', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', +'\013', 'm', 'e', 's', 's', 'a', 'g', 'e', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e', +'\030', '\005', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\010', 'e', 'n', 'u', 'm', +'T', 'y', 'p', 'e', '\022', 'A', '\n', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\030', '\006', ' ', '\003', '(', '\013', '2', '\'', '.', 'g', +'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's', +'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\022', 'C', '\n', '\t', +'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\007', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', +'r', 'o', 't', 'o', 'R', '\t', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\022', '6', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', +'s', '\030', '\010', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', 'I', '\n', '\020', +'s', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'd', 'e', '_', 'i', 'n', 'f', 'o', '\030', '\t', ' ', '\001', '(', '\013', '2', '\037', '.', +'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', +'e', 'I', 'n', 'f', 'o', 'R', '\016', 's', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', '\026', '\n', '\006', +'s', 'y', 'n', 't', 'a', 'x', '\030', '\014', ' ', '\001', '(', '\t', 'R', '\006', 's', 'y', 'n', 't', 'a', 'x', '\"', '\271', '\006', '\n', '\017', +'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', +' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ';', '\n', '\005', 'f', 'i', 'e', 'l', 'd', '\030', '\002', ' ', '\003', '(', '\013', +'2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', +'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\005', 'f', 'i', 'e', 'l', 'd', '\022', 'C', '\n', '\t', +'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\006', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', +'r', 'o', 't', 'o', 'R', '\t', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\022', 'A', '\n', '\013', 'n', 'e', 's', 't', 'e', 'd', +'_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\003', '(', '\013', '2', ' ', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', +'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\n', 'n', 'e', 's', +'t', 'e', 'd', 'T', 'y', 'p', 'e', '\022', 'A', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e', '\030', '\004', ' ', '\003', '(', +'\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D', +'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\010', 'e', 'n', 'u', 'm', 'T', 'y', 'p', 'e', '\022', +'X', '\n', '\017', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\005', ' ', '\003', '(', '\013', '2', +'/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', +'t', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'R', '\016', +'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', 'D', '\n', '\n', 'o', 'n', 'e', 'o', 'f', '_', 'd', +'e', 'c', 'l', '\030', '\010', ' ', '\003', '(', '\013', '2', '%', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\t', +'o', 'n', 'e', 'o', 'f', 'D', 'e', 'c', 'l', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\007', ' ', '\001', '(', +'\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 's', 's', 'a', +'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', 'U', '\n', '\016', 'r', 'e', 's', +'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\t', ' ', '\003', '(', '\013', '2', '.', '.', 'g', 'o', 'o', 'g', 'l', +'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', +'o', '.', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', +'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ', +'\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', 'z', '\n', '\016', 'E', 'x', 't', 'e', +'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', +'R', '\005', 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', +'\022', '@', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', +'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', +'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\032', '7', '\n', '\r', 'R', 'e', 's', 'e', 'r', +'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', +'s', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '|', +'\n', '\025', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'X', +'\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', +' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', +'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', +'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', +'\301', '\006', '\n', '\024', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', +'\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', +'m', 'b', 'e', 'r', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', 'A', '\n', '\005', 'l', 'a', 'b', +'e', 'l', '\030', '\004', ' ', '\001', '(', '\016', '2', '+', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', +'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'L', 'a', +'b', 'e', 'l', 'R', '\005', 'l', 'a', 'b', 'e', 'l', '\022', '>', '\n', '\004', 't', 'y', 'p', 'e', '\030', '\005', ' ', '\001', '(', '\016', '2', +'*', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', +'s', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'T', 'y', 'p', 'e', 'R', '\004', 't', 'y', 'p', 'e', '\022', +'\033', '\n', '\t', 't', 'y', 'p', 'e', '_', 'n', 'a', 'm', 'e', '\030', '\006', ' ', '\001', '(', '\t', 'R', '\010', 't', 'y', 'p', 'e', 'N', +'a', 'm', 'e', '\022', '\032', '\n', '\010', 'e', 'x', 't', 'e', 'n', 'd', 'e', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\010', 'e', 'x', +'t', 'e', 'n', 'd', 'e', 'e', '\022', '#', '\n', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', +' ', '\001', '(', '\t', 'R', '\014', 'd', 'e', 'f', 'a', 'u', 'l', 't', 'V', 'a', 'l', 'u', 'e', '\022', '\037', '\n', '\013', 'o', 'n', 'e', +'o', 'f', '_', 'i', 'n', 'd', 'e', 'x', '\030', '\t', ' ', '\001', '(', '\005', 'R', '\n', 'o', 'n', 'e', 'o', 'f', 'I', 'n', 'd', 'e', +'x', '\022', '\033', '\n', '\t', 'j', 's', 'o', 'n', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ', '\001', '(', '\t', 'R', '\010', 'j', 's', 'o', +'n', 'N', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\035', '.', +'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', +'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '\'', '\n', '\017', 'p', 'r', 'o', 't', 'o', '3', '_', 'o', 'p', +'t', 'i', 'o', 'n', 'a', 'l', '\030', '\021', ' ', '\001', '(', '\010', 'R', '\016', 'p', 'r', 'o', 't', 'o', '3', 'O', 'p', 't', 'i', 'o', +'n', 'a', 'l', '\"', '\266', '\002', '\n', '\004', 'T', 'y', 'p', 'e', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B', +'L', 'E', '\020', '\001', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T', +'Y', 'P', 'E', '_', 'I', 'N', 'T', '6', '4', '\020', '\003', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6', +'4', '\020', '\004', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y', +'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\006', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E', +'D', '3', '2', '\020', '\007', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T', +'Y', 'P', 'E', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\t', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U', +'P', '\020', '\n', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n', +'T', 'Y', 'P', 'E', '_', 'B', 'Y', 'T', 'E', 'S', '\020', '\014', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', +'3', '2', '\020', '\r', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y', +'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\017', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I', +'X', 'E', 'D', '6', '4', '\020', '\020', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022', +'\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '6', '4', '\020', '\022', '\"', 'C', '\n', '\005', 'L', 'a', 'b', 'e', 'l', +'\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'O', 'P', 'T', 'I', 'O', 'N', 'A', 'L', '\020', '\001', '\022', '\022', '\n', '\016', 'L', +'A', 'B', 'E', 'L', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\002', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', +'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', '\020', '\003', '\"', 'c', '\n', '\024', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i', +'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', +'n', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\035', '.', 'g', +'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o', +'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\343', '\002', '\n', '\023', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', +'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', +'\004', 'n', 'a', 'm', 'e', '\022', '?', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', ')', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e', +'s', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\022', '6', '\n', '\007', 'o', +'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', +'s', '\022', ']', '\n', '\016', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\004', ' ', '\003', '(', '\013', +'2', '6', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D', 'e', +'s', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', +'d', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r', +'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', '\030', '\005', ' ', '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e', +'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', ';', '\n', '\021', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', +'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', 's', 't', 'a', 'r', +'t', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '\203', '\001', '\n', '\030', 'E', +'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', +'\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm', +'b', 'e', 'r', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', ';', '\n', '\007', 'o', 'p', 't', 'i', +'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '!', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', +'o', 'n', 's', '\"', '\247', '\001', '\n', '\026', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', +'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', +'\022', '>', '\n', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\030', '\002', ' ', '\003', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', +'r', 'P', 'r', 'o', 't', 'o', 'R', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', +'\030', '\003', ' ', '\001', '(', '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\211', +'\002', '\n', '\025', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', +'\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\035', '\n', '\n', 'i', 'n', +'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\t', 'i', 'n', 'p', 'u', 't', 'T', 'y', 'p', 'e', +'\022', '\037', '\n', '\013', 'o', 'u', 't', 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\n', 'o', 'u', +'t', 'p', 'u', 't', 'T', 'y', 'p', 'e', '\022', '8', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\004', ' ', '\001', '(', '\013', +'2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', +'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '0', '\n', '\020', 'c', 'l', 'i', 'e', 'n', +'t', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', +'\017', 'c', 'l', 'i', 'e', 'n', 't', 'S', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\022', '0', '\n', '\020', 's', 'e', 'r', 'v', 'e', +'r', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\006', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', +'\017', 's', 'e', 'r', 'v', 'e', 'r', 'S', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\"', '\221', '\t', '\n', '\013', 'F', 'i', 'l', 'e', +'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '!', '\n', '\014', 'j', 'a', 'v', 'a', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\001', +' ', '\001', '(', '\t', 'R', '\013', 'j', 'a', 'v', 'a', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '0', '\n', '\024', 'j', 'a', 'v', 'a', +'_', 'o', 'u', 't', 'e', 'r', '_', 'c', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\022', 'j', +'a', 'v', 'a', 'O', 'u', 't', 'e', 'r', 'C', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\022', '5', '\n', '\023', 'j', 'a', 'v', 'a', +'_', 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', '_', 'f', 'i', 'l', 'e', 's', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', +'l', 's', 'e', 'R', '\021', 'j', 'a', 'v', 'a', 'M', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'F', 'i', 'l', 'e', 's', '\022', 'D', '\n', +'\035', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'a', 't', 'e', '_', 'e', 'q', 'u', 'a', 'l', 's', '_', 'a', 'n', 'd', +'_', 'h', 'a', 's', 'h', '\030', '\024', ' ', '\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\031', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', +'r', 'a', 't', 'e', 'E', 'q', 'u', 'a', 'l', 's', 'A', 'n', 'd', 'H', 'a', 's', 'h', '\022', ':', '\n', '\026', 'j', 'a', 'v', 'a', +'_', 's', 't', 'r', 'i', 'n', 'g', '_', 'c', 'h', 'e', 'c', 'k', '_', 'u', 't', 'f', '8', '\030', '\033', ' ', '\001', '(', '\010', ':', +'\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'S', 't', 'r', 'i', 'n', 'g', 'C', 'h', 'e', 'c', 'k', 'U', 't', +'f', '8', '\022', 'S', '\n', '\014', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', '_', 'f', 'o', 'r', '\030', '\t', ' ', '\001', '(', '\016', '2', +')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'O', 'p', 't', +'i', 'o', 'n', 's', '.', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', 'e', ':', '\005', 'S', 'P', 'E', 'E', 'D', 'R', +'\013', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'F', 'o', 'r', '\022', '\035', '\n', '\n', 'g', 'o', '_', 'p', 'a', 'c', 'k', 'a', 'g', +'e', '\030', '\013', ' ', '\001', '(', '\t', 'R', '\t', 'g', 'o', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '5', '\n', '\023', 'c', 'c', '_', +'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\020', ' ', '\001', '(', '\010', ':', '\005', 'f', +'a', 'l', 's', 'e', 'R', '\021', 'c', 'c', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '9', +'\n', '\025', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\021', +' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', +'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '5', '\n', '\023', 'p', 'y', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', +'v', 'i', 'c', 'e', 's', '\030', '\022', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'p', 'y', 'G', 'e', 'n', +'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '7', '\n', '\024', 'p', 'h', 'p', '_', 'g', 'e', 'n', 'e', 'r', +'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '*', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', +'\022', 'p', 'h', 'p', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e', +'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\027', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', +'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '.', '\n', '\020', 'c', 'c', '_', 'e', 'n', 'a', 'b', 'l', 'e', '_', 'a', 'r', 'e', +'n', 'a', 's', '\030', '\037', ' ', '\001', '(', '\010', ':', '\004', 't', 'r', 'u', 'e', 'R', '\016', 'c', 'c', 'E', 'n', 'a', 'b', 'l', 'e', +'A', 'r', 'e', 'n', 'a', 's', '\022', '*', '\n', '\021', 'o', 'b', 'j', 'c', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', +'i', 'x', '\030', '$', ' ', '\001', '(', '\t', 'R', '\017', 'o', 'b', 'j', 'c', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', +'\022', ')', '\n', '\020', 'c', 's', 'h', 'a', 'r', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', '%', ' ', '\001', '(', +'\t', 'R', '\017', 'c', 's', 'h', 'a', 'r', 'p', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 's', 'w', 'i', +'f', 't', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '\'', ' ', '\001', '(', '\t', 'R', '\013', 's', 'w', 'i', 'f', 't', 'P', 'r', 'e', +'f', 'i', 'x', '\022', '(', '\n', '\020', 'p', 'h', 'p', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '(', +' ', '\001', '(', '\t', 'R', '\016', 'p', 'h', 'p', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '#', '\n', '\r', 'p', +'h', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ')', ' ', '\001', '(', '\t', 'R', '\014', 'p', 'h', 'p', 'N', 'a', +'m', 'e', 's', 'p', 'a', 'c', 'e', '\022', '4', '\n', '\026', 'p', 'h', 'p', '_', 'm', 'e', 't', 'a', 'd', 'a', 't', 'a', '_', 'n', +'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ',', ' ', '\001', '(', '\t', 'R', '\024', 'p', 'h', 'p', 'M', 'e', 't', 'a', 'd', 'a', +'t', 'a', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 'r', 'u', 'b', 'y', '_', 'p', 'a', 'c', 'k', 'a', +'g', 'e', '\030', '-', ' ', '\001', '(', '\t', 'R', '\013', 'r', 'u', 'b', 'y', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', 'X', '\n', '\024', +'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', +'(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', +'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', +'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', ':', '\n', '\014', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', +'d', 'e', '\022', '\t', '\n', '\005', 'S', 'P', 'E', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'C', 'O', 'D', 'E', '_', 'S', 'I', 'Z', +'E', '\020', '\002', '\022', '\020', '\n', '\014', 'L', 'I', 'T', 'E', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\003', '*', '\t', '\010', '\350', +'\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\321', '\002', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e', +'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '<', '\n', '\027', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 's', 'e', 't', '_', 'w', 'i', +'r', 'e', '_', 'f', 'o', 'r', 'm', 'a', 't', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\024', 'm', +'e', 's', 's', 'a', 'g', 'e', 'S', 'e', 't', 'W', 'i', 'r', 'e', 'F', 'o', 'r', 'm', 'a', 't', '\022', 'L', '\n', '\037', 'n', 'o', +'_', 's', 't', 'a', 'n', 'd', 'a', 'r', 'd', '_', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '_', 'a', 'c', 'c', 'e', +'s', 's', 'o', 'r', '\030', '\002', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\034', 'n', 'o', 'S', 't', 'a', 'n', +'d', 'a', 'r', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'A', 'c', 'c', 'e', 's', 's', 'o', 'r', '\022', '%', '\n', +'\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', +'\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\033', '\n', '\t', 'm', 'a', 'p', '_', 'e', 'n', 't', 'r', 'y', '\030', +'\007', ' ', '\001', '(', '\010', 'R', '\010', 'm', 'a', 'p', 'E', 'n', 't', 'r', 'y', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', +'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', +'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', +'t', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', +'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\010', '\020', '\t', 'J', '\004', '\010', +'\t', '\020', '\n', '\"', '\342', '\003', '\n', '\014', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'A', '\n', '\005', 'c', +'t', 'y', 'p', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'C', 'T', 'y', 'p', 'e', ':', '\006', 'S', +'T', 'R', 'I', 'N', 'G', 'R', '\005', 'c', 't', 'y', 'p', 'e', '\022', '\026', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\002', ' ', +'\001', '(', '\010', 'R', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\022', 'G', '\n', '\006', 'j', 's', 't', 'y', 'p', 'e', '\030', '\006', ' ', '\001', +'(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', +'d', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'J', 'S', 'T', 'y', 'p', 'e', ':', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', +'L', 'R', '\006', 'j', 's', 't', 'y', 'p', 'e', '\022', '\031', '\n', '\004', 'l', 'a', 'z', 'y', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', +'f', 'a', 'l', 's', 'e', 'R', '\004', 'l', 'a', 'z', 'y', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', +'\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', +'\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'w', 'e', +'a', 'k', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', +'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', +'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', +'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p', +'e', '\022', '\n', '\n', '\006', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\000', '\022', '\010', '\n', '\004', 'C', 'O', 'R', 'D', '\020', '\001', '\022', '\020', +'\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_', 'P', 'I', 'E', 'C', 'E', '\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p', +'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', '\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T', +'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'U', 'M', 'B', 'E', 'R', '\020', '\002', '*', '\t', '\010', '\350', +'\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', '\"', 's', '\n', '\014', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', +'i', 'o', 'n', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', +'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', +'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', +'\200', '\200', '\200', '\200', '\002', '\"', '\300', '\001', '\n', '\013', 'E', 'n', 'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\037', '\n', '\013', +'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i', 'a', 's', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A', +'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', +'\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', +'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', +'$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', +'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', +'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\005', '\020', '\006', +'\"', '\236', '\001', '\n', '\020', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', +'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', +'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', +'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', +'t', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', +'*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\234', '\001', '\n', '\016', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', +'t', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', +':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', +'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', +'2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', +'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', +'t', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\340', '\002', '\n', '\r', +'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', +'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', +'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"', +' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', +'t', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', +'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R', +'\020', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', +'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', +'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', +'d', 'O', 'p', 't', 'i', 'o', 'n', '\"', 'P', '\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', +'e', 'l', '\022', '\027', '\n', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', +'\020', '\000', '\022', '\023', '\n', '\017', 'N', 'O', '_', 'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016', +'\n', '\n', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', +'\"', '\232', '\003', '\n', '\023', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022', +'A', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', +'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', +'n', '.', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't', +'i', 'f', 'i', 'e', 'r', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i', +'f', 'i', 'e', 'r', 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', +'_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ', '\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't', +'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', +'u', 'e', '\030', '\005', ' ', '\001', '(', '\003', 'R', '\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', +'e', '\022', '!', '\n', '\014', 'd', 'o', 'u', 'b', 'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013', +'d', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l', +'u', 'e', '\030', '\007', ' ', '\001', '(', '\014', 'R', '\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017', +'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g', +'g', 'r', 'e', 'g', 'a', 't', 'e', 'V', 'a', 'l', 'u', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', +'\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p', 'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P', +'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's', '_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010', +'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\"', '\247', '\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', 'C', +'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', +'2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', +'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', 'i', +'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', +' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', ' ', +'\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', +'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', 'o', +'m', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', +'t', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', +'s', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', 'm', +'m', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', 'c', +'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\321', '\001', '\n', '\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', +'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', +'\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', +'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', +'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\032', 'm', '\n', '\n', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', +'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', +'\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o', +'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005', +'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', 'B', '~', +'\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', +'s', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', +'/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', +'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', +'n', +}; + +static upb_def_init *deps[1] = { + NULL +}; + +upb_def_init google_protobuf_descriptor_proto_upbdefinit = { + deps, + layouts, + "google/protobuf/descriptor.proto", + UPB_STRVIEW_INIT(descriptor, 7601) +}; + + +#include +#include +#include +#include +#include + + +typedef struct { + size_t len; + char str[1]; /* Null-terminated string data follows. */ +} str_t; + +struct upb_fielddef { + const upb_filedef *file; + const upb_msgdef *msgdef; + const char *full_name; + const char *json_name; + union { + int64_t sint; + uint64_t uint; + double dbl; + float flt; + bool boolean; + str_t *str; + } defaultval; + const upb_oneofdef *oneof; + union { + const upb_msgdef *msgdef; + const upb_enumdef *enumdef; + const google_protobuf_FieldDescriptorProto *unresolved; + } sub; + uint32_t number_; + uint16_t index_; + uint16_t layout_index; + uint32_t selector_base; /* Used to index into a upb::Handlers table. */ + bool is_extension_; + bool lazy_; + bool packed_; + bool proto3_optional_; + upb_descriptortype_t type_; + upb_label_t label_; +}; + +struct upb_msgdef { + const upb_msglayout *layout; + const upb_filedef *file; + const char *full_name; + uint32_t selector_count; + uint32_t submsg_field_count; + + /* Tables for looking up fields by number and name. */ + upb_inttable itof; + upb_strtable ntof; + + const upb_fielddef *fields; + const upb_oneofdef *oneofs; + int field_count; + int oneof_count; + int real_oneof_count; + + /* Is this a map-entry message? */ + bool map_entry; + upb_wellknowntype_t well_known_type; + + /* TODO(haberman): proper extension ranges (there can be multiple). */ +}; + +struct upb_enumdef { + const upb_filedef *file; + const char *full_name; + upb_strtable ntoi; + upb_inttable iton; + int32_t defaultval; +}; + +struct upb_oneofdef { + const upb_msgdef *parent; + const char *full_name; + int field_count; + bool synthetic; + const upb_fielddef **fields; + upb_strtable ntof; + upb_inttable itof; +}; + +struct upb_filedef { + const char *name; + const char *package; + const char *phpprefix; + const char *phpnamespace; + upb_syntax_t syntax; + + const upb_filedef **deps; + const upb_msgdef *msgs; + const upb_enumdef *enums; + const upb_fielddef *exts; + + int dep_count; + int msg_count; + int enum_count; + int ext_count; +}; + +struct upb_symtab { + upb_arena *arena; + upb_strtable syms; /* full_name -> packed def ptr */ + upb_strtable files; /* file_name -> upb_filedef* */ + size_t bytes_loaded; +}; + +/* Inside a symtab we store tagged pointers to specific def types. */ +typedef enum { + UPB_DEFTYPE_FIELD = 0, + + /* Only inside symtab table. */ + UPB_DEFTYPE_MSG = 1, + UPB_DEFTYPE_ENUM = 2, + + /* Only inside message table. */ + UPB_DEFTYPE_ONEOF = 1, + UPB_DEFTYPE_FIELD_JSONNAME = 2 +} upb_deftype_t; + +static const void *unpack_def(upb_value v, upb_deftype_t type) { + uintptr_t num = (uintptr_t)upb_value_getconstptr(v); + return (num & 3) == type ? (const void*)(num & ~3) : NULL; +} + +static upb_value pack_def(const void *ptr, upb_deftype_t type) { + uintptr_t num = (uintptr_t)ptr | type; + return upb_value_constptr((const void*)num); +} + +/* isalpha() etc. from are locale-dependent, which we don't want. */ +static bool upb_isbetween(char c, char low, char high) { + return c >= low && c <= high; +} + +static bool upb_isletter(char c) { + return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_'; +} + +static bool upb_isalphanum(char c) { + return upb_isletter(c) || upb_isbetween(c, '0', '9'); +} + +static const char *shortdefname(const char *fullname) { + const char *p; + + if (fullname == NULL) { + return NULL; + } else if ((p = strrchr(fullname, '.')) == NULL) { + /* No '.' in the name, return the full string. */ + return fullname; + } else { + /* Return one past the last '.'. */ + return p + 1; + } +} + +/* All submessage fields are lower than all other fields. + * Secondly, fields are increasing in order. */ +uint32_t field_rank(const upb_fielddef *f) { + uint32_t ret = upb_fielddef_number(f); + const uint32_t high_bit = 1 << 30; + UPB_ASSERT(ret < high_bit); + if (!upb_fielddef_issubmsg(f)) + ret |= high_bit; + return ret; +} + +int cmp_fields(const void *p1, const void *p2) { + const upb_fielddef *f1 = *(upb_fielddef*const*)p1; + const upb_fielddef *f2 = *(upb_fielddef*const*)p2; + return field_rank(f1) - field_rank(f2); +} + +/* A few implementation details of handlers. We put these here to avoid + * a def -> handlers dependency. */ + +#define UPB_STATIC_SELECTOR_COUNT 3 /* Warning: also in upb/handlers.h. */ + +static uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) { + return upb_fielddef_isseq(f) ? 2 : 0; +} + +static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) { + uint32_t ret = 1; + if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */ + if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */ + if (upb_fielddef_issubmsg(f)) { + /* ENDSUBMSG (STARTSUBMSG is at table beginning) */ + ret += 0; + if (upb_fielddef_lazy(f)) { + /* STARTSTR/ENDSTR/STRING (for lazy) */ + ret += 3; + } + } + return ret; +} + +static void upb_status_setoom(upb_status *status) { + upb_status_seterrmsg(status, "out of memory"); +} + +static void assign_msg_wellknowntype(upb_msgdef *m) { + const char *name = upb_msgdef_fullname(m); + if (name == NULL) { + m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + return; + } + if (!strcmp(name, "google.protobuf.Any")) { + m->well_known_type = UPB_WELLKNOWN_ANY; + } else if (!strcmp(name, "google.protobuf.FieldMask")) { + m->well_known_type = UPB_WELLKNOWN_FIELDMASK; + } else if (!strcmp(name, "google.protobuf.Duration")) { + m->well_known_type = UPB_WELLKNOWN_DURATION; + } else if (!strcmp(name, "google.protobuf.Timestamp")) { + m->well_known_type = UPB_WELLKNOWN_TIMESTAMP; + } else if (!strcmp(name, "google.protobuf.DoubleValue")) { + m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE; + } else if (!strcmp(name, "google.protobuf.FloatValue")) { + m->well_known_type = UPB_WELLKNOWN_FLOATVALUE; + } else if (!strcmp(name, "google.protobuf.Int64Value")) { + m->well_known_type = UPB_WELLKNOWN_INT64VALUE; + } else if (!strcmp(name, "google.protobuf.UInt64Value")) { + m->well_known_type = UPB_WELLKNOWN_UINT64VALUE; + } else if (!strcmp(name, "google.protobuf.Int32Value")) { + m->well_known_type = UPB_WELLKNOWN_INT32VALUE; + } else if (!strcmp(name, "google.protobuf.UInt32Value")) { + m->well_known_type = UPB_WELLKNOWN_UINT32VALUE; + } else if (!strcmp(name, "google.protobuf.BoolValue")) { + m->well_known_type = UPB_WELLKNOWN_BOOLVALUE; + } else if (!strcmp(name, "google.protobuf.StringValue")) { + m->well_known_type = UPB_WELLKNOWN_STRINGVALUE; + } else if (!strcmp(name, "google.protobuf.BytesValue")) { + m->well_known_type = UPB_WELLKNOWN_BYTESVALUE; + } else if (!strcmp(name, "google.protobuf.Value")) { + m->well_known_type = UPB_WELLKNOWN_VALUE; + } else if (!strcmp(name, "google.protobuf.ListValue")) { + m->well_known_type = UPB_WELLKNOWN_LISTVALUE; + } else if (!strcmp(name, "google.protobuf.Struct")) { + m->well_known_type = UPB_WELLKNOWN_STRUCT; + } else { + m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; + } +} + + +/* upb_enumdef ****************************************************************/ + +const char *upb_enumdef_fullname(const upb_enumdef *e) { + return e->full_name; +} + +const char *upb_enumdef_name(const upb_enumdef *e) { + return shortdefname(e->full_name); +} + +const upb_filedef *upb_enumdef_file(const upb_enumdef *e) { + return e->file; +} + +int32_t upb_enumdef_default(const upb_enumdef *e) { + UPB_ASSERT(upb_enumdef_iton(e, e->defaultval)); + return e->defaultval; +} + +int upb_enumdef_numvals(const upb_enumdef *e) { + return (int)upb_strtable_count(&e->ntoi); +} + +void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) { + /* We iterate over the ntoi table, to account for duplicate numbers. */ + upb_strtable_begin(i, &e->ntoi); +} + +void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); } +bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); } + +bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name, + size_t len, int32_t *num) { + upb_value v; + if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) { + return false; + } + if (num) *num = upb_value_getint32(v); + return true; +} + +const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) { + upb_value v; + return upb_inttable_lookup32(&def->iton, num, &v) ? + upb_value_getcstr(v) : NULL; +} + +const char *upb_enum_iter_name(upb_enum_iter *iter) { + return upb_strtable_iter_key(iter).data; +} + +int32_t upb_enum_iter_number(upb_enum_iter *iter) { + return upb_value_getint32(upb_strtable_iter_value(iter)); +} + + +/* upb_fielddef ***************************************************************/ + +const char *upb_fielddef_fullname(const upb_fielddef *f) { + return f->full_name; +} + +upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) { + switch (f->type_) { + case UPB_DESCRIPTOR_TYPE_DOUBLE: + return UPB_TYPE_DOUBLE; + case UPB_DESCRIPTOR_TYPE_FLOAT: + return UPB_TYPE_FLOAT; + case UPB_DESCRIPTOR_TYPE_INT64: + case UPB_DESCRIPTOR_TYPE_SINT64: + case UPB_DESCRIPTOR_TYPE_SFIXED64: + return UPB_TYPE_INT64; + case UPB_DESCRIPTOR_TYPE_INT32: + case UPB_DESCRIPTOR_TYPE_SFIXED32: + case UPB_DESCRIPTOR_TYPE_SINT32: + return UPB_TYPE_INT32; + case UPB_DESCRIPTOR_TYPE_UINT64: + case UPB_DESCRIPTOR_TYPE_FIXED64: + return UPB_TYPE_UINT64; + case UPB_DESCRIPTOR_TYPE_UINT32: + case UPB_DESCRIPTOR_TYPE_FIXED32: + return UPB_TYPE_UINT32; + case UPB_DESCRIPTOR_TYPE_ENUM: + return UPB_TYPE_ENUM; + case UPB_DESCRIPTOR_TYPE_BOOL: + return UPB_TYPE_BOOL; + case UPB_DESCRIPTOR_TYPE_STRING: + return UPB_TYPE_STRING; + case UPB_DESCRIPTOR_TYPE_BYTES: + return UPB_TYPE_BYTES; + case UPB_DESCRIPTOR_TYPE_GROUP: + case UPB_DESCRIPTOR_TYPE_MESSAGE: + return UPB_TYPE_MESSAGE; + } + UPB_UNREACHABLE(); +} + +upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) { + return f->type_; +} + +uint32_t upb_fielddef_index(const upb_fielddef *f) { + return f->index_; +} + +upb_label_t upb_fielddef_label(const upb_fielddef *f) { + return f->label_; +} + +uint32_t upb_fielddef_number(const upb_fielddef *f) { + return f->number_; +} + +bool upb_fielddef_isextension(const upb_fielddef *f) { + return f->is_extension_; +} + +bool upb_fielddef_lazy(const upb_fielddef *f) { + return f->lazy_; +} + +bool upb_fielddef_packed(const upb_fielddef *f) { + return f->packed_; +} + +const char *upb_fielddef_name(const upb_fielddef *f) { + return shortdefname(f->full_name); +} + +const char *upb_fielddef_jsonname(const upb_fielddef *f) { + return f->json_name; +} + +uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) { + return f->selector_base; +} + +const upb_filedef *upb_fielddef_file(const upb_fielddef *f) { + return f->file; +} + +const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { + return f->msgdef; +} + +const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) { + return f->oneof; +} + +const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) { + if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL; + return f->oneof; +} + +static void chkdefaulttype(const upb_fielddef *f, int ctype) { + UPB_UNUSED(f); + UPB_UNUSED(ctype); +} + +int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { + chkdefaulttype(f, UPB_TYPE_INT64); + return f->defaultval.sint; +} + +int32_t upb_fielddef_defaultint32(const upb_fielddef *f) { + chkdefaulttype(f, UPB_TYPE_INT32); + return (int32_t)f->defaultval.sint; +} + +uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { + chkdefaulttype(f, UPB_TYPE_UINT64); + return f->defaultval.uint; +} + +uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) { + chkdefaulttype(f, UPB_TYPE_UINT32); + return (uint32_t)f->defaultval.uint; +} + +bool upb_fielddef_defaultbool(const upb_fielddef *f) { + chkdefaulttype(f, UPB_TYPE_BOOL); + return f->defaultval.boolean; +} + +float upb_fielddef_defaultfloat(const upb_fielddef *f) { + chkdefaulttype(f, UPB_TYPE_FLOAT); + return f->defaultval.flt; +} + +double upb_fielddef_defaultdouble(const upb_fielddef *f) { + chkdefaulttype(f, UPB_TYPE_DOUBLE); + return f->defaultval.dbl; +} + +const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) { + str_t *str = f->defaultval.str; + UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING || + upb_fielddef_type(f) == UPB_TYPE_BYTES || + upb_fielddef_type(f) == UPB_TYPE_ENUM); + if (str) { + if (len) *len = str->len; + return str->str; + } else { + if (len) *len = 0; + return NULL; + } +} + +const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) { + return upb_fielddef_type(f) == UPB_TYPE_MESSAGE ? f->sub.msgdef : NULL; +} + +const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) { + return upb_fielddef_type(f) == UPB_TYPE_ENUM ? f->sub.enumdef : NULL; +} + +const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) { + return &f->msgdef->layout->fields[f->layout_index]; +} + +bool upb_fielddef_issubmsg(const upb_fielddef *f) { + return upb_fielddef_type(f) == UPB_TYPE_MESSAGE; +} + +bool upb_fielddef_isstring(const upb_fielddef *f) { + return upb_fielddef_type(f) == UPB_TYPE_STRING || + upb_fielddef_type(f) == UPB_TYPE_BYTES; +} + +bool upb_fielddef_isseq(const upb_fielddef *f) { + return upb_fielddef_label(f) == UPB_LABEL_REPEATED; +} + +bool upb_fielddef_isprimitive(const upb_fielddef *f) { + return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f); +} + +bool upb_fielddef_ismap(const upb_fielddef *f) { + return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) && + upb_msgdef_mapentry(upb_fielddef_msgsubdef(f)); +} + +bool upb_fielddef_hassubdef(const upb_fielddef *f) { + return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM; +} + +bool upb_fielddef_haspresence(const upb_fielddef *f) { + if (upb_fielddef_isseq(f)) return false; + return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) || + f->file->syntax == UPB_SYNTAX_PROTO2; +} + +static bool between(int32_t x, int32_t low, int32_t high) { + return x >= low && x <= high; +} + +bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); } +bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); } +bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); } + +bool upb_fielddef_checkdescriptortype(int32_t type) { + return between(type, 1, 18); +} + +/* upb_msgdef *****************************************************************/ + +const char *upb_msgdef_fullname(const upb_msgdef *m) { + return m->full_name; +} + +const upb_filedef *upb_msgdef_file(const upb_msgdef *m) { + return m->file; +} + +const char *upb_msgdef_name(const upb_msgdef *m) { + return shortdefname(m->full_name); +} + +upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) { + return m->file->syntax; +} + +size_t upb_msgdef_selectorcount(const upb_msgdef *m) { + return m->selector_count; +} + +uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) { + return m->submsg_field_count; +} + +const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) { + upb_value val; + return upb_inttable_lookup32(&m->itof, i, &val) ? + upb_value_getconstptr(val) : NULL; +} + +const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, + size_t len) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return NULL; + } + + return unpack_def(val, UPB_DEFTYPE_FIELD); +} + +const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, + size_t len) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return NULL; + } + + return unpack_def(val, UPB_DEFTYPE_ONEOF); +} + +bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, + const upb_fielddef **f, const upb_oneofdef **o) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return false; + } + + *o = unpack_def(val, UPB_DEFTYPE_ONEOF); + *f = unpack_def(val, UPB_DEFTYPE_FIELD); + return *o || *f; /* False if this was a JSON name. */ +} + +const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, + const char *name, size_t len) { + upb_value val; + const upb_fielddef* f; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return NULL; + } + + f = unpack_def(val, UPB_DEFTYPE_FIELD); + if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME); + + return f; +} + +int upb_msgdef_numfields(const upb_msgdef *m) { + return m->field_count; +} + +int upb_msgdef_numoneofs(const upb_msgdef *m) { + return m->oneof_count; +} + +int upb_msgdef_numrealoneofs(const upb_msgdef *m) { + return m->real_oneof_count; +} + +int upb_msgdef_fieldcount(const upb_msgdef *m) { + return m->field_count; +} + +int upb_msgdef_oneofcount(const upb_msgdef *m) { + return m->oneof_count; +} + +int upb_msgdef_realoneofcount(const upb_msgdef *m) { + return m->real_oneof_count; +} + +const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) { + return m->layout; +} + +const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i) { + UPB_ASSERT(i >= 0 && i < m->field_count); + return &m->fields[i]; +} + +const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i) { + UPB_ASSERT(i >= 0 && i < m->oneof_count); + return &m->oneofs[i]; +} + +bool upb_msgdef_mapentry(const upb_msgdef *m) { + return m->map_entry; +} + +upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) { + return m->well_known_type; +} + +bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) { + upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); + return type >= UPB_WELLKNOWN_DOUBLEVALUE && + type <= UPB_WELLKNOWN_UINT32VALUE; +} + +bool upb_msgdef_iswrapper(const upb_msgdef *m) { + upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); + return type >= UPB_WELLKNOWN_DOUBLEVALUE && + type <= UPB_WELLKNOWN_BOOLVALUE; +} + +void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) { + upb_inttable_begin(iter, &m->itof); +} + +void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); } + +bool upb_msg_field_done(const upb_msg_field_iter *iter) { + return upb_inttable_done(iter); +} + +upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) { + return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +} + +void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { + upb_inttable_iter_setdone(iter); +} + +bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, + const upb_msg_field_iter * iter2) { + return upb_inttable_iter_isequal(iter1, iter2); +} + +void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) { + upb_strtable_begin(iter, &m->ntof); + /* We need to skip past any initial fields. */ + while (!upb_strtable_done(iter) && + !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)) { + upb_strtable_next(iter); + } +} + +void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { + /* We need to skip past fields to return only oneofs. */ + do { + upb_strtable_next(iter); + } while (!upb_strtable_done(iter) && + !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)); +} + +bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { + return upb_strtable_done(iter); +} + +const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { + return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); +} + +void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { + upb_strtable_iter_setdone(iter); +} + +bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, + const upb_msg_oneof_iter *iter2) { + return upb_strtable_iter_isequal(iter1, iter2); +} + +/* upb_oneofdef ***************************************************************/ + +const char *upb_oneofdef_name(const upb_oneofdef *o) { + return shortdefname(o->full_name); +} + +const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { + return o->parent; +} + +int upb_oneofdef_fieldcount(const upb_oneofdef *o) { + return o->field_count; +} + +const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i) { + UPB_ASSERT(i < o->field_count); + return o->fields[i]; +} + +int upb_oneofdef_numfields(const upb_oneofdef *o) { + return o->field_count; +} + +uint32_t upb_oneofdef_index(const upb_oneofdef *o) { + return o - o->parent->oneofs; +} + +bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { + return o->synthetic; +} + +const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, + const char *name, size_t length) { + upb_value val; + return upb_strtable_lookup2(&o->ntof, name, length, &val) ? + upb_value_getptr(val) : NULL; +} + +const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) { + upb_value val; + return upb_inttable_lookup32(&o->itof, num, &val) ? + upb_value_getptr(val) : NULL; +} + +void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { + upb_inttable_begin(iter, &o->itof); +} + +void upb_oneof_next(upb_oneof_iter *iter) { + upb_inttable_next(iter); +} + +bool upb_oneof_done(upb_oneof_iter *iter) { + return upb_inttable_done(iter); +} + +upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { + return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +} + +void upb_oneof_iter_setdone(upb_oneof_iter *iter) { + upb_inttable_iter_setdone(iter); +} + +/* upb_filedef ****************************************************************/ + +const char *upb_filedef_name(const upb_filedef *f) { + return f->name; +} + +const char *upb_filedef_package(const upb_filedef *f) { + return f->package; +} + +const char *upb_filedef_phpprefix(const upb_filedef *f) { + return f->phpprefix; +} + +const char *upb_filedef_phpnamespace(const upb_filedef *f) { + return f->phpnamespace; +} + +upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { + return f->syntax; +} + +int upb_filedef_msgcount(const upb_filedef *f) { + return f->msg_count; +} + +int upb_filedef_depcount(const upb_filedef *f) { + return f->dep_count; +} + +int upb_filedef_enumcount(const upb_filedef *f) { + return f->enum_count; +} + +const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { + return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; +} + +const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { + return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; +} + +const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { + return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; +} + +void upb_symtab_free(upb_symtab *s) { + upb_arena_free(s->arena); + upb_gfree(s); +} + +upb_symtab *upb_symtab_new(void) { + upb_symtab *s = upb_gmalloc(sizeof(*s)); + upb_alloc *alloc; + + if (!s) { + return NULL; + } + + s->arena = upb_arena_new(); + s->bytes_loaded = 0; + alloc = upb_arena_alloc(s->arena); + + if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, 32, alloc) || + !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, 4, alloc)) { + upb_arena_free(s->arena); + upb_gfree(s); + s = NULL; + } + return s; +} + +const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { + upb_value v; + return upb_strtable_lookup(&s->syms, sym, &v) ? + unpack_def(v, UPB_DEFTYPE_MSG) : NULL; +} + +const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, + size_t len) { + upb_value v; + return upb_strtable_lookup2(&s->syms, sym, len, &v) ? + unpack_def(v, UPB_DEFTYPE_MSG) : NULL; +} + +const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { + upb_value v; + return upb_strtable_lookup(&s->syms, sym, &v) ? + unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; +} + +const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) { + upb_value v; + return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) + : NULL; +} + +const upb_filedef *upb_symtab_lookupfile2( + const upb_symtab *s, const char *name, size_t len) { + upb_value v; + return upb_strtable_lookup2(&s->files, name, len, &v) ? + upb_value_getconstptr(v) : NULL; +} + +int upb_symtab_filecount(const upb_symtab *s) { + return (int)upb_strtable_count(&s->files); +} + +/* Code to build defs from descriptor protos. *********************************/ + +/* There is a question of how much validation to do here. It will be difficult + * to perfectly match the amount of validation performed by proto2. But since + * this code is used to directly build defs from Ruby (for example) we do need + * to validate important constraints like uniqueness of names and numbers. */ + +#define CHK_OOM(x) if (!(x)) { symtab_oomerr(ctx); } + +typedef struct { + upb_symtab *symtab; + upb_filedef *file; /* File we are building. */ + upb_arena *file_arena; /* Allocate defs here. */ + upb_alloc *alloc; /* Alloc of file_arena, for tables. */ + const upb_msglayout **layouts; /* NULL if we should build layouts. */ + upb_status *status; /* Record errors here. */ + jmp_buf err; /* longjmp() on error. */ +} symtab_addctx; + +UPB_NORETURN UPB_NOINLINE +static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + upb_status_vseterrf(ctx->status, fmt, argp); + va_end(argp); + longjmp(ctx->err, 1); +} + +UPB_NORETURN UPB_NOINLINE +static void symtab_oomerr(symtab_addctx *ctx) { + upb_status_setoom(ctx->status); + longjmp(ctx->err, 1); +} + +void *symtab_alloc(symtab_addctx *ctx, size_t bytes) { + void *ret = upb_arena_malloc(ctx->file_arena, bytes); + if (!ret) symtab_oomerr(ctx); + return ret; +} + +static void check_ident(symtab_addctx *ctx, upb_strview name, bool full) { + const char *str = name.data; + size_t len = name.size; + bool start = true; + size_t i; + for (i = 0; i < len; i++) { + char c = str[i]; + if (c == '.') { + if (start || !full) { + symtab_errf(ctx, "invalid name: unexpected '.' (%.*s)", (int)len, str); + } + start = true; + } else if (start) { + if (!upb_isletter(c)) { + symtab_errf( + ctx, + "invalid name: path components must start with a letter (%.*s)", + (int)len, str); + } + start = false; + } else { + if (!upb_isalphanum(c)) { + symtab_errf(ctx, "invalid name: non-alphanumeric character (%.*s)", + (int)len, str); + } + } + } + if (start) { + symtab_errf(ctx, "invalid name: empty part (%.*s)", (int)len, str); + } +} + +static size_t div_round_up(size_t n, size_t d) { + return (n + d - 1) / d; +} + +static size_t upb_msgval_sizeof(upb_fieldtype_t type) { + switch (type) { + case UPB_TYPE_DOUBLE: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + return 8; + case UPB_TYPE_ENUM: + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_FLOAT: + return 4; + case UPB_TYPE_BOOL: + return 1; + case UPB_TYPE_MESSAGE: + return sizeof(void*); + case UPB_TYPE_BYTES: + case UPB_TYPE_STRING: + return sizeof(upb_strview); + } + UPB_UNREACHABLE(); +} + +static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { + if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) { + upb_map_entry ent; + UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v)); + return sizeof(ent.k); + } else if (upb_fielddef_isseq(f)) { + return sizeof(void*); + } else { + return upb_msgval_sizeof(upb_fielddef_type(f)); + } +} + +static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) { + uint32_t ret; + + l->size = UPB_ALIGN_UP(l->size, size); + ret = l->size; + l->size += size; + return ret; +} + +static int field_number_cmp(const void *p1, const void *p2) { + const upb_msglayout_field *f1 = p1; + const upb_msglayout_field *f2 = p2; + return f1->number - f2->number; +} + +static void assign_layout_indices(const upb_msgdef *m, upb_msglayout_field *fields) { + int i; + int n = upb_msgdef_numfields(m); + for (i = 0; i < n; i++) { + upb_fielddef *f = (upb_fielddef*)upb_msgdef_itof(m, fields[i].number); + UPB_ASSERT(f); + f->layout_index = i; + } +} + +/* This function is the dynamic equivalent of message_layout.{cc,h} in upbc. + * It computes a dynamic layout for all of the fields in |m|. */ +static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) { + upb_msglayout *l = (upb_msglayout*)m->layout; + upb_msg_field_iter it; + upb_msg_oneof_iter oit; + size_t hasbit; + size_t submsg_count = m->submsg_field_count; + const upb_msglayout **submsgs; + upb_msglayout_field *fields; + + memset(l, 0, sizeof(*l)); + + fields = symtab_alloc(ctx, upb_msgdef_numfields(m) * sizeof(*fields)); + submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs)); + + l->field_count = upb_msgdef_numfields(m); + l->fields = fields; + l->submsgs = submsgs; + + if (upb_msgdef_mapentry(m)) { + /* TODO(haberman): refactor this method so this special case is more + * elegant. */ + const upb_fielddef *key = upb_msgdef_itof(m, 1); + const upb_fielddef *val = upb_msgdef_itof(m, 2); + fields[0].number = 1; + fields[1].number = 2; + fields[0].label = UPB_LABEL_OPTIONAL; + fields[1].label = UPB_LABEL_OPTIONAL; + fields[0].presence = 0; + fields[1].presence = 0; + fields[0].descriptortype = upb_fielddef_descriptortype(key); + fields[1].descriptortype = upb_fielddef_descriptortype(val); + fields[0].offset = 0; + fields[1].offset = sizeof(upb_strview); + fields[1].submsg_index = 0; + + if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) { + submsgs[0] = upb_fielddef_msgsubdef(val)->layout; + } + + l->field_count = 2; + l->size = 2 * sizeof(upb_strview); + l->size = UPB_ALIGN_UP(l->size, 8); + return; + } + + /* Allocate data offsets in three stages: + * + * 1. hasbits. + * 2. regular fields. + * 3. oneof fields. + * + * OPT: There is a lot of room for optimization here to minimize the size. + */ + + /* Allocate hasbits and set basic field attributes. */ + submsg_count = 0; + for (upb_msg_field_begin(&it, m), hasbit = 0; + !upb_msg_field_done(&it); + upb_msg_field_next(&it)) { + upb_fielddef* f = upb_msg_iter_field(&it); + upb_msglayout_field *field = &fields[upb_fielddef_index(f)]; + + field->number = upb_fielddef_number(f); + field->descriptortype = upb_fielddef_descriptortype(f); + field->label = upb_fielddef_label(f); + + if (field->descriptortype == UPB_DTYPE_STRING && + f->file->syntax == UPB_SYNTAX_PROTO2) { + /* See TableDescriptorType() in upbc/generator.cc for details and + * rationale. */ + field->descriptortype = UPB_DTYPE_BYTES; + } + + if (upb_fielddef_ismap(f)) { + field->label = _UPB_LABEL_MAP; + } else if (upb_fielddef_packed(f)) { + field->label = _UPB_LABEL_PACKED; + } + + if (upb_fielddef_issubmsg(f)) { + const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + field->submsg_index = submsg_count++; + submsgs[field->submsg_index] = subm->layout; + } + + if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) { + /* We don't use hasbit 0, so that 0 can indicate "no presence" in the + * table. This wastes one hasbit, but we don't worry about it for now. */ + field->presence = ++hasbit; + } else { + field->presence = 0; + } + } + + /* Account for space used by hasbits. */ + l->size = div_round_up(hasbit, 8); + + /* Allocate non-oneof fields. */ + for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it); + upb_msg_field_next(&it)) { + const upb_fielddef* f = upb_msg_iter_field(&it); + size_t field_size = upb_msg_fielddefsize(f); + size_t index = upb_fielddef_index(f); + + if (upb_fielddef_realcontainingoneof(f)) { + /* Oneofs are handled separately below. */ + continue; + } + + fields[index].offset = upb_msglayout_place(l, field_size); + } + + /* Allocate oneof fields. Each oneof field consists of a uint32 for the case + * and space for the actual data. */ + for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit); + upb_msg_oneof_next(&oit)) { + const upb_oneofdef* o = upb_msg_iter_oneof(&oit); + upb_oneof_iter fit; + + size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ + size_t field_size = 0; + uint32_t case_offset; + uint32_t data_offset; + + if (upb_oneofdef_issynthetic(o)) continue; + + /* Calculate field size: the max of all field sizes. */ + for (upb_oneof_begin(&fit, o); + !upb_oneof_done(&fit); + upb_oneof_next(&fit)) { + const upb_fielddef* f = upb_oneof_iter_field(&fit); + field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f)); + } + + /* Align and allocate case offset. */ + case_offset = upb_msglayout_place(l, case_size); + data_offset = upb_msglayout_place(l, field_size); + + for (upb_oneof_begin(&fit, o); + !upb_oneof_done(&fit); + upb_oneof_next(&fit)) { + const upb_fielddef* f = upb_oneof_iter_field(&fit); + fields[upb_fielddef_index(f)].offset = data_offset; + fields[upb_fielddef_index(f)].presence = ~case_offset; + } + } + + /* Size of the entire structure should be a multiple of its greatest + * alignment. TODO: track overall alignment for real? */ + l->size = UPB_ALIGN_UP(l->size, 8); + + /* Sort fields by number. */ + qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp); + assign_layout_indices(m, fields); +} + +static void assign_msg_indices(symtab_addctx *ctx, upb_msgdef *m) { + /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the + * lowest indexes, but we do not publicly guarantee this. */ + upb_msg_field_iter j; + int i; + uint32_t selector; + int n = upb_msgdef_numfields(m); + upb_fielddef **fields; + + if (n == 0) { + m->selector_count = UPB_STATIC_SELECTOR_COUNT; + m->submsg_field_count = 0; + return; + } + + fields = upb_gmalloc(n * sizeof(*fields)); + + m->submsg_field_count = 0; + for(i = 0, upb_msg_field_begin(&j, m); + !upb_msg_field_done(&j); + upb_msg_field_next(&j), i++) { + upb_fielddef *f = upb_msg_iter_field(&j); + UPB_ASSERT(f->msgdef == m); + if (upb_fielddef_issubmsg(f)) { + m->submsg_field_count++; + } + fields[i] = f; + } + + qsort(fields, n, sizeof(*fields), cmp_fields); + + selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count; + for (i = 0; i < n; i++) { + upb_fielddef *f = fields[i]; + f->index_ = i; + f->selector_base = selector + upb_handlers_selectorbaseoffset(f); + selector += upb_handlers_selectorcount(f); + } + m->selector_count = selector; + + upb_gfree(fields); +} + +static char *strviewdup(symtab_addctx *ctx, upb_strview view) { + return upb_strdup2(view.data, view.size, ctx->alloc); +} + +static bool streql2(const char *a, size_t n, const char *b) { + return n == strlen(b) && memcmp(a, b, n) == 0; +} + +static bool streql_view(upb_strview view, const char *b) { + return streql2(view.data, view.size, b); +} + +static const char *makefullname(symtab_addctx *ctx, const char *prefix, + upb_strview name) { + if (prefix) { + /* ret = prefix + '.' + name; */ + size_t n = strlen(prefix); + char *ret = symtab_alloc(ctx, n + name.size + 2); + strcpy(ret, prefix); + ret[n] = '.'; + memcpy(&ret[n + 1], name.data, name.size); + ret[n + 1 + name.size] = '\0'; + return ret; + } else { + return strviewdup(ctx, name); + } +} + +static void finalize_oneofs(symtab_addctx *ctx, upb_msgdef *m) { + int i; + int synthetic_count = 0; + upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs; + + for (i = 0; i < m->oneof_count; i++) { + upb_oneofdef *o = &mutable_oneofs[i]; + + if (o->synthetic && o->field_count != 1) { + symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s", + o->field_count, upb_oneofdef_name(o)); + } + + if (o->synthetic) { + synthetic_count++; + } else if (synthetic_count != 0) { + symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s", + upb_oneofdef_name(o)); + } + + o->fields = symtab_alloc(ctx, sizeof(upb_fielddef *) * o->field_count); + o->field_count = 0; + } + + for (i = 0; i < m->field_count; i++) { + const upb_fielddef *f = &m->fields[i]; + upb_oneofdef *o = (upb_oneofdef*)f->oneof; + if (o) { + o->fields[o->field_count++] = f; + } + } + + m->real_oneof_count = m->oneof_count - synthetic_count; +} + +size_t getjsonname(const char *name, char *buf, size_t len) { + size_t src, dst = 0; + bool ucase_next = false; + +#define WRITE(byte) \ + ++dst; \ + if (dst < len) buf[dst - 1] = byte; \ + else if (dst == len) buf[dst - 1] = '\0' + + if (!name) { + WRITE('\0'); + return 0; + } + + /* Implement the transformation as described in the spec: + * 1. upper case all letters after an underscore. + * 2. remove all underscores. + */ + for (src = 0; name[src]; src++) { + if (name[src] == '_') { + ucase_next = true; + continue; + } + + if (ucase_next) { + WRITE(toupper(name[src])); + ucase_next = false; + } else { + WRITE(name[src]); + } + } + + WRITE('\0'); + return dst; + +#undef WRITE +} + +static char* makejsonname(symtab_addctx *ctx, const char* name) { + size_t size = getjsonname(name, NULL, 0); + char* json_name = symtab_alloc(ctx, size); + getjsonname(name, json_name, size); + return json_name; +} + +static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) { + if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) { + symtab_errf(ctx, "duplicate symbol '%s'", name); + } + upb_alloc *alloc = upb_arena_alloc(ctx->symtab->arena); + size_t len = strlen(name); + CHK_OOM(upb_strtable_insert3(&ctx->symtab->syms, name, len, v, alloc)); +} + +/* Given a symbol and the base symbol inside which it is defined, find the + * symbol's definition in t. */ +static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f, + const char *base, upb_strview sym, + upb_deftype_t type) { + const upb_strtable *t = &ctx->symtab->syms; + if(sym.size == 0) goto notfound; + if(sym.data[0] == '.') { + /* Symbols starting with '.' are absolute, so we do a single lookup. + * Slice to omit the leading '.' */ + upb_value v; + if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) { + goto notfound; + } + + const void *ret = unpack_def(v, type); + if (!ret) { + symtab_errf(ctx, "type mismatch when resolving field %s, name %s", + f->full_name, sym.data); + } + return ret; + } else { + /* Remove components from base until we find an entry or run out. + * TODO: This branch is totally broken, but currently not used. */ + (void)base; + UPB_ASSERT(false); + goto notfound; + } + +notfound: + symtab_errf(ctx, "couldn't resolve name '%s'", sym.data); +} + +static void create_oneofdef( + symtab_addctx *ctx, upb_msgdef *m, + const google_protobuf_OneofDescriptorProto *oneof_proto) { + upb_oneofdef *o; + upb_strview name = google_protobuf_OneofDescriptorProto_name(oneof_proto); + upb_value v; + + o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; + o->parent = m; + o->full_name = makefullname(ctx, m->full_name, name); + o->field_count = 0; + o->synthetic = false; + + v = pack_def(o, UPB_DEFTYPE_ONEOF); + symtab_add(ctx, o->full_name, v); + CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc)); + + CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, 4, ctx->alloc)); +} + +static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) { + str_t *ret = symtab_alloc(ctx, sizeof(*ret) + len); + if (!ret) return NULL; + ret->len = len; + if (len) memcpy(ret->str, data, len); + ret->str[len] = '\0'; + return ret; +} + +static void parse_default(symtab_addctx *ctx, const char *str, size_t len, + upb_fielddef *f) { + char *end; + char nullz[64]; + errno = 0; + + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT32: + case UPB_TYPE_UINT64: + case UPB_TYPE_DOUBLE: + case UPB_TYPE_FLOAT: + /* Standard C number parsing functions expect null-terminated strings. */ + if (len >= sizeof(nullz) - 1) { + symtab_errf(ctx, "Default too long: %.*s", (int)len, str); + } + memcpy(nullz, str, len); + nullz[len] = '\0'; + str = nullz; + break; + default: + break; + } + + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: { + long val = strtol(str, &end, 0); + if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.sint = val; + break; + } + case UPB_TYPE_ENUM: { + const upb_enumdef *e = f->sub.enumdef; + int32_t val; + if (!upb_enumdef_ntoi(e, str, len, &val)) { + goto invalid; + } + f->defaultval.sint = val; + break; + } + case UPB_TYPE_INT64: { + /* XXX: Need to write our own strtoll, since it's not available in c89. */ + int64_t val = strtol(str, &end, 0); + if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.sint = val; + break; + } + case UPB_TYPE_UINT32: { + unsigned long val = strtoul(str, &end, 0); + if (val > UINT32_MAX || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.uint = val; + break; + } + case UPB_TYPE_UINT64: { + /* XXX: Need to write our own strtoull, since it's not available in c89. */ + uint64_t val = strtoul(str, &end, 0); + if (val > UINT64_MAX || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.uint = val; + break; + } + case UPB_TYPE_DOUBLE: { + double val = strtod(str, &end); + if (errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.dbl = val; + break; + } + case UPB_TYPE_FLOAT: { + /* XXX: Need to write our own strtof, since it's not available in c89. */ + float val = strtod(str, &end); + if (errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.flt = val; + break; + } + case UPB_TYPE_BOOL: { + if (streql2(str, len, "false")) { + f->defaultval.boolean = false; + } else if (streql2(str, len, "true")) { + f->defaultval.boolean = true; + } else { + } + break; + } + case UPB_TYPE_STRING: + f->defaultval.str = newstr(ctx, str, len); + break; + case UPB_TYPE_BYTES: + /* XXX: need to interpret the C-escaped value. */ + f->defaultval.str = newstr(ctx, str, len); + break; + case UPB_TYPE_MESSAGE: + /* Should not have a default value. */ + symtab_errf(ctx, "Message should not have a default (%s)", + upb_fielddef_fullname(f)); + } + + return; + +invalid: + symtab_errf(ctx, "Invalid default '%.*s' for field %f", (int)len, str, + upb_fielddef_fullname(f)); +} + +static void set_default_default(symtab_addctx *ctx, upb_fielddef *f) { + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_INT64: + case UPB_TYPE_ENUM: + f->defaultval.sint = 0; + break; + case UPB_TYPE_UINT64: + case UPB_TYPE_UINT32: + f->defaultval.uint = 0; + break; + case UPB_TYPE_DOUBLE: + case UPB_TYPE_FLOAT: + f->defaultval.dbl = 0; + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + f->defaultval.str = newstr(ctx, NULL, 0); + break; + case UPB_TYPE_BOOL: + f->defaultval.boolean = false; + break; + case UPB_TYPE_MESSAGE: + break; + } +} + +static void create_fielddef( + symtab_addctx *ctx, const char *prefix, upb_msgdef *m, + const google_protobuf_FieldDescriptorProto *field_proto) { + upb_alloc *alloc = ctx->alloc; + upb_fielddef *f; + const google_protobuf_FieldOptions *options; + upb_strview name; + const char *full_name; + const char *json_name; + const char *shortname; + uint32_t field_number; + + if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { + symtab_errf(ctx, "field has no name (%s)", upb_msgdef_fullname(m)); + } + + name = google_protobuf_FieldDescriptorProto_name(field_proto); + check_ident(ctx, name, false); + full_name = makefullname(ctx, prefix, name); + shortname = shortdefname(full_name); + + if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) { + json_name = strviewdup( + ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto)); + } else { + json_name = makejsonname(ctx, shortname); + } + + field_number = google_protobuf_FieldDescriptorProto_number(field_proto); + + if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) { + symtab_errf(ctx, "invalid field number (%u)", field_number); + } + + if (m) { + /* direct message field. */ + upb_value v, field_v, json_v; + size_t json_size; + + f = (upb_fielddef*)&m->fields[m->field_count++]; + f->msgdef = m; + f->is_extension_ = false; + + if (upb_strtable_lookup(&m->ntof, shortname, NULL)) { + symtab_errf(ctx, "duplicate field name (%s)", shortname); + } + + if (upb_strtable_lookup(&m->ntof, json_name, NULL)) { + symtab_errf(ctx, "duplicate json_name (%s)", json_name); + } + + if (upb_inttable_lookup(&m->itof, field_number, NULL)) { + symtab_errf(ctx, "duplicate field number (%u)", field_number); + } + + field_v = pack_def(f, UPB_DEFTYPE_FIELD); + json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME); + v = upb_value_constptr(f); + json_size = strlen(json_name); + + CHK_OOM( + upb_strtable_insert3(&m->ntof, name.data, name.size, field_v, alloc)); + CHK_OOM(upb_inttable_insert2(&m->itof, field_number, v, alloc)); + + if (strcmp(shortname, json_name) != 0) { + upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc); + } + + if (ctx->layouts) { + const upb_msglayout_field *fields = m->layout->fields; + int count = m->layout->field_count; + bool found = false; + int i; + for (i = 0; i < count; i++) { + if (fields[i].number == field_number) { + f->layout_index = i; + found = true; + break; + } + } + UPB_ASSERT(found); + } + } else { + /* extension field. */ + f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++]; + f->is_extension_ = true; + symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD)); + } + + f->full_name = full_name; + f->json_name = json_name; + f->file = ctx->file; + f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); + f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); + f->number_ = field_number; + f->oneof = NULL; + f->proto3_optional_ = + google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); + + /* We can't resolve the subdef or (in the case of extensions) the containing + * message yet, because it may not have been defined yet. We stash a pointer + * to the field_proto until later when we can properly resolve it. */ + f->sub.unresolved = field_proto; + + if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) { + symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name); + } + + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + int oneof_index = + google_protobuf_FieldDescriptorProto_oneof_index(field_proto); + upb_oneofdef *oneof; + upb_value v = upb_value_constptr(f); + + if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { + symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)", + f->full_name); + } + + if (!m) { + symtab_errf(ctx, "oneof_index provided for extension field (%s)", + f->full_name); + } + + if (oneof_index >= m->oneof_count) { + symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name); + } + + oneof = (upb_oneofdef*)&m->oneofs[oneof_index]; + f->oneof = oneof; + + oneof->field_count++; + if (f->proto3_optional_) { + oneof->synthetic = true; + } + CHK_OOM(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc)); + CHK_OOM(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc)); + } else { + f->oneof = NULL; + if (f->proto3_optional_) { + symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)", + f->full_name); + } + } + + options = google_protobuf_FieldDescriptorProto_has_options(field_proto) ? + google_protobuf_FieldDescriptorProto_options(field_proto) : NULL; + + if (options && google_protobuf_FieldOptions_has_packed(options)) { + f->packed_ = google_protobuf_FieldOptions_packed(options); + } else { + /* Repeated fields default to packed for proto3 only. */ + f->packed_ = upb_fielddef_isprimitive(f) && + f->label_ == UPB_LABEL_REPEATED && f->file->syntax == UPB_SYNTAX_PROTO3; + } + + if (options) { + f->lazy_ = google_protobuf_FieldOptions_lazy(options); + } else { + f->lazy_ = false; + } +} + +static void create_enumdef( + symtab_addctx *ctx, const char *prefix, + const google_protobuf_EnumDescriptorProto *enum_proto) { + upb_enumdef *e; + const google_protobuf_EnumValueDescriptorProto *const *values; + upb_strview name; + size_t i, n; + + name = google_protobuf_EnumDescriptorProto_name(enum_proto); + check_ident(ctx, name, false); + + e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++]; + e->full_name = makefullname(ctx, prefix, name); + symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM)); + + values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); + CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, n, ctx->alloc)); + CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc)); + + e->file = ctx->file; + e->defaultval = 0; + + if (n == 0) { + symtab_errf(ctx, "enums must contain at least one value (%s)", + e->full_name); + } + + for (i = 0; i < n; i++) { + const google_protobuf_EnumValueDescriptorProto *value = values[i]; + upb_strview name = google_protobuf_EnumValueDescriptorProto_name(value); + char *name2 = strviewdup(ctx, name); + int32_t num = google_protobuf_EnumValueDescriptorProto_number(value); + upb_value v = upb_value_int32(num); + + if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) { + symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)", + e->full_name); + } + + if (upb_strtable_lookup(&e->ntoi, name2, NULL)) { + symtab_errf(ctx, "duplicate enum label '%s'", name2); + } + + CHK_OOM(name2) + CHK_OOM( + upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc)); + + if (!upb_inttable_lookup(&e->iton, num, NULL)) { + upb_value v = upb_value_cstr(name2); + CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc)); + } + } + + upb_inttable_compact2(&e->iton, ctx->alloc); +} + +static void create_msgdef(symtab_addctx *ctx, const char *prefix, + const google_protobuf_DescriptorProto *msg_proto) { + upb_msgdef *m; + const google_protobuf_MessageOptions *options; + const google_protobuf_OneofDescriptorProto *const *oneofs; + const google_protobuf_FieldDescriptorProto *const *fields; + const google_protobuf_EnumDescriptorProto *const *enums; + const google_protobuf_DescriptorProto *const *msgs; + size_t i, n_oneof, n_field, n; + upb_strview name; + + name = google_protobuf_DescriptorProto_name(msg_proto); + check_ident(ctx, name, false); + + m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++]; + m->full_name = makefullname(ctx, prefix, name); + symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG)); + + oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof); + fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field); + + CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); + CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, n_oneof + n_field, + ctx->alloc)); + + m->file = ctx->file; + m->map_entry = false; + + options = google_protobuf_DescriptorProto_options(msg_proto); + + if (options) { + m->map_entry = google_protobuf_MessageOptions_map_entry(options); + } + + if (ctx->layouts) { + m->layout = *ctx->layouts; + ctx->layouts++; + } else { + /* Allocate now (to allow cross-linking), populate later. */ + m->layout = symtab_alloc(ctx, sizeof(*m->layout)); + } + + m->oneof_count = 0; + m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof); + for (i = 0; i < n_oneof; i++) { + create_oneofdef(ctx, m, oneofs[i]); + } + + m->field_count = 0; + m->fields = symtab_alloc(ctx, sizeof(*m->fields) * n_field); + for (i = 0; i < n_field; i++) { + create_fielddef(ctx, m->full_name, m, fields[i]); + } + + assign_msg_indices(ctx, m); + finalize_oneofs(ctx, m); + assign_msg_wellknowntype(m); + upb_inttable_compact2(&m->itof, ctx->alloc); + + /* This message is built. Now build nested messages and enums. */ + + enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n); + for (i = 0; i < n; i++) { + create_enumdef(ctx, m->full_name, enums[i]); + } + + msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (i = 0; i < n; i++) { + create_msgdef(ctx, m->full_name, msgs[i]); + } +} + +static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, + upb_filedef *file) { + const google_protobuf_DescriptorProto *const *msgs; + size_t i, n; + + file->msg_count++; + + msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (i = 0; i < n; i++) { + count_types_in_msg(msgs[i], file); + } + + google_protobuf_DescriptorProto_enum_type(msg_proto, &n); + file->enum_count += n; + + google_protobuf_DescriptorProto_extension(msg_proto, &n); + file->ext_count += n; +} + +static void count_types_in_file( + const google_protobuf_FileDescriptorProto *file_proto, + upb_filedef *file) { + const google_protobuf_DescriptorProto *const *msgs; + size_t i, n; + + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (i = 0; i < n; i++) { + count_types_in_msg(msgs[i], file); + } + + google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + file->enum_count += n; + + google_protobuf_FileDescriptorProto_extension(file_proto, &n); + file->ext_count += n; +} + +static void resolve_fielddef(symtab_addctx *ctx, const char *prefix, + upb_fielddef *f) { + upb_strview name; + const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved; + + if (f->is_extension_) { + if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { + symtab_errf(ctx, "extension for field '%s' had no extendee", + f->full_name); + } + + name = google_protobuf_FieldDescriptorProto_extendee(field_proto); + f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); + } + + if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) && + !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) { + symtab_errf(ctx, "field '%s' is missing type name", f->full_name); + } + + name = google_protobuf_FieldDescriptorProto_type_name(field_proto); + + if (upb_fielddef_issubmsg(f)) { + f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); + } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) { + f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM); + } + + /* Have to delay resolving of the default value until now because of the enum + * case, since enum defaults are specified with a label. */ + if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { + upb_strview defaultval = + google_protobuf_FieldDescriptorProto_default_value(field_proto); + + if (f->file->syntax == UPB_SYNTAX_PROTO3) { + symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)", + f->full_name); + } + + if (upb_fielddef_issubmsg(f)) { + symtab_errf(ctx, "message fields cannot have explicit defaults (%s)", + f->full_name); + } + + parse_default(ctx, defaultval.data, defaultval.size, f); + } else { + set_default_default(ctx, f); + } +} + +static void build_filedef( + symtab_addctx *ctx, upb_filedef *file, + const google_protobuf_FileDescriptorProto *file_proto) { + const google_protobuf_FileOptions *file_options_proto; + const google_protobuf_DescriptorProto *const *msgs; + const google_protobuf_EnumDescriptorProto *const *enums; + const google_protobuf_FieldDescriptorProto *const *exts; + const upb_strview* strs; + size_t i, n; + + count_types_in_file(file_proto, file); + + file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count); + file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count); + file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count); + + /* We increment these as defs are added. */ + file->msg_count = 0; + file->enum_count = 0; + file->ext_count = 0; + + if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) { + symtab_errf(ctx, "File has no name"); + } + + file->name = + strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto)); + file->phpprefix = NULL; + file->phpnamespace = NULL; + + if (google_protobuf_FileDescriptorProto_has_package(file_proto)) { + upb_strview package = + google_protobuf_FileDescriptorProto_package(file_proto); + check_ident(ctx, package, true); + file->package = strviewdup(ctx, package); + } else { + file->package = NULL; + } + + if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { + upb_strview syntax = + google_protobuf_FileDescriptorProto_syntax(file_proto); + + if (streql_view(syntax, "proto2")) { + file->syntax = UPB_SYNTAX_PROTO2; + } else if (streql_view(syntax, "proto3")) { + file->syntax = UPB_SYNTAX_PROTO3; + } else { + symtab_errf(ctx, "Invalid syntax '" UPB_STRVIEW_FORMAT "'", + UPB_STRVIEW_ARGS(syntax)); + } + } else { + file->syntax = UPB_SYNTAX_PROTO2; + } + + /* Read options. */ + file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto); + if (file_options_proto) { + if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) { + file->phpprefix = strviewdup( + ctx, + google_protobuf_FileOptions_php_class_prefix(file_options_proto)); + } + if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) { + file->phpnamespace = strviewdup( + ctx, google_protobuf_FileOptions_php_namespace(file_options_proto)); + } + } + + /* Verify dependencies. */ + strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); + file->deps = symtab_alloc(ctx, sizeof(*file->deps) * n); + + for (i = 0; i < n; i++) { + upb_strview dep_name = strs[i]; + upb_value v; + if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data, + dep_name.size, &v)) { + symtab_errf(ctx, + "Depends on file '" UPB_STRVIEW_FORMAT + "', but it has not been loaded", + UPB_STRVIEW_ARGS(dep_name)); + } + file->deps[i] = upb_value_getconstptr(v); + } + + /* Create messages. */ + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (i = 0; i < n; i++) { + create_msgdef(ctx, file->package, msgs[i]); + } + + /* Create enums. */ + enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + for (i = 0; i < n; i++) { + create_enumdef(ctx, file->package, enums[i]); + } + + /* Create extensions. */ + exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); + file->exts = symtab_alloc(ctx, sizeof(*file->exts) * n); + for (i = 0; i < n; i++) { + create_fielddef(ctx, file->package, NULL, exts[i]); + } + + /* Now that all names are in the table, build layouts and resolve refs. */ + for (i = 0; i < (size_t)file->ext_count; i++) { + resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]); + } + + for (i = 0; i < (size_t)file->msg_count; i++) { + const upb_msgdef *m = &file->msgs[i]; + int j; + for (j = 0; j < m->field_count; j++) { + resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j]); + } + } + + if (!ctx->layouts) { + for (i = 0; i < (size_t)file->msg_count; i++) { + const upb_msgdef *m = &file->msgs[i]; + make_layout(ctx, m); + } + } +} + +static void remove_filedef(upb_symtab *s, upb_filedef *file) { + upb_alloc *alloc = upb_arena_alloc(s->arena); + int i; + for (i = 0; i < file->msg_count; i++) { + const char *name = file->msgs[i].full_name; + upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc); + } + for (i = 0; i < file->enum_count; i++) { + const char *name = file->enums[i].full_name; + upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc); + } + for (i = 0; i < file->ext_count; i++) { + const char *name = file->exts[i].full_name; + upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc); + } +} + +static const upb_filedef *_upb_symtab_addfile( + upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, + const upb_msglayout **layouts, upb_status *status) { + upb_arena *file_arena = upb_arena_new(); + upb_filedef *file; + symtab_addctx ctx; + + if (!file_arena) return NULL; + + file = upb_arena_malloc(file_arena, sizeof(*file)); + if (!file) goto done; + + ctx.file = file; + ctx.symtab = s; + ctx.file_arena = file_arena; + ctx.alloc = upb_arena_alloc(file_arena); + ctx.layouts = layouts; + ctx.status = status; + + file->msg_count = 0; + file->enum_count = 0; + file->ext_count = 0; + + if (UPB_UNLIKELY(setjmp(ctx.err))) { + UPB_ASSERT(!upb_ok(status)); + remove_filedef(s, file); + file = NULL; + } else { + build_filedef(&ctx, file, file_proto); + upb_strtable_insert3(&s->files, file->name, strlen(file->name), + upb_value_constptr(file), ctx.alloc); + UPB_ASSERT(upb_ok(status)); + upb_arena_fuse(s->arena, file_arena); + } + +done: + upb_arena_free(file_arena); + return file; +} + +const upb_filedef *upb_symtab_addfile( + upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, + upb_status *status) { + return _upb_symtab_addfile(s, file_proto, NULL, status); +} + +/* Include here since we want most of this file to be stdio-free. */ +#include + +bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { + /* Since this function should never fail (it would indicate a bug in upb) we + * print errors to stderr instead of returning error status to the user. */ + upb_def_init **deps = init->deps; + google_protobuf_FileDescriptorProto *file; + upb_arena *arena; + upb_status status; + + upb_status_clear(&status); + + if (upb_strtable_lookup(&s->files, init->filename, NULL)) { + return true; + } + + arena = upb_arena_new(); + + for (; *deps; deps++) { + if (!_upb_symtab_loaddefinit(s, *deps)) goto err; + } + + file = google_protobuf_FileDescriptorProto_parse( + init->descriptor.data, init->descriptor.size, arena); + s->bytes_loaded += init->descriptor.size; + + if (!file) { + upb_status_seterrf( + &status, + "Failed to parse compiled-in descriptor for file '%s'. This should " + "never happen.", + init->filename); + goto err; + } + + if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err; + + upb_arena_free(arena); + return true; + +err: + fprintf(stderr, "Error loading compiled-in descriptor: %s\n", + upb_status_errmsg(&status)); + upb_arena_free(arena); + return false; +} + +size_t _upb_symtab_bytesloaded(const upb_symtab *s) { + return s->bytes_loaded; +} + +#undef CHK_OOM + + +#include + + +static size_t get_field_size(const upb_msglayout_field *f) { + static unsigned char sizes[] = { + 0,/* 0 */ + 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */ + 4, /* UPB_DESCRIPTOR_TYPE_FLOAT */ + 8, /* UPB_DESCRIPTOR_TYPE_INT64 */ + 8, /* UPB_DESCRIPTOR_TYPE_UINT64 */ + 4, /* UPB_DESCRIPTOR_TYPE_INT32 */ + 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */ + 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */ + 1, /* UPB_DESCRIPTOR_TYPE_BOOL */ + sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */ + sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */ + sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */ + sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */ + 4, /* UPB_DESCRIPTOR_TYPE_UINT32 */ + 4, /* UPB_DESCRIPTOR_TYPE_ENUM */ + 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */ + 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */ + 4, /* UPB_DESCRIPTOR_TYPE_SINT32 */ + 8, /* UPB_DESCRIPTOR_TYPE_SINT64 */ + }; + return _upb_repeated_or_map(f) ? sizeof(void *) : sizes[f->descriptortype]; +} + +/* Strings/bytes are special-cased in maps. */ +static char _upb_fieldtype_to_mapsize[12] = { + 0, + 1, /* UPB_TYPE_BOOL */ + 4, /* UPB_TYPE_FLOAT */ + 4, /* UPB_TYPE_INT32 */ + 4, /* UPB_TYPE_UINT32 */ + 4, /* UPB_TYPE_ENUM */ + sizeof(void*), /* UPB_TYPE_MESSAGE */ + 8, /* UPB_TYPE_DOUBLE */ + 8, /* UPB_TYPE_INT64 */ + 8, /* UPB_TYPE_UINT64 */ + 0, /* UPB_TYPE_STRING */ + 0, /* UPB_TYPE_BYTES */ +}; + +static const char _upb_fieldtype_to_sizelg2[12] = { + 0, + 0, /* UPB_TYPE_BOOL */ + 2, /* UPB_TYPE_FLOAT */ + 2, /* UPB_TYPE_INT32 */ + 2, /* UPB_TYPE_UINT32 */ + 2, /* UPB_TYPE_ENUM */ + UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */ + 3, /* UPB_TYPE_DOUBLE */ + 3, /* UPB_TYPE_INT64 */ + 3, /* UPB_TYPE_UINT64 */ + UPB_SIZE(3, 4), /* UPB_TYPE_STRING */ + UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */ +}; + +/** upb_msg *******************************************************************/ + +upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) { + return _upb_msg_new(upb_msgdef_layout(m), a); +} + +static bool in_oneof(const upb_msglayout_field *field) { + return field->presence < 0; +} + +static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + const char *mem = UPB_PTR_AT(msg, field->offset, char); + upb_msgval val = {0}; + memcpy(&val, mem, get_field_size(field)); + return val; +} + +bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + if (in_oneof(field)) { + return _upb_getoneofcase_field(msg, field) == field->number; + } else if (field->presence > 0) { + return _upb_hasbit_field(msg, field); + } else { + UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || + field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP); + return _upb_msg_getraw(msg, f).msg_val != NULL; + } +} + +const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg, + const upb_oneofdef *o) { + const upb_fielddef *f = upb_oneofdef_field(o, 0); + if (upb_oneofdef_issynthetic(o)) { + UPB_ASSERT(upb_oneofdef_fieldcount(o) == 1); + return upb_msg_has(msg, f) ? f : NULL; + } else { + const upb_msglayout_field *field = upb_fielddef_layout(f); + uint32_t oneof_case = _upb_getoneofcase_field(msg, field); + f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL; + UPB_ASSERT((f != NULL) == (oneof_case != 0)); + return f; + } +} + +upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) { + if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) { + return _upb_msg_getraw(msg, f); + } else { + /* TODO(haberman): change upb_fielddef to not require this switch(). */ + upb_msgval val = {0}; + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_ENUM: + val.int32_val = upb_fielddef_defaultint32(f); + break; + case UPB_TYPE_INT64: + val.int64_val = upb_fielddef_defaultint64(f); + break; + case UPB_TYPE_UINT32: + val.uint32_val = upb_fielddef_defaultuint32(f); + break; + case UPB_TYPE_UINT64: + val.uint64_val = upb_fielddef_defaultuint64(f); + break; + case UPB_TYPE_FLOAT: + val.float_val = upb_fielddef_defaultfloat(f); + break; + case UPB_TYPE_DOUBLE: + val.double_val = upb_fielddef_defaultdouble(f); + break; + case UPB_TYPE_BOOL: + val.double_val = upb_fielddef_defaultbool(f); + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size); + break; + case UPB_TYPE_MESSAGE: + val.msg_val = NULL; + break; + } + return val; + } +} + +upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, + upb_arena *a) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + upb_mutmsgval ret; + char *mem = UPB_PTR_AT(msg, field->offset, char); + bool wrong_oneof = + in_oneof(field) && _upb_getoneofcase_field(msg, field) != field->number; + + memcpy(&ret, mem, sizeof(void*)); + + if (a && (!ret.msg || wrong_oneof)) { + if (upb_fielddef_ismap(f)) { + const upb_msgdef *entry = upb_fielddef_msgsubdef(f); + const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY); + const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE); + ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value)); + } else if (upb_fielddef_isseq(f)) { + ret.array = upb_array_new(a, upb_fielddef_type(f)); + } else { + UPB_ASSERT(upb_fielddef_issubmsg(f)); + ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a); + } + + memcpy(mem, &ret, sizeof(void*)); + + if (wrong_oneof) { + *_upb_oneofcase_field(msg, field) = field->number; + } else if (field->presence > 0) { + _upb_sethas_field(msg, field); + } + } + return ret; +} + +void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, + upb_arena *a) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + char *mem = UPB_PTR_AT(msg, field->offset, char); + UPB_UNUSED(a); /* We reserve the right to make set insert into a map. */ + memcpy(mem, &val, get_field_size(field)); + if (field->presence > 0) { + _upb_sethas_field(msg, field); + } else if (in_oneof(field)) { + *_upb_oneofcase_field(msg, field) = field->number; + } +} + +void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + char *mem = UPB_PTR_AT(msg, field->offset, char); + + if (field->presence > 0) { + _upb_clearhas_field(msg, field); + } else if (in_oneof(field)) { + uint32_t *oneof_case = _upb_oneofcase_field(msg, field); + if (*oneof_case != field->number) return; + *oneof_case = 0; + } + + memset(mem, 0, get_field_size(field)); +} + +void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) { + _upb_msg_clear(msg, upb_msgdef_layout(m)); +} + +bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, const upb_fielddef **out_f, + upb_msgval *out_val, size_t *iter) { + int i = *iter; + int n = upb_msgdef_fieldcount(m); + const upb_msgval zero = {0}; + UPB_UNUSED(ext_pool); + while (++i < n) { + const upb_fielddef *f = upb_msgdef_field(m, i); + upb_msgval val = _upb_msg_getraw(msg, f); + + /* Skip field if unset or empty. */ + if (upb_fielddef_haspresence(f)) { + if (!upb_msg_has(msg, f)) continue; + } else { + upb_msgval test = val; + if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) { + /* Clear string pointer, only size matters (ptr could be non-NULL). */ + test.str_val.data = NULL; + } + /* Continue if NULL or 0. */ + if (memcmp(&test, &zero, sizeof(test)) == 0) continue; + + /* Continue on empty array or map. */ + if (upb_fielddef_ismap(f)) { + if (upb_map_size(test.map_val) == 0) continue; + } else if (upb_fielddef_isseq(f)) { + if (upb_array_size(test.array_val) == 0) continue; + } + } + + *out_val = val; + *out_f = f; + *iter = i; + return true; + } + *iter = i; + return false; +} + +bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth) { + size_t iter = UPB_MSG_BEGIN; + const upb_fielddef *f; + upb_msgval val; + bool ret = true; + + if (--depth == 0) return false; + + _upb_msg_discardunknown_shallow(msg); + + while (upb_msg_next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) { + const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + if (!subm) continue; + if (upb_fielddef_ismap(f)) { + const upb_fielddef *val_f = upb_msgdef_itof(subm, 2); + const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f); + upb_map *map = (upb_map*)val.map_val; + size_t iter = UPB_MAP_BEGIN; + + if (!val_m) continue; + + while (upb_mapiter_next(map, &iter)) { + upb_msgval map_val = upb_mapiter_value(map, iter); + if (!_upb_msg_discardunknown((upb_msg*)map_val.msg_val, val_m, depth)) { + ret = false; + } + } + } else if (upb_fielddef_isseq(f)) { + const upb_array *arr = val.array_val; + size_t i, n = upb_array_size(arr); + for (i = 0; i < n; i++) { + upb_msgval elem = upb_array_get(arr, i); + if (!_upb_msg_discardunknown((upb_msg*)elem.msg_val, subm, depth)) { + ret = false; + } + } + } else { + if (!_upb_msg_discardunknown((upb_msg*)val.msg_val, subm, depth)) { + ret = false; + } + } + } + + return ret; +} + +bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) { + return _upb_msg_discardunknown(msg, m, maxdepth); +} + +/** upb_array *****************************************************************/ + +upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) { + return _upb_array_new(a, 4, _upb_fieldtype_to_sizelg2[type]); +} + +size_t upb_array_size(const upb_array *arr) { + return arr->len; +} + +upb_msgval upb_array_get(const upb_array *arr, size_t i) { + upb_msgval ret; + const char* data = _upb_array_constptr(arr); + int lg2 = arr->data & 7; + UPB_ASSERT(i < arr->len); + memcpy(&ret, data + (i << lg2), 1 << lg2); + return ret; +} + +void upb_array_set(upb_array *arr, size_t i, upb_msgval val) { + char* data = _upb_array_ptr(arr); + int lg2 = arr->data & 7; + UPB_ASSERT(i < arr->len); + memcpy(data + (i << lg2), &val, 1 << lg2); +} + +bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) { + if (!_upb_array_realloc(arr, arr->len + 1, arena)) { + return false; + } + arr->len++; + upb_array_set(arr, arr->len - 1, val); + return true; +} + +bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) { + return _upb_array_resize(arr, size, arena); +} + +/** upb_map *******************************************************************/ + +upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, + upb_fieldtype_t value_type) { + return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type], + _upb_fieldtype_to_mapsize[value_type]); +} + +size_t upb_map_size(const upb_map *map) { + return _upb_map_size(map); +} + +bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) { + return _upb_map_get(map, &key, map->key_size, val, map->val_size); +} + +bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, + upb_arena *arena) { + return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena); +} + +bool upb_map_delete(upb_map *map, upb_msgval key) { + return _upb_map_delete(map, &key, map->key_size); +} + +bool upb_mapiter_next(const upb_map *map, size_t *iter) { + return _upb_map_next(map, iter); +} + +bool upb_mapiter_done(const upb_map *map, size_t iter) { + upb_strtable_iter i; + UPB_ASSERT(iter != UPB_MAP_BEGIN); + i.t = &map->table; + i.index = iter; + return upb_strtable_done(&i); +} + +/* Returns the key and value for this entry of the map. */ +upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) { + upb_strtable_iter i; + upb_msgval ret; + i.t = &map->table; + i.index = iter; + _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size); + return ret; +} + +upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) { + upb_strtable_iter i; + upb_msgval ret; + i.t = &map->table; + i.index = iter; + _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size); + return ret; +} + +/* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */ + + +#ifdef UPB_MSVC_VSNPRINTF +/* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and + * vsnprintf. To support them, missing functions are manually implemented + * using the existing secure functions. */ +int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) { + if (!s) { + return _vscprintf(format, arg); + } + int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg); + if (ret < 0) { + ret = _vscprintf(format, arg); + } + return ret; +} + +int msvc_snprintf(char* s, size_t n, const char* format, ...) { + va_list arg; + va_start(arg, format); + int ret = msvc_vsnprintf(s, n, format, arg); + va_end(arg); + return ret; +} +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Special header, must be included last. */ + +typedef struct { + const char *ptr, *end; + upb_arena *arena; /* TODO: should we have a tmp arena for tmp data? */ + const upb_symtab *any_pool; + int depth; + upb_status *status; + jmp_buf err; + int line; + const char *line_begin; + bool is_first; + int options; + const upb_fielddef *debug_field; +} jsondec; + +enum { JD_OBJECT, JD_ARRAY, JD_STRING, JD_NUMBER, JD_TRUE, JD_FALSE, JD_NULL }; + +/* Forward declarations of mutually-recursive functions. */ +static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m); +static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f); +static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg, + const upb_msgdef *m); +static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m); + +static bool jsondec_streql(upb_strview str, const char *lit) { + return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0; +} + +static bool jsondec_isnullvalue(const upb_fielddef *f) { + return upb_fielddef_type(f) == UPB_TYPE_ENUM && + strcmp(upb_enumdef_fullname(upb_fielddef_enumsubdef(f)), + "google.protobuf.NullValue") == 0; +} + +static bool jsondec_isvalue(const upb_fielddef *f) { + return (upb_fielddef_type(f) == UPB_TYPE_MESSAGE && + upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(f)) == + UPB_WELLKNOWN_VALUE) || + jsondec_isnullvalue(f); +} + +UPB_NORETURN static void jsondec_err(jsondec *d, const char *msg) { + upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: %s", d->line, + (int)(d->ptr - d->line_begin), msg); + longjmp(d->err, 1); +} + +UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) { + va_list argp; + upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: ", d->line, + (int)(d->ptr - d->line_begin)); + va_start(argp, fmt); + upb_status_vappenderrf(d->status, fmt, argp); + va_end(argp); + longjmp(d->err, 1); +} + +static void jsondec_skipws(jsondec *d) { + while (d->ptr != d->end) { + switch (*d->ptr) { + case '\n': + d->line++; + d->line_begin = d->ptr; + /* Fallthrough. */ + case '\r': + case '\t': + case ' ': + d->ptr++; + break; + default: + return; + } + } + jsondec_err(d, "Unexpected EOF"); +} + +static bool jsondec_tryparsech(jsondec *d, char ch) { + if (d->ptr == d->end || *d->ptr != ch) return false; + d->ptr++; + return true; +} + +static void jsondec_parselit(jsondec *d, const char *lit) { + size_t avail = d->end - d->ptr; + size_t len = strlen(lit); + if (avail < len || memcmp(d->ptr, lit, len) != 0) { + jsondec_errf(d, "Expected: '%s'", lit); + } + d->ptr += len; +} + +static void jsondec_wsch(jsondec *d, char ch) { + jsondec_skipws(d); + if (!jsondec_tryparsech(d, ch)) { + jsondec_errf(d, "Expected: '%c'", ch); + } +} + +static void jsondec_true(jsondec *d) { jsondec_parselit(d, "true"); } +static void jsondec_false(jsondec *d) { jsondec_parselit(d, "false"); } +static void jsondec_null(jsondec *d) { jsondec_parselit(d, "null"); } + +static void jsondec_entrysep(jsondec *d) { + jsondec_skipws(d); + jsondec_parselit(d, ":"); +} + +static int jsondec_rawpeek(jsondec *d) { + switch (*d->ptr) { + case '{': + return JD_OBJECT; + case '[': + return JD_ARRAY; + case '"': + return JD_STRING; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return JD_NUMBER; + case 't': + return JD_TRUE; + case 'f': + return JD_FALSE; + case 'n': + return JD_NULL; + default: + jsondec_errf(d, "Unexpected character: '%c'", *d->ptr); + } +} + +/* JSON object/array **********************************************************/ + +/* These are used like so: + * + * jsondec_objstart(d); + * while (jsondec_objnext(d)) { + * ... + * } + * jsondec_objend(d) */ + +static int jsondec_peek(jsondec *d) { + jsondec_skipws(d); + return jsondec_rawpeek(d); +} + +static void jsondec_push(jsondec *d) { + if (--d->depth < 0) { + jsondec_err(d, "Recursion limit exceeded"); + } + d->is_first = true; +} + +static bool jsondec_seqnext(jsondec *d, char end_ch) { + bool is_first = d->is_first; + d->is_first = false; + jsondec_skipws(d); + if (*d->ptr == end_ch) return false; + if (!is_first) jsondec_parselit(d, ","); + return true; +} + +static void jsondec_arrstart(jsondec *d) { + jsondec_push(d); + jsondec_wsch(d, '['); +} + +static void jsondec_arrend(jsondec *d) { + d->depth++; + jsondec_wsch(d, ']'); +} + +static bool jsondec_arrnext(jsondec *d) { + return jsondec_seqnext(d, ']'); +} + +static void jsondec_objstart(jsondec *d) { + jsondec_push(d); + jsondec_wsch(d, '{'); +} + +static void jsondec_objend(jsondec *d) { + d->depth++; + jsondec_wsch(d, '}'); +} + +static bool jsondec_objnext(jsondec *d) { + if (!jsondec_seqnext(d, '}')) return false; + if (jsondec_peek(d) != JD_STRING) { + jsondec_err(d, "Object must start with string"); + } + return true; +} + +/* JSON number ****************************************************************/ + +static bool jsondec_tryskipdigits(jsondec *d) { + const char *start = d->ptr; + + while (d->ptr < d->end) { + if (*d->ptr < '0' || *d->ptr > '9') { + break; + } + d->ptr++; + } + + return d->ptr != start; +} + +static void jsondec_skipdigits(jsondec *d) { + if (!jsondec_tryskipdigits(d)) { + jsondec_err(d, "Expected one or more digits"); + } +} + +static double jsondec_number(jsondec *d) { + const char *start = d->ptr; + + assert(jsondec_rawpeek(d) == JD_NUMBER); + + /* Skip over the syntax of a number, as specified by JSON. */ + if (*d->ptr == '-') d->ptr++; + + if (jsondec_tryparsech(d, '0')) { + if (jsondec_tryskipdigits(d)) { + jsondec_err(d, "number cannot have leading zero"); + } + } else { + jsondec_skipdigits(d); + } + + if (d->ptr == d->end) goto parse; + if (jsondec_tryparsech(d, '.')) { + jsondec_skipdigits(d); + } + if (d->ptr == d->end) goto parse; + + if (*d->ptr == 'e' || *d->ptr == 'E') { + d->ptr++; + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF in number"); + } + if (*d->ptr == '+' || *d->ptr == '-') { + d->ptr++; + } + jsondec_skipdigits(d); + } + +parse: + /* Having verified the syntax of a JSON number, use strtod() to parse + * (strtod() accepts a superset of JSON syntax). */ + errno = 0; + { + char* end; + double val = strtod(start, &end); + assert(end == d->ptr); + + /* Currently the min/max-val conformance tests fail if we check this. Does + * this mean the conformance tests are wrong or strtod() is wrong, or + * something else? Investigate further. */ + /* + if (errno == ERANGE) { + jsondec_err(d, "Number out of range"); + } + */ + + if (val > DBL_MAX || val < -DBL_MAX) { + jsondec_err(d, "Number out of range"); + } + + return val; + } +} + +/* JSON string ****************************************************************/ + +static char jsondec_escape(jsondec *d) { + switch (*d->ptr++) { + case '"': + return '\"'; + case '\\': + return '\\'; + case '/': + return '/'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + default: + jsondec_err(d, "Invalid escape char"); + } +} + +static uint32_t jsondec_codepoint(jsondec *d) { + uint32_t cp = 0; + const char *end; + + if (d->end - d->ptr < 4) { + jsondec_err(d, "EOF inside string"); + } + + end = d->ptr + 4; + while (d->ptr < end) { + char ch = *d->ptr++; + if (ch >= '0' && ch <= '9') { + ch -= '0'; + } else if (ch >= 'a' && ch <= 'f') { + ch = ch - 'a' + 10; + } else if (ch >= 'A' && ch <= 'F') { + ch = ch - 'A' + 10; + } else { + jsondec_err(d, "Invalid hex digit"); + } + cp = (cp << 4) | ch; + } + + return cp; +} + +/* Parses a \uXXXX unicode escape (possibly a surrogate pair). */ +static size_t jsondec_unicode(jsondec *d, char* out) { + uint32_t cp = jsondec_codepoint(d); + if (cp >= 0xd800 && cp <= 0xdbff) { + /* Surrogate pair: two 16-bit codepoints become a 32-bit codepoint. */ + uint32_t high = cp; + uint32_t low; + jsondec_parselit(d, "\\u"); + low = jsondec_codepoint(d); + if (low < 0xdc00 || low > 0xdfff) { + jsondec_err(d, "Invalid low surrogate"); + } + cp = (high & 0x3ff) << 10; + cp |= (low & 0x3ff); + cp += 0x10000; + } else if (cp >= 0xdc00 && cp <= 0xdfff) { + jsondec_err(d, "Unpaired low surrogate"); + } + + /* Write to UTF-8 */ + if (cp <= 0x7f) { + out[0] = cp; + return 1; + } else if (cp <= 0x07FF) { + out[0] = ((cp >> 6) & 0x1F) | 0xC0; + out[1] = ((cp >> 0) & 0x3F) | 0x80; + return 2; + } else if (cp <= 0xFFFF) { + out[0] = ((cp >> 12) & 0x0F) | 0xE0; + out[1] = ((cp >> 6) & 0x3F) | 0x80; + out[2] = ((cp >> 0) & 0x3F) | 0x80; + return 3; + } else if (cp < 0x10FFFF) { + out[0] = ((cp >> 18) & 0x07) | 0xF0; + out[1] = ((cp >> 12) & 0x3f) | 0x80; + out[2] = ((cp >> 6) & 0x3f) | 0x80; + out[3] = ((cp >> 0) & 0x3f) | 0x80; + return 4; + } else { + jsondec_err(d, "Invalid codepoint"); + } +} + +static void jsondec_resize(jsondec *d, char **buf, char **end, char **buf_end) { + size_t oldsize = *buf_end - *buf; + size_t len = *end - *buf; + size_t size = UPB_MAX(8, 2 * oldsize); + + *buf = upb_arena_realloc(d->arena, *buf, len, size); + if (!*buf) jsondec_err(d, "Out of memory"); + + *end = *buf + len; + *buf_end = *buf + size; +} + +static upb_strview jsondec_string(jsondec *d) { + char *buf = NULL; + char *end = NULL; + char *buf_end = NULL; + + jsondec_skipws(d); + + if (*d->ptr++ != '"') { + jsondec_err(d, "Expected string"); + } + + while (d->ptr < d->end) { + char ch = *d->ptr++; + + if (end == buf_end) { + jsondec_resize(d, &buf, &end, &buf_end); + } + + switch (ch) { + case '"': { + upb_strview ret; + ret.data = buf; + ret.size = end - buf; + *end = '\0'; /* Needed for possible strtod(). */ + return ret; + } + case '\\': + if (d->ptr == d->end) goto eof; + if (*d->ptr == 'u') { + d->ptr++; + if (buf_end - end < 4) { + /* Allow space for maximum-sized code point (4 bytes). */ + jsondec_resize(d, &buf, &end, &buf_end); + } + end += jsondec_unicode(d, end); + } else { + *end++ = jsondec_escape(d); + } + break; + default: + if ((unsigned char)*d->ptr < 0x20) { + jsondec_err(d, "Invalid char in JSON string"); + } + *end++ = ch; + break; + } + } + +eof: + jsondec_err(d, "EOF inside string"); +} + +static void jsondec_skipval(jsondec *d) { + switch (jsondec_peek(d)) { + case JD_OBJECT: + jsondec_objstart(d); + while (jsondec_objnext(d)) { + jsondec_string(d); + jsondec_entrysep(d); + jsondec_skipval(d); + } + jsondec_objend(d); + break; + case JD_ARRAY: + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + jsondec_skipval(d); + } + jsondec_arrend(d); + break; + case JD_TRUE: + jsondec_true(d); + break; + case JD_FALSE: + jsondec_false(d); + break; + case JD_NULL: + jsondec_null(d); + break; + case JD_STRING: + jsondec_string(d); + break; + case JD_NUMBER: + jsondec_number(d); + break; + } +} + +/* Base64 decoding for bytes fields. ******************************************/ + +static unsigned int jsondec_base64_tablelookup(const char ch) { + /* Table includes the normal base64 chars plus the URL-safe variant. */ + const signed char table[256] = { + -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, 62 /*-*/, -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, 63 /*_*/, -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}; + + /* Sign-extend return value so high bit will be set on any unexpected char. */ + return table[(unsigned)ch]; +} + +static char *jsondec_partialbase64(jsondec *d, const char *ptr, const char *end, + char *out) { + int32_t val = -1; + + switch (end - ptr) { + case 2: + val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12; + out[0] = val >> 16; + out += 1; + break; + case 3: + val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12 | + jsondec_base64_tablelookup(ptr[2]) << 6; + out[0] = val >> 16; + out[1] = (val >> 8) & 0xff; + out += 2; + break; + } + + if (val < 0) { + jsondec_err(d, "Corrupt base64"); + } + + return out; +} + +static size_t jsondec_base64(jsondec *d, upb_strview str) { + /* We decode in place. This is safe because this is a new buffer (not + * aliasing the input) and because base64 decoding shrinks 4 bytes into 3. */ + char *out = (char*)str.data; + const char *ptr = str.data; + const char *end = ptr + str.size; + const char *end4 = ptr + (str.size & -4); /* Round down to multiple of 4. */ + + for (; ptr < end4; ptr += 4, out += 3) { + int val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12 | + jsondec_base64_tablelookup(ptr[2]) << 6 | + jsondec_base64_tablelookup(ptr[3]) << 0; + + if (val < 0) { + /* Junk chars or padding. Remove trailing padding, if any. */ + if (end - ptr == 4 && ptr[3] == '=') { + if (ptr[2] == '=') { + end -= 2; + } else { + end -= 1; + } + } + break; + } + + out[0] = val >> 16; + out[1] = (val >> 8) & 0xff; + out[2] = val & 0xff; + } + + if (ptr < end) { + /* Process remaining chars. We do not require padding. */ + out = jsondec_partialbase64(d, ptr, end, out); + } + + return out - str.data; +} + +/* Low-level integer parsing **************************************************/ + +/* We use these hand-written routines instead of strto[u]l() because the "long + * long" variants aren't in c89. Also our version allows setting a ptr limit. */ + +static const char *jsondec_buftouint64(jsondec *d, const char *ptr, + const char *end, uint64_t *val) { + uint64_t u64 = 0; + while (ptr < end) { + unsigned ch = *ptr - '0'; + if (ch >= 10) break; + if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) { + jsondec_err(d, "Integer overflow"); + } + u64 *= 10; + u64 += ch; + ptr++; + } + + *val = u64; + return ptr; +} + +static const char *jsondec_buftoint64(jsondec *d, const char *ptr, + const char *end, int64_t *val) { + bool neg = false; + uint64_t u64; + + if (ptr != end && *ptr == '-') { + ptr++; + neg = true; + } + + ptr = jsondec_buftouint64(d, ptr, end, &u64); + if (u64 > (uint64_t)INT64_MAX + neg) { + jsondec_err(d, "Integer overflow"); + } + + *val = neg ? -u64 : u64; + return ptr; +} + +static uint64_t jsondec_strtouint64(jsondec *d, upb_strview str) { + const char *end = str.data + str.size; + uint64_t ret; + if (jsondec_buftouint64(d, str.data, end, &ret) != end) { + jsondec_err(d, "Non-number characters in quoted integer"); + } + return ret; +} + +static int64_t jsondec_strtoint64(jsondec *d, upb_strview str) { + const char *end = str.data + str.size; + int64_t ret; + if (jsondec_buftoint64(d, str.data, end, &ret) != end) { + jsondec_err(d, "Non-number characters in quoted integer"); + } + return ret; +} + +/* Primitive value types ******************************************************/ + +/* Parse INT32 or INT64 value. */ +static upb_msgval jsondec_int(jsondec *d, const upb_fielddef *f) { + upb_msgval val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: { + double dbl = jsondec_number(d); + if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) { + jsondec_err(d, "JSON number is out of range."); + } + val.int64_val = dbl; /* must be guarded, overflow here is UB */ + if (val.int64_val != dbl) { + jsondec_errf(d, "JSON number was not integral (%d != %" PRId64 ")", dbl, + val.int64_val); + } + break; + } + case JD_STRING: { + upb_strview str = jsondec_string(d); + val.int64_val = jsondec_strtoint64(d, str); + break; + } + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_fielddef_type(f) == UPB_TYPE_INT32) { + if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) { + jsondec_err(d, "Integer out of range."); + } + val.int32_val = (int32_t)val.int64_val; + } + + return val; +} + +/* Parse UINT32 or UINT64 value. */ +static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) { + upb_msgval val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: { + double dbl = jsondec_number(d); + if (dbl > 18446744073709549568.0 || dbl < 0) { + jsondec_err(d, "JSON number is out of range."); + } + val.uint64_val = dbl; /* must be guarded, overflow here is UB */ + if (val.uint64_val != dbl) { + jsondec_errf(d, "JSON number was not integral (%d != %" PRIu64 ")", dbl, + val.uint64_val); + } + break; + } + case JD_STRING: { + upb_strview str = jsondec_string(d); + val.uint64_val = jsondec_strtouint64(d, str); + break; + } + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_fielddef_type(f) == UPB_TYPE_UINT32) { + if (val.uint64_val > UINT32_MAX) { + jsondec_err(d, "Integer out of range."); + } + val.uint32_val = (uint32_t)val.uint64_val; + } + + return val; +} + +/* Parse DOUBLE or FLOAT value. */ +static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) { + upb_strview str; + upb_msgval val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: + val.double_val = jsondec_number(d); + break; + case JD_STRING: + str = jsondec_string(d); + if (jsondec_streql(str, "NaN")) { + val.double_val = NAN; + } else if (jsondec_streql(str, "Infinity")) { + val.double_val = INFINITY; + } else if (jsondec_streql(str, "-Infinity")) { + val.double_val = -INFINITY; + } else { + val.double_val = strtod(str.data, NULL); + } + break; + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_fielddef_type(f) == UPB_TYPE_FLOAT) { + if (val.double_val != INFINITY && val.double_val != -INFINITY && + (val.double_val > FLT_MAX || val.double_val < -FLT_MAX)) { + jsondec_err(d, "Float out of range"); + } + val.float_val = val.double_val; + } + + return val; +} + +/* Parse STRING or BYTES value. */ +static upb_msgval jsondec_strfield(jsondec *d, const upb_fielddef *f) { + upb_msgval val; + val.str_val = jsondec_string(d); + if (upb_fielddef_type(f) == UPB_TYPE_BYTES) { + val.str_val.size = jsondec_base64(d, val.str_val); + } + return val; +} + +static upb_msgval jsondec_enum(jsondec *d, const upb_fielddef *f) { + switch (jsondec_peek(d)) { + case JD_STRING: { + const upb_enumdef *e = upb_fielddef_enumsubdef(f); + upb_strview str = jsondec_string(d); + upb_msgval val; + if (!upb_enumdef_ntoi(e, str.data, str.size, &val.int32_val)) { + if (d->options & UPB_JSONDEC_IGNOREUNKNOWN) { + val.int32_val = 0; + } else { + jsondec_errf(d, "Unknown enumerator: '" UPB_STRVIEW_FORMAT "'", + UPB_STRVIEW_ARGS(str)); + } + } + return val; + } + case JD_NULL: { + if (jsondec_isnullvalue(f)) { + upb_msgval val; + jsondec_null(d); + val.int32_val = 0; + return val; + } + } + /* Fallthrough. */ + default: + return jsondec_int(d, f); + } +} + +static upb_msgval jsondec_bool(jsondec *d, const upb_fielddef *f) { + bool is_map_key = upb_fielddef_number(f) == 1 && + upb_msgdef_mapentry(upb_fielddef_containingtype(f)); + upb_msgval val; + + if (is_map_key) { + upb_strview str = jsondec_string(d); + if (jsondec_streql(str, "true")) { + val.bool_val = true; + } else if (jsondec_streql(str, "false")) { + val.bool_val = false; + } else { + jsondec_err(d, "Invalid boolean map key"); + } + } else { + switch (jsondec_peek(d)) { + case JD_TRUE: + val.bool_val = true; + jsondec_true(d); + break; + case JD_FALSE: + val.bool_val = false; + jsondec_false(d); + break; + default: + jsondec_err(d, "Expected true or false"); + } + } + + return val; +} + +/* Composite types (array/message/map) ****************************************/ + +static void jsondec_array(jsondec *d, upb_msg *msg, const upb_fielddef *f) { + upb_array *arr = upb_msg_mutable(msg, f, d->arena).array; + + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + upb_msgval elem = jsondec_value(d, f); + upb_array_append(arr, elem, d->arena); + } + jsondec_arrend(d); +} + +static void jsondec_map(jsondec *d, upb_msg *msg, const upb_fielddef *f) { + upb_map *map = upb_msg_mutable(msg, f, d->arena).map; + const upb_msgdef *entry = upb_fielddef_msgsubdef(f); + const upb_fielddef *key_f = upb_msgdef_itof(entry, 1); + const upb_fielddef *val_f = upb_msgdef_itof(entry, 2); + + jsondec_objstart(d); + while (jsondec_objnext(d)) { + upb_msgval key, val; + key = jsondec_value(d, key_f); + jsondec_entrysep(d); + val = jsondec_value(d, val_f); + upb_map_set(map, key, val, d->arena); + } + jsondec_objend(d); +} + +static void jsondec_tomsg(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + if (upb_msgdef_wellknowntype(m) == UPB_WELLKNOWN_UNSPECIFIED) { + jsondec_object(d, msg, m); + } else { + jsondec_wellknown(d, msg, m); + } +} + +static upb_msgval jsondec_msg(jsondec *d, const upb_fielddef *f) { + const upb_msgdef *m = upb_fielddef_msgsubdef(f); + upb_msg *msg = upb_msg_new(m, d->arena); + upb_msgval val; + + jsondec_tomsg(d, msg, m); + val.msg_val = msg; + return val; +} + +static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + upb_strview name; + const upb_fielddef *f; + const upb_fielddef *preserved; + + name = jsondec_string(d); + jsondec_entrysep(d); + f = upb_msgdef_lookupjsonname(m, name.data, name.size); + + if (!f) { + if ((d->options & UPB_JSONDEC_IGNOREUNKNOWN) == 0) { + jsondec_errf(d, "Unknown field: '" UPB_STRVIEW_FORMAT "'", + UPB_STRVIEW_ARGS(name)); + } + jsondec_skipval(d); + return; + } + + if (upb_fielddef_realcontainingoneof(f) && + upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) { + jsondec_err(d, "More than one field for this oneof."); + } + + if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) { + /* JSON "null" indicates a default value, so no need to set anything. */ + jsondec_null(d); + return; + } + + preserved = d->debug_field; + d->debug_field = f; + + if (upb_fielddef_ismap(f)) { + jsondec_map(d, msg, f); + } else if (upb_fielddef_isseq(f)) { + jsondec_array(d, msg, f); + } else if (upb_fielddef_issubmsg(f)) { + upb_msg *submsg = upb_msg_mutable(msg, f, d->arena).msg; + const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + jsondec_tomsg(d, submsg, subm); + } else { + upb_msgval val = jsondec_value(d, f); + upb_msg_set(msg, f, val, d->arena); + } + + d->debug_field = preserved; +} + +static void jsondec_object(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + jsondec_objstart(d); + while (jsondec_objnext(d)) { + jsondec_field(d, msg, m); + } + jsondec_objend(d); +} + +static upb_msgval jsondec_value(jsondec *d, const upb_fielddef *f) { + switch (upb_fielddef_type(f)) { + case UPB_TYPE_BOOL: + return jsondec_bool(d, f); + case UPB_TYPE_FLOAT: + case UPB_TYPE_DOUBLE: + return jsondec_double(d, f); + case UPB_TYPE_UINT32: + case UPB_TYPE_UINT64: + return jsondec_uint(d, f); + case UPB_TYPE_INT32: + case UPB_TYPE_INT64: + return jsondec_int(d, f); + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + return jsondec_strfield(d, f); + case UPB_TYPE_ENUM: + return jsondec_enum(d, f); + case UPB_TYPE_MESSAGE: + return jsondec_msg(d, f); + default: + UPB_UNREACHABLE(); + } +} + +/* Well-known types ***********************************************************/ + +static int jsondec_tsdigits(jsondec *d, const char **ptr, size_t digits, + const char *after) { + uint64_t val; + const char *p = *ptr; + const char *end = p + digits; + size_t after_len = after ? strlen(after) : 0; + + UPB_ASSERT(digits <= 9); /* int can't overflow. */ + + if (jsondec_buftouint64(d, p, end, &val) != end || + (after_len && memcmp(end, after, after_len) != 0)) { + jsondec_err(d, "Malformed timestamp"); + } + + UPB_ASSERT(val < INT_MAX); + + *ptr = end + after_len; + return (int)val; +} + +static int jsondec_nanos(jsondec *d, const char **ptr, const char *end) { + uint64_t nanos = 0; + const char *p = *ptr; + + if (p != end && *p == '.') { + const char *nano_end = jsondec_buftouint64(d, p + 1, end, &nanos); + int digits = (int)(nano_end - p - 1); + int exp_lg10 = 9 - digits; + if (digits > 9) { + jsondec_err(d, "Too many digits for partial seconds"); + } + while (exp_lg10--) nanos *= 10; + *ptr = nano_end; + } + + UPB_ASSERT(nanos < INT_MAX); + + return (int)nanos; +} + +/* jsondec_epochdays(1970, 1, 1) == 1970-01-01 == 0. */ +int jsondec_epochdays(int y, int m, int d) { + const uint32_t year_base = 4800; /* Before min year, multiple of 400. */ + const uint32_t m_adj = m - 3; /* March-based month. */ + const uint32_t carry = m_adj > (uint32_t)m ? 1 : 0; + const uint32_t adjust = carry ? 12 : 0; + const uint32_t y_adj = y + year_base - carry; + const uint32_t month_days = ((m_adj + adjust) * 62719 + 769) / 2048; + const uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400; + return y_adj * 365 + leap_days + month_days + (d - 1) - 2472632; +} + +static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s) { + return (int64_t)jsondec_epochdays(y, m, d) * 86400 + h * 3600 + min * 60 + s; +} + +static void jsondec_timestamp(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + upb_msgval seconds; + upb_msgval nanos; + upb_strview str = jsondec_string(d); + const char *ptr = str.data; + const char *end = ptr + str.size; + + if (str.size < 20) goto malformed; + + { + /* 1972-01-01T01:00:00 */ + int year = jsondec_tsdigits(d, &ptr, 4, "-"); + int mon = jsondec_tsdigits(d, &ptr, 2, "-"); + int day = jsondec_tsdigits(d, &ptr, 2, "T"); + int hour = jsondec_tsdigits(d, &ptr, 2, ":"); + int min = jsondec_tsdigits(d, &ptr, 2, ":"); + int sec = jsondec_tsdigits(d, &ptr, 2, NULL); + + seconds.int64_val = jsondec_unixtime(year, mon, day, hour, min, sec); + } + + nanos.int32_val = jsondec_nanos(d, &ptr, end); + + { + /* [+-]08:00 or Z */ + int ofs = 0; + bool neg = false; + + if (ptr == end) goto malformed; + + switch (*ptr++) { + case '-': + neg = true; + /* fallthrough */ + case '+': + if ((end - ptr) != 5) goto malformed; + ofs = jsondec_tsdigits(d, &ptr, 2, ":00"); + ofs *= 60 * 60; + seconds.int64_val += (neg ? ofs : -ofs); + break; + case 'Z': + if (ptr != end) goto malformed; + break; + default: + goto malformed; + } + } + + if (seconds.int64_val < -62135596800) { + jsondec_err(d, "Timestamp out of range"); + } + + upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena); + upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena); + return; + +malformed: + jsondec_err(d, "Malformed timestamp"); +} + +static void jsondec_duration(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + upb_msgval seconds; + upb_msgval nanos; + upb_strview str = jsondec_string(d); + const char *ptr = str.data; + const char *end = ptr + str.size; + const int64_t max = (uint64_t)3652500 * 86400; + + /* "3.000000001s", "3s", etc. */ + ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val); + nanos.int32_val = jsondec_nanos(d, &ptr, end); + + if (end - ptr != 1 || *ptr != 's') { + jsondec_err(d, "Malformed duration"); + } + + if (seconds.int64_val < -max || seconds.int64_val > max) { + jsondec_err(d, "Duration out of range"); + } + + if (seconds.int64_val < 0) { + nanos.int32_val = - nanos.int32_val; + } + + upb_msg_set(msg, upb_msgdef_itof(m, 1), seconds, d->arena); + upb_msg_set(msg, upb_msgdef_itof(m, 2), nanos, d->arena); +} + +static void jsondec_listvalue(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + const upb_fielddef *values_f = upb_msgdef_itof(m, 1); + const upb_msgdef *value_m = upb_fielddef_msgsubdef(values_f); + upb_array *values = upb_msg_mutable(msg, values_f, d->arena).array; + + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + upb_msg *value_msg = upb_msg_new(value_m, d->arena); + upb_msgval value; + value.msg_val = value_msg; + upb_array_append(values, value, d->arena); + jsondec_wellknownvalue(d, value_msg, value_m); + } + jsondec_arrend(d); +} + +static void jsondec_struct(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + const upb_fielddef *fields_f = upb_msgdef_itof(m, 1); + const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f); + const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2); + const upb_msgdef *value_m = upb_fielddef_msgsubdef(value_f); + upb_map *fields = upb_msg_mutable(msg, fields_f, d->arena).map; + + jsondec_objstart(d); + while (jsondec_objnext(d)) { + upb_msgval key, value; + upb_msg *value_msg = upb_msg_new(value_m, d->arena); + key.str_val = jsondec_string(d); + value.msg_val = value_msg; + upb_map_set(fields, key, value, d->arena); + jsondec_entrysep(d); + jsondec_wellknownvalue(d, value_msg, value_m); + } + jsondec_objend(d); +} + +static void jsondec_wellknownvalue(jsondec *d, upb_msg *msg, + const upb_msgdef *m) { + upb_msgval val; + const upb_fielddef *f; + upb_msg *submsg; + + switch (jsondec_peek(d)) { + case JD_NUMBER: + /* double number_value = 2; */ + f = upb_msgdef_itof(m, 2); + val.double_val = jsondec_number(d); + break; + case JD_STRING: + /* string string_value = 3; */ + f = upb_msgdef_itof(m, 3); + val.str_val = jsondec_string(d); + break; + case JD_FALSE: + /* bool bool_value = 4; */ + f = upb_msgdef_itof(m, 4); + val.bool_val = false; + jsondec_false(d); + break; + case JD_TRUE: + /* bool bool_value = 4; */ + f = upb_msgdef_itof(m, 4); + val.bool_val = true; + jsondec_true(d); + break; + case JD_NULL: + /* NullValue null_value = 1; */ + f = upb_msgdef_itof(m, 1); + val.int32_val = 0; + jsondec_null(d); + break; + /* Note: these cases return, because upb_msg_mutable() is enough. */ + case JD_OBJECT: + /* Struct struct_value = 5; */ + f = upb_msgdef_itof(m, 5); + submsg = upb_msg_mutable(msg, f, d->arena).msg; + jsondec_struct(d, submsg, upb_fielddef_msgsubdef(f)); + return; + case JD_ARRAY: + /* ListValue list_value = 6; */ + f = upb_msgdef_itof(m, 6); + submsg = upb_msg_mutable(msg, f, d->arena).msg; + jsondec_listvalue(d, submsg, upb_fielddef_msgsubdef(f)); + return; + default: + UPB_UNREACHABLE(); + } + + upb_msg_set(msg, f, val, d->arena); +} + +static upb_strview jsondec_mask(jsondec *d, const char *buf, const char *end) { + /* FieldMask fields grow due to inserted '_' characters, so we can't do the + * transform in place. */ + const char *ptr = buf; + upb_strview ret; + char *out; + + ret.size = end - ptr; + while (ptr < end) { + ret.size += (*ptr >= 'A' && *ptr <= 'Z'); + ptr++; + } + + out = upb_arena_malloc(d->arena, ret.size); + ptr = buf; + ret.data = out; + + while (ptr < end) { + char ch = *ptr++; + if (ch >= 'A' && ch <= 'Z') { + *out++ = '_'; + *out++ = ch + 32; + } else if (ch == '_') { + jsondec_err(d, "field mask may not contain '_'"); + } else { + *out++ = ch; + } + } + + return ret; +} + +static void jsondec_fieldmask(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + /* repeated string paths = 1; */ + const upb_fielddef *paths_f = upb_msgdef_itof(m, 1); + upb_array *arr = upb_msg_mutable(msg, paths_f, d->arena).array; + upb_strview str = jsondec_string(d); + const char *ptr = str.data; + const char *end = ptr + str.size; + upb_msgval val; + + while (ptr < end) { + const char *elem_end = memchr(ptr, ',', end - ptr); + if (elem_end) { + val.str_val = jsondec_mask(d, ptr, elem_end); + ptr = elem_end + 1; + } else { + val.str_val = jsondec_mask(d, ptr, end); + ptr = end; + } + upb_array_append(arr, val, d->arena); + } +} + +static void jsondec_anyfield(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + if (upb_msgdef_wellknowntype(m) == UPB_WELLKNOWN_UNSPECIFIED) { + /* For regular types: {"@type": "[user type]", "f1": , "f2": } + * where f1, f2, etc. are the normal fields of this type. */ + jsondec_field(d, msg, m); + } else { + /* For well-known types: {"@type": "[well-known type]", "value": } + * where is whatever encoding the WKT normally uses. */ + upb_strview str = jsondec_string(d); + jsondec_entrysep(d); + if (!jsondec_streql(str, "value")) { + jsondec_err(d, "Key for well-known type must be 'value'"); + } + jsondec_wellknown(d, msg, m); + } +} + +static const upb_msgdef *jsondec_typeurl(jsondec *d, upb_msg *msg, + const upb_msgdef *m) { + const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1); + const upb_msgdef *type_m; + upb_strview type_url = jsondec_string(d); + const char *end = type_url.data + type_url.size; + const char *ptr = end; + upb_msgval val; + + val.str_val = type_url; + upb_msg_set(msg, type_url_f, val, d->arena); + + /* Find message name after the last '/' */ + while (ptr > type_url.data && *--ptr != '/') {} + + if (ptr == type_url.data || ptr == end) { + jsondec_err(d, "Type url must have at least one '/' and non-empty host"); + } + + ptr++; + type_m = upb_symtab_lookupmsg2(d->any_pool, ptr, end - ptr); + + if (!type_m) { + jsondec_err(d, "Type was not found"); + } + + return type_m; +} + +static void jsondec_any(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + /* string type_url = 1; + * bytes value = 2; */ + const upb_fielddef *value_f = upb_msgdef_itof(m, 2); + upb_msg *any_msg; + const upb_msgdef *any_m = NULL; + const char *pre_type_data = NULL; + const char *pre_type_end = NULL; + upb_msgval encoded; + + jsondec_objstart(d); + + /* Scan looking for "@type", which is not necessarily first. */ + while (!any_m && jsondec_objnext(d)) { + const char *start = d->ptr; + upb_strview name = jsondec_string(d); + jsondec_entrysep(d); + if (jsondec_streql(name, "@type")) { + any_m = jsondec_typeurl(d, msg, m); + if (pre_type_data) { + pre_type_end = start; + while (*pre_type_end != ',') pre_type_end--; + } + } else { + if (!pre_type_data) pre_type_data = start; + jsondec_skipval(d); + } + } + + if (!any_m) { + jsondec_err(d, "Any object didn't contain a '@type' field"); + } + + any_msg = upb_msg_new(any_m, d->arena); + + if (pre_type_data) { + size_t len = pre_type_end - pre_type_data + 1; + char *tmp = upb_arena_malloc(d->arena, len); + const char *saved_ptr = d->ptr; + const char *saved_end = d->end; + memcpy(tmp, pre_type_data, len - 1); + tmp[len - 1] = '}'; + d->ptr = tmp; + d->end = tmp + len; + d->is_first = true; + while (jsondec_objnext(d)) { + jsondec_anyfield(d, any_msg, any_m); + } + d->ptr = saved_ptr; + d->end = saved_end; + } + + while (jsondec_objnext(d)) { + jsondec_anyfield(d, any_msg, any_m); + } + + jsondec_objend(d); + + encoded.str_val.data = upb_encode(any_msg, upb_msgdef_layout(any_m), d->arena, + &encoded.str_val.size); + upb_msg_set(msg, value_f, encoded, d->arena); +} + +static void jsondec_wrapper(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + const upb_fielddef *value_f = upb_msgdef_itof(m, 1); + upb_msgval val = jsondec_value(d, value_f); + upb_msg_set(msg, value_f, val, d->arena); +} + +static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m) { + switch (upb_msgdef_wellknowntype(m)) { + case UPB_WELLKNOWN_ANY: + jsondec_any(d, msg, m); + break; + case UPB_WELLKNOWN_FIELDMASK: + jsondec_fieldmask(d, msg, m); + break; + case UPB_WELLKNOWN_DURATION: + jsondec_duration(d, msg, m); + break; + case UPB_WELLKNOWN_TIMESTAMP: + jsondec_timestamp(d, msg, m); + break; + case UPB_WELLKNOWN_VALUE: + jsondec_wellknownvalue(d, msg, m); + break; + case UPB_WELLKNOWN_LISTVALUE: + jsondec_listvalue(d, msg, m); + break; + case UPB_WELLKNOWN_STRUCT: + jsondec_struct(d, msg, m); + break; + case UPB_WELLKNOWN_DOUBLEVALUE: + case UPB_WELLKNOWN_FLOATVALUE: + case UPB_WELLKNOWN_INT64VALUE: + case UPB_WELLKNOWN_UINT64VALUE: + case UPB_WELLKNOWN_INT32VALUE: + case UPB_WELLKNOWN_UINT32VALUE: + case UPB_WELLKNOWN_STRINGVALUE: + case UPB_WELLKNOWN_BYTESVALUE: + case UPB_WELLKNOWN_BOOLVALUE: + jsondec_wrapper(d, msg, m); + break; + default: + UPB_UNREACHABLE(); + } +} + +bool upb_json_decode(const char *buf, size_t size, upb_msg *msg, + const upb_msgdef *m, const upb_symtab *any_pool, + int options, upb_arena *arena, upb_status *status) { + jsondec d; + d.ptr = buf; + d.end = buf + size; + d.arena = arena; + d.any_pool = any_pool; + d.status = status; + d.options = options; + d.depth = 64; + d.line = 1; + d.line_begin = d.ptr; + d.debug_field = NULL; + d.is_first = false; + + if (setjmp(d.err)) return false; + + jsondec_tomsg(&d, msg, m); + return true; +} + + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Must be last. */ + +typedef struct { + char *buf, *ptr, *end; + size_t overflow; + int indent_depth; + int options; + const upb_symtab *ext_pool; + jmp_buf err; + upb_status *status; + upb_arena *arena; +} jsonenc; + +static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m); +static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f); +static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m); +static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m); +static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m); + +UPB_NORETURN static void jsonenc_err(jsonenc *e, const char *msg) { + upb_status_seterrmsg(e->status, msg); + longjmp(e->err, 1); +} + +UPB_NORETURN static void jsonenc_errf(jsonenc *e, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + upb_status_vseterrf(e->status, fmt, argp); + va_end(argp); + longjmp(e->err, 1); +} + +static upb_arena *jsonenc_arena(jsonenc *e) { + /* Create lazily, since it's only needed for Any */ + if (!e->arena) { + e->arena = upb_arena_new(); + } + return e->arena; +} + +static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) { + size_t have = e->end - e->ptr; + if (UPB_LIKELY(have >= len)) { + memcpy(e->ptr, data, len); + e->ptr += len; + } else { + if (have) memcpy(e->ptr, data, have); + e->ptr += have; + e->overflow += (len - have); + } +} + +static void jsonenc_putstr(jsonenc *e, const char *str) { + jsonenc_putbytes(e, str, strlen(str)); +} + +static void jsonenc_printf(jsonenc *e, const char *fmt, ...) { + size_t n; + size_t have = e->end - e->ptr; + va_list args; + + va_start(args, fmt); + n = vsnprintf(e->ptr, have, fmt, args); + va_end(args); + + if (UPB_LIKELY(have > n)) { + e->ptr += n; + } else { + e->ptr += have; + e->overflow += (n - have); + } +} + +static void jsonenc_nanos(jsonenc *e, int32_t nanos) { + int digits = 9; + + if (nanos == 0) return; + if (nanos < 0 || nanos >= 1000000000) { + jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos"); + } + + while (nanos % 1000 == 0) { + nanos /= 1000; + digits -= 3; + } + + jsonenc_printf(e, ".%0.*" PRId32, digits, nanos); +} + +static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m) { + const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1); + const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2); + int64_t seconds = upb_msg_get(msg, seconds_f).int64_val; + int32_t nanos = upb_msg_get(msg, nanos_f).int32_val; + int L, N, I, J, K, hour, min, sec; + + if (seconds < -62135596800) { + jsonenc_err(e, + "error formatting timestamp as JSON: minimum acceptable value " + "is 0001-01-01T00:00:00Z"); + } else if (seconds > 253402300799) { + jsonenc_err(e, + "error formatting timestamp as JSON: maximum acceptable value " + "is 9999-12-31T23:59:59Z"); + } + + /* Julian Day -> Y/M/D, Algorithm from: + * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for + * Processing Calendar Dates," Communications of the Association of + * Computing Machines, vol. 11 (1968), p. 657. */ + L = (int)(seconds / 86400) + 68569 + 2440588; + N = 4 * L / 146097; + L = L - (146097 * N + 3) / 4; + I = 4000 * (L + 1) / 1461001; + L = L - 1461 * I / 4 + 31; + J = 80 * L / 2447; + K = L - 2447 * J / 80; + L = J / 11; + J = J + 2 - 12 * L; + I = 100 * (N - 49) + I + L; + + sec = seconds % 60; + min = (seconds / 60) % 60; + hour = (seconds / 3600) % 24; + + jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec); + jsonenc_nanos(e, nanos); + jsonenc_putstr(e, "Z\""); +} + +static void jsonenc_duration(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { + const upb_fielddef *seconds_f = upb_msgdef_itof(m, 1); + const upb_fielddef *nanos_f = upb_msgdef_itof(m, 2); + int64_t seconds = upb_msg_get(msg, seconds_f).int64_val; + int32_t nanos = upb_msg_get(msg, nanos_f).int32_val; + + if (seconds > 315576000000 || seconds < -315576000000 || + (seconds < 0) != (nanos < 0)) { + jsonenc_err(e, "bad duration"); + } + + if (nanos < 0) { + nanos = -nanos; + } + + jsonenc_printf(e, "\"%" PRId64, seconds); + jsonenc_nanos(e, nanos); + jsonenc_putstr(e, "s\""); +} + +static void jsonenc_enum(int32_t val, const upb_fielddef *f, jsonenc *e) { + const upb_enumdef *e_def = upb_fielddef_enumsubdef(f); + + if (strcmp(upb_enumdef_fullname(e_def), "google.protobuf.NullValue") == 0) { + jsonenc_putstr(e, "null"); + } else { + const char *name = upb_enumdef_iton(e_def, val); + + if (name) { + jsonenc_printf(e, "\"%s\"", name); + } else { + jsonenc_printf(e, "%" PRId32, val); + } + } +} + +static void jsonenc_bytes(jsonenc *e, upb_strview str) { + /* This is the regular base64, not the "web-safe" version. */ + static const char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + const unsigned char *ptr = (unsigned char*)str.data; + const unsigned char *end = ptr + str.size; + char buf[4]; + + jsonenc_putstr(e, "\""); + + while (end - ptr >= 3) { + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)]; + buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)]; + buf[3] = base64[ptr[2] & 0x3f]; + jsonenc_putbytes(e, buf, 4); + ptr += 3; + } + + switch (end - ptr) { + case 2: + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)]; + buf[2] = base64[(ptr[1] & 0xf) << 2]; + buf[3] = '='; + jsonenc_putbytes(e, buf, 4); + break; + case 1: + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4)]; + buf[2] = '='; + buf[3] = '='; + jsonenc_putbytes(e, buf, 4); + break; + } + + jsonenc_putstr(e, "\""); +} + +static void jsonenc_stringbody(jsonenc *e, upb_strview str) { + const char *ptr = str.data; + const char *end = ptr + str.size; + + while (ptr < end) { + switch (*ptr) { + case '\n': + jsonenc_putstr(e, "\\n"); + break; + case '\r': + jsonenc_putstr(e, "\\r"); + break; + case '\t': + jsonenc_putstr(e, "\\t"); + break; + case '\"': + jsonenc_putstr(e, "\\\""); + break; + case '\f': + jsonenc_putstr(e, "\\f"); + break; + case '\b': + jsonenc_putstr(e, "\\b"); + break; + case '\\': + jsonenc_putstr(e, "\\\\"); + break; + default: + if ((uint8_t)*ptr < 0x20) { + jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr); + } else { + /* This could be a non-ASCII byte. We rely on the string being valid + * UTF-8. */ + jsonenc_putbytes(e, ptr, 1); + } + break; + } + ptr++; + } +} + +static void jsonenc_string(jsonenc *e, upb_strview str) { + jsonenc_putstr(e, "\""); + jsonenc_stringbody(e, str); + jsonenc_putstr(e, "\""); +} + +static void jsonenc_double(jsonenc *e, const char *fmt, double val) { + if (val == INFINITY) { + jsonenc_putstr(e, "\"Infinity\""); + } else if (val == -INFINITY) { + jsonenc_putstr(e, "\"-Infinity\""); + } else if (val != val) { + jsonenc_putstr(e, "\"NaN\""); + } else { + jsonenc_printf(e, fmt, val); + } +} + +static void jsonenc_wrapper(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m) { + const upb_fielddef *val_f = upb_msgdef_itof(m, 1); + upb_msgval val = upb_msg_get(msg, val_f); + jsonenc_scalar(e, val, val_f); +} + +static const upb_msgdef *jsonenc_getanymsg(jsonenc *e, upb_strview type_url) { + /* Find last '/', if any. */ + const char *end = type_url.data + type_url.size; + const char *ptr = end; + const upb_msgdef *ret; + + if (!e->ext_pool) { + jsonenc_err(e, "Tried to encode Any, but no symtab was provided"); + } + + if (type_url.size == 0) goto badurl; + + while (true) { + if (--ptr == type_url.data) { + /* Type URL must contain at least one '/', with host before. */ + goto badurl; + } + if (*ptr == '/') { + ptr++; + break; + } + } + + ret = upb_symtab_lookupmsg2(e->ext_pool, ptr, end - ptr); + + if (!ret) { + jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr); + } + + return ret; + +badurl: + jsonenc_errf( + e, "Bad type URL: " UPB_STRVIEW_FORMAT, UPB_STRVIEW_ARGS(type_url)); +} + +static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { + const upb_fielddef *type_url_f = upb_msgdef_itof(m, 1); + const upb_fielddef *value_f = upb_msgdef_itof(m, 2); + upb_strview type_url = upb_msg_get(msg, type_url_f).str_val; + upb_strview value = upb_msg_get(msg, value_f).str_val; + const upb_msgdef *any_m = jsonenc_getanymsg(e, type_url); + const upb_msglayout *any_layout = upb_msgdef_layout(any_m); + upb_arena *arena = jsonenc_arena(e); + upb_msg *any = upb_msg_new(any_m, arena); + + if (!upb_decode(value.data, value.size, any, any_layout, arena)) { + jsonenc_err(e, "Error decoding message in Any"); + } + + jsonenc_putstr(e, "{\"@type\":"); + jsonenc_string(e, type_url); + jsonenc_putstr(e, ","); + + if (upb_msgdef_wellknowntype(any_m) == UPB_WELLKNOWN_UNSPECIFIED) { + /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */ + jsonenc_msgfields(e, any, any_m); + } else { + /* Well-known type: {"@type": "...","value": } */ + jsonenc_putstr(e, "\"value\":"); + jsonenc_msgfield(e, any, any_m); + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_putsep(jsonenc *e, const char *str, bool *first) { + if (*first) { + *first = false; + } else { + jsonenc_putstr(e, str); + } +} + +static void jsonenc_fieldpath(jsonenc *e, upb_strview path) { + const char *ptr = path.data; + const char *end = ptr + path.size; + + while (ptr < end) { + char ch = *ptr; + + if (ch >= 'A' && ch <= 'Z') { + jsonenc_err(e, "Field mask element may not have upper-case letter."); + } else if (ch == '_') { + if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') { + jsonenc_err(e, "Underscore must be followed by a lowercase letter."); + } + ch = *++ptr - 32; + } + + jsonenc_putbytes(e, &ch, 1); + ptr++; + } +} + +static void jsonenc_fieldmask(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m) { + const upb_fielddef *paths_f = upb_msgdef_itof(m, 1); + const upb_array *paths = upb_msg_get(msg, paths_f).array_val; + bool first = true; + size_t i, n = 0; + + if (paths) n = upb_array_size(paths); + + jsonenc_putstr(e, "\""); + + for (i = 0; i < n; i++) { + jsonenc_putsep(e, ",", &first); + jsonenc_fieldpath(e, upb_array_get(paths, i).str_val); + } + + jsonenc_putstr(e, "\""); +} + +static void jsonenc_struct(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m) { + const upb_fielddef *fields_f = upb_msgdef_itof(m, 1); + const upb_map *fields = upb_msg_get(msg, fields_f).map_val; + const upb_msgdef *entry_m = upb_fielddef_msgsubdef(fields_f); + const upb_fielddef *value_f = upb_msgdef_itof(entry_m, 2); + size_t iter = UPB_MAP_BEGIN; + bool first = true; + + jsonenc_putstr(e, "{"); + + if (fields) { + while (upb_mapiter_next(fields, &iter)) { + upb_msgval key = upb_mapiter_key(fields, iter); + upb_msgval val = upb_mapiter_value(fields, iter); + + jsonenc_putsep(e, ",", &first); + jsonenc_string(e, key.str_val); + jsonenc_putstr(e, ":"); + jsonenc_value(e, val.msg_val, upb_fielddef_msgsubdef(value_f)); + } + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_listvalue(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m) { + const upb_fielddef *values_f = upb_msgdef_itof(m, 1); + const upb_msgdef *values_m = upb_fielddef_msgsubdef(values_f); + const upb_array *values = upb_msg_get(msg, values_f).array_val; + size_t i; + bool first = true; + + jsonenc_putstr(e, "["); + + if (values) { + const size_t size = upb_array_size(values); + for (i = 0; i < size; i++) { + upb_msgval elem = upb_array_get(values, i); + + jsonenc_putsep(e, ",", &first); + jsonenc_value(e, elem.msg_val, values_m); + } + } + + jsonenc_putstr(e, "]"); +} + +static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { + /* TODO(haberman): do we want a reflection method to get oneof case? */ + size_t iter = UPB_MSG_BEGIN; + const upb_fielddef *f; + upb_msgval val; + + if (!upb_msg_next(msg, m, NULL, &f, &val, &iter)) { + jsonenc_err(e, "No value set in Value proto"); + } + + switch (upb_fielddef_number(f)) { + case 1: + jsonenc_putstr(e, "null"); + break; + case 2: + jsonenc_double(e, "%.17g", val.double_val); + break; + case 3: + jsonenc_string(e, val.str_val); + break; + case 4: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case 5: + jsonenc_struct(e, val.msg_val, upb_fielddef_msgsubdef(f)); + break; + case 6: + jsonenc_listvalue(e, val.msg_val, upb_fielddef_msgsubdef(f)); + break; + } +} + +static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m) { + switch (upb_msgdef_wellknowntype(m)) { + case UPB_WELLKNOWN_UNSPECIFIED: + jsonenc_msg(e, msg, m); + break; + case UPB_WELLKNOWN_ANY: + jsonenc_any(e, msg, m); + break; + case UPB_WELLKNOWN_FIELDMASK: + jsonenc_fieldmask(e, msg, m); + break; + case UPB_WELLKNOWN_DURATION: + jsonenc_duration(e, msg, m); + break; + case UPB_WELLKNOWN_TIMESTAMP: + jsonenc_timestamp(e, msg, m); + break; + case UPB_WELLKNOWN_DOUBLEVALUE: + case UPB_WELLKNOWN_FLOATVALUE: + case UPB_WELLKNOWN_INT64VALUE: + case UPB_WELLKNOWN_UINT64VALUE: + case UPB_WELLKNOWN_INT32VALUE: + case UPB_WELLKNOWN_UINT32VALUE: + case UPB_WELLKNOWN_STRINGVALUE: + case UPB_WELLKNOWN_BYTESVALUE: + case UPB_WELLKNOWN_BOOLVALUE: + jsonenc_wrapper(e, msg, m); + break; + case UPB_WELLKNOWN_VALUE: + jsonenc_value(e, msg, m); + break; + case UPB_WELLKNOWN_LISTVALUE: + jsonenc_listvalue(e, msg, m); + break; + case UPB_WELLKNOWN_STRUCT: + jsonenc_struct(e, msg, m); + break; + } +} + +static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f) { + switch (upb_fielddef_type(f)) { + case UPB_TYPE_BOOL: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case UPB_TYPE_FLOAT: + jsonenc_double(e, "%.9g", val.float_val); + break; + case UPB_TYPE_DOUBLE: + jsonenc_double(e, "%.17g", val.double_val); + break; + case UPB_TYPE_INT32: + jsonenc_printf(e, "%" PRId32, val.int32_val); + break; + case UPB_TYPE_UINT32: + jsonenc_printf(e, "%" PRIu32, val.uint32_val); + break; + case UPB_TYPE_INT64: + jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val); + break; + case UPB_TYPE_UINT64: + jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val); + break; + case UPB_TYPE_STRING: + jsonenc_string(e, val.str_val); + break; + case UPB_TYPE_BYTES: + jsonenc_bytes(e, val.str_val); + break; + case UPB_TYPE_ENUM: + jsonenc_enum(val.int32_val, f, e); + break; + case UPB_TYPE_MESSAGE: + jsonenc_msgfield(e, val.msg_val, upb_fielddef_msgsubdef(f)); + break; + } +} + +static void jsonenc_mapkey(jsonenc *e, upb_msgval val, const upb_fielddef *f) { + jsonenc_putstr(e, "\""); + + switch (upb_fielddef_type(f)) { + case UPB_TYPE_BOOL: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case UPB_TYPE_INT32: + jsonenc_printf(e, "%" PRId32, val.int32_val); + break; + case UPB_TYPE_UINT32: + jsonenc_printf(e, "%" PRIu32, val.uint32_val); + break; + case UPB_TYPE_INT64: + jsonenc_printf(e, "%" PRId64, val.int64_val); + break; + case UPB_TYPE_UINT64: + jsonenc_printf(e, "%" PRIu64, val.uint64_val); + break; + case UPB_TYPE_STRING: + jsonenc_stringbody(e, val.str_val); + break; + default: + UPB_UNREACHABLE(); + } + + jsonenc_putstr(e, "\":"); +} + +static void jsonenc_array(jsonenc *e, const upb_array *arr, + const upb_fielddef *f) { + size_t i; + size_t size = upb_array_size(arr); + bool first = true; + + jsonenc_putstr(e, "["); + + for (i = 0; i < size; i++) { + jsonenc_putsep(e, ",", &first); + jsonenc_scalar(e, upb_array_get(arr, i), f); + } + + jsonenc_putstr(e, "]"); +} + +static void jsonenc_map(jsonenc *e, const upb_map *map, const upb_fielddef *f) { + const upb_msgdef *entry = upb_fielddef_msgsubdef(f); + const upb_fielddef *key_f = upb_msgdef_itof(entry, 1); + const upb_fielddef *val_f = upb_msgdef_itof(entry, 2); + size_t iter = UPB_MAP_BEGIN; + bool first = true; + + jsonenc_putstr(e, "{"); + + while (upb_mapiter_next(map, &iter)) { + jsonenc_putsep(e, ",", &first); + jsonenc_mapkey(e, upb_mapiter_key(map, iter), key_f); + jsonenc_scalar(e, upb_mapiter_value(map, iter), val_f); + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f, + upb_msgval val, bool *first) { + const char *name; + + if (e->options & UPB_JSONENC_PROTONAMES) { + name = upb_fielddef_name(f); + } else { + name = upb_fielddef_jsonname(f); + } + + jsonenc_putsep(e, ",", first); + jsonenc_printf(e, "\"%s\":", name); + + if (upb_fielddef_ismap(f)) { + jsonenc_map(e, val.map_val, f); + } else if (upb_fielddef_isseq(f)) { + jsonenc_array(e, val.array_val, f); + } else { + jsonenc_scalar(e, val, f); + } +} + +static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg, + const upb_msgdef *m) { + upb_msgval val; + const upb_fielddef *f; + bool first = true; + + if (e->options & UPB_JSONENC_EMITDEFAULTS) { + /* Iterate over all fields. */ + int i = 0; + int n = upb_msgdef_fieldcount(m); + for (i = 0; i < n; i++) { + f = upb_msgdef_field(m, i); + jsonenc_fieldval(e, f, upb_msg_get(msg, f), &first); + } + } else { + /* Iterate over non-empty fields. */ + size_t iter = UPB_MSG_BEGIN; + while (upb_msg_next(msg, m, e->ext_pool, &f, &val, &iter)) { + jsonenc_fieldval(e, f, val, &first); + } + } +} + +static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { + jsonenc_putstr(e, "{"); + jsonenc_msgfields(e, msg, m); + jsonenc_putstr(e, "}"); +} + +static size_t jsonenc_nullz(jsonenc *e, size_t size) { + size_t ret = e->ptr - e->buf + e->overflow; + + if (size > 0) { + if (e->ptr == e->end) e->ptr--; + *e->ptr = '\0'; + } + + return ret; +} + +size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, int options, char *buf, + size_t size, upb_status *status) { + jsonenc e; + + e.buf = buf; + e.ptr = buf; + e.end = buf + size; + e.overflow = 0; + e.options = options; + e.ext_pool = ext_pool; + e.status = status; + e.arena = NULL; + + if (setjmp(e.err)) return -1; + + jsonenc_msgfield(&e, msg, m); + if (e.arena) upb_arena_free(e.arena); + return jsonenc_nullz(&e, size); +} +/* See port_def.inc. This should #undef all macros #defined there. */ + +#undef UPB_MAPTYPE_STRING +#undef UPB_SIZE +#undef UPB_PTR_AT +#undef UPB_READ_ONEOF +#undef UPB_WRITE_ONEOF +#undef UPB_INLINE +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF +#undef UPB_FORCEINLINE +#undef UPB_NOINLINE +#undef UPB_NORETURN +#undef UPB_MAX +#undef UPB_MIN +#undef UPB_UNUSED +#undef UPB_ASSUME +#undef UPB_ASSERT +#undef UPB_UNREACHABLE +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h new file mode 100644 index 000000000000..d22b4aa0e0e1 --- /dev/null +++ b/php/ext/google/protobuf/php-upb.h @@ -0,0 +1,3982 @@ +/* Amalgamated source file */ +#include /* +* This is where we define macros used across upb. +* +* All of these macros are undef'd in port_undef.inc to avoid leaking them to +* users. +* +* The correct usage is: +* +* #include "upb/foobar.h" +* #include "upb/baz.h" +* +* // MUST be last included header. +* #include "upb/port_def.inc" +* +* // Code for this file. +* // <...> +* +* // Can be omitted for .c files, required for .h. +* #include "upb/port_undef.inc" +* +* This file is private and must not be included by users! +*/ + +#if !(__STDC_VERSION__ >= 199901L || __cplusplus >= 201103L) +#error upb requires C99 or C++11 +#endif + +#if (defined(_MSC_VER) && _MSC_VER < 1900) +#error upb requires MSVC >= 2015. +#endif + +#include +#include + +#if UINTPTR_MAX == 0xffffffff +#define UPB_SIZE(size32, size64) size32 +#else +#define UPB_SIZE(size32, size64) size64 +#endif + +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) + +#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ + *UPB_PTR_AT(msg, case_offset, int) == case_val \ + ? *UPB_PTR_AT(msg, offset, fieldtype) \ + : default + +#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ + *UPB_PTR_AT(msg, case_offset, int) = case_val; \ + *UPB_PTR_AT(msg, offset, fieldtype) = value; + +#define UPB_MAPTYPE_STRING 0 + +/* UPB_INLINE: inline if possible, emit standalone code if required. */ +#ifdef __cplusplus +#define UPB_INLINE inline +#elif defined (__GNUC__) || defined(__clang__) +#define UPB_INLINE static __inline__ +#else +#define UPB_INLINE static +#endif + +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, 16) +#define UPB_ALIGN_OF(type) offsetof (struct { char c; type member; }, member) + +/* Hints to the compiler about likely/unlikely branches. */ +#if defined (__GNUC__) || defined(__clang__) +#define UPB_LIKELY(x) __builtin_expect((x),1) +#define UPB_UNLIKELY(x) __builtin_expect((x),0) +#else +#define UPB_LIKELY(x) (x) +#define UPB_UNLIKELY(x) (x) +#endif + +/* Macros for function attributes on compilers that support them. */ +#ifdef __GNUC__ +#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) +#define UPB_NOINLINE __attribute__((noinline)) +#define UPB_NORETURN __attribute__((__noreturn__)) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE +#define UPB_NORETURN __declspec(noreturn) +#else /* !defined(__GNUC__) */ +#define UPB_FORCEINLINE +#define UPB_NOINLINE +#define UPB_NORETURN +#endif + +#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define UPB_UNUSED(var) (void)var + +/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. + */ +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable() +#elif defined _MSC_VER +#define UPB_ASSUME(expr) if (!(expr)) __assume(0) +#else +#define UPB_ASSUME(expr) do {} while (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + +/* UPB_ASSERT(): in release mode, we use the expression without letting it be + * evaluated. This prevents "unused variable" warnings. */ +#ifdef NDEBUG +#define UPB_ASSERT(expr) do {} while (false && (expr)) +#else +#define UPB_ASSERT(expr) assert(expr) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0) +#else +#define UPB_UNREACHABLE() do { assert(0); } while(0) +#endif + +#if defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#ifdef __cplusplus +extern "C" { +#endif +void __asan_poison_memory_region(void const volatile *addr, size_t size); +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#ifdef __cplusplus +} /* extern "C" */ +#endif +#define UPB_POISON_MEMORY_REGION(addr, size) \ + __asan_poison_memory_region((addr), (size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + __asan_unpoison_memory_region((addr), (size)) +#else +#define UPB_ASAN 0 +#define UPB_POISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#define UPB_UNPOISON_MEMORY_REGION(addr, size) \ + ((void)(addr), (void)(size)) +#endif +/* +** upb_decode: parsing into a upb_msg using a upb_msglayout. +*/ + +#ifndef UPB_DECODE_H_ +#define UPB_DECODE_H_ + +/* +** Our memory representation for parsing tables and messages themselves. +** Functions in this file are used by generated code and possibly reflection. +** +** The definitions in this file are internal to upb. +**/ + +#ifndef UPB_MSG_H_ +#define UPB_MSG_H_ + +#include +#include + +/* +** upb_table +** +** This header is INTERNAL-ONLY! Its interfaces are not public or stable! +** This file defines very fast int->upb_value (inttable) and string->upb_value +** (strtable) hash tables. +** +** The table uses chained scatter with Brent's variation (inspired by the Lua +** implementation of hash tables). The hash function for strings is Austin +** Appleby's "MurmurHash." +** +** The inttable uses uintptr_t as its key, which guarantees it can be used to +** store pointers or integers of at least 32 bits (upb isn't really useful on +** systems where sizeof(void*) < 4). +** +** The table must be homogeneous (all values of the same type). In debug +** mode, we check this on insert and lookup. +*/ + +#ifndef UPB_TABLE_H_ +#define UPB_TABLE_H_ + +#include +#include +/* +** This file contains shared definitions that are widely used across upb. +*/ + +#ifndef UPB_H_ +#define UPB_H_ + +#include +#include +#include +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +/* upb_status *****************************************************************/ + +#define UPB_STATUS_MAX_MESSAGE 127 + +typedef struct { + bool ok; + char msg[UPB_STATUS_MAX_MESSAGE]; /* Error message; NULL-terminated. */ +} upb_status; + +const char *upb_status_errmsg(const upb_status *status); +bool upb_ok(const upb_status *status); + +/* These are no-op if |status| is NULL. */ +void upb_status_clear(upb_status *status); +void upb_status_seterrmsg(upb_status *status, const char *msg); +void upb_status_seterrf(upb_status *status, const char *fmt, ...); +void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args); +void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args); + +/** upb_strview ************************************************************/ + +typedef struct { + const char *data; + size_t size; +} upb_strview; + +UPB_INLINE upb_strview upb_strview_make(const char *data, size_t size) { + upb_strview ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_strview upb_strview_makez(const char *data) { + return upb_strview_make(data, strlen(data)); +} + +UPB_INLINE bool upb_strview_eql(upb_strview a, upb_strview b) { + return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; +} + +#define UPB_STRVIEW_INIT(ptr, len) {ptr, len} + +#define UPB_STRVIEW_FORMAT "%.*s" +#define UPB_STRVIEW_ARGS(view) (int)(view).size, (view).data + +/** upb_alloc *****************************************************************/ + +/* A upb_alloc is a possibly-stateful allocator object. + * + * It could either be an arena allocator (which doesn't require individual + * free() calls) or a regular malloc() (which does). The client must therefore + * free memory unless it knows that the allocator is an arena allocator. */ + +struct upb_alloc; +typedef struct upb_alloc upb_alloc; + +/* A malloc()/free() function. + * If "size" is 0 then the function acts like free(), otherwise it acts like + * realloc(). Only "oldsize" bytes from a previous allocation are preserved. */ +typedef void *upb_alloc_func(upb_alloc *alloc, void *ptr, size_t oldsize, + size_t size); + +struct upb_alloc { + upb_alloc_func *func; +}; + +UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) { + UPB_ASSERT(alloc); + return alloc->func(alloc, NULL, 0, size); +} + +UPB_INLINE void *upb_realloc(upb_alloc *alloc, void *ptr, size_t oldsize, + size_t size) { + UPB_ASSERT(alloc); + return alloc->func(alloc, ptr, oldsize, size); +} + +UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr) { + assert(alloc); + alloc->func(alloc, ptr, 0, 0); +} + +/* The global allocator used by upb. Uses the standard malloc()/free(). */ + +extern upb_alloc upb_alloc_global; + +/* Functions that hard-code the global malloc. + * + * We still get benefit because we can put custom logic into our global + * allocator, like injecting out-of-memory faults in debug/testing builds. */ + +UPB_INLINE void *upb_gmalloc(size_t size) { + return upb_malloc(&upb_alloc_global, size); +} + +UPB_INLINE void *upb_grealloc(void *ptr, size_t oldsize, size_t size) { + return upb_realloc(&upb_alloc_global, ptr, oldsize, size); +} + +UPB_INLINE void upb_gfree(void *ptr) { + upb_free(&upb_alloc_global, ptr); +} + +/* upb_arena ******************************************************************/ + +/* upb_arena is a specific allocator implementation that uses arena allocation. + * The user provides an allocator that will be used to allocate the underlying + * arena blocks. Arenas by nature do not require the individual allocations + * to be freed. However the Arena does allow users to register cleanup + * functions that will run when the arena is destroyed. + * + * A upb_arena is *not* thread-safe. + * + * You could write a thread-safe arena allocator that satisfies the + * upb_alloc interface, but it would not be as efficient for the + * single-threaded case. */ + +typedef void upb_cleanup_func(void *ud); + +struct upb_arena; +typedef struct upb_arena upb_arena; + +typedef struct { + /* We implement the allocator interface. + * This must be the first member of upb_arena! + * TODO(haberman): remove once handlers are gone. */ + upb_alloc alloc; + + char *ptr, *end; +} _upb_arena_head; + +/* Creates an arena from the given initial block (if any -- n may be 0). + * Additional blocks will be allocated from |alloc|. If |alloc| is NULL, this + * is a fixed-size arena and cannot grow. */ +upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc); +void upb_arena_free(upb_arena *a); +bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func); +void upb_arena_fuse(upb_arena *a, upb_arena *b); +void *_upb_arena_slowmalloc(upb_arena *a, size_t size); + +UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; } + +UPB_INLINE bool _upb_arenahas(upb_arena *a, size_t size) { + _upb_arena_head *h = (_upb_arena_head*)a; + return (size_t)(h->end - h->ptr) >= size; +} + +UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { + _upb_arena_head *h = (_upb_arena_head*)a; + void* ret; + size = UPB_ALIGN_MALLOC(size); + + if (UPB_UNLIKELY(!_upb_arenahas(a, size))) { + return _upb_arena_slowmalloc(a, size); + } + + ret = h->ptr; + h->ptr += size; + UPB_UNPOISON_MEMORY_REGION(ret, size); + +#if UPB_ASAN + { + size_t guard_size = 32; + if (_upb_arenahas(a, guard_size)) { + h->ptr += guard_size; + } else { + h->ptr = h->end; + } + } +#endif + + return ret; +} + +UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, + size_t size) { + void *ret = upb_arena_malloc(a, size); + + if (ret && oldsize > 0) { + memcpy(ret, ptr, oldsize); + } + + return ret; +} + +UPB_INLINE upb_arena *upb_arena_new(void) { + return upb_arena_init(NULL, 0, &upb_alloc_global); +} + +/* Constants ******************************************************************/ + +/* Generic function type. */ +typedef void upb_func(void); + +/* A list of types as they are encoded on-the-wire. */ +typedef enum { + UPB_WIRE_TYPE_VARINT = 0, + UPB_WIRE_TYPE_64BIT = 1, + UPB_WIRE_TYPE_DELIMITED = 2, + UPB_WIRE_TYPE_START_GROUP = 3, + UPB_WIRE_TYPE_END_GROUP = 4, + UPB_WIRE_TYPE_32BIT = 5 +} upb_wiretype_t; + +/* The types a field can have. Note that this list is not identical to the + * types defined in descriptor.proto, which gives INT32 and SINT32 separate + * types (we distinguish the two with the "integer encoding" enum below). */ +typedef enum { + UPB_TYPE_BOOL = 1, + UPB_TYPE_FLOAT = 2, + UPB_TYPE_INT32 = 3, + UPB_TYPE_UINT32 = 4, + UPB_TYPE_ENUM = 5, /* Enum values are int32. */ + UPB_TYPE_MESSAGE = 6, + UPB_TYPE_DOUBLE = 7, + UPB_TYPE_INT64 = 8, + UPB_TYPE_UINT64 = 9, + UPB_TYPE_STRING = 10, + UPB_TYPE_BYTES = 11 +} upb_fieldtype_t; + +/* The repeated-ness of each field; this matches descriptor.proto. */ +typedef enum { + UPB_LABEL_OPTIONAL = 1, + UPB_LABEL_REQUIRED = 2, + UPB_LABEL_REPEATED = 3 +} upb_label_t; + +/* Descriptor types, as defined in descriptor.proto. */ +typedef enum { + /* Old (long) names. TODO(haberman): remove */ + UPB_DESCRIPTOR_TYPE_DOUBLE = 1, + UPB_DESCRIPTOR_TYPE_FLOAT = 2, + UPB_DESCRIPTOR_TYPE_INT64 = 3, + UPB_DESCRIPTOR_TYPE_UINT64 = 4, + UPB_DESCRIPTOR_TYPE_INT32 = 5, + UPB_DESCRIPTOR_TYPE_FIXED64 = 6, + UPB_DESCRIPTOR_TYPE_FIXED32 = 7, + UPB_DESCRIPTOR_TYPE_BOOL = 8, + UPB_DESCRIPTOR_TYPE_STRING = 9, + UPB_DESCRIPTOR_TYPE_GROUP = 10, + UPB_DESCRIPTOR_TYPE_MESSAGE = 11, + UPB_DESCRIPTOR_TYPE_BYTES = 12, + UPB_DESCRIPTOR_TYPE_UINT32 = 13, + UPB_DESCRIPTOR_TYPE_ENUM = 14, + UPB_DESCRIPTOR_TYPE_SFIXED32 = 15, + UPB_DESCRIPTOR_TYPE_SFIXED64 = 16, + UPB_DESCRIPTOR_TYPE_SINT32 = 17, + UPB_DESCRIPTOR_TYPE_SINT64 = 18, + + UPB_DTYPE_DOUBLE = 1, + UPB_DTYPE_FLOAT = 2, + UPB_DTYPE_INT64 = 3, + UPB_DTYPE_UINT64 = 4, + UPB_DTYPE_INT32 = 5, + UPB_DTYPE_FIXED64 = 6, + UPB_DTYPE_FIXED32 = 7, + UPB_DTYPE_BOOL = 8, + UPB_DTYPE_STRING = 9, + UPB_DTYPE_GROUP = 10, + UPB_DTYPE_MESSAGE = 11, + UPB_DTYPE_BYTES = 12, + UPB_DTYPE_UINT32 = 13, + UPB_DTYPE_ENUM = 14, + UPB_DTYPE_SFIXED32 = 15, + UPB_DTYPE_SFIXED64 = 16, + UPB_DTYPE_SINT32 = 17, + UPB_DTYPE_SINT64 = 18 +} upb_descriptortype_t; + +#define UPB_MAP_BEGIN ((size_t)-1) + +UPB_INLINE bool _upb_isle(void) { + int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t _upb_be_swap32(uint32_t val) { + if (_upb_isle()) { + return val; + } else { + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); + } +} + +UPB_INLINE uint64_t _upb_be_swap64(uint64_t val) { + if (_upb_isle()) { + return val; + } else { + return ((uint64_t)_upb_be_swap32(val) << 32) | _upb_be_swap32(val >> 32); + } +} + +UPB_INLINE int _upb_lg2ceil(int x) { + if (x <= 1) return 0; +#ifdef __GNUC__ + return 32 - __builtin_clz(x - 1); +#else + int lg2 = 0; + while (1 << lg2 < x) lg2++; + return lg2; +#endif +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_H_ */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* upb_value ******************************************************************/ + +/* A tagged union (stored untagged inside the table) so that we can check that + * clients calling table accessors are correctly typed without having to have + * an explosion of accessors. */ +typedef enum { + UPB_CTYPE_INT32 = 1, + UPB_CTYPE_INT64 = 2, + UPB_CTYPE_UINT32 = 3, + UPB_CTYPE_UINT64 = 4, + UPB_CTYPE_BOOL = 5, + UPB_CTYPE_CSTR = 6, + UPB_CTYPE_PTR = 7, + UPB_CTYPE_CONSTPTR = 8, + UPB_CTYPE_FPTR = 9, + UPB_CTYPE_FLOAT = 10, + UPB_CTYPE_DOUBLE = 11 +} upb_ctype_t; + +typedef struct { + uint64_t val; +} upb_value; + +/* Like strdup(), which isn't always available since it's not ANSI C. */ +char *upb_strdup(const char *s, upb_alloc *a); +/* Variant that works with a length-delimited rather than NULL-delimited string, + * as supported by strtable. */ +char *upb_strdup2(const char *s, size_t len, upb_alloc *a); + +UPB_INLINE char *upb_gstrdup(const char *s) { + return upb_strdup(s, &upb_alloc_global); +} + +UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) { + v->val = val; +} + +UPB_INLINE upb_value _upb_value_val(uint64_t val) { + upb_value ret; + _upb_value_setval(&ret, val); + return ret; +} + +/* For each value ctype, define the following set of functions: + * + * // Get/set an int32 from a upb_value. + * int32_t upb_value_getint32(upb_value val); + * void upb_value_setint32(upb_value *val, int32_t cval); + * + * // Construct a new upb_value from an int32. + * upb_value upb_value_int32(int32_t val); */ +#define FUNCS(name, membername, type_t, converter, proto_type) \ + UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \ + val->val = (converter)cval; \ + } \ + UPB_INLINE upb_value upb_value_ ## name(type_t val) { \ + upb_value ret; \ + upb_value_set ## name(&ret, val); \ + return ret; \ + } \ + UPB_INLINE type_t upb_value_get ## name(upb_value val) { \ + return (type_t)(converter)val.val; \ + } + +FUNCS(int32, int32, int32_t, int32_t, UPB_CTYPE_INT32) +FUNCS(int64, int64, int64_t, int64_t, UPB_CTYPE_INT64) +FUNCS(uint32, uint32, uint32_t, uint32_t, UPB_CTYPE_UINT32) +FUNCS(uint64, uint64, uint64_t, uint64_t, UPB_CTYPE_UINT64) +FUNCS(bool, _bool, bool, bool, UPB_CTYPE_BOOL) +FUNCS(cstr, cstr, char*, uintptr_t, UPB_CTYPE_CSTR) +FUNCS(ptr, ptr, void*, uintptr_t, UPB_CTYPE_PTR) +FUNCS(constptr, constptr, const void*, uintptr_t, UPB_CTYPE_CONSTPTR) +FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR) + +#undef FUNCS + +UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) { + memcpy(&val->val, &cval, sizeof(cval)); +} + +UPB_INLINE void upb_value_setdouble(upb_value *val, double cval) { + memcpy(&val->val, &cval, sizeof(cval)); +} + +UPB_INLINE upb_value upb_value_float(float cval) { + upb_value ret; + upb_value_setfloat(&ret, cval); + return ret; +} + +UPB_INLINE upb_value upb_value_double(double cval) { + upb_value ret; + upb_value_setdouble(&ret, cval); + return ret; +} + +#undef SET_TYPE + + +/* upb_tabkey *****************************************************************/ + +/* Either: + * 1. an actual integer key, or + * 2. a pointer to a string prefixed by its uint32_t length, owned by us. + * + * ...depending on whether this is a string table or an int table. We would + * make this a union of those two types, but C89 doesn't support statically + * initializing a non-first union member. */ +typedef uintptr_t upb_tabkey; + +UPB_INLINE char *upb_tabstr(upb_tabkey key, uint32_t *len) { + char* mem = (char*)key; + if (len) memcpy(len, mem, sizeof(*len)); + return mem + sizeof(*len); +} + + +/* upb_tabval *****************************************************************/ + +typedef struct { + uint64_t val; +} upb_tabval; + +#define UPB_TABVALUE_EMPTY_INIT {-1} + +/* upb_table ******************************************************************/ + +typedef struct _upb_tabent { + upb_tabkey key; + upb_tabval val; + + /* Internal chaining. This is const so we can create static initializers for + * tables. We cast away const sometimes, but *only* when the containing + * upb_table is known to be non-const. This requires a bit of care, but + * the subtlety is confined to table.c. */ + const struct _upb_tabent *next; +} upb_tabent; + +typedef struct { + size_t count; /* Number of entries in the hash part. */ + uint32_t mask; /* Mask to turn hash value -> bucket. */ + uint32_t max_count; /* Max count before we hit our load limit. */ + uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */ + + /* Hash table entries. + * Making this const isn't entirely accurate; what we really want is for it to + * have the same const-ness as the table it's inside. But there's no way to + * declare that in C. So we have to make it const so that we can statically + * initialize const hash tables. Then we cast away const when we have to. + */ + const upb_tabent *entries; +} upb_table; + +typedef struct { + upb_table t; +} upb_strtable; + +typedef struct { + upb_table t; /* For entries that don't fit in the array part. */ + const upb_tabval *array; /* Array part of the table. See const note above. */ + size_t array_size; /* Array part size. */ + size_t array_count; /* Array part number of elements. */ +} upb_inttable; + +#define UPB_ARRAY_EMPTYENT -1 + +UPB_INLINE size_t upb_table_size(const upb_table *t) { + if (t->size_lg2 == 0) + return 0; + else + return 1 << t->size_lg2; +} + +/* Internal-only functions, in .h file only out of necessity. */ +UPB_INLINE bool upb_tabent_isempty(const upb_tabent *e) { + return e->key == 0; +} + +/* Used by some of the unit tests for generic hashing functionality. */ +uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed); + +UPB_INLINE uintptr_t upb_intkey(uintptr_t key) { + return key; +} + +UPB_INLINE uint32_t upb_inthash(uintptr_t key) { + return (uint32_t)key; +} + +static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) { + return t->entries + (hash & t->mask); +} + +UPB_INLINE bool upb_arrhas(upb_tabval key) { + return key.val != (uint64_t)-1; +} + +/* Initialize and uninitialize a table, respectively. If memory allocation + * failed, false is returned that the table is uninitialized. */ +bool upb_inttable_init2(upb_inttable *table, upb_ctype_t ctype, upb_alloc *a); +bool upb_strtable_init2(upb_strtable *table, upb_ctype_t ctype, + size_t expected_size, upb_alloc *a); +void upb_inttable_uninit2(upb_inttable *table, upb_alloc *a); +void upb_strtable_uninit2(upb_strtable *table, upb_alloc *a); + +UPB_INLINE bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype) { + return upb_inttable_init2(table, ctype, &upb_alloc_global); +} + +UPB_INLINE bool upb_strtable_init(upb_strtable *table, upb_ctype_t ctype) { + return upb_strtable_init2(table, ctype, 4, &upb_alloc_global); +} + +UPB_INLINE void upb_inttable_uninit(upb_inttable *table) { + upb_inttable_uninit2(table, &upb_alloc_global); +} + +UPB_INLINE void upb_strtable_uninit(upb_strtable *table) { + upb_strtable_uninit2(table, &upb_alloc_global); +} + +/* Returns the number of values in the table. */ +size_t upb_inttable_count(const upb_inttable *t); +UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) { + return t->t.count; +} + +void upb_inttable_packedsize(const upb_inttable *t, size_t *size); +void upb_strtable_packedsize(const upb_strtable *t, size_t *size); +upb_inttable *upb_inttable_pack(const upb_inttable *t, void *p, size_t *ofs, + size_t size); +upb_strtable *upb_strtable_pack(const upb_strtable *t, void *p, size_t *ofs, + size_t size); +void upb_strtable_clear(upb_strtable *t); + +/* Inserts the given key into the hashtable with the given value. The key must + * not already exist in the hash table. For string tables, the key must be + * NULL-terminated, and the table will make an internal copy of the key. + * Inttables must not insert a value of UINTPTR_MAX. + * + * If a table resize was required but memory allocation failed, false is + * returned and the table is unchanged. */ +bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, + upb_alloc *a); +bool upb_strtable_insert3(upb_strtable *t, const char *key, size_t len, + upb_value val, upb_alloc *a); + +UPB_INLINE bool upb_inttable_insert(upb_inttable *t, uintptr_t key, + upb_value val) { + return upb_inttable_insert2(t, key, val, &upb_alloc_global); +} + +UPB_INLINE bool upb_strtable_insert2(upb_strtable *t, const char *key, + size_t len, upb_value val) { + return upb_strtable_insert3(t, key, len, val, &upb_alloc_global); +} + +/* For NULL-terminated strings. */ +UPB_INLINE bool upb_strtable_insert(upb_strtable *t, const char *key, + upb_value val) { + return upb_strtable_insert2(t, key, strlen(key), val); +} + +/* Looks up key in this table, returning "true" if the key was found. + * If v is non-NULL, copies the value for this key into *v. */ +bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v); +bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, + upb_value *v); + +/* For NULL-terminated strings. */ +UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key, + upb_value *v) { + return upb_strtable_lookup2(t, key, strlen(key), v); +} + +/* Removes an item from the table. Returns true if the remove was successful, + * and stores the removed item in *val if non-NULL. */ +bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val); +bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, + upb_value *val, upb_alloc *alloc); + +UPB_INLINE bool upb_strtable_remove2(upb_strtable *t, const char *key, + size_t len, upb_value *val) { + return upb_strtable_remove3(t, key, len, val, &upb_alloc_global); +} + +/* For NULL-terminated strings. */ +UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key, + upb_value *v) { + return upb_strtable_remove2(t, key, strlen(key), v); +} + +/* Updates an existing entry in an inttable. If the entry does not exist, + * returns false and does nothing. Unlike insert/remove, this does not + * invalidate iterators. */ +bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val); + +/* Convenience routines for inttables with pointer keys. */ +bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, + upb_alloc *a); +bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val); +bool upb_inttable_lookupptr( + const upb_inttable *t, const void *key, upb_value *val); + +UPB_INLINE bool upb_inttable_insertptr(upb_inttable *t, const void *key, + upb_value val) { + return upb_inttable_insertptr2(t, key, val, &upb_alloc_global); +} + +/* Optimizes the table for the current set of entries, for both memory use and + * lookup time. Client should call this after all entries have been inserted; + * inserting more entries is legal, but will likely require a table resize. */ +void upb_inttable_compact2(upb_inttable *t, upb_alloc *a); + +UPB_INLINE void upb_inttable_compact(upb_inttable *t) { + upb_inttable_compact2(t, &upb_alloc_global); +} + +/* A special-case inlinable version of the lookup routine for 32-bit + * integers. */ +UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key, + upb_value *v) { + *v = upb_value_int32(0); /* Silence compiler warnings. */ + if (key < t->array_size) { + upb_tabval arrval = t->array[key]; + if (upb_arrhas(arrval)) { + _upb_value_setval(v, arrval.val); + return true; + } else { + return false; + } + } else { + const upb_tabent *e; + if (t->t.entries == NULL) return false; + for (e = upb_getentry(&t->t, upb_inthash(key)); true; e = e->next) { + if ((uint32_t)e->key == key) { + _upb_value_setval(v, e->val.val); + return true; + } + if (e->next == NULL) return false; + } + } +} + +/* Exposed for testing only. */ +bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a); + +/* Iterators ******************************************************************/ + +/* Iterators for int and string tables. We are subject to some kind of unusual + * design constraints: + * + * For high-level languages: + * - we must be able to guarantee that we don't crash or corrupt memory even if + * the program accesses an invalidated iterator. + * + * For C++11 range-based for: + * - iterators must be copyable + * - iterators must be comparable + * - it must be possible to construct an "end" value. + * + * Iteration order is undefined. + * + * Modifying the table invalidates iterators. upb_{str,int}table_done() is + * guaranteed to work even on an invalidated iterator, as long as the table it + * is iterating over has not been freed. Calling next() or accessing data from + * an invalidated iterator yields unspecified elements from the table, but it is + * guaranteed not to crash and to return real table elements (except when done() + * is true). */ + + +/* upb_strtable_iter **********************************************************/ + +/* upb_strtable_iter i; + * upb_strtable_begin(&i, t); + * for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { + * const char *key = upb_strtable_iter_key(&i); + * const upb_value val = upb_strtable_iter_value(&i); + * // ... + * } + */ + +typedef struct { + const upb_strtable *t; + size_t index; +} upb_strtable_iter; + +void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t); +void upb_strtable_next(upb_strtable_iter *i); +bool upb_strtable_done(const upb_strtable_iter *i); +upb_strview upb_strtable_iter_key(const upb_strtable_iter *i); +upb_value upb_strtable_iter_value(const upb_strtable_iter *i); +void upb_strtable_iter_setdone(upb_strtable_iter *i); +bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, + const upb_strtable_iter *i2); + + +/* upb_inttable_iter **********************************************************/ + +/* upb_inttable_iter i; + * upb_inttable_begin(&i, t); + * for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { + * uintptr_t key = upb_inttable_iter_key(&i); + * upb_value val = upb_inttable_iter_value(&i); + * // ... + * } + */ + +typedef struct { + const upb_inttable *t; + size_t index; + bool array_part; +} upb_inttable_iter; + +UPB_INLINE const upb_tabent *str_tabent(const upb_strtable_iter *i) { + return &i->t->t.entries[i->index]; +} + +void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t); +void upb_inttable_next(upb_inttable_iter *i); +bool upb_inttable_done(const upb_inttable_iter *i); +uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i); +upb_value upb_inttable_iter_value(const upb_inttable_iter *i); +void upb_inttable_iter_setdone(upb_inttable_iter *i); +bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, + const upb_inttable_iter *i2); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_TABLE_H_ */ + + +#ifdef __cplusplus +extern "C" { +#endif + +#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) + +typedef void upb_msg; + +/** upb_msglayout *************************************************************/ + +/* upb_msglayout represents the memory layout of a given upb_msgdef. The + * members are public so generated code can initialize them, but users MUST NOT + * read or write any of its members. */ + +/* These aren't real labels according to descriptor.proto, but in the table we + * use these for map/packed fields instead of UPB_LABEL_REPEATED. */ +enum { + _UPB_LABEL_MAP = 4, + _UPB_LABEL_PACKED = 7 /* Low 3 bits are common with UPB_LABEL_REPEATED. */ +}; + +typedef struct { + uint32_t number; + uint16_t offset; + int16_t presence; /* If >0, hasbit_index. If <0, ~oneof_index. */ + uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */ + uint8_t descriptortype; + uint8_t label; /* google.protobuf.Label or _UPB_LABEL_* above. */ +} upb_msglayout_field; + +typedef struct upb_msglayout { + const struct upb_msglayout *const* submsgs; + const upb_msglayout_field *fields; + /* Must be aligned to sizeof(void*). Doesn't include internal members like + * unknown fields, extension dict, pointer to msglayout, etc. */ + uint16_t size; + uint16_t field_count; + bool extendable; +} upb_msglayout; + +/** upb_msg *******************************************************************/ + +/* Internal members of a upb_msg. We can change this without breaking binary + * compatibility. We put these before the user's data. The user's upb_msg* + * points after the upb_msg_internal. */ + +typedef struct { + uint32_t len; + uint32_t size; + /* Data follows. */ +} upb_msg_unknowndata; + +/* Used when a message is not extendable. */ +typedef struct { + upb_msg_unknowndata *unknown; +} upb_msg_internal; + +/* Maps upb_fieldtype_t -> memory size. */ +extern char _upb_fieldtype_to_size[12]; + +UPB_INLINE size_t upb_msg_sizeof(const upb_msglayout *l) { + return l->size + sizeof(upb_msg_internal); +} + +UPB_INLINE upb_msg *_upb_msg_new_inl(const upb_msglayout *l, upb_arena *a) { + size_t size = upb_msg_sizeof(l); + void *mem = upb_arena_malloc(a, size); + upb_msg *msg; + if (UPB_UNLIKELY(!mem)) return NULL; + msg = UPB_PTR_AT(mem, sizeof(upb_msg_internal), upb_msg); + memset(mem, 0, size); + return msg; +} + +/* Creates a new messages with the given layout on the given arena. */ +upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a); + +UPB_INLINE upb_msg_internal *upb_msg_getinternal(upb_msg *msg) { + ptrdiff_t size = sizeof(upb_msg_internal); + return (upb_msg_internal*)((char*)msg - size); +} + +/* Clears the given message. */ +void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l); + +/* Discards the unknown fields for this message only. */ +void _upb_msg_discardunknown_shallow(upb_msg *msg); + +/* Adds unknown data (serialized protobuf data) to the given message. The data + * is copied into the message instance. */ +bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena); + +/* Returns a reference to the message's unknown data. */ +const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); + +/** Hasbit access *************************************************************/ + +UPB_INLINE bool _upb_hasbit(const upb_msg *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; +} + +UPB_INLINE void _upb_sethas(const upb_msg *msg, size_t idx) { + (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); +} + +UPB_INLINE void _upb_clearhas(const upb_msg *msg, size_t idx) { + (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); +} + +UPB_INLINE size_t _upb_msg_hasidx(const upb_msglayout_field *f) { + UPB_ASSERT(f->presence > 0); + return f->presence; +} + +UPB_INLINE bool _upb_hasbit_field(const upb_msg *msg, + const upb_msglayout_field *f) { + return _upb_hasbit(msg, _upb_msg_hasidx(f)); +} + +UPB_INLINE void _upb_sethas_field(const upb_msg *msg, + const upb_msglayout_field *f) { + _upb_sethas(msg, _upb_msg_hasidx(f)); +} + +UPB_INLINE void _upb_clearhas_field(const upb_msg *msg, + const upb_msglayout_field *f) { + _upb_clearhas(msg, _upb_msg_hasidx(f)); +} + +/** Oneof case access *********************************************************/ + +UPB_INLINE uint32_t *_upb_oneofcase(upb_msg *msg, size_t case_ofs) { + return PTR_AT(msg, case_ofs, uint32_t); +} + +UPB_INLINE uint32_t _upb_getoneofcase(const void *msg, size_t case_ofs) { + return *PTR_AT(msg, case_ofs, uint32_t); +} + +UPB_INLINE size_t _upb_oneofcase_ofs(const upb_msglayout_field *f) { + UPB_ASSERT(f->presence < 0); + return ~(ptrdiff_t)f->presence; +} + +UPB_INLINE uint32_t *_upb_oneofcase_field(upb_msg *msg, + const upb_msglayout_field *f) { + return _upb_oneofcase(msg, _upb_oneofcase_ofs(f)); +} + +UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_msg *msg, + const upb_msglayout_field *f) { + return _upb_getoneofcase(msg, _upb_oneofcase_ofs(f)); +} + +UPB_INLINE bool _upb_has_submsg_nohasbit(const upb_msg *msg, size_t ofs) { + return *PTR_AT(msg, ofs, const upb_msg*) != NULL; +} + +UPB_INLINE bool _upb_isrepeated(const upb_msglayout_field *field) { + return (field->label & 3) == UPB_LABEL_REPEATED; +} + +UPB_INLINE bool _upb_repeated_or_map(const upb_msglayout_field *field) { + return field->label >= UPB_LABEL_REPEATED; +} + +/** upb_array *****************************************************************/ + +/* Our internal representation for repeated fields. */ +typedef struct { + uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ + size_t len; /* Measured in elements. */ + size_t size; /* Measured in elements. */ + uint64_t junk; +} upb_array; + +UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) { + UPB_ASSERT((arr->data & 7) <= 4); + return (void*)(arr->data & ~(uintptr_t)7); +} + +UPB_INLINE void *_upb_array_ptr(upb_array *arr) { + return (void*)_upb_array_constptr(arr); +} + +UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) { + UPB_ASSERT(elem_size_lg2 <= 4); + UPB_ASSERT(((uintptr_t)ptr & 7) == 0); + return (uintptr_t)ptr | (unsigned)elem_size_lg2; +} + +UPB_INLINE upb_array *_upb_array_new(upb_arena *a, size_t init_size, + int elem_size_lg2) { + const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_array), 8); + const size_t bytes = sizeof(upb_array) + (init_size << elem_size_lg2); + upb_array *arr = (upb_array*)upb_arena_malloc(a, bytes); + if (!arr) return NULL; + arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2); + arr->len = 0; + arr->size = init_size; + return arr; +} + +/* Resizes the capacity of the array to be at least min_size. */ +bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena); + +/* Fallback functions for when the accessors require a resize. */ +void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, + int elem_size_lg2, upb_arena *arena); +bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, + int elem_size_lg2, upb_arena *arena); + +UPB_INLINE bool _upb_array_reserve(upb_array *arr, size_t size, + upb_arena *arena) { + if (arr->size < size) return _upb_array_realloc(arr, size, arena); + return true; +} + +UPB_INLINE bool _upb_array_resize(upb_array *arr, size_t size, + upb_arena *arena) { + if (!_upb_array_reserve(arr, size, arena)) return false; + arr->len = size; + return true; +} + +UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, + size_t *size) { + const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*); + if (arr) { + if (size) *size = arr->len; + return _upb_array_constptr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, + size_t *size) { + upb_array *arr = *PTR_AT(msg, ofs, upb_array*); + if (arr) { + if (size) *size = arr->len; + return _upb_array_ptr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE void *_upb_array_resize_accessor2(void *msg, size_t ofs, size_t size, + int elem_size_lg2, + upb_arena *arena) { + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array *); + upb_array *arr = *arr_ptr; + if (!arr || arr->size < size) { + return _upb_array_resize_fallback(arr_ptr, size, elem_size_lg2, arena); + } + arr->len = size; + return _upb_array_ptr(arr); +} + +UPB_INLINE bool _upb_array_append_accessor2(void *msg, size_t ofs, + int elem_size_lg2, + const void *value, + upb_arena *arena) { + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array *); + size_t elem_size = 1 << elem_size_lg2; + upb_array *arr = *arr_ptr; + void *ptr; + if (!arr || arr->len == arr->size) { + return _upb_array_append_fallback(arr_ptr, value, elem_size_lg2, arena); + } + ptr = _upb_array_ptr(arr); + memcpy(PTR_AT(ptr, arr->len * elem_size, char), value, elem_size); + arr->len++; + return true; +} + +/* Used by old generated code, remove once all code has been regenerated. */ +UPB_INLINE int _upb_sizelg2(upb_fieldtype_t type) { + switch (type) { + case UPB_TYPE_BOOL: + return 0; + case UPB_TYPE_FLOAT: + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_ENUM: + return 2; + case UPB_TYPE_MESSAGE: + return UPB_SIZE(2, 3); + case UPB_TYPE_DOUBLE: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + return 3; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + return UPB_SIZE(3, 4); + } + UPB_UNREACHABLE(); +} +UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, + upb_fieldtype_t type, + upb_arena *arena) { + return _upb_array_resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena); +} +UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs, + size_t elem_size, upb_fieldtype_t type, + const void *value, + upb_arena *arena) { + (void)elem_size; + return _upb_array_append_accessor2(msg, ofs, _upb_sizelg2(type), value, + arena); +} + +/** upb_map *******************************************************************/ + +/* Right now we use strmaps for everything. We'll likely want to use + * integer-specific maps for integer-keyed maps.*/ +typedef struct { + /* Size of key and val, based on the map type. Strings are represented as '0' + * because they must be handled specially. */ + char key_size; + char val_size; + + upb_strtable table; +} upb_map; + +/* Map entries aren't actually stored, they are only used during parsing. For + * parsing, it helps a lot if all map entry messages have the same layout. + * The compiler and def.c must ensure that all map entries have this layout. */ +typedef struct { + upb_msg_internal internal; + union { + upb_strview str; /* For str/bytes. */ + upb_value val; /* For all other types. */ + } k; + union { + upb_strview str; /* For str/bytes. */ + upb_value val; /* For all other types. */ + } v; +} upb_map_entry; + +/* Creates a new map on the given arena with this key/value type. */ +upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size); + +/* Converting between internal table representation and user values. + * + * _upb_map_tokey() and _upb_map_fromkey() are inverses. + * _upb_map_tovalue() and _upb_map_fromvalue() are inverses. + * + * These functions account for the fact that strings are treated differently + * from other types when stored in a map. + */ + +UPB_INLINE upb_strview _upb_map_tokey(const void *key, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + return *(upb_strview*)key; + } else { + return upb_strview_make((const char*)key, size); + } +} + +UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + memcpy(out, &key, sizeof(key)); + } else { + memcpy(out, key.data, size); + } +} + +UPB_INLINE bool _upb_map_tovalue(const void *val, size_t size, upb_value *msgval, + upb_arena *a) { + if (size == UPB_MAPTYPE_STRING) { + upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp)); + if (!strp) return false; + *strp = *(upb_strview*)val; + *msgval = upb_value_ptr(strp); + } else { + memcpy(msgval, val, size); + } + return true; +} + +UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + const upb_strview *strp = (const upb_strview*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_strview)); + } else { + memcpy(out, &val, size); + } +} + +/* Map operations, shared by reflection and generated code. */ + +UPB_INLINE size_t _upb_map_size(const upb_map *map) { + return map->table.t.count; +} + +UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key, + size_t key_size, void *val, size_t val_size) { + upb_value tabval; + upb_strview k = _upb_map_tokey(key, key_size); + bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval); + if (ret && val) { + _upb_map_fromvalue(tabval, val, val_size); + } + return ret; +} + +UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { + upb_strtable_iter it; + it.t = &map->table; + it.index = *iter; + upb_strtable_next(&it); + *iter = it.index; + if (upb_strtable_done(&it)) return NULL; + return (void*)str_tabent(&it); +} + +UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size, + void *val, size_t val_size, upb_arena *arena) { + upb_strview strkey = _upb_map_tokey(key, key_size); + upb_value tabval = {0}; + if (!_upb_map_tovalue(val, val_size, &tabval, arena)) return false; + upb_alloc *a = upb_arena_alloc(arena); + + /* TODO(haberman): add overwrite operation to minimize number of lookups. */ + upb_strtable_remove3(&map->table, strkey.data, strkey.size, NULL, a); + return upb_strtable_insert3(&map->table, strkey.data, strkey.size, tabval, a); +} + +UPB_INLINE bool _upb_map_delete(upb_map *map, const void *key, size_t key_size) { + upb_strview k = _upb_map_tokey(key, key_size); + return upb_strtable_remove3(&map->table, k.data, k.size, NULL, NULL); +} + +UPB_INLINE void _upb_map_clear(upb_map *map) { + upb_strtable_clear(&map->table); +} + +/* Message map operations, these get the map from the message first. */ + +UPB_INLINE size_t _upb_msg_map_size(const upb_msg *msg, size_t ofs) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + return map ? _upb_map_size(map) : 0; +} + +UPB_INLINE bool _upb_msg_map_get(const upb_msg *msg, size_t ofs, + const void *key, size_t key_size, void *val, + size_t val_size) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return false; + return _upb_map_get(map, key, key_size, val, val_size); +} + +UPB_INLINE void *_upb_msg_map_next(const upb_msg *msg, size_t ofs, + size_t *iter) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return NULL; + return _upb_map_next(map, iter); +} + +UPB_INLINE bool _upb_msg_map_set(upb_msg *msg, size_t ofs, const void *key, + size_t key_size, void *val, size_t val_size, + upb_arena *arena) { + upb_map **map = PTR_AT(msg, ofs, upb_map *); + if (!*map) { + *map = _upb_map_new(arena, key_size, val_size); + } + return _upb_map_set(*map, key, key_size, val, val_size, arena); +} + +UPB_INLINE bool _upb_msg_map_delete(upb_msg *msg, size_t ofs, const void *key, + size_t key_size) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return false; + return _upb_map_delete(map, key, key_size); +} + +UPB_INLINE void _upb_msg_map_clear(upb_msg *msg, size_t ofs) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return; + _upb_map_clear(map); +} + +/* Accessing map key/value from a pointer, used by generated code only. */ + +UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) { + const upb_tabent *ent = (const upb_tabent*)msg; + uint32_t u32len; + upb_strview k; + k.data = upb_tabstr(ent->key, &u32len); + k.size = u32len; + _upb_map_fromkey(k, key, size); +} + +UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) { + const upb_tabent *ent = (const upb_tabent*)msg; + upb_value v; + _upb_value_setval(&v, ent->val.val); + _upb_map_fromvalue(v, val, size); +} + +UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, size_t size) { + upb_tabent *ent = (upb_tabent*)msg; + /* This is like _upb_map_tovalue() except the entry already exists so we can + * reuse the allocated upb_strview for string fields. */ + if (size == UPB_MAPTYPE_STRING) { + upb_strview *strp = (upb_strview*)(uintptr_t)ent->val.val; + memcpy(strp, val, sizeof(*strp)); + } else { + memcpy(&ent->val.val, val, size); + } +} + +#undef PTR_AT + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MSG_H_ */ + +#ifdef __cplusplus +extern "C" { +#endif + +bool upb_decode(const char *buf, size_t size, upb_msg *msg, + const upb_msglayout *l, upb_arena *arena); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_DECODE_H_ */ + +#ifndef UPB_INT_H_ +#define UPB_INT_H_ + + +struct mem_block; +typedef struct mem_block mem_block; + +struct upb_arena { + _upb_arena_head head; + uint32_t *cleanups; + + /* Allocator to allocate arena blocks. We are responsible for freeing these + * when we are destroyed. */ + upb_alloc *block_alloc; + uint32_t last_size; + + /* When multiple arenas are fused together, each arena points to a parent + * arena (root points to itself). The root tracks how many live arenas + * reference it. */ + uint32_t refcount; /* Only used when a->parent == a */ + struct upb_arena *parent; + + /* Linked list of blocks to free/cleanup. */ + mem_block *freelist, *freelist_tail; +}; + +#endif /* UPB_INT_H_ */ +/* +** upb_encode: parsing into a upb_msg using a upb_msglayout. +*/ + +#ifndef UPB_ENCODE_H_ +#define UPB_ENCODE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena, + size_t *size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_ENCODE_H_ */ +/* 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_ + + + +#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 bool google_protobuf_FileDescriptorSet_has_file(const google_protobuf_FileDescriptorSet *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } +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_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &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_hasbit(msg, 1); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } +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 bool google_protobuf_FileDescriptorProto_has_message_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } +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 bool google_protobuf_FileDescriptorProto_has_enum_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); } +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 bool google_protobuf_FileDescriptorProto_has_service(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); } +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 bool google_protobuf_FileDescriptorProto_has_extension(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); } +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_hasbit(msg, 4); } +UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_FileOptions*); } +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_hasbit(msg, 5); } +UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const google_protobuf_SourceCodeInfo*); } +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_hasbit(msg, 3); } +UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); } + +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = 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_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(3, 4), arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor2(msg, UPB_SIZE(36, 72), UPB_SIZE(3, 4), &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_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(44, 88), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(48, 96), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(48, 96), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(52, 104), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(52, 104), UPB_SIZE(2, 3), &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_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_FileOptions*) = 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_PTR_AT(msg, UPB_SIZE(32, 64), google_protobuf_SourceCodeInfo*) = 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_accessor2(msg, UPB_SIZE(56, 112), len, 2, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor2(msg, UPB_SIZE(56, 112), 2, &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_accessor2(msg, UPB_SIZE(60, 120), len, 2, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) { + return _upb_array_append_accessor2(msg, UPB_SIZE(60, 120), 2, &val, + arena); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = 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_hasbit(msg, 1); } +UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_field(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } +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 bool google_protobuf_DescriptorProto_has_nested_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } +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 bool google_protobuf_DescriptorProto_has_enum_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); } +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 bool google_protobuf_DescriptorProto_has_extension_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); } +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 bool google_protobuf_DescriptorProto_has_extension(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); } +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_hasbit(msg, 2); } +UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_MessageOptions*); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_oneof_decl(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); } +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 bool google_protobuf_DescriptorProto_has_reserved_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } +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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(24, 48), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(28, 56), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(32, 64), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(32, 64), UPB_SIZE(2, 3), &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_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_MessageOptions*) = 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_accessor2(msg, UPB_SIZE(36, 72), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(36, 72), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(40, 80), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(40, 80), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(44, 88), len, UPB_SIZE(3, 4), arena); +} +UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor2(msg, UPB_SIZE(44, 88), UPB_SIZE(3, 4), &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_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_hasbit(msg, 3); } +UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const google_protobuf_ExtensionRangeOptions*); } + +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange *msg, google_protobuf_ExtensionRangeOptions* value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(12, 16), google_protobuf_ExtensionRangeOptions*) = 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_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } + +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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 bool google_protobuf_ExtensionRangeOptions_has_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } +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_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &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_hasbit(msg, 6); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 3); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 8); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 9); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 11); } +UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(64, 104), const google_protobuf_FieldOptions*); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 10); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); } + +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 6); + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 7); + *UPB_PTR_AT(msg, UPB_SIZE(32, 40), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 8); + *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 9); + *UPB_PTR_AT(msg, UPB_SIZE(48, 72), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) { + _upb_sethas(msg, 11); + *UPB_PTR_AT(msg, UPB_SIZE(64, 104), google_protobuf_FieldOptions*) = 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_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 10); + *UPB_PTR_AT(msg, UPB_SIZE(56, 88), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) { + _upb_sethas(msg, 5); + *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool) = 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_hasbit(msg, 1); } +UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_OneofOptions*); } + +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto *msg, google_protobuf_OneofOptions* value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_OneofOptions*) = 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_hasbit(msg, 1); } +UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_value(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } +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_hasbit(msg, 2); } +UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_EnumOptions*); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_reserved_range(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } +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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &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_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_EnumOptions*) = 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_accessor2(msg, UPB_SIZE(20, 40), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(20, 40), UPB_SIZE(2, 3), &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_accessor2(msg, UPB_SIZE(24, 48), len, UPB_SIZE(3, 4), arena); +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor2(msg, UPB_SIZE(24, 48), UPB_SIZE(3, 4), &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_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } + +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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_hasbit(msg, 2); } +UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_hasbit(msg, 3); } +UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const google_protobuf_EnumValueOptions*); } + +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(16, 24), google_protobuf_EnumValueOptions*) = 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_hasbit(msg, 1); } +UPB_INLINE upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_method(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } +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_hasbit(msg, 2); } +UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_ServiceOptions*); } + +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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_accessor2(msg, UPB_SIZE(16, 32), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(16, 32), UPB_SIZE(2, 3), &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_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_ServiceOptions*) = 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_hasbit(msg, 3); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 4); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 5); } +UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 6); } +UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_MethodOptions*); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } + +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 4); + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) { + _upb_sethas(msg, 5); + *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) { + _upb_sethas(msg, 6); + *UPB_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_MethodOptions*) = 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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = 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_hasbit(msg, 11); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); } +UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); } +UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); } +UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); } +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); } +UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 6); } +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 7); } +UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 8); } +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 9); } +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); } +UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 15); } +UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 16); } +UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 17); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 18); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 10); } +UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); } +UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 19); } +UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 20); } +UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(100, 184)); } +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(100, 184), len); } + +UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 11); + *UPB_PTR_AT(msg, UPB_SIZE(20, 24), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 12); + *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 13); + *UPB_PTR_AT(msg, UPB_SIZE(36, 56), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(9, 9), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 4); + *UPB_PTR_AT(msg, UPB_SIZE(10, 10), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 5); + *UPB_PTR_AT(msg, UPB_SIZE(11, 11), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 6); + *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 7); + *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 8); + *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 9); + *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 14); + *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 15); + *UPB_PTR_AT(msg, UPB_SIZE(52, 88), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 16); + *UPB_PTR_AT(msg, UPB_SIZE(60, 104), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 17); + *UPB_PTR_AT(msg, UPB_SIZE(68, 120), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 18); + *UPB_PTR_AT(msg, UPB_SIZE(76, 136), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) { + _upb_sethas(msg, 10); + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 19); + *UPB_PTR_AT(msg, UPB_SIZE(84, 152), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) { + _upb_sethas(msg, 20); + *UPB_PTR_AT(msg, UPB_SIZE(92, 168), upb_strview) = 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(100, 184), 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_accessor2(msg, UPB_SIZE(100, 184), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(100, 184), UPB_SIZE(2, 3), &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_hasbit(msg, 1); } +UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_hasbit(msg, 3); } +UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); } +UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_hasbit(msg, 4); } +UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); } +UPB_INLINE bool google_protobuf_MessageOptions_has_uninterpreted_option(const google_protobuf_MessageOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); } +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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value; +} +UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions *msg, bool value) { + _upb_sethas(msg, 4); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool) = 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_accessor2(msg, UPB_SIZE(8, 8), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(8, 8), UPB_SIZE(2, 3), &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_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 3); } +UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 4); } +UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 5); } +UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_hasbit(msg, 6); } +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 16)); } +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(16, 16), len); } + +UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(12, 12), bool) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 4); + *UPB_PTR_AT(msg, UPB_SIZE(13, 13), bool) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 5); + *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; +} +UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) { + _upb_sethas(msg, 6); + *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) = 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(16, 16), 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_accessor2(msg, UPB_SIZE(16, 16), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(16, 16), UPB_SIZE(2, 3), &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 bool google_protobuf_OneofOptions_has_uninterpreted_option(const google_protobuf_OneofOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } +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_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &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_hasbit(msg, 1); } +UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } +UPB_INLINE bool google_protobuf_EnumOptions_has_uninterpreted_option(const google_protobuf_EnumOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } +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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions *msg, bool value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = 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_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &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_hasbit(msg, 1); } +UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_EnumValueOptions_has_uninterpreted_option(const google_protobuf_EnumValueOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } +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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &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_hasbit(msg, 1); } +UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_ServiceOptions_has_uninterpreted_option(const google_protobuf_ServiceOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } +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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(4, 8), UPB_SIZE(2, 3), &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_hasbit(msg, 2); } +UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); } +UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 16)); } +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(12, 16), len); } + +UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value; +} +UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = 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(12, 16), 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_accessor2(msg, UPB_SIZE(12, 16), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(12, 16), UPB_SIZE(2, 3), &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 bool google_protobuf_UninterpretedOption_has_name(const google_protobuf_UninterpretedOption *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 80)); } +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_hasbit(msg, 4); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 3); } +UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 5); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_hasbit(msg, 6); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview); } + +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_accessor2(msg, UPB_SIZE(56, 80), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(56, 80), UPB_SIZE(2, 3), &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_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) { + _upb_sethas(msg, 3); + *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 5); + *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_strview value) { + _upb_sethas(msg, 6); + *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview) = 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_hasbit(msg, 2); } +UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } + +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_strview value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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 bool google_protobuf_SourceCodeInfo_has_location(const google_protobuf_SourceCodeInfo *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } +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_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &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_hasbit(msg, 1); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } +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_accessor2(msg, UPB_SIZE(20, 40), len, 2, 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_accessor2(msg, UPB_SIZE(20, 40), 2, &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_accessor2(msg, UPB_SIZE(24, 48), len, 2, 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_accessor2(msg, UPB_SIZE(24, 48), 2, &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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = 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_accessor2(msg, UPB_SIZE(28, 56), len, UPB_SIZE(3, 4), 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_accessor2(msg, UPB_SIZE(28, 56), UPB_SIZE(3, 4), &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 bool google_protobuf_GeneratedCodeInfo_has_annotation(const google_protobuf_GeneratedCodeInfo *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } +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_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(2, 3), 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_accessor2( + msg, UPB_SIZE(0, 0), UPB_SIZE(2, 3), &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_hasbit(msg, 3); } +UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_hasbit(msg, 2); } +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } + +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_accessor2(msg, UPB_SIZE(20, 32), len, 2, 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_accessor2(msg, UPB_SIZE(20, 32), 2, &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_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) { + _upb_sethas(msg, 2); + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */ +/* +** Defs are upb's internal representation of the constructs that can appear +** in a .proto file: +** +** - upb_msgdef: describes a "message" construct. +** - upb_fielddef: describes a message field. +** - upb_filedef: describes a .proto file and its defs. +** - upb_enumdef: describes an enum. +** - upb_oneofdef: describes a oneof. +** +** TODO: definitions of services. +*/ + +#ifndef UPB_DEF_H_ +#define UPB_DEF_H_ + + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +struct upb_enumdef; +typedef struct upb_enumdef upb_enumdef; +struct upb_fielddef; +typedef struct upb_fielddef upb_fielddef; +struct upb_filedef; +typedef struct upb_filedef upb_filedef; +struct upb_msgdef; +typedef struct upb_msgdef upb_msgdef; +struct upb_oneofdef; +typedef struct upb_oneofdef upb_oneofdef; +struct upb_symtab; +typedef struct upb_symtab upb_symtab; + +typedef enum { + UPB_SYNTAX_PROTO2 = 2, + UPB_SYNTAX_PROTO3 = 3 +} upb_syntax_t; + +/* All the different kind of well known type messages. For simplicity of check, + * number wrappers and string wrappers are grouped together. Make sure the + * order and merber of these groups are not changed. + */ +typedef enum { + UPB_WELLKNOWN_UNSPECIFIED, + UPB_WELLKNOWN_ANY, + UPB_WELLKNOWN_FIELDMASK, + UPB_WELLKNOWN_DURATION, + UPB_WELLKNOWN_TIMESTAMP, + /* number wrappers */ + UPB_WELLKNOWN_DOUBLEVALUE, + UPB_WELLKNOWN_FLOATVALUE, + UPB_WELLKNOWN_INT64VALUE, + UPB_WELLKNOWN_UINT64VALUE, + UPB_WELLKNOWN_INT32VALUE, + UPB_WELLKNOWN_UINT32VALUE, + /* string wrappers */ + UPB_WELLKNOWN_STRINGVALUE, + UPB_WELLKNOWN_BYTESVALUE, + UPB_WELLKNOWN_BOOLVALUE, + UPB_WELLKNOWN_VALUE, + UPB_WELLKNOWN_LISTVALUE, + UPB_WELLKNOWN_STRUCT +} upb_wellknowntype_t; + +/* upb_fielddef ***************************************************************/ + +/* Maximum field number allowed for FieldDefs. This is an inherent limit of the + * protobuf wire format. */ +#define UPB_MAX_FIELDNUMBER ((1 << 29) - 1) + +const char *upb_fielddef_fullname(const upb_fielddef *f); +upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f); +upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f); +upb_label_t upb_fielddef_label(const upb_fielddef *f); +uint32_t upb_fielddef_number(const upb_fielddef *f); +const char *upb_fielddef_name(const upb_fielddef *f); +const char *upb_fielddef_jsonname(const upb_fielddef *f); +bool upb_fielddef_isextension(const upb_fielddef *f); +bool upb_fielddef_lazy(const upb_fielddef *f); +bool upb_fielddef_packed(const upb_fielddef *f); +const upb_filedef *upb_fielddef_file(const upb_fielddef *f); +const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f); +const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f); +const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f); +uint32_t upb_fielddef_index(const upb_fielddef *f); +bool upb_fielddef_issubmsg(const upb_fielddef *f); +bool upb_fielddef_isstring(const upb_fielddef *f); +bool upb_fielddef_isseq(const upb_fielddef *f); +bool upb_fielddef_isprimitive(const upb_fielddef *f); +bool upb_fielddef_ismap(const upb_fielddef *f); +int64_t upb_fielddef_defaultint64(const upb_fielddef *f); +int32_t upb_fielddef_defaultint32(const upb_fielddef *f); +uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f); +uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f); +bool upb_fielddef_defaultbool(const upb_fielddef *f); +float upb_fielddef_defaultfloat(const upb_fielddef *f); +double upb_fielddef_defaultdouble(const upb_fielddef *f); +const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len); +bool upb_fielddef_hassubdef(const upb_fielddef *f); +bool upb_fielddef_haspresence(const upb_fielddef *f); +const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f); +const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f); +const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f); + +/* Internal only. */ +uint32_t upb_fielddef_selectorbase(const upb_fielddef *f); + +/* upb_oneofdef ***************************************************************/ + +typedef upb_inttable_iter upb_oneof_iter; + +const char *upb_oneofdef_name(const upb_oneofdef *o); +const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o); +uint32_t upb_oneofdef_index(const upb_oneofdef *o); +bool upb_oneofdef_issynthetic(const upb_oneofdef *o); +int upb_oneofdef_fieldcount(const upb_oneofdef *o); +const upb_fielddef *upb_oneofdef_field(const upb_oneofdef *o, int i); + +/* Oneof lookups: + * - ntof: look up a field by name. + * - ntofz: look up a field by name (as a null-terminated string). + * - itof: look up a field by number. */ +const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, + const char *name, size_t length); +UPB_INLINE const upb_fielddef *upb_oneofdef_ntofz(const upb_oneofdef *o, + const char *name) { + return upb_oneofdef_ntof(o, name, strlen(name)); +} +const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num); + +/* DEPRECATED, slated for removal. */ +int upb_oneofdef_numfields(const upb_oneofdef *o); +void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o); +void upb_oneof_next(upb_oneof_iter *iter); +bool upb_oneof_done(upb_oneof_iter *iter); +upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter); +void upb_oneof_iter_setdone(upb_oneof_iter *iter); +bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1, + const upb_oneof_iter *iter2); +/* END DEPRECATED */ + +/* upb_msgdef *****************************************************************/ + +typedef upb_inttable_iter upb_msg_field_iter; +typedef upb_strtable_iter upb_msg_oneof_iter; + +/* Well-known field tag numbers for map-entry messages. */ +#define UPB_MAPENTRY_KEY 1 +#define UPB_MAPENTRY_VALUE 2 + +/* Well-known field tag numbers for Any messages. */ +#define UPB_ANY_TYPE 1 +#define UPB_ANY_VALUE 2 + +/* Well-known field tag numbers for timestamp messages. */ +#define UPB_DURATION_SECONDS 1 +#define UPB_DURATION_NANOS 2 + +/* Well-known field tag numbers for duration messages. */ +#define UPB_TIMESTAMP_SECONDS 1 +#define UPB_TIMESTAMP_NANOS 2 + +const char *upb_msgdef_fullname(const upb_msgdef *m); +const upb_filedef *upb_msgdef_file(const upb_msgdef *m); +const char *upb_msgdef_name(const upb_msgdef *m); +upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); +bool upb_msgdef_mapentry(const upb_msgdef *m); +upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); +bool upb_msgdef_iswrapper(const upb_msgdef *m); +bool upb_msgdef_isnumberwrapper(const upb_msgdef *m); +int upb_msgdef_fieldcount(const upb_msgdef *m); +int upb_msgdef_oneofcount(const upb_msgdef *m); +const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i); +const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i); +const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i); +const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, + size_t len); +const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, + size_t len); +const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m); + +UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m, + const char *name) { + return upb_msgdef_ntoo(m, name, strlen(name)); +} + +UPB_INLINE const upb_fielddef *upb_msgdef_ntofz(const upb_msgdef *m, + const char *name) { + return upb_msgdef_ntof(m, name, strlen(name)); +} + +/* Internal-only. */ +size_t upb_msgdef_selectorcount(const upb_msgdef *m); +uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m); + +/* Lookup of either field or oneof by name. Returns whether either was found. + * If the return is true, then the found def will be set, and the non-found + * one set to NULL. */ +bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, + const upb_fielddef **f, const upb_oneofdef **o); + +UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name, + const upb_fielddef **f, + const upb_oneofdef **o) { + return upb_msgdef_lookupname(m, name, strlen(name), f, o); +} + +/* Returns a field by either JSON name or regular proto name. */ +const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, + const char *name, size_t len); + +/* DEPRECATED, slated for removal */ +int upb_msgdef_numfields(const upb_msgdef *m); +int upb_msgdef_numoneofs(const upb_msgdef *m); +int upb_msgdef_numrealoneofs(const upb_msgdef *m); +void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m); +void upb_msg_field_next(upb_msg_field_iter *iter); +bool upb_msg_field_done(const upb_msg_field_iter *iter); +upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter); +void upb_msg_field_iter_setdone(upb_msg_field_iter *iter); +bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, + const upb_msg_field_iter * iter2); +void upb_msg_oneof_begin(upb_msg_oneof_iter * iter, const upb_msgdef *m); +void upb_msg_oneof_next(upb_msg_oneof_iter * iter); +bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter); +const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter); +void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter); +bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, + const upb_msg_oneof_iter *iter2); +/* END DEPRECATED */ + +/* upb_enumdef ****************************************************************/ + +typedef upb_strtable_iter upb_enum_iter; + +const char *upb_enumdef_fullname(const upb_enumdef *e); +const char *upb_enumdef_name(const upb_enumdef *e); +const upb_filedef *upb_enumdef_file(const upb_enumdef *e); +int32_t upb_enumdef_default(const upb_enumdef *e); +int upb_enumdef_numvals(const upb_enumdef *e); + +/* Enum lookups: + * - ntoi: look up a name with specified length. + * - ntoiz: look up a name provided as a null-terminated string. + * - iton: look up an integer, returning the name as a null-terminated + * string. */ +bool upb_enumdef_ntoi(const upb_enumdef *e, const char *name, size_t len, + int32_t *num); +UPB_INLINE bool upb_enumdef_ntoiz(const upb_enumdef *e, + const char *name, int32_t *num) { + return upb_enumdef_ntoi(e, name, strlen(name), num); +} +const char *upb_enumdef_iton(const upb_enumdef *e, int32_t num); + +void upb_enum_begin(upb_enum_iter *iter, const upb_enumdef *e); +void upb_enum_next(upb_enum_iter *iter); +bool upb_enum_done(upb_enum_iter *iter); +const char *upb_enum_iter_name(upb_enum_iter *iter); +int32_t upb_enum_iter_number(upb_enum_iter *iter); + +/* upb_filedef ****************************************************************/ + +const char *upb_filedef_name(const upb_filedef *f); +const char *upb_filedef_package(const upb_filedef *f); +const char *upb_filedef_phpprefix(const upb_filedef *f); +const char *upb_filedef_phpnamespace(const upb_filedef *f); +upb_syntax_t upb_filedef_syntax(const upb_filedef *f); +int upb_filedef_depcount(const upb_filedef *f); +int upb_filedef_msgcount(const upb_filedef *f); +int upb_filedef_enumcount(const upb_filedef *f); +const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i); +const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i); +const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i); + +/* upb_symtab *****************************************************************/ + +upb_symtab *upb_symtab_new(void); +void upb_symtab_free(upb_symtab* s); +const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym); +const upb_msgdef *upb_symtab_lookupmsg2( + const upb_symtab *s, const char *sym, size_t len); +const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym); +const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name); +const upb_filedef *upb_symtab_lookupfile2( + const upb_symtab *s, const char *name, size_t len); +int upb_symtab_filecount(const upb_symtab *s); +const upb_filedef *upb_symtab_addfile( + upb_symtab *s, const google_protobuf_FileDescriptorProto *file, + upb_status *status); +size_t _upb_symtab_bytesloaded(const upb_symtab *s); + +/* For generated code only: loads a generated descriptor. */ +typedef struct upb_def_init { + struct upb_def_init **deps; /* Dependencies of this file. */ + const upb_msglayout **layouts; /* Pre-order layouts of all messages. */ + const char *filename; + upb_strview descriptor; /* Serialized descriptor. */ +} upb_def_init; + +bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* UPB_DEF_H_ */ +/* 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_UPBDEFS_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPBDEFS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + +extern upb_def_init google_protobuf_descriptor_proto_upbdefinit; + +UPB_INLINE const upb_msgdef *google_protobuf_FileDescriptorSet_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorSet"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_FileDescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.FileDescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_DescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_DescriptorProto_ExtensionRange_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto.ExtensionRange"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_DescriptorProto_ReservedRange_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.DescriptorProto.ReservedRange"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_ExtensionRangeOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.ExtensionRangeOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_FieldDescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.FieldDescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_OneofDescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.OneofDescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_EnumDescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.EnumDescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_EnumDescriptorProto_EnumReservedRange_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.EnumDescriptorProto.EnumReservedRange"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_EnumValueDescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.EnumValueDescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_ServiceDescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.ServiceDescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_MethodDescriptorProto_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.MethodDescriptorProto"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_FileOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.FileOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_MessageOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.MessageOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_FieldOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.FieldOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_OneofOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.OneofOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_EnumOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.EnumOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_EnumValueOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.EnumValueOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_ServiceOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.ServiceOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_MethodOptions_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.MethodOptions"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_UninterpretedOption_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_UninterpretedOption_NamePart_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.UninterpretedOption.NamePart"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_SourceCodeInfo_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_SourceCodeInfo_Location_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.SourceCodeInfo.Location"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_GeneratedCodeInfo_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.GeneratedCodeInfo"); +} + +UPB_INLINE const upb_msgdef *google_protobuf_GeneratedCodeInfo_Annotation_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &google_protobuf_descriptor_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "google.protobuf.GeneratedCodeInfo.Annotation"); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPBDEFS_H_ */ + +#ifndef UPB_REFLECTION_H_ +#define UPB_REFLECTION_H_ + + + +typedef union { + bool bool_val; + float float_val; + double double_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + const upb_map* map_val; + const upb_msg* msg_val; + const upb_array* array_val; + upb_strview str_val; +} upb_msgval; + +typedef union { + upb_map* map; + upb_msg* msg; + upb_array* array; +} upb_mutmsgval; + +/** upb_msg *******************************************************************/ + +/* Creates a new message of the given type in the given arena. */ +upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a); + +/* Returns the value associated with this field. */ +upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f); + +/* Returns a mutable pointer to a map, array, or submessage value. If the given + * arena is non-NULL this will construct a new object if it was not previously + * present. May not be called for primitive fields. */ +upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, upb_arena *a); + +/* May only be called for fields where upb_fielddef_haspresence(f) == true. */ +bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f); + +/* Returns the field that is set in the oneof, or NULL if none are set. */ +const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg, + const upb_oneofdef *o); + +/* Sets the given field to the given value. For a msg/array/map/string, the + * value must be in the same arena. */ +void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, + upb_arena *a); + +/* Clears any field presence and sets the value back to its default. */ +void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f); + +/* Clear all data and unknown fields. */ +void upb_msg_clear(upb_msg *msg, const upb_msgdef *m); + +/* Iterate over present fields. + * + * size_t iter = UPB_MSG_BEGIN; + * const upb_fielddef *f; + * upb_msgval val; + * while (upb_msg_next(msg, m, ext_pool, &f, &val, &iter)) { + * process_field(f, val); + * } + * + * If ext_pool is NULL, no extensions will be returned. If the given symtab + * returns extensions that don't match what is in this message, those extensions + * will be skipped. + */ + +#define UPB_MSG_BEGIN -1 +bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, const upb_fielddef **f, + upb_msgval *val, size_t *iter); + +/* Adds unknown data (serialized protobuf data) to the given message. The data + * is copied into the message instance. */ +void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena); + +/* Clears all unknown field data from this message and all submessages. */ +bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth); + +/* Returns a reference to the message's unknown data. */ +const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); + +/** upb_array *****************************************************************/ + +/* Creates a new array on the given arena that holds elements of this type. */ +upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type); + +/* Returns the size of the array. */ +size_t upb_array_size(const upb_array *arr); + +/* Returns the given element, which must be within the array's current size. */ +upb_msgval upb_array_get(const upb_array *arr, size_t i); + +/* Sets the given element, which must be within the array's current size. */ +void upb_array_set(upb_array *arr, size_t i, upb_msgval val); + +/* Appends an element to the array. Returns false on allocation failure. */ +bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena); + +/* Changes the size of a vector. New elements are initialized to empty/0. + * Returns false on allocation failure. */ +bool upb_array_resize(upb_array *array, size_t size, upb_arena *arena); + +/** upb_map *******************************************************************/ + +/* Creates a new map on the given arena with the given key/value size. */ +upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, + upb_fieldtype_t value_type); + +/* Returns the number of entries in the map. */ +size_t upb_map_size(const upb_map *map); + +/* Stores a value for the given key into |*val| (or the zero value if the key is + * not present). Returns whether the key was present. The |val| pointer may be + * NULL, in which case the function tests whether the given key is present. */ +bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val); + +/* Removes all entries in the map. */ +void upb_map_clear(upb_map *map); + +/* Sets the given key to the given value. Returns true if this was a new key in + * the map, or false if an existing key was replaced. */ +bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, + upb_arena *arena); + +/* Deletes this key from the table. Returns true if the key was present. */ +bool upb_map_delete(upb_map *map, upb_msgval key); + +/* Map iteration: + * + * size_t iter = UPB_MAP_BEGIN; + * while (upb_mapiter_next(map, &iter)) { + * upb_msgval key = upb_mapiter_key(map, iter); + * upb_msgval val = upb_mapiter_value(map, iter); + * + * // If mutating is desired. + * upb_mapiter_setvalue(map, iter, value2); + * } + */ + +/* Advances to the next entry. Returns false if no more entries are present. */ +bool upb_mapiter_next(const upb_map *map, size_t *iter); + +/* Returns true if the iterator still points to a valid entry, or false if the + * iterator is past the last element. It is an error to call this function with + * UPB_MAP_BEGIN (you must call next() at least once first). */ +bool upb_mapiter_done(const upb_map *map, size_t iter); + +/* Returns the key and value for this entry of the map. */ +upb_msgval upb_mapiter_key(const upb_map *map, size_t iter); +upb_msgval upb_mapiter_value(const upb_map *map, size_t iter); + +/* Sets the value for this entry. The iterator must not be done, and the + * iterator must not have been initialized const. */ +void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); + + +#endif /* UPB_REFLECTION_H_ */ + +#ifndef UPB_JSONDECODE_H_ +#define UPB_JSONDECODE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + UPB_JSONDEC_IGNOREUNKNOWN = 1 +}; + +bool upb_json_decode(const char *buf, size_t size, upb_msg *msg, + const upb_msgdef *m, const upb_symtab *any_pool, + int options, upb_arena *arena, upb_status *status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_JSONDECODE_H_ */ + +#ifndef UPB_JSONENCODE_H_ +#define UPB_JSONENCODE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + /* When set, emits 0/default values. TODO(haberman): proto3 only? */ + UPB_JSONENC_EMITDEFAULTS = 1, + + /* When set, use normal (snake_caes) field names instead of JSON (camelCase) + names. */ + UPB_JSONENC_PROTONAMES = 2 +}; + +/* Encodes the given |msg| to JSON format. The message's reflection is given in + * |m|. The symtab in |symtab| is used to find extensions (if NULL, extensions + * will not be printed). + * + * Output is placed in the given buffer, and always NULL-terminated. The output + * size (excluding NULL) is returned. This means that a return value >= |size| + * implies that the output was truncated. (These are the same semantics as + * snprintf()). */ +size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, int options, char *buf, + size_t size, upb_status *status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_JSONENCODE_H_ */ +/* See port_def.inc. This should #undef all macros #defined there. */ + +#undef UPB_MAPTYPE_STRING +#undef UPB_SIZE +#undef UPB_PTR_AT +#undef UPB_READ_ONEOF +#undef UPB_WRITE_ONEOF +#undef UPB_INLINE +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF +#undef UPB_FORCEINLINE +#undef UPB_NOINLINE +#undef UPB_NORETURN +#undef UPB_MAX +#undef UPB_MIN +#undef UPB_UNUSED +#undef UPB_ASSUME +#undef UPB_ASSERT +#undef UPB_UNREACHABLE +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c index e9ac93594931..761eeeb53257 100644 --- a/php/ext/google/protobuf/protobuf.c +++ b/php/ext/google/protobuf/protobuf.c @@ -30,273 +30,243 @@ #include "protobuf.h" -#include +#include +#include -static PHP_GINIT_FUNCTION(protobuf); -static PHP_GSHUTDOWN_FUNCTION(protobuf); -static PHP_RINIT_FUNCTION(protobuf); -static PHP_RSHUTDOWN_FUNCTION(protobuf); -static PHP_MINIT_FUNCTION(protobuf); -static PHP_MSHUTDOWN_FUNCTION(protobuf); - -ZEND_DECLARE_MODULE_GLOBALS(protobuf) - -// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor -// instances. -static HashTable* upb_def_to_php_obj_map; -static upb_inttable upb_def_to_desc_map_persistent; -static upb_inttable upb_def_to_enumdesc_map_persistent; -// Global map from message/enum's php class entry to corresponding wrapper -// Descriptor/EnumDescriptor instances. -static HashTable* ce_to_php_obj_map; -static upb_strtable ce_to_desc_map_persistent; -static upb_strtable ce_to_enumdesc_map_persistent; -// Global map from message/enum's proto fully-qualified name to corresponding -// wrapper Descriptor/EnumDescriptor instances. -static upb_strtable proto_to_desc_map_persistent; -static upb_strtable class_to_desc_map_persistent; - -upb_strtable reserved_names; +#include "arena.h" +#include "array.h" +#include "convert.h" +#include "def.h" +#include "map.h" +#include "message.h" +#include "names.h" // ----------------------------------------------------------------------------- -// Global maps. +// Module "globals" // ----------------------------------------------------------------------------- -static void add_to_table(HashTable* t, const void* def, void* value) { - zval* pDest = NULL; - php_proto_zend_hash_index_update_mem(t, (zend_ulong)def, &value, - sizeof(zval*), (void**)&pDest); -} +// Despite the name, module "globals" are really thread-locals: +// * PROTOBUF_G(var) accesses the thread-local variable for 'var'. Either: +// * PROTOBUF_G(var) -> protobuf_globals.var (Non-ZTS / non-thread-safe) +// * PROTOBUF_G(var) -> (ZTS / thread-safe builds) -static void* get_from_table(const HashTable* t, const void* def) { - void** value; - if (php_proto_zend_hash_index_find_mem(t, (zend_ulong)def, (void**)&value) == - FAILURE) { - return NULL; - } - return *value; -} +#define PROTOBUF_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(protobuf, v) -void add_def_obj(const void* def, PHP_PROTO_HASHTABLE_VALUE value) { -#if PHP_MAJOR_VERSION < 7 - Z_ADDREF_P(value); -#else - GC_ADDREF(value); -#endif - add_to_table(upb_def_to_php_obj_map, def, value); -} +ZEND_BEGIN_MODULE_GLOBALS(protobuf) + // Set by the user to make the descriptor pool persist between requests. + zend_bool keep_descriptor_pool_after_request; -PHP_PROTO_HASHTABLE_VALUE get_def_obj(const void* def) { - return (PHP_PROTO_HASHTABLE_VALUE)get_from_table(upb_def_to_php_obj_map, def); -} + // Currently we make the generated pool a "global", which means that if a user + // does explicitly create threads within their request, the other threads will + // get different results from DescriptorPool::getGeneratedPool(). We require + // that all descriptors are loaded from the main thread. + zval generated_pool; -void add_msgdef_desc(const upb_msgdef* m, DescriptorInternal* desc) { - upb_inttable_insertptr(&upb_def_to_desc_map_persistent, - m, upb_value_ptr(desc)); -} + // A upb_symtab that we are saving for the next request so that we don't have + // to rebuild it from scratch. When keep_descriptor_pool_after_request==true, + // we steal the upb_symtab from the global DescriptorPool object just before + // destroying it. + upb_symtab *saved_symtab; -DescriptorInternal* get_msgdef_desc(const upb_msgdef* m) { - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_PTR; -#endif - if (!upb_inttable_lookupptr(&upb_def_to_desc_map_persistent, m, &v)) { - return NULL; - } else { - return upb_value_getptr(v); - } -} + // Object cache (see interface in protobuf.h). + HashTable object_cache; -void add_enumdef_enumdesc(const upb_enumdef* e, EnumDescriptorInternal* desc) { - upb_inttable_insertptr(&upb_def_to_enumdesc_map_persistent, - e, upb_value_ptr(desc)); -} + // Name cache (see interface in protobuf.h). + HashTable name_msg_cache; + HashTable name_enum_cache; +ZEND_END_MODULE_GLOBALS(protobuf) -EnumDescriptorInternal* get_enumdef_enumdesc(const upb_enumdef* e) { - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_PTR; -#endif - if (!upb_inttable_lookupptr(&upb_def_to_enumdesc_map_persistent, e, &v)) { - return NULL; - } else { - return upb_value_getptr(v); - } -} +ZEND_DECLARE_MODULE_GLOBALS(protobuf) -void add_ce_obj(const void* ce, PHP_PROTO_HASHTABLE_VALUE value) { -#if PHP_MAJOR_VERSION < 7 - Z_ADDREF_P(value); -#else - GC_ADDREF(value); -#endif - add_to_table(ce_to_php_obj_map, ce, value); +const zval *get_generated_pool() { + return &PROTOBUF_G(generated_pool); } -PHP_PROTO_HASHTABLE_VALUE get_ce_obj(const void* ce) { - return (PHP_PROTO_HASHTABLE_VALUE)get_from_table(ce_to_php_obj_map, ce); +// This is a PHP extension (not a Zend extension). What follows is a summary of +// a PHP extension's lifetime and when various handlers are called. +// +// * PHP_GINIT_FUNCTION(protobuf) / PHP_GSHUTDOWN_FUNCTION(protobuf) +// are the constructor/destructor for the globals. The sequence over the +// course of a process lifetime is: +// +// # Process startup +// GINIT(
    ) +// MINIT +// +// foreach request: +// RINIT +// # Request is processed here. +// RSHUTDOWN +// +// foreach thread: +// GINIT() +// # Code for the thread runs here. +// GSHUTDOWN() +// +// # Process Shutdown +// # +// # These should be running per the docs, but I have not been able to +// # actually get the process-wide shutdown functions to run. +// # +// # MSHUTDOWN +// # GSHUTDOWN(
    ) +// +// * Threads can be created either explicitly by the user, inside a request, +// or implicitly by the runtime, to process multiple requests concurrently. +// If the latter is being used, then the "foreach thread" block above +// actually looks like this: +// +// foreach thread: +// GINIT() +// # A non-main thread will only receive requests when using a threaded +// # MPM with Apache +// foreach request: +// RINIT +// # Request is processed here. +// RSHUTDOWN +// GSHUTDOWN() +// +// That said, it appears that few people use threads with PHP: +// * The pthread package documented at +// https://www.php.net/manual/en/class.thread.php nas not been released +// since 2016, and the current release fails to compile against any PHP +// newer than 7.0.33. +// * The GitHub master branch supports 7.2+, but this has not been released +// to PECL. +// * Its owner has disavowed it as "broken by design" and "in an untenable +// position for the future": https://github.com/krakjoe/pthreads/issues/929 +// * The only way to use PHP with requests in different threads is to use the +// Apache 2 mod_php with the "worker" MPM. But this is explicitly +// discouraged by the documentation: https://serverfault.com/a/231660 + +static PHP_GSHUTDOWN_FUNCTION(protobuf) { + if (protobuf_globals->saved_symtab) { + upb_symtab_free(protobuf_globals->saved_symtab); + } } -void add_ce_desc(const zend_class_entry* ce, DescriptorInternal* desc) { -#if PHP_MAJOR_VERSION < 7 - const char* klass = ce->name; -#else - const char* klass = ZSTR_VAL(ce->name); -#endif - upb_strtable_insert(&ce_to_desc_map_persistent, klass, - upb_value_ptr(desc)); +static PHP_GINIT_FUNCTION(protobuf) { + ZVAL_NULL(&protobuf_globals->generated_pool); + protobuf_globals->saved_symtab = NULL; } -DescriptorInternal* get_ce_desc(const zend_class_entry* ce) { -#if PHP_MAJOR_VERSION < 7 - const char* klass = ce->name; -#else - const char* klass = ZSTR_VAL(ce->name); -#endif +/** + * PHP_RINIT_FUNCTION(protobuf) + * + * This function is run at the beginning of processing each request. + */ +static PHP_RINIT_FUNCTION(protobuf) { + // Create the global generated pool. + // Reuse the symtab (if any) left to us by the last request. + upb_symtab *symtab = PROTOBUF_G(saved_symtab); + DescriptorPool_CreateWithSymbolTable(&PROTOBUF_G(generated_pool), symtab); - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_PTR; -#endif + zend_hash_init(&PROTOBUF_G(object_cache), 64, NULL, NULL, 0); + zend_hash_init(&PROTOBUF_G(name_msg_cache), 64, NULL, NULL, 0); + zend_hash_init(&PROTOBUF_G(name_enum_cache), 64, NULL, NULL, 0); - if (!upb_strtable_lookup(&ce_to_desc_map_persistent, klass, &v)) { - return NULL; - } else { - return upb_value_getptr(v); - } -} - -void add_ce_enumdesc(const zend_class_entry* ce, EnumDescriptorInternal* desc) { -#if PHP_MAJOR_VERSION < 7 - const char* klass = ce->name; -#else - const char* klass = ZSTR_VAL(ce->name); -#endif - upb_strtable_insert(&ce_to_enumdesc_map_persistent, klass, - upb_value_ptr(desc)); + return SUCCESS; } -EnumDescriptorInternal* get_ce_enumdesc(const zend_class_entry* ce) { -#if PHP_MAJOR_VERSION < 7 - const char* klass = ce->name; -#else - const char* klass = ZSTR_VAL(ce->name); -#endif - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_PTR; -#endif - if (!upb_strtable_lookup(&ce_to_enumdesc_map_persistent, klass, &v)) { - return NULL; - } else { - return upb_value_getptr(v); +/** + * PHP_RSHUTDOWN_FUNCTION(protobuf) + * + * This function is run at the end of processing each request. + */ +static PHP_RSHUTDOWN_FUNCTION(protobuf) { + // Preserve the symtab if requested. + if (PROTOBUF_G(keep_descriptor_pool_after_request)) { + zval *zv = &PROTOBUF_G(generated_pool); + PROTOBUF_G(saved_symtab) = DescriptorPool_Steal(zv); } -} -bool class_added(const void* ce) { - return get_ce_desc(ce) != NULL; -} + zval_dtor(&PROTOBUF_G(generated_pool)); + zend_hash_destroy(&PROTOBUF_G(object_cache)); + zend_hash_destroy(&PROTOBUF_G(name_msg_cache)); + zend_hash_destroy(&PROTOBUF_G(name_enum_cache)); -void add_proto_desc(const char* proto, DescriptorInternal* desc) { - upb_strtable_insert(&proto_to_desc_map_persistent, proto, - upb_value_ptr(desc)); + return SUCCESS; } -DescriptorInternal* get_proto_desc(const char* proto) { - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_PTR; -#endif - if (!upb_strtable_lookup(&proto_to_desc_map_persistent, proto, &v)) { - return NULL; - } else { - return upb_value_getptr(v); - } -} +// ----------------------------------------------------------------------------- +// Object Cache. +// ----------------------------------------------------------------------------- -void add_class_desc(const char* klass, DescriptorInternal* desc) { - upb_strtable_insert(&class_to_desc_map_persistent, klass, - upb_value_ptr(desc)); +void ObjCache_Add(const void *upb_obj, zend_object *php_obj) { + zend_ulong k = (zend_ulong)upb_obj; + zend_hash_index_add_ptr(&PROTOBUF_G(object_cache), k, php_obj); } -DescriptorInternal* get_class_desc(const char* klass) { - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_PTR; -#endif - if (!upb_strtable_lookup(&class_to_desc_map_persistent, klass, &v)) { - return NULL; - } else { - return upb_value_getptr(v); +void ObjCache_Delete(const void *upb_obj) { + if (upb_obj) { + zend_ulong k = (zend_ulong)upb_obj; + int ret = zend_hash_index_del(&PROTOBUF_G(object_cache), k); + PBPHP_ASSERT(ret == SUCCESS); } } -void add_class_enumdesc(const char* klass, EnumDescriptorInternal* desc) { - upb_strtable_insert(&class_to_desc_map_persistent, klass, - upb_value_ptr(desc)); -} +bool ObjCache_Get(const void *upb_obj, zval *val) { + zend_ulong k = (zend_ulong)upb_obj; + zend_object *obj = zend_hash_index_find_ptr(&PROTOBUF_G(object_cache), k); -EnumDescriptorInternal* get_class_enumdesc(const char* klass) { - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_PTR; -#endif - if (!upb_strtable_lookup(&class_to_desc_map_persistent, klass, &v)) { - return NULL; + if (obj) { + GC_ADDREF(obj); + ZVAL_OBJ(val, obj); + return true; } else { - return upb_value_getptr(v); + ZVAL_NULL(val); + return false; } } // ----------------------------------------------------------------------------- -// Well Known Types. +// Name Cache. // ----------------------------------------------------------------------------- -bool is_inited_file_any; -bool is_inited_file_api; -bool is_inited_file_duration; -bool is_inited_file_field_mask; -bool is_inited_file_empty; -bool is_inited_file_source_context; -bool is_inited_file_struct; -bool is_inited_file_timestamp; -bool is_inited_file_type; -bool is_inited_file_wrappers; +void NameMap_AddMessage(const upb_msgdef *m) { + char *k = GetPhpClassname(upb_msgdef_file(m), upb_msgdef_fullname(m)); + zend_hash_str_add_ptr(&PROTOBUF_G(name_msg_cache), k, strlen(k), (void*)m); + free(k); +} -// ----------------------------------------------------------------------------- -// Reserved Name. -// ----------------------------------------------------------------------------- +void NameMap_AddEnum(const upb_enumdef *e) { + char *k = GetPhpClassname(upb_enumdef_file(e), upb_enumdef_fullname(e)); + zend_hash_str_add_ptr(&PROTOBUF_G(name_enum_cache), k, strlen(k), (void*)e); + free(k); +} + +const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce) { + const upb_msgdef *ret = + zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name); -// Although we already have kReservedNames, we still add them to hash table to -// speed up look up. -const char *const kReservedNames[] = { - "abstract", "and", "array", "as", "break", - "callable", "case", "catch", "class", "clone", - "const", "continue", "declare", "default", "die", - "do", "echo", "else", "elseif", "empty", - "enddeclare", "endfor", "endforeach", "endif", "endswitch", - "endwhile", "eval", "exit", "extends", "final", - "for", "foreach", "function", "global", "goto", - "if", "implements", "include", "include_once", "instanceof", - "insteadof", "interface", "isset", "list", "namespace", - "new", "or", "print", "private", "protected", - "public", "require", "require_once", "return", "static", - "switch", "throw", "trait", "try", "unset", - "use", "var", "while", "xor", "int", - "float", "bool", "string", "true", "false", - "null", "void", "iterable"}; -const int kReservedNamesSize = 73; - -bool is_reserved_name(const char* name) { - upb_value v; -#ifndef NDEBUG - v.ctype = UPB_CTYPE_UINT64; + if (!ret && ce->create_object) { +#if PHP_VERSION_ID < 80000 + zval tmp; + zval zv; + ZVAL_OBJ(&tmp, ce->create_object(ce)); + zend_call_method_with_0_params(&tmp, ce, NULL, "__construct", &zv); + zval_ptr_dtor(&tmp); +#else + zval zv; + zend_object *tmp = ce->create_object(ce); + zend_call_method_with_0_params(tmp, ce, NULL, "__construct", &zv); + OBJ_RELEASE(tmp); #endif - return upb_strtable_lookup2(&reserved_names, name, strlen(name), &v); + zval_ptr_dtor(&zv); + ret = zend_hash_find_ptr(&PROTOBUF_G(name_msg_cache), ce->name); + } + + return ret; +} + +const upb_enumdef *NameMap_GetEnum(zend_class_entry *ce) { + const upb_enumdef *ret = + zend_hash_find_ptr(&PROTOBUF_G(name_enum_cache), ce->name); + return ret; } // ----------------------------------------------------------------------------- -// Utilities. +// Module init. // ----------------------------------------------------------------------------- zend_function_entry protobuf_functions[] = { @@ -308,292 +278,45 @@ static const zend_module_dep protobuf_deps[] = { ZEND_MOD_END }; +PHP_INI_BEGIN() +STD_PHP_INI_ENTRY("protobuf.keep_descriptor_pool_after_request", "0", + PHP_INI_SYSTEM, OnUpdateBool, + keep_descriptor_pool_after_request, zend_protobuf_globals, + protobuf_globals) +PHP_INI_END() + +static PHP_MINIT_FUNCTION(protobuf) { + REGISTER_INI_ENTRIES(); + Arena_ModuleInit(); + Array_ModuleInit(); + Convert_ModuleInit(); + Def_ModuleInit(); + Map_ModuleInit(); + Message_ModuleInit(); + return SUCCESS; +} + +static PHP_MSHUTDOWN_FUNCTION(protobuf) { + return SUCCESS; +} + zend_module_entry protobuf_module_entry = { STANDARD_MODULE_HEADER_EX, NULL, protobuf_deps, - PHP_PROTOBUF_EXTNAME, // extension name + "protobuf", // extension name protobuf_functions, // function list PHP_MINIT(protobuf), // process startup PHP_MSHUTDOWN(protobuf), // process shutdown PHP_RINIT(protobuf), // request shutdown PHP_RSHUTDOWN(protobuf), // request shutdown - NULL, // extension info - PHP_PROTOBUF_VERSION, // extension version + NULL, // extension info + PHP_PROTOBUF_VERSION, // extension version PHP_MODULE_GLOBALS(protobuf), // globals descriptor - PHP_GINIT(protobuf), // globals ctor + PHP_GINIT(protobuf), // globals ctor PHP_GSHUTDOWN(protobuf), // globals dtor - NULL, // post deactivate + NULL, // post deactivate STANDARD_MODULE_PROPERTIES_EX }; -// install module ZEND_GET_MODULE(protobuf) - -// global variables -static PHP_GINIT_FUNCTION(protobuf) { -} - -static PHP_GSHUTDOWN_FUNCTION(protobuf) { -} - -#if PHP_MAJOR_VERSION >= 7 -static void php_proto_hashtable_descriptor_release(zval* value) { - void* ptr = Z_PTR_P(value); - zend_object* object = *(zend_object**)ptr; - GC_DELREF(object); - if(GC_REFCOUNT(object) == 0) { - zend_objects_store_del(object); - } - efree(ptr); -} -#endif - -static void initialize_persistent_descriptor_pool(TSRMLS_D) { - upb_inttable_init(&upb_def_to_desc_map_persistent, UPB_CTYPE_PTR); - upb_inttable_init(&upb_def_to_enumdesc_map_persistent, UPB_CTYPE_PTR); - upb_strtable_init(&ce_to_desc_map_persistent, UPB_CTYPE_PTR); - upb_strtable_init(&ce_to_enumdesc_map_persistent, UPB_CTYPE_PTR); - upb_strtable_init(&proto_to_desc_map_persistent, UPB_CTYPE_PTR); - upb_strtable_init(&class_to_desc_map_persistent, UPB_CTYPE_PTR); - - internal_descriptor_pool_impl_init(&generated_pool_impl TSRMLS_CC); - - is_inited_file_any = false; - is_inited_file_api = false; - is_inited_file_duration = false; - is_inited_file_field_mask = false; - is_inited_file_empty = false; - is_inited_file_source_context = false; - is_inited_file_struct = false; - is_inited_file_timestamp = false; - is_inited_file_type = false; - is_inited_file_wrappers = false; -} - -static PHP_RINIT_FUNCTION(protobuf) { - ALLOC_HASHTABLE(upb_def_to_php_obj_map); - zend_hash_init(upb_def_to_php_obj_map, 16, NULL, HASHTABLE_VALUE_DTOR, 0); - - ALLOC_HASHTABLE(ce_to_php_obj_map); - zend_hash_init(ce_to_php_obj_map, 16, NULL, HASHTABLE_VALUE_DTOR, 0); - - generated_pool = NULL; - generated_pool_php = NULL; - internal_generated_pool_php = NULL; - - if (PROTOBUF_G(keep_descriptor_pool_after_request)) { - // Needs to clean up obsolete class entry - upb_strtable_iter i; - upb_value v; - - DescriptorInternal* desc; - for(upb_strtable_begin(&i, &ce_to_desc_map_persistent); - !upb_strtable_done(&i); - upb_strtable_next(&i)) { - v = upb_strtable_iter_value(&i); - desc = upb_value_getptr(v); - desc->klass = NULL; - } - - EnumDescriptorInternal* enumdesc; - for(upb_strtable_begin(&i, &ce_to_enumdesc_map_persistent); - !upb_strtable_done(&i); - upb_strtable_next(&i)) { - v = upb_strtable_iter_value(&i); - enumdesc = upb_value_getptr(v); - enumdesc->klass = NULL; - } - } else { - initialize_persistent_descriptor_pool(TSRMLS_C); - } - - return 0; -} - -static void cleanup_desc_table(upb_inttable* t) { - upb_inttable_iter i; - upb_value v; - DescriptorInternal* desc; - for(upb_inttable_begin(&i, t); - !upb_inttable_done(&i); - upb_inttable_next(&i)) { - v = upb_inttable_iter_value(&i); - desc = upb_value_getptr(v); - if (desc->layout) { - free_layout(desc->layout); - desc->layout = NULL; - } - free(desc->classname); - SYS_FREE(desc); - } -} - -static void cleanup_enumdesc_table(upb_inttable* t) { - upb_inttable_iter i; - upb_value v; - EnumDescriptorInternal* desc; - for(upb_inttable_begin(&i, t); - !upb_inttable_done(&i); - upb_inttable_next(&i)) { - v = upb_inttable_iter_value(&i); - desc = upb_value_getptr(v); - free(desc->classname); - SYS_FREE(desc); - } -} - -static void cleanup_persistent_descriptor_pool(TSRMLS_D) { - // Clean up - - // Only needs to clean one map out of three (def=>desc, ce=>desc, proto=>desc) - cleanup_desc_table(&upb_def_to_desc_map_persistent); - cleanup_enumdesc_table(&upb_def_to_enumdesc_map_persistent); - - internal_descriptor_pool_impl_destroy(&generated_pool_impl TSRMLS_CC); - - upb_inttable_uninit(&upb_def_to_desc_map_persistent); - upb_inttable_uninit(&upb_def_to_enumdesc_map_persistent); - upb_strtable_uninit(&ce_to_desc_map_persistent); - upb_strtable_uninit(&ce_to_enumdesc_map_persistent); - upb_strtable_uninit(&proto_to_desc_map_persistent); - upb_strtable_uninit(&class_to_desc_map_persistent); -} - -static PHP_RSHUTDOWN_FUNCTION(protobuf) { - zend_hash_destroy(upb_def_to_php_obj_map); - FREE_HASHTABLE(upb_def_to_php_obj_map); - - zend_hash_destroy(ce_to_php_obj_map); - FREE_HASHTABLE(ce_to_php_obj_map); - -#if PHP_MAJOR_VERSION < 7 - if (generated_pool_php != NULL) { - zval_dtor(generated_pool_php); - FREE_ZVAL(generated_pool_php); - } - if (internal_generated_pool_php != NULL) { - zval_dtor(internal_generated_pool_php); - FREE_ZVAL(internal_generated_pool_php); - } -#else - if (generated_pool_php != NULL) { - zval tmp; - ZVAL_OBJ(&tmp, generated_pool_php); - zval_dtor(&tmp); - } - if (internal_generated_pool_php != NULL) { - zval tmp; - ZVAL_OBJ(&tmp, internal_generated_pool_php); - zval_dtor(&tmp); - } -#endif - - if (!PROTOBUF_G(keep_descriptor_pool_after_request)) { - cleanup_persistent_descriptor_pool(TSRMLS_C); - } - - return 0; -} - -static void reserved_names_init() { - size_t i; - upb_value v = upb_value_bool(false); - for (i = 0; i < kReservedNamesSize; i++) { - upb_strtable_insert2(&reserved_names, kReservedNames[i], - strlen(kReservedNames[i]), v); - } -} - -PHP_INI_BEGIN() -STD_PHP_INI_ENTRY("protobuf.keep_descriptor_pool_after_request", "0", - PHP_INI_SYSTEM, OnUpdateBool, - keep_descriptor_pool_after_request, zend_protobuf_globals, - protobuf_globals) -PHP_INI_END() - -static PHP_MINIT_FUNCTION(protobuf) { - REGISTER_INI_ENTRIES(); - - upb_strtable_init(&reserved_names, UPB_CTYPE_UINT64); - reserved_names_init(); - - if (PROTOBUF_G(keep_descriptor_pool_after_request)) { - initialize_persistent_descriptor_pool(TSRMLS_C); - } - - descriptor_pool_init(TSRMLS_C); - descriptor_init(TSRMLS_C); - enum_descriptor_init(TSRMLS_C); - enum_value_descriptor_init(TSRMLS_C); - field_descriptor_init(TSRMLS_C); - gpb_type_init(TSRMLS_C); - internal_descriptor_pool_init(TSRMLS_C); - map_field_init(TSRMLS_C); - map_field_iter_init(TSRMLS_C); - message_init(TSRMLS_C); - oneof_descriptor_init(TSRMLS_C); - repeated_field_init(TSRMLS_C); - repeated_field_iter_init(TSRMLS_C); - util_init(TSRMLS_C); - - gpb_metadata_any_init(TSRMLS_C); - gpb_metadata_api_init(TSRMLS_C); - gpb_metadata_duration_init(TSRMLS_C); - gpb_metadata_field_mask_init(TSRMLS_C); - gpb_metadata_empty_init(TSRMLS_C); - gpb_metadata_source_context_init(TSRMLS_C); - gpb_metadata_struct_init(TSRMLS_C); - gpb_metadata_timestamp_init(TSRMLS_C); - gpb_metadata_type_init(TSRMLS_C); - gpb_metadata_wrappers_init(TSRMLS_C); - - any_init(TSRMLS_C); - api_init(TSRMLS_C); - bool_value_init(TSRMLS_C); - bytes_value_init(TSRMLS_C); - double_value_init(TSRMLS_C); - duration_init(TSRMLS_C); - enum_init(TSRMLS_C); - enum_value_init(TSRMLS_C); - field_cardinality_init(TSRMLS_C); - field_init(TSRMLS_C); - field_kind_init(TSRMLS_C); - field_mask_init(TSRMLS_C); - float_value_init(TSRMLS_C); - empty_init(TSRMLS_C); - int32_value_init(TSRMLS_C); - int64_value_init(TSRMLS_C); - list_value_init(TSRMLS_C); - method_init(TSRMLS_C); - mixin_init(TSRMLS_C); - null_value_init(TSRMLS_C); - option_init(TSRMLS_C); - source_context_init(TSRMLS_C); - string_value_init(TSRMLS_C); - struct_init(TSRMLS_C); - syntax_init(TSRMLS_C); - timestamp_init(TSRMLS_C); - type_init(TSRMLS_C); - u_int32_value_init(TSRMLS_C); - u_int64_value_init(TSRMLS_C); - value_init(TSRMLS_C); - - return 0; -} - -static PHP_MSHUTDOWN_FUNCTION(protobuf) { - if (PROTOBUF_G(keep_descriptor_pool_after_request)) { - cleanup_persistent_descriptor_pool(TSRMLS_C); - } - - upb_strtable_uninit(&reserved_names); - - PEFREE(message_handlers); - PEFREE(repeated_field_handlers); - PEFREE(repeated_field_iter_handlers); - PEFREE(map_field_handlers); - PEFREE(map_field_iter_handlers); - - return 0; -} diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 4e6d56a358a4..fe0b5a714772 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -28,1556 +28,90 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ -#define __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ +#ifndef PHP_PROTOBUF_H_ +#define PHP_PROTOBUF_H_ #include +#include -// ubp.h has to be placed after php.h. Othwise, php.h will introduce NDEBUG. -#include "upb.h" +#include "php-upb.h" -#define PHP_PROTOBUF_EXTNAME "protobuf" -#define PHP_PROTOBUF_VERSION "3.11.2" - -#define MAX_LENGTH_OF_INT64 20 -#define SIZEOF_INT64 8 - -/* From Chromium. */ -#define ARRAY_SIZE(x) \ - ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) - -#define PHP_PROTO_UNUSED(var) (void)var -/* PHP_PROTO_ASSERT(): in release mode, we use the expression without letting - * it be evaluated. This prevents "unused variable" warnings. */ -#ifdef NDEBUG -#define PHP_PROTO_ASSERT(expr) do {} while (false && (expr)) -#else -#define PHP_PROTO_ASSERT(expr) assert(expr) -#endif - -// ----------------------------------------------------------------------------- -// PHP7 Wrappers -// ---------------------------------------------------------------------------- +const zval *get_generated_pool(); #if PHP_VERSION_ID < 70300 #define GC_ADDREF(h) ++GC_REFCOUNT(h) #define GC_DELREF(h) --GC_REFCOUNT(h) #endif -#if PHP_MAJOR_VERSION < 7 - -#define php_proto_zend_literal const zend_literal* -#define PHP_PROTO_CASE_IS_BOOL IS_BOOL -#define PHP_PROTO_SIZE int -#define PHP_PROTO_LONG long -#define PHP_PROTO_TSRMLS_DC TSRMLS_DC -#define PHP_PROTO_TSRMLS_CC TSRMLS_CC - -// PHP String - -#define PHP_PROTO_ZVAL_STRING(zval_ptr, s, copy) \ - ZVAL_STRING(zval_ptr, s, copy) -#define PHP_PROTO_ZVAL_STRINGL(zval_ptr, s, len, copy) \ - ZVAL_STRINGL(zval_ptr, s, len, copy) -#define PHP_PROTO_RETURN_STRING(s, copy) RETURN_STRING(s, copy) -#define PHP_PROTO_RETURN_STRINGL(s, len, copy) RETURN_STRINGL(s, len, copy) -#define PHP_PROTO_RETVAL_STRINGL(s, len, copy) RETVAL_STRINGL(s, len, copy) -#define php_proto_zend_make_printable_zval(from, to) \ - { \ - int use_copy; \ - zend_make_printable_zval(from, to, &use_copy); \ - } - -// PHP Array - -#define PHP_PROTO_HASH_OF(array) Z_ARRVAL_P(array) - -#define php_proto_zend_hash_index_update_zval(ht, h, pData) \ - zend_hash_index_update(ht, h, &(pData), sizeof(void*), NULL) - -#define php_proto_zend_hash_update_zval(ht, key, key_len, value) \ - zend_hash_update(ht, key, key_len, value, sizeof(void*), NULL) - -#define php_proto_zend_hash_update(ht, key, key_len) \ - zend_hash_update(ht, key, key_len, 0, 0, NULL) - -#define php_proto_zend_hash_index_update_mem(ht, h, pData, nDataSize, pDest) \ - zend_hash_index_update(ht, h, pData, nDataSize, pDest) - -#define php_proto_zend_hash_update_mem(ht, key, key_len, pData, nDataSize, \ - pDest) \ - zend_hash_update(ht, key, key_len, pData, nDataSize, pDest) - -#define php_proto_zend_hash_index_find_zval(ht, h, pDest) \ - zend_hash_index_find(ht, h, pDest) - -#define php_proto_zend_hash_find(ht, key, key_len, pDest) \ - zend_hash_find(ht, key, key_len, pDest) - -#define php_proto_zend_hash_index_find_mem(ht, h, pDest) \ - zend_hash_index_find(ht, h, pDest) - -#define php_proto_zend_hash_find_zval(ht, key, key_len, pDest) \ - zend_hash_find(ht, key, key_len, pDest) - -#define php_proto_zend_hash_find_mem(ht, key, key_len, pDest) \ - zend_hash_find(ht, key, key_len, pDest) - -#define php_proto_zend_hash_next_index_insert_zval(ht, pData) \ - zend_hash_next_index_insert(ht, pData, sizeof(void*), NULL) - -#define php_proto_zend_hash_next_index_insert_mem(ht, pData, nDataSize, pDest) \ - zend_hash_next_index_insert(ht, pData, nDataSize, pDest) - -#define php_proto_zend_hash_get_current_data_ex(ht, pDest, pos) \ - zend_hash_get_current_data_ex(ht, pDest, pos) - -// PHP Object - -#define PHP_PROTO_WRAP_OBJECT_START(name) \ - struct name { \ - zend_object std; -#define PHP_PROTO_WRAP_OBJECT_END \ - }; - -#define PHP_PROTO_INIT_SUBMSGCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ - void LOWWERNAME##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ - LOWWERNAME##_methods); \ - LOWWERNAME##_type = zend_register_internal_class_ex( \ - &class_type, message_type, NULL TSRMLS_CC); \ - LOWWERNAME##_type->create_object = message_create; \ - zend_do_inheritance(LOWWERNAME##_type, message_type TSRMLS_CC); -#define PHP_PROTO_INIT_SUBMSGCLASS_END \ - } - -#define PHP_PROTO_INIT_ENUMCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ - void LOWWERNAME##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ - LOWWERNAME##_methods); \ - LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); -#define PHP_PROTO_INIT_ENUMCLASS_END \ - } - -#define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ - void LOWWERNAME##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ - LOWWERNAME##_methods); \ - LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \ - LOWWERNAME##_type->create_object = LOWWERNAME##_create; \ - LOWWERNAME##_handlers = PEMALLOC(zend_object_handlers, 1); \ - memcpy(LOWWERNAME##_handlers, zend_get_std_object_handlers(), \ - sizeof(zend_object_handlers)); -#define PHP_PROTO_INIT_CLASS_END \ - } - -#define PHP_PROTO_OBJECT_CREATE_START(NAME, LOWWERNAME) \ - static zend_object_value LOWWERNAME##_create( \ - zend_class_entry* ce TSRMLS_DC) { \ - PHP_PROTO_ALLOC_CLASS_OBJECT(NAME, ce); \ - zend_object_std_init(&intern->std, ce TSRMLS_CC); \ - object_properties_init(&intern->std, ce); -#define PHP_PROTO_OBJECT_CREATE_END(NAME, LOWWERNAME) \ - PHP_PROTO_FREE_CLASS_OBJECT(NAME, LOWWERNAME##_free, LOWWERNAME##_handlers); \ - } - -#define PHP_PROTO_OBJECT_EMPTY_FREE_START(classname, lowername) \ - void lowername##_free(void* object TSRMLS_DC) { \ - classname* intern = object; -#define PHP_PROTO_OBJECT_FREE_START(classname, lowername) \ - void lowername##_free(void* object TSRMLS_DC) { \ - classname* intern = object; -#define PHP_PROTO_OBJECT_FREE_END \ - zend_object_std_dtor(&intern->std TSRMLS_CC); \ - efree(intern); \ - } - -#define PHP_PROTO_OBJECT_EMPTY_DTOR_START(classname, lowername) -#define PHP_PROTO_OBJECT_DTOR_START(classname, lowername) -#define PHP_PROTO_OBJECT_DTOR_END - -#define CACHED_VALUE zval* -#define CACHED_TO_ZVAL_PTR(VALUE) (VALUE) -#define CACHED_PTR_TO_ZVAL_PTR(VALUE) (*(CACHED_VALUE*)(VALUE)) -#define ZVAL_PTR_TO_CACHED_PTR(VALUE) (&VALUE) -#define ZVAL_PTR_TO_CACHED_VALUE(VALUE) (VALUE) -#define ZVAL_TO_CACHED_VALUE(VALUE) (&VALUE) - -#define CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(zval_ptr, class_type) \ - ZVAL_OBJ(zval_ptr, class_type->create_object(class_type TSRMLS_CC)); - -#define PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(value) \ - SEPARATE_ZVAL_IF_NOT_REF(value) - -#define PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL EG(uninitialized_zval_ptr) - -#define OBJ_PROP(OBJECT, OFFSET) &((OBJECT)->properties_table[OFFSET]) - -#define php_proto_zval_ptr_dtor(zval_ptr) \ - zval_ptr_dtor(&(zval_ptr)) - -#define PHP_PROTO_ALLOC_CLASS_OBJECT(class_object, class_type) \ - class_object* intern; \ - intern = (class_object*)emalloc(sizeof(class_object)); \ - memset(intern, 0, sizeof(class_object)); - -#define PHP_PROTO_FREE_CLASS_OBJECT(class_object, class_object_free, handler) \ - zend_object_value retval = {0}; \ - retval.handle = zend_objects_store_put( \ - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \ - class_object_free, NULL TSRMLS_CC); \ - retval.handlers = handler; \ - return retval; - -#define PHP_PROTO_ALLOC_ARRAY(zval_ptr) \ - ALLOC_HASHTABLE(Z_ARRVAL_P(zval_ptr)); \ - Z_TYPE_P(zval_ptr) = IS_ARRAY; - -#define ZVAL_OBJ(zval_ptr, call_create) \ - Z_TYPE_P(zval_ptr) = IS_OBJECT; \ - Z_OBJVAL_P(zval_ptr) = call_create; - -#define UNBOX(class_name, val) \ - (class_name*)zend_object_store_get_object(val TSRMLS_CC); - -#define UNBOX_HASHTABLE_VALUE(class_name, val) UNBOX(class_name, val) - -#define HASHTABLE_VALUE_DTOR ZVAL_PTR_DTOR - -#define PHP_PROTO_HASHTABLE_VALUE zval* -#define HASHTABLE_VALUE_CE(val) Z_OBJCE_P(val) - -#define CREATE_HASHTABLE_VALUE(OBJ, WRAPPED_OBJ, OBJ_TYPE, OBJ_CLASS_ENTRY) \ - OBJ_TYPE* OBJ; \ - PHP_PROTO_HASHTABLE_VALUE WRAPPED_OBJ; \ - MAKE_STD_ZVAL(WRAPPED_OBJ); \ - ZVAL_OBJ(WRAPPED_OBJ, \ - OBJ_CLASS_ENTRY->create_object(OBJ_CLASS_ENTRY TSRMLS_CC)); \ - OBJ = UNBOX_HASHTABLE_VALUE(OBJ_TYPE, WRAPPED_OBJ); \ - Z_DELREF_P(desc_php); - -#define PHP_PROTO_CE_DECLARE zend_class_entry** -#define PHP_PROTO_CE_UNREF(ce) (*ce) - -#define php_proto_zend_lookup_class(name, name_length, ce) \ - zend_lookup_class(name, name_length, ce TSRMLS_CC) - -#define PHP_PROTO_RETVAL_ZVAL(value) ZVAL_ZVAL(return_value, value, 1, 0) - -#else // PHP_MAJOR_VERSION >= 7 - -#define php_proto_zend_literal void** -#define PHP_PROTO_CASE_IS_BOOL IS_TRUE: case IS_FALSE -#define PHP_PROTO_SIZE size_t -#define PHP_PROTO_LONG zend_long -#define PHP_PROTO_TSRMLS_DC -#define PHP_PROTO_TSRMLS_CC - -// PHP String - -#define PHP_PROTO_ZVAL_STRING(zval_ptr, s, copy) \ - ZVAL_STRING(zval_ptr, s) -#define PHP_PROTO_ZVAL_STRINGL(zval_ptr, s, len, copy) \ - ZVAL_STRINGL(zval_ptr, s, len) -#define PHP_PROTO_RETURN_STRING(s, copy) RETURN_STRING(s) -#define PHP_PROTO_RETURN_STRINGL(s, len, copy) RETURN_STRINGL(s, len) -#define PHP_PROTO_RETVAL_STRINGL(s, len, copy) RETVAL_STRINGL(s, len) -#define php_proto_zend_make_printable_zval(from, to) \ - zend_make_printable_zval(from, to) - -// PHP Array - -#define PHP_PROTO_HASH_OF(array) Z_ARRVAL_P(&array) - -static inline int php_proto_zend_hash_index_update_zval(HashTable* ht, ulong h, - zval* pData) { - void* result = NULL; - result = zend_hash_index_update(ht, h, pData); - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_update(HashTable* ht, const char* key, - size_t key_len) { - void* result = NULL; - zval temp; - ZVAL_LONG(&temp, 0); - result = zend_hash_str_update(ht, key, key_len, &temp); - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_index_update_mem(HashTable* ht, ulong h, - void* pData, uint nDataSize, - void** pDest) { - void* result = NULL; - result = zend_hash_index_update_mem(ht, h, pData, nDataSize); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_update_zval(HashTable* ht, - const char* key, uint key_len, - zval* pData) { - void* result = NULL; - zend_string* internal_key = zend_string_init(key, key_len, 0); - result = zend_hash_update(ht, internal_key, pData); - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_update_mem(HashTable* ht, const char* key, - uint key_len, void* pData, - uint nDataSize, void** pDest) { - zend_string* internal_key = zend_string_init(key, key_len, 0); - void* result = zend_hash_update_mem(ht, internal_key, pData, nDataSize); - zend_string_release(internal_key); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_index_find_zval(const HashTable* ht, - ulong h, void** pDest) { - zval* result = zend_hash_index_find(ht, h); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_find(const HashTable* ht, const char* key, - size_t key_len, void** pDest) { - void* result = NULL; - result = zend_hash_str_find(ht, key, key_len); - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_index_find_mem(const HashTable* ht, - ulong h, void** pDest) { - void* result = NULL; - result = zend_hash_index_find_ptr(ht, h); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_find_zval(const HashTable* ht, - const char* key, uint key_len, - void** pDest) { - zend_string* internal_key = zend_string_init(key, key_len, 1); - zval* result = zend_hash_find(ht, internal_key); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_find_mem(const HashTable* ht, - const char* key, uint key_len, - void** pDest) { - zend_string* internal_key = zend_string_init(key, key_len, 1); - void* result = zend_hash_find_ptr(ht, internal_key); - zend_string_release(internal_key); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_next_index_insert_zval(HashTable* ht, - void* pData) { - zval tmp; - ZVAL_OBJ(&tmp, *(zend_object**)pData); - zval* result = zend_hash_next_index_insert(ht, &tmp); - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_next_index_insert_mem(HashTable* ht, - void* pData, - uint nDataSize, - void** pDest) { - void* result = NULL; - result = zend_hash_next_index_insert_mem(ht, pData, nDataSize); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht, - void** pDest, - HashPosition* pos) { - void* result = NULL; - result = zend_hash_get_current_data_ex(ht, pos); - if (pDest != NULL) *pDest = result; - return result != NULL ? SUCCESS : FAILURE; -} - -// PHP Object - -#define PHP_PROTO_WRAP_OBJECT_START(name) struct name { -#define PHP_PROTO_WRAP_OBJECT_END \ - zend_object std; \ - }; - -#define PHP_PROTO_INIT_SUBMSGCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ - void LOWWERNAME##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ - LOWWERNAME##_methods); \ - LOWWERNAME##_type = zend_register_internal_class(&class_type); \ - zend_do_inheritance(LOWWERNAME##_type, message_type); -#define PHP_PROTO_INIT_SUBMSGCLASS_END \ - } - -#define PHP_PROTO_INIT_ENUMCLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ - void LOWWERNAME##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ - LOWWERNAME##_methods); \ - LOWWERNAME##_type = zend_register_internal_class(&class_type); -#define PHP_PROTO_INIT_ENUMCLASS_END \ - } - -#define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ - void LOWWERNAME##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ - LOWWERNAME##_methods); \ - LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \ - LOWWERNAME##_type->create_object = LOWWERNAME##_create; \ - LOWWERNAME##_handlers = PEMALLOC(zend_object_handlers, 1); \ - memcpy(LOWWERNAME##_handlers, zend_get_std_object_handlers(), \ - sizeof(zend_object_handlers)); \ - LOWWERNAME##_handlers->free_obj = LOWWERNAME##_free; \ - LOWWERNAME##_handlers->dtor_obj = LOWWERNAME##_dtor; \ - LOWWERNAME##_handlers->offset = XtOffsetOf(CAMELNAME, std); -#define PHP_PROTO_INIT_CLASS_END \ - } - -#define PHP_PROTO_OBJECT_EMPTY_FREE_START(classname, lowername) \ - void lowername##_free(zend_object* object) { -#define PHP_PROTO_OBJECT_FREE_START(classname, lowername) \ - void lowername##_free(zend_object* object) { \ - classname* intern = \ - (classname*)((char*)object - XtOffsetOf(classname, std)); -#define PHP_PROTO_OBJECT_FREE_END \ - } - -#define PHP_PROTO_OBJECT_EMPTY_DTOR_START(classname, lowername) \ - void lowername##_dtor(zend_object* object) { -#define PHP_PROTO_OBJECT_DTOR_START(classname, lowername) \ - void lowername##_dtor(zend_object* object) { \ - classname* intern = \ - (classname*)((char*)object - XtOffsetOf(classname, std)); -#define PHP_PROTO_OBJECT_DTOR_END \ - zend_object_std_dtor(object TSRMLS_CC); \ - } - -#define PHP_PROTO_OBJECT_CREATE_START(NAME, LOWWERNAME) \ - static zend_object* LOWWERNAME##_create(zend_class_entry* ce TSRMLS_DC) { \ - PHP_PROTO_ALLOC_CLASS_OBJECT(NAME, ce); \ - zend_object_std_init(&intern->std, ce TSRMLS_CC); \ - object_properties_init(&intern->std, ce); -#define PHP_PROTO_OBJECT_CREATE_END(NAME, LOWWERNAME) \ - PHP_PROTO_FREE_CLASS_OBJECT(NAME, LOWWERNAME##_free, LOWWERNAME##_handlers); \ - } - -#define CACHED_VALUE zval -#define CACHED_TO_ZVAL_PTR(VALUE) (&VALUE) -#define CACHED_PTR_TO_ZVAL_PTR(VALUE) ((CACHED_VALUE*)(VALUE)) -#define ZVAL_PTR_TO_CACHED_PTR(VALUE) (VALUE) -#define ZVAL_PTR_TO_CACHED_VALUE(VALUE) (*VALUE) -#define ZVAL_TO_CACHED_VALUE(VALUE) (VALUE) - -#define CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(zval_ptr, class_type) \ - ZVAL_OBJ(zval_ptr, class_type->create_object(class_type)); - -#define PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(value) ; - -#define PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL &EG(uninitialized_zval) - -#define php_proto_zval_ptr_dtor(zval_ptr) \ - zval_ptr_dtor(zval_ptr) - -#define PHP_PROTO_ALLOC_CLASS_OBJECT(class_object, class_type) \ - class_object* intern; \ - int size = sizeof(class_object) + zend_object_properties_size(class_type); \ - intern = ecalloc(1, size); \ - memset(intern, 0, size); - -#define PHP_PROTO_FREE_CLASS_OBJECT(class_object, class_object_free, handler) \ - intern->std.handlers = handler; \ - return &intern->std; - -#define PHP_PROTO_ALLOC_ARRAY(zval_ptr) \ - ZVAL_NEW_ARR(zval_ptr) - -#define UNBOX(class_name, val) \ - (class_name*)((char*)Z_OBJ_P(val) - XtOffsetOf(class_name, std)); - -#define UNBOX_HASHTABLE_VALUE(class_name, val) \ - (class_name*)((char*)val - XtOffsetOf(class_name, std)) - -#define HASHTABLE_VALUE_DTOR php_proto_hashtable_descriptor_release - -#define PHP_PROTO_HASHTABLE_VALUE zend_object* -#define HASHTABLE_VALUE_CE(val) val->ce - -#define CREATE_HASHTABLE_VALUE(OBJ, WRAPPED_OBJ, OBJ_TYPE, OBJ_CLASS_ENTRY) \ - OBJ_TYPE* OBJ; \ - PHP_PROTO_HASHTABLE_VALUE WRAPPED_OBJ; \ - WRAPPED_OBJ = OBJ_CLASS_ENTRY->create_object(OBJ_CLASS_ENTRY); \ - OBJ = UNBOX_HASHTABLE_VALUE(OBJ_TYPE, WRAPPED_OBJ); \ - GC_DELREF(WRAPPED_OBJ); - -#define PHP_PROTO_CE_DECLARE zend_class_entry* -#define PHP_PROTO_CE_UNREF(ce) (ce) - -static inline int php_proto_zend_lookup_class( - const char* name, int name_length, zend_class_entry** ce TSRMLS_DC) { - zend_string *zstr_name = zend_string_init(name, name_length, 0); - *ce = zend_lookup_class(zstr_name); - zend_string_release(zstr_name); - return *ce != NULL ? SUCCESS : FAILURE; -} - -#define PHP_PROTO_RETVAL_ZVAL(value) ZVAL_COPY(return_value, value) - -#endif // PHP_MAJOR_VERSION >= 7 - -#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0) -#define PHP_PROTO_FAKE_SCOPE_BEGIN(klass) \ - zend_class_entry* old_scope = EG(scope); \ - EG(scope) = klass; -#define PHP_PROTO_FAKE_SCOPE_RESTART(klass) \ - old_scope = EG(scope); \ - EG(scope) = klass; -#define PHP_PROTO_FAKE_SCOPE_END EG(scope) = old_scope; -#else -#define PHP_PROTO_FAKE_SCOPE_BEGIN(klass) \ - zend_class_entry* old_scope = EG(fake_scope); \ - EG(fake_scope) = klass; -#define PHP_PROTO_FAKE_SCOPE_RESTART(klass) \ - old_scope = EG(fake_scope); \ - EG(fake_scope) = klass; -#define PHP_PROTO_FAKE_SCOPE_END EG(fake_scope) = old_scope; -#endif - -// Define PHP class -#define DEFINE_PROTOBUF_INIT_CLASS(CLASSNAME, CAMELNAME, LOWERNAME) \ - PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWERNAME) \ - PHP_PROTO_INIT_CLASS_END - -#define DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \ - PHP_PROTO_OBJECT_CREATE_START(NAME, LOWERNAME) \ - LOWERNAME##_init_c_instance(intern TSRMLS_CC); \ - PHP_PROTO_OBJECT_CREATE_END(NAME, LOWERNAME) - -#define DEFINE_PROTOBUF_FREE(CAMELNAME, LOWERNAME) \ - PHP_PROTO_OBJECT_FREE_START(CAMELNAME, LOWERNAME) \ - LOWERNAME##_free_c(intern TSRMLS_CC); \ - PHP_PROTO_OBJECT_FREE_END - -#define DEFINE_PROTOBUF_DTOR(CAMELNAME, LOWERNAME) \ - PHP_PROTO_OBJECT_EMPTY_DTOR_START(CAMELNAME, LOWERNAME) \ - PHP_PROTO_OBJECT_DTOR_END - -#define DEFINE_CLASS(NAME, LOWERNAME, string_name) \ - zend_class_entry *LOWERNAME##_type; \ - zend_object_handlers *LOWERNAME##_handlers; \ - DEFINE_PROTOBUF_FREE(NAME, LOWERNAME) \ - DEFINE_PROTOBUF_DTOR(NAME, LOWERNAME) \ - DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \ - DEFINE_PROTOBUF_INIT_CLASS(string_name, NAME, LOWERNAME) - -// ----------------------------------------------------------------------------- -// Forward Declaration -// ---------------------------------------------------------------------------- - -struct Any; -struct Api; -struct BoolValue; -struct BytesValue; -struct Descriptor; -struct DescriptorInternal; -struct DescriptorPool; -struct DoubleValue; -struct Duration; -struct Enum; -struct EnumDescriptor; -struct EnumDescriptorInternal; -struct EnumValue; -struct EnumValueDescriptor; -struct Field; -struct FieldDescriptor; -struct FieldMask; -struct Field_Cardinality; -struct Field_Kind; -struct FloatValue; -struct GPBEmpty; -struct Int32Value; -struct Int64Value; -struct InternalDescriptorPool; -struct InternalDescriptorPoolImpl; -struct ListValue; -struct Map; -struct MapIter; -struct MessageField; -struct MessageHeader; -struct MessageLayout; -struct Method; -struct Mixin; -struct NullValue; -struct Oneof; -struct Option; -struct RepeatedField; -struct RepeatedFieldIter; -struct SourceContext; -struct StringValue; -struct Struct; -struct Syntax; -struct Timestamp; -struct Type; -struct UInt32Value; -struct UInt64Value; -struct Value; - -typedef struct Any Any; -typedef struct Api Api; -typedef struct BoolValue BoolValue; -typedef struct BytesValue BytesValue; -typedef struct Descriptor Descriptor; -typedef struct DescriptorInternal DescriptorInternal; -typedef struct DescriptorPool DescriptorPool; -typedef struct DoubleValue DoubleValue; -typedef struct Duration Duration; -typedef struct EnumDescriptor EnumDescriptor; -typedef struct EnumDescriptorInternal EnumDescriptorInternal; -typedef struct Enum Enum; -typedef struct EnumValueDescriptor EnumValueDescriptor; -typedef struct EnumValue EnumValue; -typedef struct Field_Cardinality Field_Cardinality; -typedef struct FieldDescriptor FieldDescriptor; -typedef struct Field Field; -typedef struct Field_Kind Field_Kind; -typedef struct FieldMask FieldMask; -typedef struct FloatValue FloatValue; -typedef struct GPBEmpty GPBEmpty; -typedef struct Int32Value Int32Value; -typedef struct Int64Value Int64Value; -typedef struct InternalDescriptorPool InternalDescriptorPool; -typedef struct InternalDescriptorPoolImpl InternalDescriptorPoolImpl; -typedef struct ListValue ListValue; -typedef struct MapIter MapIter; -typedef struct Map Map; -typedef struct MessageField MessageField; -typedef struct MessageHeader MessageHeader; -typedef struct MessageLayout MessageLayout; -typedef struct Method Method; -typedef struct Mixin Mixin; -typedef struct NullValue NullValue; -typedef struct Oneof Oneof; -typedef struct Option Option; -typedef struct RepeatedFieldIter RepeatedFieldIter; -typedef struct RepeatedField RepeatedField; -typedef struct SourceContext SourceContext; -typedef struct StringValue StringValue; -typedef struct Struct Struct; -typedef struct Syntax Syntax; -typedef struct Timestamp Timestamp; -typedef struct Type Type; -typedef struct UInt32Value UInt32Value; -typedef struct UInt64Value UInt64Value; -typedef struct Value Value; - -// ----------------------------------------------------------------------------- -// Globals. -// ----------------------------------------------------------------------------- - -ZEND_BEGIN_MODULE_GLOBALS(protobuf) - zend_bool keep_descriptor_pool_after_request; -ZEND_END_MODULE_GLOBALS(protobuf) - -ZEND_EXTERN_MODULE_GLOBALS(protobuf) - -#ifdef ZTS -#define PROTOBUF_G(v) TSRMG(protobuf_globals_id, zend_protobuf_globals *, v) -#else -#define PROTOBUF_G(v) (protobuf_globals.v) -#endif - -// Init module and PHP classes. -void any_init(TSRMLS_D); -void api_init(TSRMLS_D); -void bool_value_init(TSRMLS_D); -void bytes_value_init(TSRMLS_D); -void descriptor_init(TSRMLS_D); -void descriptor_pool_init(TSRMLS_D); -void double_value_init(TSRMLS_D); -void duration_init(TSRMLS_D); -void empty_init(TSRMLS_D); -void enum_descriptor_init(TSRMLS_D); -void enum_value_descriptor_init(TSRMLS_D); -void enum_init(TSRMLS_D); -void enum_value_init(TSRMLS_D); -void field_cardinality_init(TSRMLS_D); -void field_descriptor_init(TSRMLS_D); -void field_init(TSRMLS_D); -void field_kind_init(TSRMLS_D); -void field_mask_init(TSRMLS_D); -void float_value_init(TSRMLS_D); -void gpb_type_init(TSRMLS_D); -void int32_value_init(TSRMLS_D); -void int64_value_init(TSRMLS_D); -void internal_descriptor_pool_init(TSRMLS_D); -void list_value_init(TSRMLS_D); -void map_field_init(TSRMLS_D); -void map_field_iter_init(TSRMLS_D); -void message_init(TSRMLS_D); -void method_init(TSRMLS_D); -void mixin_init(TSRMLS_D); -void null_value_init(TSRMLS_D); -void oneof_descriptor_init(TSRMLS_D); -void option_init(TSRMLS_D); -void repeated_field_init(TSRMLS_D); -void repeated_field_iter_init(TSRMLS_D); -void source_context_init(TSRMLS_D); -void string_value_init(TSRMLS_D); -void struct_init(TSRMLS_D); -void syntax_init(TSRMLS_D); -void timestamp_init(TSRMLS_D); -void type_init(TSRMLS_D); -void u_int32_value_init(TSRMLS_D); -void u_int64_value_init(TSRMLS_D); -void util_init(TSRMLS_D); -void value_init(TSRMLS_D); - -void gpb_metadata_any_init(TSRMLS_D); -void gpb_metadata_api_init(TSRMLS_D); -void gpb_metadata_duration_init(TSRMLS_D); -void gpb_metadata_field_mask_init(TSRMLS_D); -void gpb_metadata_empty_init(TSRMLS_D); -void gpb_metadata_source_context_init(TSRMLS_D); -void gpb_metadata_struct_init(TSRMLS_D); -void gpb_metadata_timestamp_init(TSRMLS_D); -void gpb_metadata_type_init(TSRMLS_D); -void gpb_metadata_wrappers_init(TSRMLS_D); - -// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor -// instances. -void add_def_obj(const void* def, PHP_PROTO_HASHTABLE_VALUE value); -PHP_PROTO_HASHTABLE_VALUE get_def_obj(const void* def); -void add_msgdef_desc(const upb_msgdef* m, DescriptorInternal* desc); -DescriptorInternal* get_msgdef_desc(const upb_msgdef* m); -void add_enumdef_enumdesc(const upb_enumdef* e, EnumDescriptorInternal* desc); -EnumDescriptorInternal* get_enumdef_enumdesc(const upb_enumdef* e); - -// Global map from PHP class entries to wrapper Descriptor/EnumDescriptor -// instances. -void add_ce_obj(const void* ce, PHP_PROTO_HASHTABLE_VALUE value); -PHP_PROTO_HASHTABLE_VALUE get_ce_obj(const void* ce); -bool class_added(const void* ce); -void add_ce_desc(const zend_class_entry* ce, DescriptorInternal* desc); -DescriptorInternal* get_ce_desc(const zend_class_entry* ce); -void add_ce_enumdesc(const zend_class_entry* ce, EnumDescriptorInternal* desc); -EnumDescriptorInternal* get_ce_enumdesc(const zend_class_entry* ce); - -// Global map from message/enum's proto fully-qualified name to corresponding -// wrapper Descriptor/EnumDescriptor instances. -void add_proto_desc(const char* proto, DescriptorInternal* desc); -DescriptorInternal* get_proto_desc(const char* proto); -void add_class_desc(const char* klass, DescriptorInternal* desc); -DescriptorInternal* get_class_desc(const char* klass); -void add_class_enumdesc(const char* klass, EnumDescriptorInternal* desc); -EnumDescriptorInternal* get_class_enumdesc(const char* klass); - -extern zend_class_entry* map_field_type; -extern zend_class_entry* repeated_field_type; - -// ----------------------------------------------------------------------------- -// Descriptor. -// ----------------------------------------------------------------------------- - -PHP_PROTO_WRAP_OBJECT_START(DescriptorPool) - InternalDescriptorPoolImpl* intern; -PHP_PROTO_WRAP_OBJECT_END - -PHP_METHOD(DescriptorPool, getGeneratedPool); -PHP_METHOD(DescriptorPool, getDescriptorByClassName); -PHP_METHOD(DescriptorPool, getEnumDescriptorByClassName); - -struct InternalDescriptorPoolImpl { - upb_symtab* symtab; - upb_handlercache* fill_handler_cache; - upb_handlercache* pb_serialize_handler_cache; - upb_handlercache* json_serialize_handler_cache; - upb_handlercache* json_serialize_handler_preserve_cache; - upb_pbcodecache* fill_method_cache; - upb_json_codecache* json_fill_method_cache; -}; - -PHP_PROTO_WRAP_OBJECT_START(InternalDescriptorPool) - InternalDescriptorPoolImpl* intern; -PHP_PROTO_WRAP_OBJECT_END - -PHP_METHOD(InternalDescriptorPool, getGeneratedPool); -PHP_METHOD(InternalDescriptorPool, internalAddGeneratedFile); - -void internal_add_generated_file(const char* data, PHP_PROTO_SIZE data_len, - InternalDescriptorPoolImpl* pool, - bool use_nested_submsg TSRMLS_DC); -void init_generated_pool_once(TSRMLS_D); -void add_handlers_for_message(const void* closure, upb_handlers* h); -void register_class(void *desc, bool is_enum TSRMLS_DC); - -// wrapper of generated pool -#if PHP_MAJOR_VERSION < 7 -extern zval* generated_pool_php; -extern zval* internal_generated_pool_php; -void descriptor_pool_free(void* object TSRMLS_DC); -void internal_descriptor_pool_free(void* object TSRMLS_DC); +// Since php 7.4, the write_property() object handler now returns the assigned +// value (after possible type coercions) rather than void. +// https://github.com/php/php-src/blob/PHP-7.4.0/UPGRADING.INTERNALS#L171-L173 +#if PHP_VERSION_ID < 70400 +#define PROTO_RETURN_VAL void #else -extern zend_object *generated_pool_php; -extern zend_object *internal_generated_pool_php; -void descriptor_pool_free(zend_object* object); -void internal_descriptor_pool_free(zend_object* object); +#define PROTO_RETURN_VAL zval* #endif -extern InternalDescriptorPoolImpl* generated_pool; -// The actual generated pool -extern InternalDescriptorPoolImpl generated_pool_impl; - -void internal_descriptor_pool_impl_init( - InternalDescriptorPoolImpl *pool TSRMLS_DC); -void internal_descriptor_pool_impl_destroy( - InternalDescriptorPoolImpl *pool TSRMLS_DC); - -struct DescriptorInternal { - InternalDescriptorPoolImpl* pool; - const upb_msgdef* msgdef; - MessageLayout* layout; - zend_class_entry* klass; // begins as NULL - bool use_nested_submsg; - char* classname; -}; - -PHP_PROTO_WRAP_OBJECT_START(Descriptor) - DescriptorInternal* intern; -PHP_PROTO_WRAP_OBJECT_END - -PHP_METHOD(Descriptor, getClass); -PHP_METHOD(Descriptor, getFullName); -PHP_METHOD(Descriptor, getField); -PHP_METHOD(Descriptor, getFieldCount); -PHP_METHOD(Descriptor, getOneofDecl); -PHP_METHOD(Descriptor, getOneofDeclCount); - -extern zend_class_entry* descriptor_type; - -void descriptor_name_set(Descriptor *desc, const char *name); - -PHP_PROTO_WRAP_OBJECT_START(FieldDescriptor) - const upb_fielddef* fielddef; -PHP_PROTO_WRAP_OBJECT_END - -PHP_METHOD(FieldDescriptor, getName); -PHP_METHOD(FieldDescriptor, getNumber); -PHP_METHOD(FieldDescriptor, getLabel); -PHP_METHOD(FieldDescriptor, getType); -PHP_METHOD(FieldDescriptor, isMap); -PHP_METHOD(FieldDescriptor, getEnumType); -PHP_METHOD(FieldDescriptor, getMessageType); - -extern zend_class_entry* field_descriptor_type; - -struct EnumDescriptorInternal { - const upb_enumdef* enumdef; - zend_class_entry* klass; // begins as NULL - bool use_nested_submsg; - char* classname; -}; - -PHP_PROTO_WRAP_OBJECT_START(EnumDescriptor) - EnumDescriptorInternal* intern; -PHP_PROTO_WRAP_OBJECT_END - -PHP_METHOD(EnumDescriptor, getValue); -PHP_METHOD(EnumDescriptor, getValueCount); - -extern zend_class_entry* enum_descriptor_type; - -PHP_PROTO_WRAP_OBJECT_START(EnumValueDescriptor) - const char* name; - int32_t number; -PHP_PROTO_WRAP_OBJECT_END - -PHP_METHOD(EnumValueDescriptor, getName); -PHP_METHOD(EnumValueDescriptor, getNumber); - -extern zend_class_entry* enum_value_descriptor_type; - -// ----------------------------------------------------------------------------- -// Message class creation. -// ----------------------------------------------------------------------------- - -void* message_data(MessageHeader* msg); -void custom_data_init(const zend_class_entry* ce, - MessageHeader* msg PHP_PROTO_TSRMLS_DC); - -extern zend_class_entry* message_type; -extern zend_object_handlers* message_handlers; - -// ----------------------------------------------------------------------------- -// Message layout / storage. -// ----------------------------------------------------------------------------- - -/* - * In c extension, each protobuf message is a zval instance. The zval instance - * is like union, which can be used to store int, string, zend_object_value and - * etc. For protobuf message, the zval instance is used to store the - * zend_object_value. - * - * The zend_object_value is composed of handlers and a handle to look up the - * actual stored data. The handlers are pointers to functions, e.g., read, - * write, and etc, to access properties. - * - * The actual data of protobuf messages is stored as MessageHeader in zend - * engine's central repository. Each MessageHeader instance is composed of a - * zend_object, a Descriptor instance and the real message data. - * - * For the reason that PHP's native types may not be large enough to store - * protobuf message's field (e.g., int64), all message's data is stored in - * custom memory layout and is indexed by the Descriptor instance. - * - * The zend_object contains the zend class entry and the properties table. The - * zend class entry contains all information about protobuf message's - * corresponding PHP class. The most useful information is the offset table of - * properties. Because read access to properties requires returning zval - * instance, we need to convert data from the custom layout to zval instance. - * Instead of creating zval instance for every read access, we use the zval - * instances in the properties table in the zend_object as cache. When - * accessing properties, the offset is needed to find the zval property in - * zend_object's properties table. These properties will be updated using the - * data from custom memory layout only when reading these properties. - * - * zval - * |-zend_object_value obj - * |-zend_object_handlers* handlers -> |-read_property_handler - * | |-write_property_handler - * | ++++++++++++++++++++++ - * |-zend_object_handle handle -> + central repository + - * ++++++++++++++++++++++ - * MessageHeader <-----------------| - * |-zend_object std - * | |-class_entry* ce -> class_entry - * | | |-HashTable properties_table (name->offset) - * | |-zval** properties_table <------------------------------| - * | |------> zval* property(cache) - * |-Descriptor* desc (name->offset) - * |-void** data <-----------| - * |-----------------------> void* property(data) - * - */ - -#define MESSAGE_FIELD_NO_CASE ((size_t)-1) - -struct MessageField { - size_t offset; - int cache_index; // Each field except oneof field has a zval cache to avoid - // multiple creation when being accessed. - size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE. -}; - -struct MessageLayout { - const upb_msgdef* msgdef; - void* empty_template; // Can memcpy() onto a layout to clear it. - MessageField* fields; - size_t size; -}; - -PHP_PROTO_WRAP_OBJECT_START(MessageHeader) - void* data; // Point to the real message data. - // Place needs to be consistent with map_parse_frame_data_t. - DescriptorInternal* descriptor; // Kept alive by self.class.descriptor - // reference. -PHP_PROTO_WRAP_OBJECT_END - -MessageLayout* create_layout(const upb_msgdef* msgdef); -void layout_init(MessageLayout* layout, void* storage, - zend_object* object PHP_PROTO_TSRMLS_DC); -zval* layout_get(MessageLayout* layout, MessageHeader* header, - const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC); -void layout_set(MessageLayout* layout, MessageHeader* header, - const upb_fielddef* field, zval* val TSRMLS_DC); -void layout_merge(MessageLayout* layout, MessageHeader* from, - MessageHeader* to TSRMLS_DC); -const char* layout_get_oneof_case(MessageLayout* layout, const void* storage, - const upb_oneofdef* oneof TSRMLS_DC); -void free_layout(MessageLayout* layout); -uint32_t* slot_oneof_case(MessageLayout* layout, const void* storage, - const upb_fielddef* field); -void* slot_memory(MessageLayout* layout, const void* storage, - const upb_fielddef* field); - -PHP_METHOD(Message, clear); -PHP_METHOD(Message, mergeFrom); -PHP_METHOD(Message, readWrapperValue); -PHP_METHOD(Message, writeWrapperValue); -PHP_METHOD(Message, readOneof); -PHP_METHOD(Message, writeOneof); -PHP_METHOD(Message, whichOneof); -PHP_METHOD(Message, __construct); - -// ----------------------------------------------------------------------------- -// Encode / Decode. -// ----------------------------------------------------------------------------- - -// Maximum depth allowed during encoding, to avoid stack overflows due to -// cycles. -#define ENCODE_MAX_NESTING 63 - -// Constructs the upb decoder method for parsing messages of this type. -// This is called from the message class creation code. -const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor *desc, - const void *owner); -void serialize_to_string(zval* val, zval* return_value TSRMLS_DC); -void merge_from_string(const char* data, int data_len, DescriptorInternal* desc, - MessageHeader* msg); - -PHP_METHOD(Message, serializeToString); -PHP_METHOD(Message, mergeFromString); -PHP_METHOD(Message, serializeToJsonString); -PHP_METHOD(Message, mergeFromJsonString); -PHP_METHOD(Message, discardUnknownFields); - -// ----------------------------------------------------------------------------- -// Type check / conversion. -// ----------------------------------------------------------------------------- - -bool protobuf_convert_to_int32(zval* from, int32_t* to); -bool protobuf_convert_to_uint32(zval* from, uint32_t* to); -bool protobuf_convert_to_int64(zval* from, int64_t* to); -bool protobuf_convert_to_uint64(zval* from, uint64_t* to); -bool protobuf_convert_to_float(zval* from, float* to); -bool protobuf_convert_to_double(zval* from, double* to); -bool protobuf_convert_to_bool(zval* from, int8_t* to); -bool protobuf_convert_to_string(zval* from); - -void check_repeated_field(const zend_class_entry* klass, PHP_PROTO_LONG type, - zval* val, zval* return_value); -void check_map_field(const zend_class_entry* klass, PHP_PROTO_LONG key_type, - PHP_PROTO_LONG value_type, zval* val, zval* return_value); - -PHP_METHOD(Util, checkInt32); -PHP_METHOD(Util, checkUint32); -PHP_METHOD(Util, checkInt64); -PHP_METHOD(Util, checkUint64); -PHP_METHOD(Util, checkEnum); -PHP_METHOD(Util, checkFloat); -PHP_METHOD(Util, checkDouble); -PHP_METHOD(Util, checkBool); -PHP_METHOD(Util, checkString); -PHP_METHOD(Util, checkBytes); -PHP_METHOD(Util, checkMessage); -PHP_METHOD(Util, checkMapField); -PHP_METHOD(Util, checkRepeatedField); - -// ----------------------------------------------------------------------------- -// Native slot storage abstraction. -// ----------------------------------------------------------------------------- - -#define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t) - -size_t native_slot_size(upb_fieldtype_t type); -bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, - void* memory, zval* value TSRMLS_DC); -// String/Message is stored differently in array/map from normal message fields. -// So we need to make a special method to handle that. -bool native_slot_set_by_array(upb_fieldtype_t type, - const zend_class_entry* klass, void* memory, - zval* value TSRMLS_DC); -bool native_slot_set_by_map(upb_fieldtype_t type, const zend_class_entry* klass, - void* memory, zval* value TSRMLS_DC); -void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache); -// For each property, in order to avoid conversion between the zval object and -// the actual data type during parsing/serialization, the containing message -// object use the custom memory layout to store the actual data type for each -// property inside of it. To access a property from php code, the property -// needs to be converted to a zval object. The message object is not responsible -// for providing such a zval object. Instead the caller needs to provide one -// (cache) and update it with the actual data (memory). -void native_slot_get(upb_fieldtype_t type, const void* memory, - CACHED_VALUE* cache TSRMLS_DC); -// String/Message is stored differently in array/map from normal message fields. -// So we need to make a special method to handle that. -void native_slot_get_by_array(upb_fieldtype_t type, const void* memory, - CACHED_VALUE* cache TSRMLS_DC); -void native_slot_get_by_map_key(upb_fieldtype_t type, const void* memory, - int length, CACHED_VALUE* cache TSRMLS_DC); -void native_slot_get_by_map_value(upb_fieldtype_t type, const void* memory, - CACHED_VALUE* cache TSRMLS_DC); -void native_slot_get_default(upb_fieldtype_t type, - CACHED_VALUE* cache TSRMLS_DC); - -// ----------------------------------------------------------------------------- -// Map Field. -// ----------------------------------------------------------------------------- - -extern zend_object_handlers* map_field_handlers; -extern zend_object_handlers* map_field_iter_handlers; - -PHP_PROTO_WRAP_OBJECT_START(Map) - upb_fieldtype_t key_type; - upb_fieldtype_t value_type; - const zend_class_entry* msg_ce; // class entry for value message - upb_strtable table; -PHP_PROTO_WRAP_OBJECT_END - -PHP_PROTO_WRAP_OBJECT_START(MapIter) - Map* self; - upb_strtable_iter it; -PHP_PROTO_WRAP_OBJECT_END - -void map_begin(zval* self, MapIter* iter TSRMLS_DC); -void map_next(MapIter* iter); -bool map_done(MapIter* iter); -const char* map_iter_key(MapIter* iter, int* len); -upb_value map_iter_value(MapIter* iter, int* len); - -// These operate on a map-entry msgdef. -const upb_fielddef* map_entry_key(const upb_msgdef* msgdef); -const upb_fielddef* map_entry_value(const upb_msgdef* msgdef); - -void map_field_ensure_created(const upb_fielddef *field, - CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC); -void map_field_create_with_field(const zend_class_entry* ce, - const upb_fielddef* field, - CACHED_VALUE* map_field PHP_PROTO_TSRMLS_DC); -void map_field_create_with_type(const zend_class_entry* ce, - upb_fieldtype_t key_type, - upb_fieldtype_t value_type, - const zend_class_entry* msg_ce, - CACHED_VALUE* map_field PHP_PROTO_TSRMLS_DC); -void* upb_value_memory(upb_value* v); - -#define MAP_KEY_FIELD 1 -#define MAP_VALUE_FIELD 2 - -// These operate on a map field (i.e., a repeated field of submessages whose -// submessage type is a map-entry msgdef). -bool is_map_field(const upb_fielddef* field); -const upb_fielddef* map_field_key(const upb_fielddef* field); -const upb_fielddef* map_field_value(const upb_fielddef* field); - -bool map_index_set(Map *intern, const char* keyval, int length, upb_value v); - -PHP_METHOD(MapField, __construct); -PHP_METHOD(MapField, offsetExists); -PHP_METHOD(MapField, offsetGet); -PHP_METHOD(MapField, offsetSet); -PHP_METHOD(MapField, offsetUnset); -PHP_METHOD(MapField, count); -PHP_METHOD(MapField, getIterator); -PHP_METHOD(MapFieldIter, rewind); -PHP_METHOD(MapFieldIter, current); -PHP_METHOD(MapFieldIter, key); -PHP_METHOD(MapFieldIter, next); -PHP_METHOD(MapFieldIter, valid); - -// ----------------------------------------------------------------------------- -// Repeated Field. -// ----------------------------------------------------------------------------- - -extern zend_object_handlers* repeated_field_handlers; -extern zend_object_handlers* repeated_field_iter_handlers; - -PHP_PROTO_WRAP_OBJECT_START(RepeatedField) -#if PHP_MAJOR_VERSION < 7 - zval* array; +// Sine php 8.0, the Object Handlers API was changed to receive zend_object* +// instead of zval* and zend_string* instead of zval* for property names. +// https://github.com/php/php-src/blob/php-8.0.0beta1/UPGRADING.INTERNALS#L37-L39 +#if PHP_VERSION_ID < 80000 +#define PROTO_VAL zval +#define PROTO_STR zval +#define PROTO_MSG_P(obj) (Message*)Z_OBJ_P(obj) +#define PROTO_STRVAL_P(obj) Z_STRVAL_P(obj) +#define PROTO_STRLEN_P(obj) Z_STRLEN_P(obj) #else - zval array; +#define PROTO_VAL zend_object +#define PROTO_STR zend_string +#define PROTO_MSG_P(obj) (Message*)(obj) +#define PROTO_STRVAL_P(obj) ZSTR_VAL(obj) +#define PROTO_STRLEN_P(obj) ZSTR_LEN(obj) #endif - upb_fieldtype_t type; - const zend_class_entry* msg_ce; // class entry for containing message - // (for message field only). -PHP_PROTO_WRAP_OBJECT_END - -PHP_PROTO_WRAP_OBJECT_START(RepeatedFieldIter) - RepeatedField* repeated_field; - long position; -PHP_PROTO_WRAP_OBJECT_END - -void repeated_field_ensure_created( - const upb_fielddef *field, - CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC); -void repeated_field_create_with_field( - zend_class_entry* ce, const upb_fielddef* field, - CACHED_VALUE* repeated_field PHP_PROTO_TSRMLS_DC); -void repeated_field_create_with_type( - zend_class_entry* ce, upb_fieldtype_t type, const zend_class_entry* msg_ce, - CACHED_VALUE* repeated_field PHP_PROTO_TSRMLS_DC); -// Return the element at the index position from the repeated field. There is -// not restriction on the type of stored elements. -void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC); -// Add the element to the end of the repeated field. There is not restriction on -// the type of stored elements. -void repeated_field_push_native(RepeatedField *intern, void *value); - -PHP_METHOD(RepeatedField, __construct); -PHP_METHOD(RepeatedField, append); -PHP_METHOD(RepeatedField, offsetExists); -PHP_METHOD(RepeatedField, offsetGet); -PHP_METHOD(RepeatedField, offsetSet); -PHP_METHOD(RepeatedField, offsetUnset); -PHP_METHOD(RepeatedField, count); -PHP_METHOD(RepeatedField, getIterator); - -PHP_METHOD(RepeatedFieldIter, rewind); -PHP_METHOD(RepeatedFieldIter, current); -PHP_METHOD(RepeatedFieldIter, key); -PHP_METHOD(RepeatedFieldIter, next); -PHP_METHOD(RepeatedFieldIter, valid); - -// ----------------------------------------------------------------------------- -// Oneof Field. -// ----------------------------------------------------------------------------- - -PHP_PROTO_WRAP_OBJECT_START(Oneof) - const upb_oneofdef* oneofdef; - int index; // Index of field in oneof. -1 if not set. - char value[NATIVE_SLOT_MAX_SIZE]; -PHP_PROTO_WRAP_OBJECT_END - -PHP_METHOD(Oneof, getName); -PHP_METHOD(Oneof, getField); -PHP_METHOD(Oneof, getFieldCount); - -extern zend_class_entry* oneof_descriptor_type; - -// Oneof case slot value to indicate that no oneof case is set. The value `0` is -// safe because field numbers are used as case identifiers, and no field can -// have a number of 0. -#define ONEOF_CASE_NONE 0 - -// ----------------------------------------------------------------------------- -// Well Known Type. -// ----------------------------------------------------------------------------- - -extern bool is_inited_file_any; -extern bool is_inited_file_api; -extern bool is_inited_file_duration; -extern bool is_inited_file_field_mask; -extern bool is_inited_file_empty; -extern bool is_inited_file_source_context; -extern bool is_inited_file_struct; -extern bool is_inited_file_timestamp; -extern bool is_inited_file_type; -extern bool is_inited_file_wrappers; - -PHP_METHOD(GPBMetadata_Any, initOnce); -PHP_METHOD(GPBMetadata_Api, initOnce); -PHP_METHOD(GPBMetadata_Duration, initOnce); -PHP_METHOD(GPBMetadata_FieldMask, initOnce); -PHP_METHOD(GPBMetadata_Empty, initOnce); -PHP_METHOD(GPBMetadata_SourceContext, initOnce); -PHP_METHOD(GPBMetadata_Struct, initOnce); -PHP_METHOD(GPBMetadata_Timestamp, initOnce); -PHP_METHOD(GPBMetadata_Type, initOnce); -PHP_METHOD(GPBMetadata_Wrappers, initOnce); - -PHP_METHOD(Any, __construct); -PHP_METHOD(Any, getTypeUrl); -PHP_METHOD(Any, setTypeUrl); -PHP_METHOD(Any, getValue); -PHP_METHOD(Any, setValue); -PHP_METHOD(Any, unpack); -PHP_METHOD(Any, pack); -PHP_METHOD(Any, is); - -PHP_METHOD(Duration, __construct); -PHP_METHOD(Duration, getSeconds); -PHP_METHOD(Duration, setSeconds); -PHP_METHOD(Duration, getNanos); -PHP_METHOD(Duration, setNanos); - -PHP_METHOD(Timestamp, __construct); -PHP_METHOD(Timestamp, fromDateTime); -PHP_METHOD(Timestamp, toDateTime); -PHP_METHOD(Timestamp, getSeconds); -PHP_METHOD(Timestamp, setSeconds); -PHP_METHOD(Timestamp, getNanos); -PHP_METHOD(Timestamp, setNanos); - -PHP_METHOD(Api, __construct); -PHP_METHOD(Api, getName); -PHP_METHOD(Api, setName); -PHP_METHOD(Api, getMethods); -PHP_METHOD(Api, setMethods); -PHP_METHOD(Api, getOptions); -PHP_METHOD(Api, setOptions); -PHP_METHOD(Api, getVersion); -PHP_METHOD(Api, setVersion); -PHP_METHOD(Api, getSourceContext); -PHP_METHOD(Api, setSourceContext); -PHP_METHOD(Api, getMixins); -PHP_METHOD(Api, setMixins); -PHP_METHOD(Api, getSyntax); -PHP_METHOD(Api, setSyntax); - -PHP_METHOD(BoolValue, __construct); -PHP_METHOD(BoolValue, getValue); -PHP_METHOD(BoolValue, setValue); - -PHP_METHOD(BytesValue, __construct); -PHP_METHOD(BytesValue, getValue); -PHP_METHOD(BytesValue, setValue); - -PHP_METHOD(DoubleValue, __construct); -PHP_METHOD(DoubleValue, getValue); -PHP_METHOD(DoubleValue, setValue); - -PHP_METHOD(Enum, __construct); -PHP_METHOD(Enum, getName); -PHP_METHOD(Enum, setName); -PHP_METHOD(Enum, getEnumvalue); -PHP_METHOD(Enum, setEnumvalue); -PHP_METHOD(Enum, getOptions); -PHP_METHOD(Enum, setOptions); -PHP_METHOD(Enum, getSourceContext); -PHP_METHOD(Enum, setSourceContext); -PHP_METHOD(Enum, getSyntax); -PHP_METHOD(Enum, setSyntax); - -PHP_METHOD(EnumValue, __construct); -PHP_METHOD(EnumValue, getName); -PHP_METHOD(EnumValue, setName); -PHP_METHOD(EnumValue, getNumber); -PHP_METHOD(EnumValue, setNumber); -PHP_METHOD(EnumValue, getOptions); -PHP_METHOD(EnumValue, setOptions); - -PHP_METHOD(FieldMask, __construct); -PHP_METHOD(FieldMask, getPaths); -PHP_METHOD(FieldMask, setPaths); - -PHP_METHOD(Field, __construct); -PHP_METHOD(Field, getKind); -PHP_METHOD(Field, setKind); -PHP_METHOD(Field, getCardinality); -PHP_METHOD(Field, setCardinality); -PHP_METHOD(Field, getNumber); -PHP_METHOD(Field, setNumber); -PHP_METHOD(Field, getName); -PHP_METHOD(Field, setName); -PHP_METHOD(Field, getTypeUrl); -PHP_METHOD(Field, setTypeUrl); -PHP_METHOD(Field, getOneofIndex); -PHP_METHOD(Field, setOneofIndex); -PHP_METHOD(Field, getPacked); -PHP_METHOD(Field, setPacked); -PHP_METHOD(Field, getOptions); -PHP_METHOD(Field, setOptions); -PHP_METHOD(Field, getJsonName); -PHP_METHOD(Field, setJsonName); -PHP_METHOD(Field, getDefaultValue); -PHP_METHOD(Field, setDefaultValue); - -PHP_METHOD(Field_Cardinality, name); -PHP_METHOD(Field_Cardinality, value); - -PHP_METHOD(Field_Kind, name); -PHP_METHOD(Field_Kind, value); - -PHP_METHOD(FloatValue, __construct); -PHP_METHOD(FloatValue, getValue); -PHP_METHOD(FloatValue, setValue); -PHP_METHOD(GPBEmpty, __construct); +#define PHP_PROTOBUF_VERSION "3.14.0" -PHP_METHOD(Int32Value, __construct); -PHP_METHOD(Int32Value, getValue); -PHP_METHOD(Int32Value, setValue); - -PHP_METHOD(Int64Value, __construct); -PHP_METHOD(Int64Value, getValue); -PHP_METHOD(Int64Value, setValue); - -PHP_METHOD(ListValue, __construct); -PHP_METHOD(ListValue, getValues); -PHP_METHOD(ListValue, setValues); - -PHP_METHOD(Method, __construct); -PHP_METHOD(Method, getName); -PHP_METHOD(Method, setName); -PHP_METHOD(Method, getRequestTypeUrl); -PHP_METHOD(Method, setRequestTypeUrl); -PHP_METHOD(Method, getRequestStreaming); -PHP_METHOD(Method, setRequestStreaming); -PHP_METHOD(Method, getResponseTypeUrl); -PHP_METHOD(Method, setResponseTypeUrl); -PHP_METHOD(Method, getResponseStreaming); -PHP_METHOD(Method, setResponseStreaming); -PHP_METHOD(Method, getOptions); -PHP_METHOD(Method, setOptions); -PHP_METHOD(Method, getSyntax); -PHP_METHOD(Method, setSyntax); - -PHP_METHOD(Mixin, __construct); -PHP_METHOD(Mixin, getName); -PHP_METHOD(Mixin, setName); -PHP_METHOD(Mixin, getRoot); -PHP_METHOD(Mixin, setRoot); - -PHP_METHOD(NullValue, name); -PHP_METHOD(NullValue, value); - -PHP_METHOD(Option, __construct); -PHP_METHOD(Option, getName); -PHP_METHOD(Option, setName); -PHP_METHOD(Option, getValue); -PHP_METHOD(Option, setValue); - -PHP_METHOD(SourceContext, __construct); -PHP_METHOD(SourceContext, getFileName); -PHP_METHOD(SourceContext, setFileName); - -PHP_METHOD(StringValue, __construct); -PHP_METHOD(StringValue, getValue); -PHP_METHOD(StringValue, setValue); - -PHP_METHOD(Struct, __construct); -PHP_METHOD(Struct, getFields); -PHP_METHOD(Struct, setFields); - -PHP_METHOD(Syntax, name); -PHP_METHOD(Syntax, value); - -PHP_METHOD(Type, __construct); -PHP_METHOD(Type, getName); -PHP_METHOD(Type, setName); -PHP_METHOD(Type, getFields); -PHP_METHOD(Type, setFields); -PHP_METHOD(Type, getOneofs); -PHP_METHOD(Type, setOneofs); -PHP_METHOD(Type, getOptions); -PHP_METHOD(Type, setOptions); -PHP_METHOD(Type, getSourceContext); -PHP_METHOD(Type, setSourceContext); -PHP_METHOD(Type, getSyntax); -PHP_METHOD(Type, setSyntax); - -PHP_METHOD(UInt32Value, __construct); -PHP_METHOD(UInt32Value, getValue); -PHP_METHOD(UInt32Value, setValue); - -PHP_METHOD(UInt64Value, __construct); -PHP_METHOD(UInt64Value, getValue); -PHP_METHOD(UInt64Value, setValue); - -PHP_METHOD(Value, __construct); -PHP_METHOD(Value, getNullValue); -PHP_METHOD(Value, setNullValue); -PHP_METHOD(Value, getNumberValue); -PHP_METHOD(Value, setNumberValue); -PHP_METHOD(Value, getStringValue); -PHP_METHOD(Value, setStringValue); -PHP_METHOD(Value, getBoolValue); -PHP_METHOD(Value, setBoolValue); -PHP_METHOD(Value, getStructValue); -PHP_METHOD(Value, setStructValue); -PHP_METHOD(Value, getListValue); -PHP_METHOD(Value, setListValue); -PHP_METHOD(Value, getKind); - -extern zend_class_entry* any_type; -extern zend_class_entry* api_type; -extern zend_class_entry* bool_value_type; -extern zend_class_entry* bytes_value_type; -extern zend_class_entry* double_value_type; -extern zend_class_entry* duration_type; -extern zend_class_entry* empty_type; -extern zend_class_entry* enum_type; -extern zend_class_entry* enum_value_type; -extern zend_class_entry* field_cardinality_type; -extern zend_class_entry* field_kind_type; -extern zend_class_entry* field_mask_type; -extern zend_class_entry* field_type; -extern zend_class_entry* float_value_type; -extern zend_class_entry* int32_value_type; -extern zend_class_entry* int64_value_type; -extern zend_class_entry* list_value_type; -extern zend_class_entry* method_type; -extern zend_class_entry* mixin_type; -extern zend_class_entry* null_value_type; -extern zend_class_entry* option_type; -extern zend_class_entry* source_context_type; -extern zend_class_entry* string_value_type; -extern zend_class_entry* struct_type; -extern zend_class_entry* syntax_type; -extern zend_class_entry* timestamp_type; -extern zend_class_entry* type_type; -extern zend_class_entry* uint32_value_type; -extern zend_class_entry* uint64_value_type; -extern zend_class_entry* value_type; - -// ----------------------------------------------------------------------------- -// Upb. -// ----------------------------------------------------------------------------- - -upb_fieldtype_t to_fieldtype(upb_descriptortype_t type); -const zend_class_entry* field_type_class( - const upb_fielddef* field PHP_PROTO_TSRMLS_DC); -void stringsink_uninit_opaque(void *sink); - -typedef struct { - upb_byteshandler handler; - upb_bytessink sink; - char *ptr; - size_t len, size; -} stringsink; - -void stringsink_init(stringsink *sink); -void stringsink_uninit(stringsink *sink); -size_t stringsink_string(void *_sink, const void *hd, const char *ptr, - size_t len, const upb_bufhandle *handle); - -// ----------------------------------------------------------------------------- -// Utilities. -// ----------------------------------------------------------------------------- - -// Memory management -#define SYS_MALLOC(class_name) (class_name*) malloc(sizeof(class_name)) -#define SYS_MALLOC_N(class_name, n) (class_name*) malloc(sizeof(class_name) * n) -#define SYS_FREE(ptr) free(ptr) -#define ALLOC(class_name) (class_name*) emalloc(sizeof(class_name)) -#define PEMALLOC(class_name, persistent) (class_name*) pemalloc(sizeof(class_name), persistent) -#define ALLOC_N(class_name, n) (class_name*) emalloc(sizeof(class_name) * n) -#define FREE(object) efree(object) -#define PEFREE(object) pefree(object, 1) - -// Find corresponding zval property for the field. -CACHED_VALUE* find_zval_property(MessageHeader* msg, const upb_fielddef* field); - -// String argument. -#define STR(str) (str), strlen(str) - -// Zend Value -#if PHP_MAJOR_VERSION < 7 -#define Z_OBJ_P(zval_p) \ - ((zend_object*)(EG(objects_store) \ - .object_buckets[Z_OBJ_HANDLE_P(zval_p)] \ - .bucket.obj.object)) -#endif - -// Message handler -static inline zval* php_proto_message_read_property( - zval* msg, zval* member PHP_PROTO_TSRMLS_DC) { -#if PHP_MAJOR_VERSION < 7 - return message_handlers->read_property(msg, member, BP_VAR_R, - NULL PHP_PROTO_TSRMLS_CC); +// ptr -> PHP object cache. This is a weak map that caches lazily-created +// wrapper objects around upb types: +// * upb_msg* -> Message +// * upb_array* -> RepeatedField +// * upb_map*, -> MapField +// * upb_msgdef* -> Descriptor +// * upb_enumdef* -> EnumDescriptor +// * zend_class_entry* -> Descriptor +// +// Each wrapped object should add itself to the map when it is constructed, and +// remove itself from the map when it is destroyed. This is how we ensure that +// the map only contains live objects. The map is weak so it does not actually +// take references to the cached objects. +void ObjCache_Add(const void *key, zend_object *php_obj); +void ObjCache_Delete(const void *key); +bool ObjCache_Get(const void *key, zval *val); + +// PHP class name map. This is necessary because the pb_name->php_class_name +// transformation is non-reversible, so when we need to look up a msgdef or +// enumdef by PHP class, we can't turn the class name into a pb_name. +// * php_class_name -> upb_msgdef* +// * php_class_name -> upb_enumdef* +void NameMap_AddMessage(const upb_msgdef *m); +void NameMap_AddEnum(const upb_enumdef *m); +const upb_msgdef *NameMap_GetMessage(zend_class_entry *ce); +const upb_enumdef *NameMap_GetEnum(zend_class_entry *ce); + +// We need our own assert() because PHP takes control of NDEBUG in its headers. +#ifdef PBPHP_ENABLE_ASSERTS +#define PBPHP_ASSERT(x) \ + do { \ + if (!(x)) { \ + fprintf(stderr, "Assertion failure at %s:%d %s", __FILE__, __LINE__, \ + #x); \ + abort(); \ + } \ + } while (false) #else - return message_handlers->read_property(msg, member, BP_VAR_R, NULL, - NULL PHP_PROTO_TSRMLS_CC); +#define PBPHP_ASSERT(x) \ + do { \ + } while (false && (x)) #endif -} - -// Reserved name -bool is_reserved_name(const char* name); -bool is_valid_constant_name(const char* name); - -// For lazy wrapper -bool is_wrapper_msg(const upb_msgdef* m); -#endif // __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ +#endif // PHP_PROTOBUF_H_ diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c deleted file mode 100644 index fec73358479c..000000000000 --- a/php/ext/google/protobuf/storage.c +++ /dev/null @@ -1,1180 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. - -#include -#include -#include - -#include "utf8.h" - -// ----------------------------------------------------------------------------- -// Native slot storage. -// ----------------------------------------------------------------------------- - -#define DEREF(memory, type) *(type*)(memory) - -size_t native_slot_size(upb_fieldtype_t type) { - switch (type) { - case UPB_TYPE_FLOAT: return 4; - case UPB_TYPE_DOUBLE: return 8; - case UPB_TYPE_BOOL: return 1; - case UPB_TYPE_STRING: return sizeof(void*); - case UPB_TYPE_BYTES: return sizeof(void*); - case UPB_TYPE_MESSAGE: return sizeof(void*); - case UPB_TYPE_ENUM: return 4; - case UPB_TYPE_INT32: return 4; - case UPB_TYPE_INT64: return 8; - case UPB_TYPE_UINT32: return 4; - case UPB_TYPE_UINT64: return 8; - default: return 0; - } -} - -static bool native_slot_is_default(upb_fieldtype_t type, const void* memory) { - switch (type) { -#define CASE_TYPE(upb_type, c_type) \ - case UPB_TYPE_##upb_type: { \ - return DEREF(memory, c_type) == 0; \ - } - CASE_TYPE(INT32, int32_t ) - CASE_TYPE(UINT32, uint32_t) - CASE_TYPE(ENUM, int32_t ) - CASE_TYPE(INT64, int64_t ) - CASE_TYPE(UINT64, uint64_t) - CASE_TYPE(FLOAT, float ) - CASE_TYPE(DOUBLE, double ) - CASE_TYPE(BOOL, int8_t ) - -#undef CASE_TYPE - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - return Z_STRLEN_P(CACHED_PTR_TO_ZVAL_PTR(memory)) == 0; - case UPB_TYPE_MESSAGE: - return Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(memory)) == IS_NULL; - default: return false; - } -} - -bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, - void* memory, zval* value PHP_PROTO_TSRMLS_DC) { - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - if (!protobuf_convert_to_string(value)) { - return false; - } - if (type == UPB_TYPE_STRING && - !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) { - zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); - return false; - } - - zval* cached_zval = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); - if (EXPECTED(cached_zval != NULL)) { -#if PHP_MAJOR_VERSION < 7 - REPLACE_ZVAL_VALUE((zval**)memory, value, 1); -#elif PHP_VERSION_ID < 70400 - zend_assign_to_variable(cached_zval, value, IS_CV); -#else - zend_assign_to_variable(cached_zval, value, IS_CV, 0); -#endif - } - break; - } - case UPB_TYPE_MESSAGE: { - if (Z_TYPE_P(value) != IS_OBJECT && Z_TYPE_P(value) != IS_NULL) { - zend_error(E_USER_ERROR, "Given value is not message."); - return false; - } - if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) { - zend_error(E_USER_ERROR, "Given message does not have correct class."); - return false; - } - -#if PHP_MAJOR_VERSION < 7 - REPLACE_ZVAL_VALUE((CACHED_VALUE*)memory, value, 1); -#else - zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); - if (EXPECTED(property_ptr != value)) { - php_proto_zval_ptr_dtor(property_ptr); - } - - ZVAL_ZVAL(property_ptr, value, 1, 0); -#endif - - break; - } - -#define CASE_TYPE(upb_type, type, c_type, php_type) \ - case UPB_TYPE_##upb_type: { \ - c_type type##_value; \ - if (protobuf_convert_to_##type(value, &type##_value)) { \ - DEREF(memory, c_type) = type##_value; \ - } \ - break; \ - } - CASE_TYPE(INT32, int32, int32_t, LONG) - CASE_TYPE(UINT32, uint32, uint32_t, LONG) - CASE_TYPE(ENUM, int32, int32_t, LONG) - CASE_TYPE(INT64, int64, int64_t, LONG) - CASE_TYPE(UINT64, uint64, uint64_t, LONG) - CASE_TYPE(FLOAT, float, float, DOUBLE) - CASE_TYPE(DOUBLE, double, double, DOUBLE) - CASE_TYPE(BOOL, bool, int8_t, BOOL) - -#undef CASE_TYPE - - default: - break; - } - - return true; -} - -bool native_slot_set_by_array(upb_fieldtype_t type, - const zend_class_entry* klass, void* memory, - zval* value TSRMLS_DC) { -#if PHP_MAJOR_VERSION >= 7 - if (Z_ISREF_P(value)) { - ZVAL_DEREF(value); - } -#endif - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - if (!protobuf_convert_to_string(value)) { - return false; - } - if (type == UPB_TYPE_STRING && - !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) { - zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); - return false; - } - - // Handles repeated/map string field. Memory provided by - // RepeatedField/Map is not initialized. -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(DEREF(memory, zval*)); - PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value), - Z_STRLEN_P(value), 1); -#else - *(zend_string**)memory = - zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0); -#endif - break; - } - case UPB_TYPE_MESSAGE: { - if (Z_TYPE_P(value) != IS_OBJECT) { - zend_error(E_USER_ERROR, "Given value is not message."); - return false; - } - if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) { - zend_error(E_USER_ERROR, "Given message does not have correct class."); - return false; - } -#if PHP_MAJOR_VERSION < 7 - if (EXPECTED(DEREF(memory, zval*) != value)) { - DEREF(memory, zval*) = value; - Z_ADDREF_P(value); - } -#else - DEREF(memory, zval*) = value; - GC_ADDREF(Z_OBJ_P(value)); -#endif - break; - } - default: - return native_slot_set(type, klass, memory, value TSRMLS_CC); - } - return true; -} - -bool native_slot_set_by_map(upb_fieldtype_t type, const zend_class_entry* klass, - void* memory, zval* value TSRMLS_DC) { -#if PHP_MAJOR_VERSION >= 7 - if (Z_ISREF_P(value)) { - ZVAL_DEREF(value); - } -#endif - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - if (!protobuf_convert_to_string(value)) { - return false; - } - if (type == UPB_TYPE_STRING && - !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) { - zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); - return false; - } - - // Handles repeated/map string field. Memory provided by - // RepeatedField/Map is not initialized. -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(DEREF(memory, zval*)); - PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value), - Z_STRLEN_P(value), 1); -#else - *(zend_string**)memory = - zend_string_init(Z_STRVAL_P(value), Z_STRLEN_P(value), 0); -#endif - break; - } - case UPB_TYPE_MESSAGE: { - if (Z_TYPE_P(value) != IS_OBJECT) { - zend_error(E_USER_ERROR, "Given value is not message."); - return false; - } - if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) { - zend_error(E_USER_ERROR, "Given message does not have correct class."); - return false; - } -#if PHP_MAJOR_VERSION < 7 - if (EXPECTED(DEREF(memory, zval*) != value)) { - DEREF(memory, zval*) = value; - Z_ADDREF_P(value); - } -#else - DEREF(memory, zend_object*) = Z_OBJ_P(value); - GC_ADDREF(Z_OBJ_P(value)); -#endif - break; - } - default: - return native_slot_set(type, klass, memory, value TSRMLS_CC); - } - return true; -} - -void native_slot_init(upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) { - switch (type) { - case UPB_TYPE_FLOAT: - DEREF(memory, float) = 0.0; - break; - case UPB_TYPE_DOUBLE: - DEREF(memory, double) = 0.0; - break; - case UPB_TYPE_BOOL: - DEREF(memory, int8_t) = 0; - break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - case UPB_TYPE_MESSAGE: - DEREF(memory, CACHED_VALUE*) = cache; - break; - case UPB_TYPE_ENUM: - case UPB_TYPE_INT32: - DEREF(memory, int32_t) = 0; - break; - case UPB_TYPE_INT64: - DEREF(memory, int64_t) = 0; - break; - case UPB_TYPE_UINT32: - DEREF(memory, uint32_t) = 0; - break; - case UPB_TYPE_UINT64: - DEREF(memory, uint64_t) = 0; - break; - default: - break; - } -} - -void native_slot_get(upb_fieldtype_t type, const void* memory, - CACHED_VALUE* cache TSRMLS_DC) { - switch (type) { -#define CASE(upb_type, php_type, c_type) \ - case UPB_TYPE_##upb_type: \ - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \ - return; - - CASE(FLOAT, DOUBLE, float) - CASE(DOUBLE, DOUBLE, double) - CASE(BOOL, BOOL, int8_t) - CASE(INT32, LONG, int32_t) - CASE(ENUM, LONG, uint32_t) - -#undef CASE - -#if SIZEOF_LONG == 4 -#define CASE(upb_type, c_type) \ - case UPB_TYPE_##upb_type: { \ - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ - char buffer[MAX_LENGTH_OF_INT64]; \ - sprintf(buffer, "%lld", DEREF(memory, c_type)); \ - PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), buffer, 1); \ - return; \ - } -#else -#define CASE(upb_type, c_type) \ - case UPB_TYPE_##upb_type: { \ - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \ - return; \ - } -#endif -CASE(UINT64, uint64_t) -CASE(INT64, int64_t) -#undef CASE - - case UPB_TYPE_UINT32: { - // Prepend bit-1 for negative numbers, so that uint32 value will be - // consistent on both 32-bit and 64-bit architectures. - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); - int value = DEREF(memory, int32_t); - if (sizeof(int) == 8) { - value |= (-((value >> 31) & 0x1) & 0xFFFFFFFF00000000); - } - ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), value); - return; - } - - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - // For optional string/bytes/message fields, the cache is owned by the - // containing message and should have been updated during - // setting/decoding. However, oneof accessor call this function by - // providing the return value directly, which is not the same as the cache - // value. - zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); - if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) { - PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), Z_STRVAL_P(value), - Z_STRLEN_P(value), 1); - } - break; - } - case UPB_TYPE_MESSAGE: { - // Same as above for string/bytes fields. - zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); - if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) { - ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0); - } - return; - } - default: - return; - } -} - -void native_slot_get_by_array(upb_fieldtype_t type, const void* memory, - CACHED_VALUE* cache TSRMLS_DC) { - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { -#if PHP_MAJOR_VERSION < 7 - zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); - if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) { - PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), - Z_STRVAL_P(value), Z_STRLEN_P(value), 1); - } -#else - ZVAL_NEW_STR(cache, zend_string_dup(*(zend_string**)memory, 0)); -#endif - return; - } - case UPB_TYPE_MESSAGE: { -#if PHP_MAJOR_VERSION < 7 - zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); - if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) { - ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0); - } -#else - ZVAL_COPY(CACHED_PTR_TO_ZVAL_PTR(cache), memory); -#endif - return; - } - default: - native_slot_get(type, memory, cache TSRMLS_CC); - } -} - -void native_slot_get_by_map_key(upb_fieldtype_t type, const void* memory, - int length, CACHED_VALUE* cache TSRMLS_DC) { - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), memory, length, 1); - return; - } - default: - native_slot_get(type, memory, cache TSRMLS_CC); - } -} - -void native_slot_get_by_map_value(upb_fieldtype_t type, const void* memory, - CACHED_VALUE* cache TSRMLS_DC) { - switch (type) { - case UPB_TYPE_MESSAGE: { -#if PHP_MAJOR_VERSION < 7 - zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); - if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) { - ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0); - } -#else - GC_ADDREF(*(zend_object**)memory); - ZVAL_OBJ(cache, *(zend_object**)memory); -#endif - return; - } - default: - native_slot_get_by_array(type, memory, cache TSRMLS_CC); - } -} - -void native_slot_get_default(upb_fieldtype_t type, - CACHED_VALUE* cache TSRMLS_DC) { - switch (type) { -#define CASE(upb_type, php_type) \ - case UPB_TYPE_##upb_type: \ - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \ - return; - - CASE(FLOAT, DOUBLE) - CASE(DOUBLE, DOUBLE) - CASE(BOOL, BOOL) - CASE(INT32, LONG) - CASE(UINT32, LONG) - CASE(ENUM, LONG) - -#undef CASE - -#if SIZEOF_LONG == 4 -#define CASE(upb_type) \ - case UPB_TYPE_##upb_type: { \ - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ - PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), "0", 1); \ - return; \ - } -#else -#define CASE(upb_type) \ - case UPB_TYPE_##upb_type: { \ - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \ - return; \ - } -#endif -CASE(UINT64) -CASE(INT64) -#undef CASE - - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); - PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), "", 0, 1); - break; - } - case UPB_TYPE_MESSAGE: { - PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); - ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(cache)); - return; - } - default: - return; - } -} - -// ----------------------------------------------------------------------------- -// Map field utilities. -// ---------------------------------------------------------------------------- - -const upb_msgdef* tryget_map_entry_msgdef(const upb_fielddef* field) { - const upb_msgdef* subdef; - if (upb_fielddef_label(field) != UPB_LABEL_REPEATED || - upb_fielddef_type(field) != UPB_TYPE_MESSAGE) { - return NULL; - } - subdef = upb_fielddef_msgsubdef(field); - return upb_msgdef_mapentry(subdef) ? subdef : NULL; -} - -const upb_msgdef* map_entry_msgdef(const upb_fielddef* field) { - const upb_msgdef* subdef = tryget_map_entry_msgdef(field); - assert(subdef); - return subdef; -} - -bool is_map_field(const upb_fielddef* field) { - return tryget_map_entry_msgdef(field) != NULL; -} - -const upb_fielddef* map_field_key(const upb_fielddef* field) { - const upb_msgdef* subdef = map_entry_msgdef(field); - return map_entry_key(subdef); -} - -const upb_fielddef* map_field_value(const upb_fielddef* field) { - const upb_msgdef* subdef = map_entry_msgdef(field); - return map_entry_value(subdef); -} - -const upb_fielddef* map_entry_key(const upb_msgdef* msgdef) { - const upb_fielddef* key_field = upb_msgdef_itof(msgdef, MAP_KEY_FIELD); - assert(key_field != NULL); - return key_field; -} - -const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) { - const upb_fielddef* value_field = upb_msgdef_itof(msgdef, MAP_VALUE_FIELD); - assert(value_field != NULL); - return value_field; -} - -const zend_class_entry* field_type_class( - const upb_fielddef* field PHP_PROTO_TSRMLS_DC) { - if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) { - DescriptorInternal* desc = get_msgdef_desc(upb_fielddef_msgsubdef(field)); - register_class(desc, false TSRMLS_CC); - return desc->klass; - } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) { - EnumDescriptorInternal* desc = - get_enumdef_enumdesc(upb_fielddef_enumsubdef(field)); - register_class(desc, false TSRMLS_CC); - return desc->klass; - } - return NULL; -} - -// ----------------------------------------------------------------------------- -// Memory layout management. -// ----------------------------------------------------------------------------- - -static size_t align_up_to(size_t offset, size_t granularity) { - // Granularity must be a power of two. - return (offset + granularity - 1) & ~(granularity - 1); -} - -uint32_t* slot_oneof_case(MessageLayout* layout, const void* storage, - const upb_fielddef* field) { - return (uint32_t*)(((uint8_t*)storage) + - layout->fields[upb_fielddef_index(field)].case_offset); -} - -void* slot_memory(MessageLayout* layout, const void* storage, - const upb_fielddef* field) { - return ((uint8_t*)storage) + layout->fields[upb_fielddef_index(field)].offset; -} - -MessageLayout* create_layout(const upb_msgdef* msgdef) { - MessageLayout* layout = SYS_MALLOC(MessageLayout); - int nfields = upb_msgdef_numfields(msgdef); - upb_msg_field_iter it; - upb_msg_oneof_iter oit; - size_t off = 0; - int i = 0; - - // Reserve space for unknown fields. - off += sizeof(void*); - - layout->empty_template = NULL; - - TSRMLS_FETCH(); - DescriptorInternal* desc = get_msgdef_desc(msgdef); - register_class(desc, false TSRMLS_CC); - layout->fields = SYS_MALLOC_N(MessageField, nfields); - - for (upb_msg_field_begin(&it, msgdef); !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* field = upb_msg_iter_field(&it); - size_t field_size; - - if (upb_fielddef_containingoneof(field)) { - // Oneofs are handled separately below. - continue; - } - - // Allocate |field_size| bytes for this field in the layout. - field_size = 0; - if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { - field_size = sizeof(zval*); - } else { - field_size = native_slot_size(upb_fielddef_type(field)); - } - - // Align current offset up to | size | granularity. - off = align_up_to(off, field_size); - layout->fields[upb_fielddef_index(field)].offset = off; - layout->fields[upb_fielddef_index(field)].case_offset = - MESSAGE_FIELD_NO_CASE; - - const char* fieldname = upb_fielddef_name(field); - -#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0) - zend_class_entry* old_scope = EG(scope); - EG(scope) = desc->klass; -#else - zend_class_entry* old_scope = EG(fake_scope); - EG(fake_scope) = desc->klass; -#endif - -#if PHP_MAJOR_VERSION < 7 - zval member; - ZVAL_STRINGL(&member, fieldname, strlen(fieldname), 0); - zend_property_info* property_info = - zend_get_property_info(desc->klass, &member, true TSRMLS_CC); -#else - zend_string* member = zend_string_init(fieldname, strlen(fieldname), 1); - zend_property_info* property_info = - zend_get_property_info(desc->klass, member, true); - zend_string_release(member); -#endif - -#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0) - EG(scope) = old_scope; -#else - EG(fake_scope) = old_scope; -#endif - - layout->fields[upb_fielddef_index(field)].cache_index = - property_info->offset; - off += field_size; - } - - // Handle oneofs now -- we iterate over oneofs specifically and allocate only - // one slot per oneof. - // - // We assign all value slots first, then pack the 'case' fields at the end, - // since in the common case (modern 64-bit platform) these are 8 bytes and 4 - // bytes respectively and we want to avoid alignment overhead. - // - // Note that we reserve 4 bytes (a uint32) per 'case' slot because the value - // space for oneof cases is conceptually as wide as field tag numbers. In - // practice, it's unlikely that a oneof would have more than e.g. 256 or 64K - // members (8 or 16 bits respectively), so conceivably we could assign - // consecutive case numbers and then pick a smaller oneof case slot size, but - // the complexity to implement this indirection is probably not worthwhile. - for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit); - upb_msg_oneof_next(&oit)) { - const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit); - upb_oneof_iter fit; - - // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between - // all fields. - size_t field_size = NATIVE_SLOT_MAX_SIZE; - // Align the offset . - off = align_up_to( off, field_size); - // Assign all fields in the oneof this same offset. - const char* oneofname = upb_oneofdef_name(oneof); - for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* field = upb_oneof_iter_field(&fit); - layout->fields[upb_fielddef_index(field)].offset = off; - -#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0) - zend_class_entry* old_scope = EG(scope); - EG(scope) = desc->klass; -#else - zend_class_entry* old_scope = EG(fake_scope); - EG(fake_scope) = desc->klass; -#endif - -#if PHP_MAJOR_VERSION < 7 - zval member; - ZVAL_STRINGL(&member, oneofname, strlen(oneofname), 0); - zend_property_info* property_info = - zend_get_property_info(desc->klass, &member, true TSRMLS_CC); -#else - zend_string* member = zend_string_init(oneofname, strlen(oneofname), 1); - zend_property_info* property_info = - zend_get_property_info(desc->klass, member, true); - zend_string_release(member); -#endif - -#if PHP_MAJOR_VERSION < 7 || (PHP_MAJOR_VERSION == 7 && PHP_MINOR_VERSION == 0) - EG(scope) = old_scope; -#else - EG(fake_scope) = old_scope; -#endif - - layout->fields[upb_fielddef_index(field)].cache_index = - property_info->offset; - } - i++; - off += field_size; - } - - // Now the case offset. - for (upb_msg_oneof_begin(&oit, msgdef); !upb_msg_oneof_done(&oit); - upb_msg_oneof_next(&oit)) { - const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit); - upb_oneof_iter fit; - - size_t field_size = sizeof(uint32_t); - // Align the offset . - off = (off + field_size - 1) & ~(field_size - 1); - // Assign all fields in the oneof this same offset. - for (upb_oneof_begin(&fit, oneof); !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* field = upb_oneof_iter_field(&fit); - layout->fields[upb_fielddef_index(field)].case_offset = off; - } - off += field_size; - } - - layout->size = off; - layout->msgdef = msgdef; - - // Create the empty message template. - layout->empty_template = SYS_MALLOC_N(char, layout->size); - memset(layout->empty_template, 0, layout->size); - - return layout; -} - -void free_layout(MessageLayout* layout) { - SYS_FREE(layout->empty_template); - SYS_FREE(layout->fields); - SYS_FREE(layout); -} - -void layout_init(MessageLayout* layout, void* storage, - zend_object* object PHP_PROTO_TSRMLS_DC) { - memcpy(storage, layout->empty_template, layout->size); -} - -// Switch memory for processing for singular fields based on field type. -// * primitive fields: memory -// * others (string, bytes and message): cache (the correspond zval -// property) -static void* value_memory( - upb_fieldtype_t type, void* memory, CACHED_VALUE* cache) { - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - case UPB_TYPE_MESSAGE: - return cache; - default: - // No operation - break; - } - return memory; -} - -CACHED_VALUE* find_zval_property( - MessageHeader* header, const upb_fielddef* field) { - int property_cache_index = - header->descriptor->layout->fields[upb_fielddef_index(field)] - .cache_index; - return OBJ_PROP(&header->std, property_cache_index); -} - -zval* layout_get(MessageLayout* layout, MessageHeader* header, - const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC) { - const void* storage = message_data(header); - void* memory = slot_memory(layout, storage, field); - uint32_t* oneof_case = slot_oneof_case(layout, storage, field); - - if (upb_fielddef_containingoneof(field)) { - if (*oneof_case != upb_fielddef_number(field)) { - native_slot_get_default(upb_fielddef_type(field), cache TSRMLS_CC); - return CACHED_PTR_TO_ZVAL_PTR(cache); - } - // Intentional fall through to be handled as a signuarl field. - } else if (is_map_field(field)) { - map_field_ensure_created(field, cache PHP_PROTO_TSRMLS_CC); - return CACHED_PTR_TO_ZVAL_PTR(cache); - } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { - repeated_field_ensure_created(field, cache PHP_PROTO_TSRMLS_CC); - return CACHED_PTR_TO_ZVAL_PTR(cache); - } - - CACHED_VALUE* stored_cache = find_zval_property(header, field); - - if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE && - is_wrapper_msg(upb_fielddef_msgsubdef(field))) { - zval * cached_zval = CACHED_PTR_TO_ZVAL_PTR(stored_cache); -#if PHP_MAJOR_VERSION >= 7 - zend_object* obj; -#endif - if (Z_TYPE_P(cached_zval) != IS_OBJECT && - Z_TYPE_P(cached_zval) != IS_NULL) { - // Needs to expand value to wrapper. - const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field); - const upb_fielddef* value_field = upb_msgdef_itof(submsgdef, 1); - MessageHeader* submsg; - DescriptorInternal* subdesc = get_msgdef_desc(submsgdef); - register_class(subdesc, false TSRMLS_CC); - zend_class_entry* subklass = subdesc->klass; -#if PHP_MAJOR_VERSION < 7 - zval* val = NULL; - MAKE_STD_ZVAL(val); - ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC)); - submsg = UNBOX(MessageHeader, val); -#else - obj = subklass->create_object(subklass TSRMLS_CC); - submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std)); -#endif - custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); - - layout_set(subdesc->layout, submsg, value_field, cached_zval TSRMLS_CC); -#if PHP_MAJOR_VERSION < 7 - ZVAL_ZVAL(cached_zval, val, 1, 1); -#else - ZVAL_OBJ(cached_zval, obj); -#endif - } - if (stored_cache != cache) { - ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), cached_zval, 1, 0); - } - } else { - upb_fieldtype_t type = upb_fielddef_type(field); - native_slot_get(type, value_memory(type, memory, stored_cache), - cache TSRMLS_CC); - } - return CACHED_PTR_TO_ZVAL_PTR(cache); -} - -void layout_set(MessageLayout* layout, MessageHeader* header, - const upb_fielddef* field, zval* val TSRMLS_DC) { - void* storage = message_data(header); - void* memory = slot_memory(layout, storage, field); - uint32_t* oneof_case = slot_oneof_case(layout, storage, field); - - if (upb_fielddef_containingoneof(field)) { - *oneof_case = upb_fielddef_number(field); - } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { - // Works for both repeated and map fields - CACHED_VALUE* cached = find_zval_property(header, field); - zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR(cached); - - if (EXPECTED(property_ptr != val)) { - zend_class_entry *subce = NULL; - zval converted_value; - - if (upb_fielddef_ismap(field)) { - const upb_msgdef* mapmsg = upb_fielddef_msgsubdef(field); - const upb_fielddef* keyfield = upb_msgdef_ntof(mapmsg, "key", 3); - const upb_fielddef* valuefield = upb_msgdef_ntof(mapmsg, "value", 5); - if (upb_fielddef_descriptortype(valuefield) == - UPB_DESCRIPTOR_TYPE_MESSAGE) { - const upb_msgdef* submsg = upb_fielddef_msgsubdef(valuefield); - DescriptorInternal* subdesc = get_msgdef_desc(submsg); - register_class(subdesc, false TSRMLS_CC); - subce = subdesc->klass; - } - check_map_field(subce, upb_fielddef_descriptortype(keyfield), - upb_fielddef_descriptortype(valuefield), val, - &converted_value); - } else { - if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) { - const upb_msgdef* submsg = upb_fielddef_msgsubdef(field); - DescriptorInternal* subdesc = get_msgdef_desc(submsg); - register_class(subdesc, false TSRMLS_CC); - subce = subdesc->klass; - } - - check_repeated_field(subce, upb_fielddef_descriptortype(field), val, - &converted_value); - } -#if PHP_MAJOR_VERSION < 7 - REPLACE_ZVAL_VALUE((zval**)cached, &converted_value, 1); -#else - php_proto_zval_ptr_dtor(property_ptr); - ZVAL_ZVAL(property_ptr, &converted_value, 1, 0); -#endif - zval_dtor(&converted_value); - } - return; - } - - upb_fieldtype_t type = upb_fielddef_type(field); - zend_class_entry *ce = NULL; - if (type == UPB_TYPE_MESSAGE) { - const upb_msgdef* msg = upb_fielddef_msgsubdef(field); - DescriptorInternal* desc = get_msgdef_desc(msg); - register_class(desc, false TSRMLS_CC); - ce = desc->klass; - } - CACHED_VALUE* cache = find_zval_property(header, field); - native_slot_set( - type, ce, value_memory(upb_fielddef_type(field), memory, cache), - val TSRMLS_CC); -} - -static void native_slot_merge( - const upb_fielddef* field, const void* from_memory, - void* to_memory PHP_PROTO_TSRMLS_DC) { - upb_fieldtype_t type = upb_fielddef_type(field); - zend_class_entry* ce = NULL; - if (!native_slot_is_default(type, from_memory)) { - switch (type) { -#define CASE_TYPE(upb_type, c_type) \ - case UPB_TYPE_##upb_type: { \ - DEREF(to_memory, c_type) = DEREF(from_memory, c_type); \ - break; \ - } - CASE_TYPE(INT32, int32_t) - CASE_TYPE(UINT32, uint32_t) - CASE_TYPE(ENUM, int32_t) - CASE_TYPE(INT64, int64_t) - CASE_TYPE(UINT64, uint64_t) - CASE_TYPE(FLOAT, float) - CASE_TYPE(DOUBLE, double) - CASE_TYPE(BOOL, int8_t) - -#undef CASE_TYPE - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - native_slot_set(type, NULL, to_memory, - CACHED_PTR_TO_ZVAL_PTR(from_memory) PHP_PROTO_TSRMLS_CC); - break; - case UPB_TYPE_MESSAGE: { - const upb_msgdef* msg = upb_fielddef_msgsubdef(field); - DescriptorInternal* desc = get_msgdef_desc(msg); - register_class(desc, false TSRMLS_CC); - ce = desc->klass; - if (native_slot_is_default(type, to_memory)) { -#if PHP_MAJOR_VERSION < 7 - SEPARATE_ZVAL_IF_NOT_REF((zval**)to_memory); -#endif - CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR( - CACHED_PTR_TO_ZVAL_PTR(to_memory), ce); - MessageHeader* submsg = - UNBOX(MessageHeader, CACHED_PTR_TO_ZVAL_PTR(to_memory)); - custom_data_init(ce, submsg PHP_PROTO_TSRMLS_CC); - } - - MessageHeader* sub_from = - UNBOX(MessageHeader, - CACHED_PTR_TO_ZVAL_PTR(from_memory)); - MessageHeader* sub_to = - UNBOX(MessageHeader, - CACHED_PTR_TO_ZVAL_PTR(to_memory)); - - layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC); - break; - } - } - } -} - -static void native_slot_merge_by_array(const upb_fielddef* field, const void* from_memory, - void* to_memory PHP_PROTO_TSRMLS_DC) { - upb_fieldtype_t type = upb_fielddef_type(field); - switch (type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(DEREF(to_memory, zval*)); - PHP_PROTO_ZVAL_STRINGL(DEREF(to_memory, zval*), - Z_STRVAL_P(*(zval**)from_memory), - Z_STRLEN_P(*(zval**)from_memory), 1); -#else - DEREF(to_memory, zend_string*) = - zend_string_dup(*(zend_string**)from_memory, 0); -#endif - break; - } - case UPB_TYPE_MESSAGE: { - DescriptorInternal* desc = get_msgdef_desc(upb_fielddef_msgsubdef(field)); - register_class(desc, false TSRMLS_CC); - zend_class_entry* ce = desc->klass; -#if PHP_MAJOR_VERSION < 7 - MAKE_STD_ZVAL(DEREF(to_memory, zval*)); - CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(DEREF(to_memory, zval*), ce); -#else - DEREF(to_memory, zend_object*) = ce->create_object(ce TSRMLS_CC); -#endif - MessageHeader* sub_from = UNBOX_HASHTABLE_VALUE( - MessageHeader, DEREF(from_memory, PHP_PROTO_HASHTABLE_VALUE)); - MessageHeader* sub_to = UNBOX_HASHTABLE_VALUE( - MessageHeader, DEREF(to_memory, PHP_PROTO_HASHTABLE_VALUE)); - custom_data_init(ce, sub_to PHP_PROTO_TSRMLS_CC); - - layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC); - break; - } - default: - native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC); - break; - } -} - -void layout_merge(MessageLayout* layout, MessageHeader* from, - MessageHeader* to PHP_PROTO_TSRMLS_DC) { - int i, j; - upb_msg_field_iter it; - - for (upb_msg_field_begin(&it, layout->msgdef), i = 0; !upb_msg_field_done(&it); - upb_msg_field_next(&it), i++) { - const upb_fielddef* field = upb_msg_iter_field(&it); - - void* to_memory = slot_memory(layout, message_data(to), field); - void* from_memory = slot_memory(layout, message_data(from), field); - - if (upb_fielddef_containingoneof(field)) { - uint32_t oneof_case_offset = - layout->fields[upb_fielddef_index(field)].case_offset; - // For a oneof, check that this field is actually present -- skip all the - // below if not. - if (DEREF((message_data(from) + oneof_case_offset), uint32_t) != - upb_fielddef_number(field)) { - continue; - } - uint32_t* from_oneof_case = slot_oneof_case(layout, message_data(from), field); - uint32_t* to_oneof_case = slot_oneof_case(layout, message_data(to), field); - - // For non-singular fields, the related memory needs to point to the - // actual zval in properties table first. - switch (upb_fielddef_type(field)) { - case UPB_TYPE_MESSAGE: - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - int property_cache_index = - layout->fields[upb_fielddef_index(field)].cache_index; - DEREF(to_memory, CACHED_VALUE*) = - OBJ_PROP(&to->std, property_cache_index); - break; - } - default: - break; - } - - *to_oneof_case = *from_oneof_case; - - // Otherwise, fall through to the appropriate singular-field handler - // below. - } - - if (is_map_field(field)) { - int size, key_length, value_length; - MapIter map_it; - - CACHED_VALUE* from_cache = find_zval_property(from, field); - CACHED_VALUE* to_cache = find_zval_property(to, field); - - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(from_cache)) == IS_NULL) { - continue; - } - map_field_ensure_created(field, to_cache PHP_PROTO_TSRMLS_CC); - - zval* to_map_php = CACHED_PTR_TO_ZVAL_PTR(to_cache); - zval* from_map_php = CACHED_PTR_TO_ZVAL_PTR(from_cache); - - Map* to_map = UNBOX(Map, to_map_php); - Map* from_map = UNBOX(Map, from_map_php); - - size = upb_strtable_count(&from_map->table); - if (size == 0) continue; - - const upb_msgdef *mapentry_def = upb_fielddef_msgsubdef(field); - const upb_fielddef *value_field = upb_msgdef_itof(mapentry_def, 2); - - for (map_begin(from_map_php, &map_it TSRMLS_CC); !map_done(&map_it); - map_next(&map_it)) { - const char* key = map_iter_key(&map_it, &key_length); - upb_value from_value = map_iter_value(&map_it, &value_length); - upb_value to_value; - void* from_mem = upb_value_memory(&from_value); - void* to_mem = upb_value_memory(&to_value); - memset(to_mem, 0, native_slot_size(to_map->value_type)); - - native_slot_merge_by_array(value_field, from_mem, - to_mem PHP_PROTO_TSRMLS_CC); - - map_index_set(to_map, key, key_length, to_value); - } - - } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { - CACHED_VALUE* from_cache = find_zval_property(from, field); - CACHED_VALUE* to_cache = find_zval_property(to, field); - - if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(from_cache)) == IS_NULL) { - continue; - } - repeated_field_ensure_created(field, to_cache PHP_PROTO_TSRMLS_CC); - - zval* to_array_php = CACHED_PTR_TO_ZVAL_PTR(to_cache); - zval* from_array_php = CACHED_PTR_TO_ZVAL_PTR(from_cache); - RepeatedField* to_array = UNBOX(RepeatedField, to_array_php); - RepeatedField* from_array = UNBOX(RepeatedField, from_array_php); - - int size = zend_hash_num_elements(PHP_PROTO_HASH_OF(from_array->array)); - if (size > 0) { - for (j = 0; j < size; j++) { - void* from_memory = NULL; - void* to_memory = - ALLOC_N(char, native_slot_size(upb_fielddef_type(field))); - memset(to_memory, 0, native_slot_size(upb_fielddef_type(field))); - - if (to_array->type == UPB_TYPE_MESSAGE) { - php_proto_zend_hash_index_find_zval( - PHP_PROTO_HASH_OF(from_array->array), j, (void**)&from_memory); -#if PHP_MAJOR_VERSION >= 7 - from_memory = &Z_OBJ_P((zval*)from_memory); -#endif - } else { - php_proto_zend_hash_index_find_mem( - PHP_PROTO_HASH_OF(from_array->array), j, (void**)&from_memory); - } - - native_slot_merge_by_array(field, from_memory, - to_memory PHP_PROTO_TSRMLS_CC); - repeated_field_push_native(to_array, to_memory); - FREE(to_memory); - } - } - } else { - switch (upb_fielddef_type(field)) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - case UPB_TYPE_MESSAGE: { - CACHED_VALUE* from_cache = find_zval_property(from, field); - CACHED_VALUE* to_cache = find_zval_property(to, field); - native_slot_merge(field, from_cache, to_cache PHP_PROTO_TSRMLS_CC); - break; - } - default: - native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC); - break; - } - } - } -} - -const char* layout_get_oneof_case(MessageLayout* layout, const void* storage, - const upb_oneofdef* oneof TSRMLS_DC) { - upb_oneof_iter i; - const upb_fielddef* first_field = NULL; - - // Oneof is guaranteed to have at least one field. Get the first field. - for(upb_oneof_begin(&i, oneof); !upb_oneof_done(&i); upb_oneof_next(&i)) { - first_field = upb_oneof_iter_field(&i); - break; - } - - uint32_t* oneof_case = slot_oneof_case(layout, storage, first_field); - if (*oneof_case == 0) { - return ""; - } - const upb_fielddef* field = upb_oneofdef_itof(oneof, *oneof_case); - return upb_fielddef_name(field); -} diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c deleted file mode 100644 index 84d06be7efb8..000000000000 --- a/php/ext/google/protobuf/type_check.c +++ /dev/null @@ -1,680 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. - -// The Zend Engine License, version 2.00 -// Copyright (c) 1999-2002 Zend Technologies Ltd. All rights reserved. -// -------------------------------------------------------------------- -// -// Redistribution and use in source and binary forms, with or without -// modification, is permitted provided that the following conditions -// are met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. 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. -// -// 3. The names "Zend" and "Zend Engine" must not be used to endorse -// or promote products derived from this software without prior -// permission from Zend Technologies Ltd. For written permission, -// please contact license@zend.com. -// -// 4. Zend Technologies Ltd. may publish revised and/or new versions -// of the license from time to time. Each version will be given a -// distinguishing version number. -// Once covered code has been published under a particular version -// of the license, you may always continue to use it under the -// terms of that version. You may also choose to use such covered -// code under the terms of any subsequent version of the license -// published by Zend Technologies Ltd. No one other than Zend -// Technologies Ltd. has the right to modify the terms applicable -// to covered code created under this License. -// -// 5. Redistributions of any form whatsoever must retain the following -// acknowledgment: -// "This product includes the Zend Engine, freely available at -// http://www.zend.com" -// -// 6. All advertising materials mentioning features or use of this -// software must display the following acknowledgment: -// "The Zend Engine is freely available at http://www.zend.com" -// -// THIS SOFTWARE IS PROVIDED BY ZEND TECHNOLOGIES LTD. ``AS IS'' AND -// ANY EXPRESSED 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 ZEND -// TECHNOLOGIES LTD. 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. - -#include -#include - -#include "protobuf.h" -#include "utf8.h" - -static zend_class_entry* util_type; -static const char int64_min_digits[] = "9223372036854775808"; - -ZEND_BEGIN_ARG_INFO_EX(arg_check_optional, 0, 0, 1) - ZEND_ARG_INFO(1, val) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arg_check_message, 0, 0, 2) - ZEND_ARG_INFO(1, val) - ZEND_ARG_INFO(0, klass) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arg_check_repeated, 0, 0, 2) - ZEND_ARG_INFO(1, val) - ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(0, klass) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arg_check_map, 0, 0, 3) - ZEND_ARG_INFO(1, val) - ZEND_ARG_INFO(0, key_type) - ZEND_ARG_INFO(0, value_type) - ZEND_ARG_INFO(0, klass) -ZEND_END_ARG_INFO() - -static zend_function_entry util_methods[] = { - PHP_ME(Util, checkInt32, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkUint32, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkInt64, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkUint64, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkEnum, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkFloat, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkDouble, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkBool, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkString, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkBytes, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkMessage, arg_check_message, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkMapField, arg_check_map, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(Util, checkRepeatedField, arg_check_repeated, - ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - ZEND_FE_END -}; - -void util_init(TSRMLS_D) { - zend_class_entry class_type; - INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\GPBUtil", - util_methods); - util_type = zend_register_internal_class(&class_type TSRMLS_CC); -} - -// ----------------------------------------------------------------------------- -// Type checking/conversion. -// ----------------------------------------------------------------------------- - -// This is modified from is_numeric_string in zend_operators.h. The behavior of -// this function is the same as is_numeric_string, except that this takes -// int64_t as input instead of long. -static zend_uchar convert_numeric_string( - const char *str, int length, int64_t *lval, double *dval) { - const char *ptr; - int base = 10, digits = 0, dp_or_e = 0; - double local_dval = 0.0; - zend_uchar type; - - if (length == 0) { - return IS_NULL; - } - - while (*str == ' ' || *str == '\t' || *str == '\n' || - *str == '\r' || *str == '\v' || *str == '\f') { - str++; - length--; - } - ptr = str; - - if (*ptr == '-' || *ptr == '+') { - ptr++; - } - - if (ZEND_IS_DIGIT(*ptr)) { - // Handle hex numbers - // str is used instead of ptr to disallow signs and keep old behavior. - if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) { - base = 16; - ptr += 2; - } - - // Skip any leading 0s. - while (*ptr == '0') { - ptr++; - } - - // Count the number of digits. If a decimal point/exponent is found, - // it's a double. Otherwise, if there's a dval or no need to check for - // a full match, stop when there are too many digits for a int64 */ - for (type = IS_LONG; - !(digits >= MAX_LENGTH_OF_INT64 && dval); - digits++, ptr++) { -check_digits: - if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) { - continue; - } else if (base == 10) { - if (*ptr == '.' && dp_or_e < 1) { - goto process_double; - } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) { - const char *e = ptr + 1; - - if (*e == '-' || *e == '+') { - ptr = e++; - } - if (ZEND_IS_DIGIT(*e)) { - goto process_double; - } - } - } - break; - } - - if (base == 10) { - if (digits >= MAX_LENGTH_OF_INT64) { - dp_or_e = -1; - goto process_double; - } - } else if (!(digits < SIZEOF_INT64 * 2 || - (digits == SIZEOF_INT64 * 2 && ptr[-digits] <= '7'))) { - if (dval) { - local_dval = zend_hex_strtod(str, &ptr); - } - type = IS_DOUBLE; - } - } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) { -process_double: - type = IS_DOUBLE; - - // If there's a dval, do the conversion; else continue checking - // the digits if we need to check for a full match. - if (dval) { - local_dval = zend_strtod(str, &ptr); - } else if (dp_or_e != -1) { - dp_or_e = (*ptr++ == '.') ? 1 : 2; - goto check_digits; - } - } else { - return IS_NULL; - } - if (ptr != str + length) { - zend_error(E_NOTICE, "A non well formed numeric value encountered"); - return 0; - } - - if (type == IS_LONG) { - if (digits == MAX_LENGTH_OF_INT64 - 1) { - int cmp = strcmp(&ptr[-digits], int64_min_digits); - - if (!(cmp < 0 || (cmp == 0 && *str == '-'))) { - if (dval) { - *dval = zend_strtod(str, NULL); - } - - return IS_DOUBLE; - } - } - if (lval) { - *lval = strtoll(str, NULL, base); - } - return IS_LONG; - } else { - if (dval) { - *dval = local_dval; - } - return IS_DOUBLE; - } -} - -#define CONVERT_TO_INTEGER(type) \ - static bool convert_int64_to_##type(int64_t val, type##_t* type##_value) { \ - *type##_value = (type##_t)val; \ - return true; \ - } \ - \ - static bool convert_double_to_##type(double val, type##_t* type##_value) { \ - *type##_value = (type##_t)zend_dval_to_lval(val); \ - return true; \ - } \ - \ - static bool convert_string_to_##type(const char* val, int len, \ - type##_t* type##_value) { \ - int64_t lval; \ - double dval; \ - TSRMLS_FETCH(); \ - switch (convert_numeric_string(val, len, &lval, &dval)) { \ - case IS_DOUBLE: { \ - return convert_double_to_##type(dval, type##_value); \ - } \ - case IS_LONG: { \ - return convert_int64_to_##type(lval, type##_value); \ - } \ - default: \ - zend_throw_exception(NULL, \ - "Given string value cannot be converted to integer.", \ - 0 TSRMLS_CC); \ - return false; \ - } \ - } \ - \ - bool protobuf_convert_to_##type(zval* from, type##_t* to) { \ - TSRMLS_FETCH(); \ - switch (Z_TYPE_P(from)) { \ - case IS_LONG: { \ - return convert_int64_to_##type(Z_LVAL_P(from), to); \ - } \ - case IS_DOUBLE: { \ - return convert_double_to_##type(Z_DVAL_P(from), to); \ - } \ - case IS_STRING: { \ - return convert_string_to_##type(Z_STRVAL_P(from), Z_STRLEN_P(from), \ - to); \ - } \ - default: { \ - zend_throw_exception(NULL, \ - "Given value cannot be converted to integer.", \ - 0 TSRMLS_CC); \ - return false; \ - } \ - } \ - return false; \ - } - -CONVERT_TO_INTEGER(int32); -CONVERT_TO_INTEGER(uint32); -CONVERT_TO_INTEGER(int64); -CONVERT_TO_INTEGER(uint64); - -#undef CONVERT_TO_INTEGER - -#define CONVERT_TO_FLOAT(type) \ - static bool convert_int64_to_##type(int64_t val, type* type##_value) { \ - *type##_value = (type)val; \ - return true; \ - } \ - \ - static bool convert_double_to_##type(double val, type* type##_value) { \ - *type##_value = (type)val; \ - return true; \ - } \ - \ - static bool convert_string_to_##type(const char* val, int len, \ - type* type##_value) { \ - int64_t lval; \ - double dval; \ - \ - TSRMLS_FETCH(); \ - switch (convert_numeric_string(val, len, &lval, &dval)) { \ - case IS_DOUBLE: { \ - *type##_value = (type)dval; \ - return true; \ - } \ - case IS_LONG: { \ - *type##_value = (type)lval; \ - return true; \ - } \ - default: \ - zend_throw_exception(NULL, \ - "Given string value cannot be converted to integer.", \ - 0 TSRMLS_CC); \ - return false; \ - } \ - } \ - \ - bool protobuf_convert_to_##type(zval* from, type* to) { \ - TSRMLS_FETCH(); \ - switch (Z_TYPE_P(from)) { \ - case IS_LONG: { \ - return convert_int64_to_##type(Z_LVAL_P(from), to); \ - } \ - case IS_DOUBLE: { \ - return convert_double_to_##type(Z_DVAL_P(from), to); \ - } \ - case IS_STRING: { \ - return convert_string_to_##type(Z_STRVAL_P(from), Z_STRLEN_P(from), \ - to); \ - } \ - default: { \ - zend_throw_exception(NULL, \ - "Given value cannot be converted to integer.", \ - 0 TSRMLS_CC); \ - return false; \ - } \ - } \ - return false; \ - } - -CONVERT_TO_FLOAT(float); -CONVERT_TO_FLOAT(double); - -#undef CONVERT_TO_FLOAT - -bool protobuf_convert_to_bool(zval* from, int8_t* to) { - TSRMLS_FETCH(); - switch (Z_TYPE_P(from)) { -#if PHP_MAJOR_VERSION < 7 - case IS_BOOL: - *to = (int8_t)Z_BVAL_P(from); - break; -#else - case IS_TRUE: - *to = 1; - break; - case IS_FALSE: - *to = 0; - break; -#endif - case IS_LONG: - *to = (int8_t)(Z_LVAL_P(from) != 0); - break; - case IS_DOUBLE: - *to = (int8_t)(Z_LVAL_P(from) != 0); - break; - case IS_STRING: { - if (Z_STRLEN_P(from) == 0 || - (Z_STRLEN_P(from) == 1 && Z_STRVAL_P(from)[0] == '0')) { - *to = 0; - } else { - *to = 1; - } - } break; - default: { - zend_throw_exception( - NULL, "Given value cannot be converted to bool.", - 0 TSRMLS_CC); - return false; - } - } - return true; -} - -bool protobuf_convert_to_string(zval* from) { -#if PHP_MAJOR_VERSION >= 7 - if (Z_ISREF_P(from)) { - ZVAL_DEREF(from); - } -#endif - TSRMLS_FETCH(); - switch (Z_TYPE_P(from)) { - case IS_STRING: { - return true; - } -#if PHP_MAJOR_VERSION < 7 - case IS_BOOL: -#else - case IS_TRUE: - case IS_FALSE: -#endif - case IS_LONG: - case IS_DOUBLE: { - zval tmp; - php_proto_zend_make_printable_zval(from, &tmp); - ZVAL_COPY_VALUE(from, &tmp); - return true; - } - default: - zend_throw_exception( - NULL, "Given value cannot be converted to string.", - 0 TSRMLS_CC); - return false; - } -} - -// ----------------------------------------------------------------------------- -// PHP Functions. -// ----------------------------------------------------------------------------- - -// The implementation of type checking for primitive fields is empty. This is -// because type checking is done when direct assigning message fields (e.g., -// foo->a = 1). Functions defined here are place holders in generated code for -// pure PHP implementation (c extension and pure PHP share the same generated -// code). -#define PHP_TYPE_CHECK(type) \ - PHP_METHOD(Util, check##type) {} - -PHP_TYPE_CHECK(Int32) -PHP_TYPE_CHECK(Uint32) -PHP_TYPE_CHECK(Int64) -PHP_TYPE_CHECK(Uint64) -PHP_TYPE_CHECK(Enum) -PHP_TYPE_CHECK(Float) -PHP_TYPE_CHECK(Double) -PHP_TYPE_CHECK(Bool) -PHP_TYPE_CHECK(String) -PHP_TYPE_CHECK(Bytes) - -#undef PHP_TYPE_CHECK - -PHP_METHOD(Util, checkMessage) { - zval* val; - zend_class_entry* klass = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o!C", &val, &klass) == - FAILURE) { - return; - } - if (val == NULL) { - RETURN_NULL(); - } - if (!instanceof_function(Z_OBJCE_P(val), klass TSRMLS_CC)) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Given value is not an instance of %s.", -#if PHP_MAJOR_VERSION < 7 - klass->name); -#else - ZSTR_VAL(klass->name)); -#endif - return; - } - RETURN_ZVAL(val, 1, 0); -} - -void check_repeated_field(const zend_class_entry* klass, PHP_PROTO_LONG type, - zval* val, zval* return_value) { -#if PHP_MAJOR_VERSION >= 7 - if (Z_ISREF_P(val)) { - ZVAL_DEREF(val); - } -#endif - - TSRMLS_FETCH(); - if (Z_TYPE_P(val) == IS_ARRAY) { - HashTable* table = HASH_OF(val); - HashPosition pointer; - void* memory; - -#if PHP_MAJOR_VERSION < 7 - zval* repeated_field; - MAKE_STD_ZVAL(repeated_field); -#else - zval repeated_field; -#endif - - repeated_field_create_with_type(repeated_field_type, to_fieldtype(type), - klass, &repeated_field TSRMLS_CC); - - for (zend_hash_internal_pointer_reset_ex(table, &pointer); - php_proto_zend_hash_get_current_data_ex(table, (void**)&memory, - &pointer) == SUCCESS; - zend_hash_move_forward_ex(table, &pointer)) { - repeated_field_handlers->write_dimension( - CACHED_TO_ZVAL_PTR(repeated_field), NULL, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); - } - - RETURN_ZVAL(CACHED_TO_ZVAL_PTR(repeated_field), 1, 1); - - } else if (Z_TYPE_P(val) == IS_OBJECT) { - if (!instanceof_function(Z_OBJCE_P(val), repeated_field_type TSRMLS_CC)) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Given value is not an instance of %s.", -#if PHP_MAJOR_VERSION < 7 - repeated_field_type->name); -#else - ZSTR_VAL(repeated_field_type->name)); -#endif - return; - } - RepeatedField* intern = UNBOX(RepeatedField, val); - if (to_fieldtype(type) != intern->type) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Incorrect repeated field type."); - return; - } - if (klass != NULL && intern->msg_ce != klass) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Expect a repeated field of %s, but %s is given.", -#if PHP_MAJOR_VERSION < 7 - klass->name, intern->msg_ce->name); -#else - ZSTR_VAL(klass->name), - ZSTR_VAL(intern->msg_ce->name)); -#endif - return; - } - RETURN_ZVAL(val, 1, 0); - } else { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Incorrect repeated field type."); - return; - } -} - -PHP_METHOD(Util, checkRepeatedField) { - zval* val; - PHP_PROTO_LONG type; - const zend_class_entry* klass = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl|C", &val, &type, - &klass) == FAILURE) { - return; - } - RETURN_ZVAL(val, 1, 0); -} - -void check_map_field(const zend_class_entry* klass, PHP_PROTO_LONG key_type, - PHP_PROTO_LONG value_type, zval* val, zval* return_value) { -#if PHP_MAJOR_VERSION >= 7 - if (Z_ISREF_P(val)) { - ZVAL_DEREF(val); - } -#endif - - TSRMLS_FETCH(); - if (Z_TYPE_P(val) == IS_ARRAY) { - HashTable* table = Z_ARRVAL_P(val); - HashPosition pointer; - zval key; - void* value; - -#if PHP_MAJOR_VERSION < 7 - zval* map_field; - MAKE_STD_ZVAL(map_field); -#else - zval map_field; -#endif - - map_field_create_with_type(map_field_type, to_fieldtype(key_type), - to_fieldtype(value_type), klass, - &map_field TSRMLS_CC); - - for (zend_hash_internal_pointer_reset_ex(table, &pointer); - php_proto_zend_hash_get_current_data_ex(table, (void**)&value, - &pointer) == SUCCESS; - zend_hash_move_forward_ex(table, &pointer)) { - zend_hash_get_current_key_zval_ex(table, &key, &pointer); - map_field_handlers->write_dimension( - CACHED_TO_ZVAL_PTR(map_field), &key, - CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value) TSRMLS_CC); - zval_dtor(&key); - } - - RETURN_ZVAL(CACHED_TO_ZVAL_PTR(map_field), 1, 1); - } else if (Z_TYPE_P(val) == IS_OBJECT) { - if (!instanceof_function(Z_OBJCE_P(val), map_field_type TSRMLS_CC)) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Given value is not an instance of %s.", -#if PHP_MAJOR_VERSION < 7 - map_field_type->name); -#else - ZSTR_VAL(map_field_type->name)); -#endif - return; - } - Map* intern = UNBOX(Map, val); - if (to_fieldtype(key_type) != intern->key_type) { - zend_throw_exception( - NULL, "Incorrect map field key type.", - 0 TSRMLS_CC); - return; - } - if (to_fieldtype(value_type) != intern->value_type) { - zend_throw_exception( - NULL, "Incorrect map field value type.", - 0 TSRMLS_CC); - return; - } - if (klass != NULL && intern->msg_ce != klass) { - zend_throw_exception_ex(NULL, 0 TSRMLS_CC, - "Expect a map field of %s, but %s is given.", -#if PHP_MAJOR_VERSION < 7 - klass->name, intern->msg_ce->name); -#else - ZSTR_VAL(klass->name), - ZSTR_VAL(intern->msg_ce->name)); -#endif - return; - } - RETURN_ZVAL(val, 1, 0); - } else { - zend_throw_exception( - NULL, "Incorrect map field type.", - 0 TSRMLS_CC); - return; - } -} - -PHP_METHOD(Util, checkMapField) { - zval* val; - PHP_PROTO_LONG key_type, value_type; - const zend_class_entry* klass = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll|C", &val, &key_type, - &value_type, &klass) == FAILURE) { - return; - } - RETURN_ZVAL(val, 1, 0); -} diff --git a/php/ext/google/protobuf/upb.c b/php/ext/google/protobuf/upb.c deleted file mode 100644 index 7608fe727c8f..000000000000 --- a/php/ext/google/protobuf/upb.c +++ /dev/null @@ -1,13302 +0,0 @@ -/* Amalgamated source file */ -#include "upb.h" -/* -* This is where we define macros used across upb. -* -* All of these macros are undef'd in port_undef.inc to avoid leaking them to -* users. -* -* The correct usage is: -* -* #include "upb/foobar.h" -* #include "upb/baz.h" -* -* // MUST be last included header. -* #include "upb/port_def.inc" -* -* // Code for this file. -* // <...> -* -* // Can be omitted for .c files, required for .h. -* #include "upb/port_undef.inc" -* -* This file is private and must not be included by users! -*/ -#ifndef UINTPTR_MAX -#error must include stdint.h first -#endif - -#if UINTPTR_MAX == 0xffffffff -#define UPB_SIZE(size32, size64) size32 -#else -#define UPB_SIZE(size32, size64) size64 -#endif - -#define UPB_FIELD_AT(msg, fieldtype, offset) \ - *(fieldtype*)((const char*)(msg) + offset) - -#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ - UPB_FIELD_AT(msg, int, case_offset) == case_val \ - ? UPB_FIELD_AT(msg, fieldtype, offset) \ - : default - -#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ - UPB_FIELD_AT(msg, int, case_offset) = case_val; \ - UPB_FIELD_AT(msg, fieldtype, offset) = value; - -/* UPB_INLINE: inline if possible, emit standalone code if required. */ -#ifdef __cplusplus -#define UPB_INLINE inline -#elif defined (__GNUC__) || defined(__clang__) -#define UPB_INLINE static __inline__ -#else -#define UPB_INLINE static -#endif - -/* Hints to the compiler about likely/unlikely branches. */ -#if defined (__GNUC__) || defined(__clang__) -#define UPB_LIKELY(x) __builtin_expect((x),1) -#define UPB_UNLIKELY(x) __builtin_expect((x),0) -#else -#define UPB_LIKELY(x) (x) -#define UPB_UNLIKELY(x) (x) -#endif - -/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler - * doesn't provide these preprocessor symbols. */ -#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define UPB_BIG_ENDIAN -#endif - -/* Macros for function attributes on compilers that support them. */ -#ifdef __GNUC__ -#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) -#define UPB_NOINLINE __attribute__((noinline)) -#define UPB_NORETURN __attribute__((__noreturn__)) -#else /* !defined(__GNUC__) */ -#define UPB_FORCEINLINE -#define UPB_NOINLINE -#define UPB_NORETURN -#endif - -#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L -/* C99/C++11 versions. */ -#include -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined(_MSC_VER) -/* Microsoft C/C++ versions. */ -#include -#include -#if _MSC_VER < 1900 -int msvc_snprintf(char* s, size_t n, const char* format, ...); -int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); -#define UPB_MSVC_VSNPRINTF -#define _upb_snprintf msvc_snprintf -#define _upb_vsnprintf msvc_vsnprintf -#else -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#endif -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined __GNUC__ -/* A few hacky workarounds for functions not in C89. - * For internal use only! - * TODO(haberman): fix these by including our own implementations, or finding - * another workaround. - */ -#define _upb_snprintf __builtin_snprintf -#define _upb_vsnprintf __builtin_vsnprintf -#define _upb_va_copy(a, b) __va_copy(a, b) -#else -#error Need implementations of [v]snprintf and va_copy -#endif - -#ifdef __cplusplus -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) -/* C++11 is present */ -#else -#error upb requires C++11 for C++ support -#endif -#endif - -#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) -#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) - -#define UPB_UNUSED(var) (void)var - -/* UPB_ASSERT(): in release mode, we use the expression without letting it be - * evaluated. This prevents "unused variable" warnings. */ -#ifdef NDEBUG -#define UPB_ASSERT(expr) do {} while (false && (expr)) -#else -#define UPB_ASSERT(expr) assert(expr) -#endif - -/* UPB_ASSERT_DEBUGVAR(): assert that uses functions or variables that only - * exist in debug mode. This turns into regular assert. */ -#define UPB_ASSERT_DEBUGVAR(expr) assert(expr) - -#if defined(__GNUC__) || defined(__clang__) -#define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0) -#else -#define UPB_UNREACHABLE() do { assert(0); } while(0) -#endif - -/* UPB_INFINITY representing floating-point positive infinity. */ -#include -#ifdef INFINITY -#define UPB_INFINITY INFINITY -#else -#define UPB_INFINITY (1.0 / 0.0) -#endif - -#include - - -/* Maps descriptor type -> upb field type. */ -const uint8_t upb_desctype_to_fieldtype[] = { - UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */ - UPB_TYPE_DOUBLE, /* DOUBLE */ - UPB_TYPE_FLOAT, /* FLOAT */ - UPB_TYPE_INT64, /* INT64 */ - UPB_TYPE_UINT64, /* UINT64 */ - UPB_TYPE_INT32, /* INT32 */ - UPB_TYPE_UINT64, /* FIXED64 */ - UPB_TYPE_UINT32, /* FIXED32 */ - UPB_TYPE_BOOL, /* BOOL */ - UPB_TYPE_STRING, /* STRING */ - UPB_TYPE_MESSAGE, /* GROUP */ - UPB_TYPE_MESSAGE, /* MESSAGE */ - UPB_TYPE_BYTES, /* BYTES */ - UPB_TYPE_UINT32, /* UINT32 */ - UPB_TYPE_ENUM, /* ENUM */ - UPB_TYPE_INT32, /* SFIXED32 */ - UPB_TYPE_INT64, /* SFIXED64 */ - UPB_TYPE_INT32, /* SINT32 */ - UPB_TYPE_INT64, /* SINT64 */ -}; - -/* Data pertaining to the parse. */ -typedef struct { - const char *ptr; /* Current parsing position. */ - const char *field_start; /* Start of this field. */ - const char *limit; /* End of delimited region or end of buffer. */ - upb_arena *arena; - int depth; - uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ -} upb_decstate; - -/* Data passed by value to each parsing function. */ -typedef struct { - char *msg; - const upb_msglayout *layout; - upb_decstate *state; -} upb_decframe; - -#define CHK(x) if (!(x)) { return 0; } - -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number); -static bool upb_decode_message(upb_decstate *d, char *msg, - const upb_msglayout *l); - -static bool upb_decode_varint(const char **ptr, const char *limit, - uint64_t *val) { - uint8_t byte; - int bitpos = 0; - const char *p = *ptr; - *val = 0; - - do { - CHK(bitpos < 70 && p < limit); - byte = *p; - *val |= (uint64_t)(byte & 0x7F) << bitpos; - p++; - bitpos += 7; - } while (byte & 0x80); - - *ptr = p; - return true; -} - -static bool upb_decode_varint32(const char **ptr, const char *limit, - uint32_t *val) { - uint64_t u64; - CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX); - *val = (uint32_t)u64; - return true; -} - -static bool upb_decode_64bit(const char **ptr, const char *limit, - uint64_t *val) { - CHK(limit - *ptr >= 8); - memcpy(val, *ptr, 8); - *ptr += 8; - return true; -} - -static bool upb_decode_32bit(const char **ptr, const char *limit, - uint32_t *val) { - CHK(limit - *ptr >= 4); - memcpy(val, *ptr, 4); - *ptr += 4; - return true; -} - -static int32_t upb_zzdecode_32(uint32_t n) { - return (n >> 1) ^ -(int32_t)(n & 1); -} - -static int64_t upb_zzdecode_64(uint64_t n) { - return (n >> 1) ^ -(int64_t)(n & 1); -} - -static bool upb_decode_string(const char **ptr, const char *limit, - int *outlen) { - uint32_t len; - - CHK(upb_decode_varint32(ptr, limit, &len) && - len < INT32_MAX && - limit - *ptr >= (int32_t)len); - - *outlen = len; - return true; -} - -static void upb_set32(void *msg, size_t ofs, uint32_t val) { - memcpy((char*)msg + ofs, &val, sizeof(val)); -} - -static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame) { - upb_msg_addunknown(frame->msg, d->field_start, d->ptr - d->field_start, - d->arena); - return true; -} - - -static bool upb_skip_unknownfielddata(upb_decstate *d, uint32_t tag, - uint32_t group_fieldnum) { - switch (tag & 7) { - case UPB_WIRE_TYPE_VARINT: { - uint64_t val; - return upb_decode_varint(&d->ptr, d->limit, &val); - } - case UPB_WIRE_TYPE_32BIT: { - uint32_t val; - return upb_decode_32bit(&d->ptr, d->limit, &val); - } - case UPB_WIRE_TYPE_64BIT: { - uint64_t val; - return upb_decode_64bit(&d->ptr, d->limit, &val); - } - case UPB_WIRE_TYPE_DELIMITED: { - int len; - CHK(upb_decode_string(&d->ptr, d->limit, &len)); - d->ptr += len; - return true; - } - case UPB_WIRE_TYPE_START_GROUP: - return upb_skip_unknowngroup(d, tag >> 3); - case UPB_WIRE_TYPE_END_GROUP: - return (tag >> 3) == group_fieldnum; - } - return false; -} - -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number) { - while (d->ptr < d->limit && d->end_group == 0) { - uint32_t tag = 0; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); - CHK(upb_skip_unknownfielddata(d, tag, field_number)); - } - - CHK(d->end_group == field_number); - d->end_group = 0; - return true; -} - -static bool upb_array_grow(upb_array *arr, size_t elements, size_t elem_size, - upb_arena *arena) { - size_t needed = arr->len + elements; - size_t new_size = UPB_MAX(arr->size, 8); - size_t new_bytes; - size_t old_bytes; - void *new_data; - upb_alloc *alloc = upb_arena_alloc(arena); - - while (new_size < needed) { - new_size *= 2; - } - - old_bytes = arr->len * elem_size; - new_bytes = new_size * elem_size; - new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes); - CHK(new_data); - - arr->data = new_data; - arr->size = new_size; - return true; -} - -static void *upb_array_reserve(upb_array *arr, size_t elements, - size_t elem_size, upb_arena *arena) { - if (arr->size - arr->len < elements) { - CHK(upb_array_grow(arr, elements, elem_size, arena)); - } - return (char*)arr->data + (arr->len * elem_size); -} - -bool upb_array_add(upb_array *arr, size_t elements, size_t elem_size, - const void *data, upb_arena *arena) { - void *dest = upb_array_reserve(arr, elements, elem_size, arena); - - CHK(dest); - arr->len += elements; - memcpy(dest, data, elements * elem_size); - - return true; -} - -static upb_array *upb_getarr(upb_decframe *frame, - const upb_msglayout_field *field) { - UPB_ASSERT(field->label == UPB_LABEL_REPEATED); - return *(upb_array**)&frame->msg[field->offset]; -} - -static upb_array *upb_getorcreatearr(upb_decframe *frame, - const upb_msglayout_field *field) { - upb_array *arr = upb_getarr(frame, field); - - if (!arr) { - arr = upb_array_new(frame->state->arena); - CHK(arr); - *(upb_array**)&frame->msg[field->offset] = arr; - } - - return arr; -} - -static upb_msg *upb_getorcreatemsg(upb_decframe *frame, - const upb_msglayout_field *field, - const upb_msglayout **subm) { - upb_msg **submsg = (void*)(frame->msg + field->offset); - *subm = frame->layout->submsgs[field->submsg_index]; - - UPB_ASSERT(field->label != UPB_LABEL_REPEATED); - - if (!*submsg) { - *submsg = upb_msg_new(*subm, frame->state->arena); - CHK(*submsg); - } - - return *submsg; -} - -static upb_msg *upb_addmsg(upb_decframe *frame, - const upb_msglayout_field *field, - const upb_msglayout **subm) { - upb_msg *submsg; - upb_array *arr = upb_getorcreatearr(frame, field); - - *subm = frame->layout->submsgs[field->submsg_index]; - submsg = upb_msg_new(*subm, frame->state->arena); - CHK(submsg); - upb_array_add(arr, 1, sizeof(submsg), &submsg, frame->state->arena); - - return submsg; -} - -static void upb_sethasbit(upb_decframe *frame, - const upb_msglayout_field *field) { - int32_t hasbit = field->presence; - UPB_ASSERT(field->presence > 0); - frame->msg[hasbit / 8] |= (1 << (hasbit % 8)); -} - -static void upb_setoneofcase(upb_decframe *frame, - const upb_msglayout_field *field) { - UPB_ASSERT(field->presence < 0); - upb_set32(frame->msg, ~field->presence, field->number); -} - -static bool upb_decode_addval(upb_decframe *frame, - const upb_msglayout_field *field, void *val, - size_t size) { - char *field_mem = frame->msg + field->offset; - upb_array *arr; - - if (field->label == UPB_LABEL_REPEATED) { - arr = upb_getorcreatearr(frame, field); - CHK(arr); - field_mem = upb_array_reserve(arr, 1, size, frame->state->arena); - CHK(field_mem); - } - - memcpy(field_mem, val, size); - return true; -} - -static void upb_decode_setpresent(upb_decframe *frame, - const upb_msglayout_field *field) { - if (field->label == UPB_LABEL_REPEATED) { - upb_array *arr = upb_getarr(frame, field); - UPB_ASSERT(arr->len < arr->size); - arr->len++; - } else if (field->presence < 0) { - upb_setoneofcase(frame, field); - } else if (field->presence > 0) { - upb_sethasbit(frame, field); - } -} - -static bool upb_decode_msgfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, int limit) { - const char* saved_limit = d->limit; - d->limit = d->ptr + limit; - CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); - d->depth++; - d->limit = saved_limit; - CHK(d->end_group == 0); - return true; -} - -static bool upb_decode_groupfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, - int field_number) { - CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); - d->depth++; - CHK(d->end_group == field_number); - d->end_group = 0; - return true; -} - -static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint64_t val; - CHK(upb_decode_varint(&d->ptr, d->limit, &val)); - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); - break; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_ENUM: { - uint32_t val32 = (uint32_t)val; - CHK(upb_decode_addval(frame, field, &val32, sizeof(val32))); - break; - } - case UPB_DESCRIPTOR_TYPE_BOOL: { - bool valbool = val != 0; - CHK(upb_decode_addval(frame, field, &valbool, sizeof(valbool))); - break; - } - case UPB_DESCRIPTOR_TYPE_SINT32: { - int32_t decoded = upb_zzdecode_32((uint32_t)val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); - break; - } - case UPB_DESCRIPTOR_TYPE_SINT64: { - int64_t decoded = upb_zzdecode_64(val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); - break; - } - default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint64_t val; - CHK(upb_decode_64bit(&d->ptr, d->limit, &val)); - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - case UPB_DESCRIPTOR_TYPE_FIXED64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); - break; - default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint32_t val; - CHK(upb_decode_32bit(&d->ptr, d->limit, &val)); - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_FLOAT: - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); - break; - default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_fixedpacked(upb_decstate *d, upb_array *arr, - uint32_t len, int elem_size) { - size_t elements = len / elem_size; - - CHK((size_t)(elements * elem_size) == len); - CHK(upb_array_add(arr, elements, elem_size, d->ptr, d->arena)); - d->ptr += len; - - return true; -} - -static upb_strview upb_decode_strfield(upb_decstate *d, uint32_t len) { - upb_strview ret; - ret.data = d->ptr; - ret.size = len; - d->ptr += len; - return ret; -} - -static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field, int len) { - upb_array *arr = upb_getorcreatearr(frame, field); - CHK(arr); - -#define VARINT_CASE(ctype, decode) \ - VARINT_CASE_EX(ctype, decode, decode) - -#define VARINT_CASE_EX(ctype, decode, dtype) \ - { \ - const char *ptr = d->ptr; \ - const char *limit = ptr + len; \ - while (ptr < limit) { \ - uint64_t val; \ - ctype decoded; \ - CHK(upb_decode_varint(&ptr, limit, &val)); \ - decoded = (decode)((dtype)val); \ - CHK(upb_array_add(arr, 1, sizeof(decoded), &decoded, d->arena)); \ - } \ - d->ptr = ptr; \ - return true; \ - } - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - return upb_array_add(arr, 1, sizeof(str), &str, d->arena); - } - case UPB_DESCRIPTOR_TYPE_FLOAT: - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - return upb_decode_fixedpacked(d, arr, len, sizeof(int32_t)); - case UPB_DESCRIPTOR_TYPE_DOUBLE: - case UPB_DESCRIPTOR_TYPE_FIXED64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - return upb_decode_fixedpacked(d, arr, len, sizeof(int64_t)); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_ENUM: - VARINT_CASE(uint32_t, uint32_t); - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - VARINT_CASE(uint64_t, uint64_t); - case UPB_DESCRIPTOR_TYPE_BOOL: - VARINT_CASE(bool, bool); - case UPB_DESCRIPTOR_TYPE_SINT32: - VARINT_CASE_EX(int32_t, upb_zzdecode_32, uint32_t); - case UPB_DESCRIPTOR_TYPE_SINT64: - VARINT_CASE_EX(int64_t, upb_zzdecode_64, uint64_t); - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_addmsg(frame, field, &subm); - CHK(submsg); - return upb_decode_msgfield(d, submsg, subm, len); - } - case UPB_DESCRIPTOR_TYPE_GROUP: - return upb_append_unknown(d, frame); - } -#undef VARINT_CASE - UPB_UNREACHABLE(); -} - -static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - int len; - - CHK(upb_decode_string(&d->ptr, d->limit, &len)); - - if (field->label == UPB_LABEL_REPEATED) { - return upb_decode_toarray(d, frame, field, len); - } else { - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - CHK(upb_decode_addval(frame, field, &str, sizeof(str))); - break; - } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_getorcreatemsg(frame, field, &subm); - CHK(submsg); - CHK(upb_decode_msgfield(d, submsg, subm, len)); - break; - } - default: - /* TODO(haberman): should we accept the last element of a packed? */ - d->ptr += len; - return upb_append_unknown(d, frame); - } - upb_decode_setpresent(frame, field); - return true; - } -} - -static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, - uint32_t field_number) { - /* Lots of optimization opportunities here. */ - int i; - for (i = 0; i < l->field_count; i++) { - if (l->fields[i].number == field_number) { - return &l->fields[i]; - } - } - - return NULL; /* Unknown field. */ -} - -static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) { - uint32_t tag; - const upb_msglayout_field *field; - int field_number; - - d->field_start = d->ptr; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); - field_number = tag >> 3; - field = upb_find_field(frame->layout, field_number); - - if (field) { - switch (tag & 7) { - case UPB_WIRE_TYPE_VARINT: - return upb_decode_varintfield(d, frame, field); - case UPB_WIRE_TYPE_32BIT: - return upb_decode_32bitfield(d, frame, field); - case UPB_WIRE_TYPE_64BIT: - return upb_decode_64bitfield(d, frame, field); - case UPB_WIRE_TYPE_DELIMITED: - return upb_decode_delimitedfield(d, frame, field); - case UPB_WIRE_TYPE_START_GROUP: { - const upb_msglayout *layout; - upb_msg *group; - - if (field->label == UPB_LABEL_REPEATED) { - group = upb_addmsg(frame, field, &layout); - } else { - group = upb_getorcreatemsg(frame, field, &layout); - } - - return upb_decode_groupfield(d, group, layout, field_number); - } - case UPB_WIRE_TYPE_END_GROUP: - d->end_group = field_number; - return true; - default: - CHK(false); - } - } else { - CHK(field_number != 0); - CHK(upb_skip_unknownfielddata(d, tag, -1)); - CHK(upb_append_unknown(d, frame)); - return true; - } - UPB_UNREACHABLE(); -} - -static bool upb_decode_message(upb_decstate *d, char *msg, const upb_msglayout *l) { - upb_decframe frame; - frame.msg = msg; - frame.layout = l; - frame.state = d; - - while (d->ptr < d->limit) { - CHK(upb_decode_field(d, &frame)); - } - - return true; -} - -bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, - upb_arena *arena) { - upb_decstate state; - state.ptr = buf; - state.limit = buf + size; - state.arena = arena; - state.depth = 64; - state.end_group = 0; - - CHK(upb_decode_message(&state, msg, l)); - return state.end_group == 0; -} - -#undef CHK -/* We encode backwards, to avoid pre-computing lengths (one-pass encode). */ - - -#include - - - -#define UPB_PB_VARINT_MAX_LEN 10 -#define CHK(x) do { if (!(x)) { return false; } } while(0) - -static size_t upb_encode_varint(uint64_t val, char *buf) { - size_t i; - if (val < 128) { buf[0] = val; return 1; } - i = 0; - while (val) { - uint8_t byte = val & 0x7fU; - val >>= 7; - if (val) byte |= 0x80U; - buf[i++] = byte; - } - return i; -} - -static uint32_t upb_zzencode_32(int32_t n) { return ((uint32_t)n << 1) ^ (n >> 31); } -static uint64_t upb_zzencode_64(int64_t n) { return ((uint64_t)n << 1) ^ (n >> 63); } - -typedef struct { - upb_alloc *alloc; - char *buf, *ptr, *limit; -} upb_encstate; - -static size_t upb_roundup_pow2(size_t bytes) { - size_t ret = 128; - while (ret < bytes) { - ret *= 2; - } - return ret; -} - -static bool upb_encode_growbuffer(upb_encstate *e, size_t bytes) { - size_t old_size = e->limit - e->buf; - size_t new_size = upb_roundup_pow2(bytes + (e->limit - e->ptr)); - char *new_buf = upb_realloc(e->alloc, e->buf, old_size, new_size); - CHK(new_buf); - - /* We want previous data at the end, realloc() put it at the beginning. */ - if (old_size > 0) { - memmove(new_buf + new_size - old_size, e->buf, old_size); - } - - e->ptr = new_buf + new_size - (e->limit - e->ptr); - e->limit = new_buf + new_size; - e->buf = new_buf; - return true; -} - -/* Call to ensure that at least "bytes" bytes are available for writing at - * e->ptr. Returns false if the bytes could not be allocated. */ -static bool upb_encode_reserve(upb_encstate *e, size_t bytes) { - CHK(UPB_LIKELY((size_t)(e->ptr - e->buf) >= bytes) || - upb_encode_growbuffer(e, bytes)); - - e->ptr -= bytes; - return true; -} - -/* Writes the given bytes to the buffer, handling reserve/advance. */ -static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) { - CHK(upb_encode_reserve(e, len)); - memcpy(e->ptr, data, len); - return true; -} - -static bool upb_put_fixed64(upb_encstate *e, uint64_t val) { - /* TODO(haberman): byte-swap for big endian. */ - return upb_put_bytes(e, &val, sizeof(uint64_t)); -} - -static bool upb_put_fixed32(upb_encstate *e, uint32_t val) { - /* TODO(haberman): byte-swap for big endian. */ - return upb_put_bytes(e, &val, sizeof(uint32_t)); -} - -static bool upb_put_varint(upb_encstate *e, uint64_t val) { - size_t len; - char *start; - CHK(upb_encode_reserve(e, UPB_PB_VARINT_MAX_LEN)); - len = upb_encode_varint(val, e->ptr); - start = e->ptr + UPB_PB_VARINT_MAX_LEN - len; - memmove(start, e->ptr, len); - e->ptr = start; - return true; -} - -static bool upb_put_double(upb_encstate *e, double d) { - uint64_t u64; - UPB_ASSERT(sizeof(double) == sizeof(uint64_t)); - memcpy(&u64, &d, sizeof(uint64_t)); - return upb_put_fixed64(e, u64); -} - -static bool upb_put_float(upb_encstate *e, float d) { - uint32_t u32; - UPB_ASSERT(sizeof(float) == sizeof(uint32_t)); - memcpy(&u32, &d, sizeof(uint32_t)); - return upb_put_fixed32(e, u32); -} - -static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) { - uint32_t ret; - uint32_t offset = ~f->presence; - memcpy(&ret, msg + offset, sizeof(ret)); - return ret; -} - -static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) { - uint32_t hasbit = f->presence; - UPB_ASSERT(f->presence > 0); - return msg[hasbit / 8] & (1 << (hasbit % 8)); -} - -static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) { - return upb_put_varint(e, (field_number << 3) | wire_type); -} - -static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr, - size_t size) { - size_t bytes = arr->len * size; - return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes); -} - -bool upb_encode_message(upb_encstate *e, const char *msg, - const upb_msglayout *m, size_t *size); - -static bool upb_encode_array(upb_encstate *e, const char *field_mem, - const upb_msglayout *m, - const upb_msglayout_field *f) { - const upb_array *arr = *(const upb_array**)field_mem; - - if (arr == NULL || arr->len == 0) { - return true; - } - -#define VARINT_CASE(ctype, encode) { \ - ctype *start = arr->data; \ - ctype *ptr = start + arr->len; \ - size_t pre_len = e->limit - e->ptr; \ - do { \ - ptr--; \ - CHK(upb_put_varint(e, encode)); \ - } while (ptr != start); \ - CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \ -} \ -break; \ -do { ; } while(0) - - switch (f->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - CHK(upb_put_fixedarray(e, arr, sizeof(double))); - break; - case UPB_DESCRIPTOR_TYPE_FLOAT: - CHK(upb_put_fixedarray(e, arr, sizeof(float))); - break; - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t))); - break; - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t))); - break; - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - VARINT_CASE(uint64_t, *ptr); - case UPB_DESCRIPTOR_TYPE_UINT32: - VARINT_CASE(uint32_t, *ptr); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_ENUM: - VARINT_CASE(int32_t, (int64_t)*ptr); - case UPB_DESCRIPTOR_TYPE_BOOL: - VARINT_CASE(bool, *ptr); - case UPB_DESCRIPTOR_TYPE_SINT32: - VARINT_CASE(int32_t, upb_zzencode_32(*ptr)); - case UPB_DESCRIPTOR_TYPE_SINT64: - VARINT_CASE(int64_t, upb_zzencode_64(*ptr)); - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview *start = arr->data; - upb_strview *ptr = start + arr->len; - do { - ptr--; - CHK(upb_put_bytes(e, ptr->data, ptr->size) && - upb_put_varint(e, ptr->size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); - } while (ptr != start); - return true; - } - case UPB_DESCRIPTOR_TYPE_GROUP: { - void **start = arr->data; - void **ptr = start + arr->len; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; - do { - size_t size; - ptr--; - CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) && - upb_encode_message(e, *ptr, subm, &size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP)); - } while (ptr != start); - return true; - } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - void **start = arr->data; - void **ptr = start + arr->len; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; - do { - size_t size; - ptr--; - CHK(upb_encode_message(e, *ptr, subm, &size) && - upb_put_varint(e, size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); - } while (ptr != start); - return true; - } - } -#undef VARINT_CASE - - /* We encode all primitive arrays as packed, regardless of what was specified - * in the .proto file. Could special case 1-sized arrays. */ - CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); - return true; -} - -static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem, - const upb_msglayout *m, - const upb_msglayout_field *f, - bool skip_zero_value) { -#define CASE(ctype, type, wire_type, encodeval) do { \ - ctype val = *(ctype*)field_mem; \ - if (skip_zero_value && val == 0) { \ - return true; \ - } \ - return upb_put_ ## type(e, encodeval) && \ - upb_put_tag(e, f->number, wire_type); \ -} while(0) - - switch (f->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - CASE(double, double, UPB_WIRE_TYPE_64BIT, val); - case UPB_DESCRIPTOR_TYPE_FLOAT: - CASE(float, float, UPB_WIRE_TYPE_32BIT, val); - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_UINT32: - CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_ENUM: - CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val); - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val); - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val); - case UPB_DESCRIPTOR_TYPE_BOOL: - CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_SINT32: - CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val)); - case UPB_DESCRIPTOR_TYPE_SINT64: - CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val)); - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview view = *(upb_strview*)field_mem; - if (skip_zero_value && view.size == 0) { - return true; - } - return upb_put_bytes(e, view.data, view.size) && - upb_put_varint(e, view.size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); - } - case UPB_DESCRIPTOR_TYPE_GROUP: { - size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; - if (submsg == NULL) { - return true; - } - return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) && - upb_encode_message(e, submsg, subm, &size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); - } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; - if (submsg == NULL) { - return true; - } - return upb_encode_message(e, submsg, subm, &size) && - upb_put_varint(e, size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); - } - } -#undef CASE - UPB_UNREACHABLE(); -} - -bool upb_encode_message(upb_encstate *e, const char *msg, - const upb_msglayout *m, size_t *size) { - int i; - size_t pre_len = e->limit - e->ptr; - const char *unknown; - size_t unknown_size; - - for (i = m->field_count - 1; i >= 0; i--) { - const upb_msglayout_field *f = &m->fields[i]; - - if (f->label == UPB_LABEL_REPEATED) { - CHK(upb_encode_array(e, msg + f->offset, m, f)); - } else { - bool skip_empty = false; - if (f->presence == 0) { - /* Proto3 presence. */ - skip_empty = true; - } else if (f->presence > 0) { - /* Proto2 presence: hasbit. */ - if (!upb_readhasbit(msg, f)) { - continue; - } - } else { - /* Field is in a oneof. */ - if (upb_readcase(msg, f) != f->number) { - continue; - } - } - CHK(upb_encode_scalarfield(e, msg + f->offset, m, f, skip_empty)); - } - } - - unknown = upb_msg_getunknown(msg, &unknown_size); - - if (unknown) { - upb_put_bytes(e, unknown, unknown_size); - } - - *size = (e->limit - e->ptr) - pre_len; - return true; -} - -char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, - size_t *size) { - upb_encstate e; - e.alloc = upb_arena_alloc(arena); - e.buf = NULL; - e.limit = NULL; - e.ptr = NULL; - - if (!upb_encode_message(&e, msg, m, size)) { - *size = 0; - return NULL; - } - - *size = e.limit - e.ptr; - - if (*size == 0) { - static char ch; - return &ch; - } else { - UPB_ASSERT(e.ptr); - return e.ptr; - } -} - -#undef CHK - - - - -#define VOIDPTR_AT(msg, ofs) (void*)((char*)msg + (int)ofs) - -/* Internal members of a upb_msg. We can change this without breaking binary - * compatibility. We put these before the user's data. The user's upb_msg* - * points after the upb_msg_internal. */ - -/* Used when a message is not extendable. */ -typedef struct { - char *unknown; - size_t unknown_len; - size_t unknown_size; -} upb_msg_internal; - -/* Used when a message is extendable. */ -typedef struct { - upb_inttable *extdict; - upb_msg_internal base; -} upb_msg_internal_withext; - -static int upb_msg_internalsize(const upb_msglayout *l) { - return sizeof(upb_msg_internal) - l->extendable * sizeof(void *); -} - -static size_t upb_msg_sizeof(const upb_msglayout *l) { - return l->size + upb_msg_internalsize(l); -} - -static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) { - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal)); -} - -static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) { - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal)); -} - -static upb_msg_internal_withext *upb_msg_getinternalwithext( - upb_msg *msg, const upb_msglayout *l) { - UPB_ASSERT(l->extendable); - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext)); -} - -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) { - upb_alloc *alloc = upb_arena_alloc(a); - void *mem = upb_malloc(alloc, upb_msg_sizeof(l)); - upb_msg_internal *in; - upb_msg *msg; - - if (!mem) { - return NULL; - } - - msg = VOIDPTR_AT(mem, upb_msg_internalsize(l)); - - /* Initialize normal members. */ - memset(msg, 0, l->size); - - /* Initialize internal members. */ - in = upb_msg_getinternal(msg); - in->unknown = NULL; - in->unknown_len = 0; - in->unknown_size = 0; - - if (l->extendable) { - upb_msg_getinternalwithext(msg, l)->extdict = NULL; - } - - return msg; -} - -upb_array *upb_array_new(upb_arena *a) { - upb_array *ret = upb_arena_malloc(a, sizeof(upb_array)); - - if (!ret) { - return NULL; - } - - ret->data = NULL; - ret->len = 0; - ret->size = 0; - - return ret; -} - -void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena) { - upb_msg_internal *in = upb_msg_getinternal(msg); - if (len > in->unknown_size - in->unknown_len) { - upb_alloc *alloc = upb_arena_alloc(arena); - size_t need = in->unknown_size + len; - size_t newsize = UPB_MAX(in->unknown_size * 2, need); - in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize); - in->unknown_size = newsize; - } - memcpy(in->unknown + in->unknown_len, data, len); - in->unknown_len += len; -} - -const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { - const upb_msg_internal* in = upb_msg_getinternal_const(msg); - *len = in->unknown_len; - return in->unknown; -} - -#undef VOIDPTR_AT - - -#ifdef UPB_MSVC_VSNPRINTF -/* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and - * vsnprintf. To support them, missing functions are manually implemented - * using the existing secure functions. */ -int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) { - if (!s) { - return _vscprintf(format, arg); - } - int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg); - if (ret < 0) { - ret = _vscprintf(format, arg); - } - return ret; -} - -int msvc_snprintf(char* s, size_t n, const char* format, ...) { - va_list arg; - va_start(arg, format); - int ret = msvc_vsnprintf(s, n, format, arg); - va_end(arg); - return ret; -} -#endif -/* -** upb_table Implementation -** -** Implementation is heavily inspired by Lua's ltable.c. -*/ - - -#include - - -#define UPB_MAXARRSIZE 16 /* 64k. */ - -/* From Chromium. */ -#define ARRAY_SIZE(x) \ - ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) - -static void upb_check_alloc(upb_table *t, upb_alloc *a) { - UPB_UNUSED(t); - UPB_UNUSED(a); - UPB_ASSERT_DEBUGVAR(t->alloc == a); -} - -static const double MAX_LOAD = 0.85; - -/* The minimum utilization of the array part of a mixed hash/array table. This - * is a speed/memory-usage tradeoff (though it's not straightforward because of - * cache effects). The lower this is, the more memory we'll use. */ -static const double MIN_DENSITY = 0.1; - -bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; } - -int log2ceil(uint64_t v) { - int ret = 0; - bool pow2 = is_pow2(v); - while (v >>= 1) ret++; - ret = pow2 ? ret : ret + 1; /* Ceiling. */ - return UPB_MIN(UPB_MAXARRSIZE, ret); -} - -char *upb_strdup(const char *s, upb_alloc *a) { - return upb_strdup2(s, strlen(s), a); -} - -char *upb_strdup2(const char *s, size_t len, upb_alloc *a) { - size_t n; - char *p; - - /* Prevent overflow errors. */ - if (len == SIZE_MAX) return NULL; - /* Always null-terminate, even if binary data; but don't rely on the input to - * have a null-terminating byte since it may be a raw binary buffer. */ - n = len + 1; - p = upb_malloc(a, n); - if (p) { - memcpy(p, s, len); - p[len] = 0; - } - return p; -} - -/* A type to represent the lookup key of either a strtable or an inttable. */ -typedef union { - uintptr_t num; - struct { - const char *str; - size_t len; - } str; -} lookupkey_t; - -static lookupkey_t strkey2(const char *str, size_t len) { - lookupkey_t k; - k.str.str = str; - k.str.len = len; - return k; -} - -static lookupkey_t intkey(uintptr_t key) { - lookupkey_t k; - k.num = key; - return k; -} - -typedef uint32_t hashfunc_t(upb_tabkey key); -typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2); - -/* Base table (shared code) ***************************************************/ - -/* For when we need to cast away const. */ -static upb_tabent *mutable_entries(upb_table *t) { - return (upb_tabent*)t->entries; -} - -static bool isfull(upb_table *t) { - if (upb_table_size(t) == 0) { - return true; - } else { - return ((double)(t->count + 1) / upb_table_size(t)) > MAX_LOAD; - } -} - -static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2, - upb_alloc *a) { - size_t bytes; - - t->count = 0; - t->ctype = ctype; - t->size_lg2 = size_lg2; - t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0; -#ifndef NDEBUG - t->alloc = a; -#endif - bytes = upb_table_size(t) * sizeof(upb_tabent); - if (bytes > 0) { - t->entries = upb_malloc(a, bytes); - if (!t->entries) return false; - memset(mutable_entries(t), 0, bytes); - } else { - t->entries = NULL; - } - return true; -} - -static void uninit(upb_table *t, upb_alloc *a) { - upb_check_alloc(t, a); - upb_free(a, mutable_entries(t)); -} - -static upb_tabent *emptyent(upb_table *t) { - upb_tabent *e = mutable_entries(t) + upb_table_size(t); - while (1) { if (upb_tabent_isempty(--e)) return e; UPB_ASSERT(e > t->entries); } -} - -static upb_tabent *getentry_mutable(upb_table *t, uint32_t hash) { - return (upb_tabent*)upb_getentry(t, hash); -} - -static const upb_tabent *findentry(const upb_table *t, lookupkey_t key, - uint32_t hash, eqlfunc_t *eql) { - const upb_tabent *e; - - if (t->size_lg2 == 0) return NULL; - e = upb_getentry(t, hash); - if (upb_tabent_isempty(e)) return NULL; - while (1) { - if (eql(e->key, key)) return e; - if ((e = e->next) == NULL) return NULL; - } -} - -static upb_tabent *findentry_mutable(upb_table *t, lookupkey_t key, - uint32_t hash, eqlfunc_t *eql) { - return (upb_tabent*)findentry(t, key, hash, eql); -} - -static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, - uint32_t hash, eqlfunc_t *eql) { - const upb_tabent *e = findentry(t, key, hash, eql); - if (e) { - if (v) { - _upb_value_setval(v, e->val.val, t->ctype); - } - return true; - } else { - return false; - } -} - -/* The given key must not already exist in the table. */ -static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, - upb_value val, uint32_t hash, - hashfunc_t *hashfunc, eqlfunc_t *eql) { - upb_tabent *mainpos_e; - upb_tabent *our_e; - - UPB_ASSERT(findentry(t, key, hash, eql) == NULL); - UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype); - - t->count++; - mainpos_e = getentry_mutable(t, hash); - our_e = mainpos_e; - - if (upb_tabent_isempty(mainpos_e)) { - /* Our main position is empty; use it. */ - our_e->next = NULL; - } else { - /* Collision. */ - upb_tabent *new_e = emptyent(t); - /* Head of collider's chain. */ - upb_tabent *chain = getentry_mutable(t, hashfunc(mainpos_e->key)); - if (chain == mainpos_e) { - /* Existing ent is in its main posisiton (it has the same hash as us, and - * is the head of our chain). Insert to new ent and append to this chain. */ - new_e->next = mainpos_e->next; - mainpos_e->next = new_e; - our_e = new_e; - } else { - /* Existing ent is not in its main position (it is a node in some other - * chain). This implies that no existing ent in the table has our hash. - * Evict it (updating its chain) and use its ent for head of our chain. */ - *new_e = *mainpos_e; /* copies next. */ - while (chain->next != mainpos_e) { - chain = (upb_tabent*)chain->next; - UPB_ASSERT(chain); - } - chain->next = new_e; - our_e = mainpos_e; - our_e->next = NULL; - } - } - our_e->key = tabkey; - our_e->val.val = val.val; - UPB_ASSERT(findentry(t, key, hash, eql) == our_e); -} - -static bool rm(upb_table *t, lookupkey_t key, upb_value *val, - upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql) { - upb_tabent *chain = getentry_mutable(t, hash); - if (upb_tabent_isempty(chain)) return false; - if (eql(chain->key, key)) { - /* Element to remove is at the head of its chain. */ - t->count--; - if (val) _upb_value_setval(val, chain->val.val, t->ctype); - if (removed) *removed = chain->key; - if (chain->next) { - upb_tabent *move = (upb_tabent*)chain->next; - *chain = *move; - move->key = 0; /* Make the slot empty. */ - } else { - chain->key = 0; /* Make the slot empty. */ - } - return true; - } else { - /* Element to remove is either in a non-head position or not in the - * table. */ - while (chain->next && !eql(chain->next->key, key)) { - chain = (upb_tabent*)chain->next; - } - if (chain->next) { - /* Found element to remove. */ - upb_tabent *rm = (upb_tabent*)chain->next; - t->count--; - if (val) _upb_value_setval(val, chain->next->val.val, t->ctype); - if (removed) *removed = rm->key; - rm->key = 0; /* Make the slot empty. */ - chain->next = rm->next; - return true; - } else { - /* Element to remove is not in the table. */ - return false; - } - } -} - -static size_t next(const upb_table *t, size_t i) { - do { - if (++i >= upb_table_size(t)) - return SIZE_MAX; - } while(upb_tabent_isempty(&t->entries[i])); - - return i; -} - -static size_t begin(const upb_table *t) { - return next(t, -1); -} - - -/* upb_strtable ***************************************************************/ - -/* A simple "subclass" of upb_table that only adds a hash function for strings. */ - -static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) { - uint32_t len = (uint32_t) k2.str.len; - char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1); - if (str == NULL) return 0; - memcpy(str, &len, sizeof(uint32_t)); - memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len); - str[sizeof(uint32_t) + k2.str.len] = '\0'; - return (uintptr_t)str; -} - -static uint32_t strhash(upb_tabkey key) { - uint32_t len; - char *str = upb_tabstr(key, &len); - return upb_murmur_hash2(str, len, 0); -} - -static bool streql(upb_tabkey k1, lookupkey_t k2) { - uint32_t len; - char *str = upb_tabstr(k1, &len); - return len == k2.str.len && memcmp(str, k2.str.str, len) == 0; -} - -bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) { - return init(&t->t, ctype, 2, a); -} - -void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) { - size_t i; - for (i = 0; i < upb_table_size(&t->t); i++) - upb_free(a, (void*)t->t.entries[i].key); - uninit(&t->t, a); -} - -bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) { - upb_strtable new_table; - upb_strtable_iter i; - - upb_check_alloc(&t->t, a); - - if (!init(&new_table.t, t->t.ctype, size_lg2, a)) - return false; - upb_strtable_begin(&i, t); - for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) { - upb_strtable_insert3( - &new_table, - upb_strtable_iter_key(&i), - upb_strtable_iter_keylength(&i), - upb_strtable_iter_value(&i), - a); - } - upb_strtable_uninit2(t, a); - *t = new_table; - return true; -} - -bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len, - upb_value v, upb_alloc *a) { - lookupkey_t key; - upb_tabkey tabkey; - uint32_t hash; - - upb_check_alloc(&t->t, a); - - if (isfull(&t->t)) { - /* Need to resize. New table of double the size, add old elements to it. */ - if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) { - return false; - } - } - - key = strkey2(k, len); - tabkey = strcopy(key, a); - if (tabkey == 0) return false; - - hash = upb_murmur_hash2(key.str.str, key.str.len, 0); - insert(&t->t, key, tabkey, v, hash, &strhash, &streql); - return true; -} - -bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, - upb_value *v) { - uint32_t hash = upb_murmur_hash2(key, len, 0); - return lookup(&t->t, strkey2(key, len), v, hash, &streql); -} - -bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, - upb_value *val, upb_alloc *alloc) { - uint32_t hash = upb_murmur_hash2(key, len, 0); - upb_tabkey tabkey; - if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) { - upb_free(alloc, (void*)tabkey); - return true; - } else { - return false; - } -} - -/* Iteration */ - -static const upb_tabent *str_tabent(const upb_strtable_iter *i) { - return &i->t->t.entries[i->index]; -} - -void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) { - i->t = t; - i->index = begin(&t->t); -} - -void upb_strtable_next(upb_strtable_iter *i) { - i->index = next(&i->t->t, i->index); -} - -bool upb_strtable_done(const upb_strtable_iter *i) { - if (!i->t) return true; - return i->index >= upb_table_size(&i->t->t) || - upb_tabent_isempty(str_tabent(i)); -} - -const char *upb_strtable_iter_key(const upb_strtable_iter *i) { - UPB_ASSERT(!upb_strtable_done(i)); - return upb_tabstr(str_tabent(i)->key, NULL); -} - -size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) { - uint32_t len; - UPB_ASSERT(!upb_strtable_done(i)); - upb_tabstr(str_tabent(i)->key, &len); - return len; -} - -upb_value upb_strtable_iter_value(const upb_strtable_iter *i) { - UPB_ASSERT(!upb_strtable_done(i)); - return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype); -} - -void upb_strtable_iter_setdone(upb_strtable_iter *i) { - i->t = NULL; - i->index = SIZE_MAX; -} - -bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, - const upb_strtable_iter *i2) { - if (upb_strtable_done(i1) && upb_strtable_done(i2)) - return true; - return i1->t == i2->t && i1->index == i2->index; -} - - -/* upb_inttable ***************************************************************/ - -/* For inttables we use a hybrid structure where small keys are kept in an - * array and large keys are put in the hash table. */ - -static uint32_t inthash(upb_tabkey key) { return upb_inthash(key); } - -static bool inteql(upb_tabkey k1, lookupkey_t k2) { - return k1 == k2.num; -} - -static upb_tabval *mutable_array(upb_inttable *t) { - return (upb_tabval*)t->array; -} - -static upb_tabval *inttable_val(upb_inttable *t, uintptr_t key) { - if (key < t->array_size) { - return upb_arrhas(t->array[key]) ? &(mutable_array(t)[key]) : NULL; - } else { - upb_tabent *e = - findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql); - return e ? &e->val : NULL; - } -} - -static const upb_tabval *inttable_val_const(const upb_inttable *t, - uintptr_t key) { - return inttable_val((upb_inttable*)t, key); -} - -size_t upb_inttable_count(const upb_inttable *t) { - return t->t.count + t->array_count; -} - -static void check(upb_inttable *t) { - UPB_UNUSED(t); -#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG) - { - /* This check is very expensive (makes inserts/deletes O(N)). */ - size_t count = 0; - upb_inttable_iter i; - upb_inttable_begin(&i, t); - for(; !upb_inttable_done(&i); upb_inttable_next(&i), count++) { - UPB_ASSERT(upb_inttable_lookup(t, upb_inttable_iter_key(&i), NULL)); - } - UPB_ASSERT(count == upb_inttable_count(t)); - } -#endif -} - -bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype, - size_t asize, int hsize_lg2, upb_alloc *a) { - size_t array_bytes; - - if (!init(&t->t, ctype, hsize_lg2, a)) return false; - /* Always make the array part at least 1 long, so that we know key 0 - * won't be in the hash part, which simplifies things. */ - t->array_size = UPB_MAX(1, asize); - t->array_count = 0; - array_bytes = t->array_size * sizeof(upb_value); - t->array = upb_malloc(a, array_bytes); - if (!t->array) { - uninit(&t->t, a); - return false; - } - memset(mutable_array(t), 0xff, array_bytes); - check(t); - return true; -} - -bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) { - return upb_inttable_sizedinit(t, ctype, 0, 4, a); -} - -void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) { - uninit(&t->t, a); - upb_free(a, mutable_array(t)); -} - -bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, - upb_alloc *a) { - upb_tabval tabval; - tabval.val = val.val; - UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */ - - upb_check_alloc(&t->t, a); - - if (key < t->array_size) { - UPB_ASSERT(!upb_arrhas(t->array[key])); - t->array_count++; - mutable_array(t)[key].val = val.val; - } else { - if (isfull(&t->t)) { - /* Need to resize the hash part, but we re-use the array part. */ - size_t i; - upb_table new_table; - - if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) { - return false; - } - - for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { - const upb_tabent *e = &t->t.entries[i]; - uint32_t hash; - upb_value v; - - _upb_value_setval(&v, e->val.val, t->t.ctype); - hash = upb_inthash(e->key); - insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql); - } - - UPB_ASSERT(t->t.count == new_table.count); - - uninit(&t->t, a); - t->t = new_table; - } - insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql); - } - check(t); - return true; -} - -bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) { - const upb_tabval *table_v = inttable_val_const(t, key); - if (!table_v) return false; - if (v) _upb_value_setval(v, table_v->val, t->t.ctype); - return true; -} - -bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val) { - upb_tabval *table_v = inttable_val(t, key); - if (!table_v) return false; - table_v->val = val.val; - return true; -} - -bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { - bool success; - if (key < t->array_size) { - if (upb_arrhas(t->array[key])) { - upb_tabval empty = UPB_TABVALUE_EMPTY_INIT; - t->array_count--; - if (val) { - _upb_value_setval(val, t->array[key].val, t->t.ctype); - } - mutable_array(t)[key] = empty; - success = true; - } else { - success = false; - } - } else { - success = rm(&t->t, intkey(key), val, NULL, upb_inthash(key), &inteql); - } - check(t); - return success; -} - -bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) { - upb_check_alloc(&t->t, a); - return upb_inttable_insert2(t, upb_inttable_count(t), val, a); -} - -upb_value upb_inttable_pop(upb_inttable *t) { - upb_value val; - bool ok = upb_inttable_remove(t, upb_inttable_count(t) - 1, &val); - UPB_ASSERT(ok); - return val; -} - -bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, - upb_alloc *a) { - upb_check_alloc(&t->t, a); - return upb_inttable_insert2(t, (uintptr_t)key, val, a); -} - -bool upb_inttable_lookupptr(const upb_inttable *t, const void *key, - upb_value *v) { - return upb_inttable_lookup(t, (uintptr_t)key, v); -} - -bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) { - return upb_inttable_remove(t, (uintptr_t)key, val); -} - -void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) { - /* A power-of-two histogram of the table keys. */ - size_t counts[UPB_MAXARRSIZE + 1] = {0}; - - /* The max key in each bucket. */ - uintptr_t max[UPB_MAXARRSIZE + 1] = {0}; - - upb_inttable_iter i; - size_t arr_count; - int size_lg2; - upb_inttable new_t; - - upb_check_alloc(&t->t, a); - - upb_inttable_begin(&i, t); - for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { - uintptr_t key = upb_inttable_iter_key(&i); - int bucket = log2ceil(key); - max[bucket] = UPB_MAX(max[bucket], key); - counts[bucket]++; - } - - /* Find the largest power of two that satisfies the MIN_DENSITY - * definition (while actually having some keys). */ - arr_count = upb_inttable_count(t); - - for (size_lg2 = ARRAY_SIZE(counts) - 1; size_lg2 > 0; size_lg2--) { - if (counts[size_lg2] == 0) { - /* We can halve again without losing any entries. */ - continue; - } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) { - break; - } - - arr_count -= counts[size_lg2]; - } - - UPB_ASSERT(arr_count <= upb_inttable_count(t)); - - { - /* Insert all elements into new, perfectly-sized table. */ - size_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */ - size_t hash_count = upb_inttable_count(t) - arr_count; - size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0; - int hashsize_lg2 = log2ceil(hash_size); - - upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a); - upb_inttable_begin(&i, t); - for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { - uintptr_t k = upb_inttable_iter_key(&i); - upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a); - } - UPB_ASSERT(new_t.array_size == arr_size); - UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2); - } - upb_inttable_uninit2(t, a); - *t = new_t; -} - -/* Iteration. */ - -static const upb_tabent *int_tabent(const upb_inttable_iter *i) { - UPB_ASSERT(!i->array_part); - return &i->t->t.entries[i->index]; -} - -static upb_tabval int_arrent(const upb_inttable_iter *i) { - UPB_ASSERT(i->array_part); - return i->t->array[i->index]; -} - -void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t) { - i->t = t; - i->index = -1; - i->array_part = true; - upb_inttable_next(i); -} - -void upb_inttable_next(upb_inttable_iter *iter) { - const upb_inttable *t = iter->t; - if (iter->array_part) { - while (++iter->index < t->array_size) { - if (upb_arrhas(int_arrent(iter))) { - return; - } - } - iter->array_part = false; - iter->index = begin(&t->t); - } else { - iter->index = next(&t->t, iter->index); - } -} - -bool upb_inttable_done(const upb_inttable_iter *i) { - if (!i->t) return true; - if (i->array_part) { - return i->index >= i->t->array_size || - !upb_arrhas(int_arrent(i)); - } else { - return i->index >= upb_table_size(&i->t->t) || - upb_tabent_isempty(int_tabent(i)); - } -} - -uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) { - UPB_ASSERT(!upb_inttable_done(i)); - return i->array_part ? i->index : int_tabent(i)->key; -} - -upb_value upb_inttable_iter_value(const upb_inttable_iter *i) { - UPB_ASSERT(!upb_inttable_done(i)); - return _upb_value_val( - i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val, - i->t->t.ctype); -} - -void upb_inttable_iter_setdone(upb_inttable_iter *i) { - i->t = NULL; - i->index = SIZE_MAX; - i->array_part = false; -} - -bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, - const upb_inttable_iter *i2) { - if (upb_inttable_done(i1) && upb_inttable_done(i2)) - return true; - return i1->t == i2->t && i1->index == i2->index && - i1->array_part == i2->array_part; -} - -#if defined(UPB_UNALIGNED_READS_OK) || defined(__s390x__) -/* ----------------------------------------------------------------------------- - * MurmurHash2, by Austin Appleby (released as public domain). - * Reformatted and C99-ified by Joshua Haberman. - * Note - This code makes a few assumptions about how your machine behaves - - * 1. We can read a 4-byte value from any address without crashing - * 2. sizeof(int) == 4 (in upb this limitation is removed by using uint32_t - * And it has a few limitations - - * 1. It will not work incrementally. - * 2. It will not produce the same results on little-endian and big-endian - * machines. */ -uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) { - /* 'm' and 'r' are mixing constants generated offline. - * They're not really 'magic', they just happen to work well. */ - const uint32_t m = 0x5bd1e995; - const int32_t r = 24; - - /* Initialize the hash to a 'random' value */ - uint32_t h = seed ^ len; - - /* Mix 4 bytes at a time into the hash */ - const uint8_t * data = (const uint8_t *)key; - while(len >= 4) { - uint32_t k = *(uint32_t *)data; - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - /* Handle the last few bytes of the input array */ - switch(len) { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; h *= m; - }; - - /* Do a few final mixes of the hash to ensure the last few - * bytes are well-incorporated. */ - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; -} - -#else /* !UPB_UNALIGNED_READS_OK */ - -/* ----------------------------------------------------------------------------- - * MurmurHashAligned2, by Austin Appleby - * Same algorithm as MurmurHash2, but only does aligned reads - should be safer - * on certain platforms. - * Performance will be lower than MurmurHash2 */ - -#define MIX(h,k,m) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; } - -uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed) { - const uint32_t m = 0x5bd1e995; - const int32_t r = 24; - const uint8_t * data = (const uint8_t *)key; - uint32_t h = (uint32_t)(seed ^ len); - uint8_t align = (uintptr_t)data & 3; - - if(align && (len >= 4)) { - /* Pre-load the temp registers */ - uint32_t t = 0, d = 0; - int32_t sl; - int32_t sr; - - switch(align) { - case 1: t |= data[2] << 16; - case 2: t |= data[1] << 8; - case 3: t |= data[0]; - } - - t <<= (8 * align); - - data += 4-align; - len -= 4-align; - - sl = 8 * (4-align); - sr = 8 * align; - - /* Mix */ - - while(len >= 4) { - uint32_t k; - - d = *(uint32_t *)data; - t = (t >> sr) | (d << sl); - - k = t; - - MIX(h,k,m); - - t = d; - - data += 4; - len -= 4; - } - - /* Handle leftover data in temp registers */ - - d = 0; - - if(len >= align) { - uint32_t k; - - switch(align) { - case 3: d |= data[2] << 16; - case 2: d |= data[1] << 8; - case 1: d |= data[0]; - } - - k = (t >> sr) | (d << sl); - MIX(h,k,m); - - data += align; - len -= align; - - /* ---------- - * Handle tail bytes */ - - switch(len) { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; h *= m; - }; - } else { - switch(len) { - case 3: d |= data[2] << 16; - case 2: d |= data[1] << 8; - case 1: d |= data[0]; - case 0: h ^= (t >> sr) | (d << sl); h *= m; - } - } - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; - } else { - while(len >= 4) { - uint32_t k = *(uint32_t *)data; - - MIX(h,k,m); - - data += 4; - len -= 4; - } - - /* ---------- - * Handle tail bytes */ - - switch(len) { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; h *= m; - }; - - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; - } -} -#undef MIX - -#endif /* UPB_UNALIGNED_READS_OK */ - - -#include -#include -#include -#include -#include -#include -#include - - -/* Guarantee null-termination and provide ellipsis truncation. - * It may be tempting to "optimize" this by initializing these final - * four bytes up-front and then being careful never to overwrite them, - * this is safer and simpler. */ -static void nullz(upb_status *status) { - const char *ellipsis = "..."; - size_t len = strlen(ellipsis); - UPB_ASSERT(sizeof(status->msg) > len); - memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len); -} - -/* upb_status *****************************************************************/ - -void upb_status_clear(upb_status *status) { - if (!status) return; - status->ok = true; - status->msg[0] = '\0'; -} - -bool upb_ok(const upb_status *status) { return status->ok; } - -const char *upb_status_errmsg(const upb_status *status) { return status->msg; } - -void upb_status_seterrmsg(upb_status *status, const char *msg) { - if (!status) return; - status->ok = false; - strncpy(status->msg, msg, sizeof(status->msg)); - nullz(status); -} - -void upb_status_seterrf(upb_status *status, const char *fmt, ...) { - va_list args; - va_start(args, fmt); - upb_status_vseterrf(status, fmt, args); - va_end(args); -} - -void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { - if (!status) return; - status->ok = false; - _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args); - nullz(status); -} - -/* upb_alloc ******************************************************************/ - -static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, - size_t size) { - UPB_UNUSED(alloc); - UPB_UNUSED(oldsize); - if (size == 0) { - free(ptr); - return NULL; - } else { - return realloc(ptr, size); - } -} - -upb_alloc upb_alloc_global = {&upb_global_allocfunc}; - -/* upb_arena ******************************************************************/ - -/* Be conservative and choose 16 in case anyone is using SSE. */ -static const size_t maxalign = 16; - -static size_t align_up_max(size_t size) { - return ((size + maxalign - 1) / maxalign) * maxalign; -} - -struct upb_arena { - /* We implement the allocator interface. - * This must be the first member of upb_arena! */ - upb_alloc alloc; - - /* Allocator to allocate arena blocks. We are responsible for freeing these - * when we are destroyed. */ - upb_alloc *block_alloc; - - size_t bytes_allocated; - size_t next_block_size; - size_t max_block_size; - - /* Linked list of blocks. Points to an arena_block, defined in env.c */ - void *block_head; - - /* Cleanup entries. Pointer to a cleanup_ent, defined in env.c */ - void *cleanup_head; -}; - -typedef struct mem_block { - struct mem_block *next; - size_t size; - size_t used; - bool owned; - /* Data follows. */ -} mem_block; - -typedef struct cleanup_ent { - struct cleanup_ent *next; - upb_cleanup_func *cleanup; - void *ud; -} cleanup_ent; - -static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size, - bool owned) { - mem_block *block = ptr; - - block->next = a->block_head; - block->size = size; - block->used = align_up_max(sizeof(mem_block)); - block->owned = owned; - - a->block_head = block; - - /* TODO(haberman): ASAN poison. */ -} - -static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) { - size_t block_size = UPB_MAX(size, a->next_block_size) + sizeof(mem_block); - mem_block *block = upb_malloc(a->block_alloc, block_size); - - if (!block) { - return NULL; - } - - upb_arena_addblock(a, block, block_size, true); - a->next_block_size = UPB_MIN(block_size * 2, a->max_block_size); - - return block; -} - -static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, - size_t size) { - upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */ - mem_block *block = a->block_head; - void *ret; - - if (size == 0) { - return NULL; /* We are an arena, don't need individual frees. */ - } - - size = align_up_max(size); - - /* TODO(haberman): special-case if this is a realloc of the last alloc? */ - - if (!block || block->size - block->used < size) { - /* Slow path: have to allocate a new block. */ - block = upb_arena_allocblock(a, size); - - if (!block) { - return NULL; /* Out of memory. */ - } - } - - ret = (char*)block + block->used; - block->used += size; - - if (oldsize > 0) { - memcpy(ret, ptr, oldsize); /* Preserve existing data. */ - } - - /* TODO(haberman): ASAN unpoison. */ - - a->bytes_allocated += size; - return ret; -} - -/* Public Arena API ***********************************************************/ - -#define upb_alignof(type) offsetof (struct { char c; type member; }, member) - -upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { - const size_t first_block_overhead = sizeof(upb_arena) + sizeof(mem_block); - upb_arena *a; - bool owned = false; - - /* Round block size down to alignof(*a) since we will allocate the arena - * itself at the end. */ - n &= ~(upb_alignof(upb_arena) - 1); - - if (n < first_block_overhead) { - /* We need to malloc the initial block. */ - n = first_block_overhead + 256; - owned = true; - if (!alloc || !(mem = upb_malloc(alloc, n))) { - return NULL; - } - } - - a = (void*)((char*)mem + n - sizeof(*a)); - n -= sizeof(*a); - - a->alloc.func = &upb_arena_doalloc; - a->block_alloc = &upb_alloc_global; - a->bytes_allocated = 0; - a->next_block_size = 256; - a->max_block_size = 16384; - a->cleanup_head = NULL; - a->block_head = NULL; - a->block_alloc = alloc; - - upb_arena_addblock(a, mem, n, owned); - - return a; -} - -#undef upb_alignof - -void upb_arena_free(upb_arena *a) { - cleanup_ent *ent = a->cleanup_head; - mem_block *block = a->block_head; - - while (ent) { - ent->cleanup(ent->ud); - ent = ent->next; - } - - /* Must do this after running cleanup functions, because this will delete - * the memory we store our cleanup entries in! */ - while (block) { - /* Load first since we are deleting block. */ - mem_block *next = block->next; - - if (block->owned) { - upb_free(a->block_alloc, block); - } - - block = next; - } -} - -bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { - cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent)); - if (!ent) { - return false; /* Out of memory. */ - } - - ent->cleanup = func; - ent->ud = ud; - ent->next = a->cleanup_head; - a->cleanup_head = ent; - - return true; -} - -size_t upb_arena_bytesallocated(const upb_arena *a) { - return a->bytes_allocated; -} -/* 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 - - -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 -#include -#include -#include - - -typedef struct { - size_t len; - char str[1]; /* Null-terminated string data follows. */ -} str_t; - -static str_t *newstr(upb_alloc *alloc, const char *data, size_t len) { - str_t *ret = upb_malloc(alloc, sizeof(*ret) + len); - if (!ret) return NULL; - ret->len = len; - memcpy(ret->str, data, len); - ret->str[len] = '\0'; - return ret; -} - -struct upb_fielddef { - const upb_filedef *file; - const upb_msgdef *msgdef; - const char *full_name; - union { - int64_t sint; - uint64_t uint; - double dbl; - float flt; - bool boolean; - str_t *str; - } defaultval; - const upb_oneofdef *oneof; - union { - const upb_msgdef *msgdef; - const upb_enumdef *enumdef; - const google_protobuf_FieldDescriptorProto *unresolved; - } sub; - uint32_t number_; - uint32_t index_; - uint32_t selector_base; /* Used to index into a upb::Handlers table. */ - bool is_extension_; - bool lazy_; - bool packed_; - upb_descriptortype_t type_; - upb_label_t label_; -}; - -struct upb_msgdef { - const upb_filedef *file; - const char *full_name; - uint32_t selector_count; - uint32_t submsg_field_count; - - /* Tables for looking up fields by number and name. */ - upb_inttable itof; - upb_strtable ntof; - - const upb_fielddef *fields; - const upb_oneofdef *oneofs; - int field_count; - int oneof_count; - - /* Is this a map-entry message? */ - bool map_entry; - upb_wellknowntype_t well_known_type; - - /* TODO(haberman): proper extension ranges (there can be multiple). */ -}; - -struct upb_enumdef { - const upb_filedef *file; - const char *full_name; - upb_strtable ntoi; - upb_inttable iton; - int32_t defaultval; -}; - -struct upb_oneofdef { - const upb_msgdef *parent; - const char *full_name; - uint32_t index; - upb_strtable ntof; - upb_inttable itof; -}; - -struct upb_filedef { - const char *name; - const char *package; - const char *phpprefix; - const char *phpnamespace; - upb_syntax_t syntax; - - const upb_filedef **deps; - const upb_msgdef *msgs; - const upb_enumdef *enums; - const upb_fielddef *exts; - - int dep_count; - int msg_count; - int enum_count; - int ext_count; -}; - -struct upb_symtab { - upb_arena *arena; - upb_strtable syms; /* full_name -> packed def ptr */ - upb_strtable files; /* file_name -> upb_filedef* */ -}; - -/* Inside a symtab we store tagged pointers to specific def types. */ -typedef enum { - UPB_DEFTYPE_MSG = 0, - UPB_DEFTYPE_ENUM = 1, - UPB_DEFTYPE_FIELD = 2, - UPB_DEFTYPE_ONEOF = 3 -} upb_deftype_t; - -static const void *unpack_def(upb_value v, upb_deftype_t type) { - uintptr_t num = (uintptr_t)upb_value_getconstptr(v); - return (num & 3) == type ? (const void*)(num & ~3) : NULL; -} - -static upb_value pack_def(const void *ptr, upb_deftype_t type) { - uintptr_t num = (uintptr_t)ptr | type; - return upb_value_constptr((const void*)num); -} - -/* isalpha() etc. from are locale-dependent, which we don't want. */ -static bool upb_isbetween(char c, char low, char high) { - return c >= low && c <= high; -} - -static bool upb_isletter(char c) { - return upb_isbetween(c, 'A', 'Z') || upb_isbetween(c, 'a', 'z') || c == '_'; -} - -static bool upb_isalphanum(char c) { - return upb_isletter(c) || upb_isbetween(c, '0', '9'); -} - -static bool upb_isident(upb_strview name, bool full, upb_status *s) { - const char *str = name.data; - size_t len = name.size; - bool start = true; - size_t i; - for (i = 0; i < len; i++) { - char c = str[i]; - if (c == '.') { - if (start || !full) { - upb_status_seterrf(s, "invalid name: unexpected '.' (%s)", str); - return false; - } - start = true; - } else if (start) { - if (!upb_isletter(c)) { - upb_status_seterrf( - s, "invalid name: path components must start with a letter (%s)", - str); - return false; - } - start = false; - } else { - if (!upb_isalphanum(c)) { - upb_status_seterrf(s, "invalid name: non-alphanumeric character (%s)", - str); - return false; - } - } - } - return !start; -} - -static const char *shortdefname(const char *fullname) { - const char *p; - - if (fullname == NULL) { - return NULL; - } else if ((p = strrchr(fullname, '.')) == NULL) { - /* No '.' in the name, return the full string. */ - return fullname; - } else { - /* Return one past the last '.'. */ - return p + 1; - } -} - -/* All submessage fields are lower than all other fields. - * Secondly, fields are increasing in order. */ -uint32_t field_rank(const upb_fielddef *f) { - uint32_t ret = upb_fielddef_number(f); - const uint32_t high_bit = 1 << 30; - UPB_ASSERT(ret < high_bit); - if (!upb_fielddef_issubmsg(f)) - ret |= high_bit; - return ret; -} - -int cmp_fields(const void *p1, const void *p2) { - const upb_fielddef *f1 = *(upb_fielddef*const*)p1; - const upb_fielddef *f2 = *(upb_fielddef*const*)p2; - return field_rank(f1) - field_rank(f2); -} - -/* A few implementation details of handlers. We put these here to avoid - * a def -> handlers dependency. */ - -#define UPB_STATIC_SELECTOR_COUNT 3 /* Warning: also in upb/handlers.h. */ - -static uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) { - return upb_fielddef_isseq(f) ? 2 : 0; -} - -static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) { - uint32_t ret = 1; - if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */ - if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */ - if (upb_fielddef_issubmsg(f)) { - /* ENDSUBMSG (STARTSUBMSG is at table beginning) */ - ret += 0; - if (upb_fielddef_lazy(f)) { - /* STARTSTR/ENDSTR/STRING (for lazy) */ - ret += 3; - } - } - return ret; -} - -static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { - /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the - * lowest indexes, but we do not publicly guarantee this. */ - upb_msg_field_iter j; - upb_msg_oneof_iter k; - int i; - uint32_t selector; - int n = upb_msgdef_numfields(m); - upb_fielddef **fields; - - if (n == 0) { - m->selector_count = UPB_STATIC_SELECTOR_COUNT; - m->submsg_field_count = 0; - return true; - } - - fields = upb_gmalloc(n * sizeof(*fields)); - if (!fields) { - upb_status_setoom(s); - return false; - } - - m->submsg_field_count = 0; - for(i = 0, upb_msg_field_begin(&j, m); - !upb_msg_field_done(&j); - upb_msg_field_next(&j), i++) { - upb_fielddef *f = upb_msg_iter_field(&j); - UPB_ASSERT(f->msgdef == m); - if (upb_fielddef_issubmsg(f)) { - m->submsg_field_count++; - } - fields[i] = f; - } - - qsort(fields, n, sizeof(*fields), cmp_fields); - - selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count; - for (i = 0; i < n; i++) { - upb_fielddef *f = fields[i]; - f->index_ = i; - f->selector_base = selector + upb_handlers_selectorbaseoffset(f); - selector += upb_handlers_selectorcount(f); - } - m->selector_count = selector; - - for(upb_msg_oneof_begin(&k, m), i = 0; - !upb_msg_oneof_done(&k); - upb_msg_oneof_next(&k), i++) { - upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k); - o->index = i; - } - - upb_gfree(fields); - return true; -} - -static void assign_msg_wellknowntype(upb_msgdef *m) { - const char *name = upb_msgdef_fullname(m); - if (name == NULL) { - m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; - return; - } - if (!strcmp(name, "google.protobuf.Any")) { - m->well_known_type = UPB_WELLKNOWN_ANY; - } else if (!strcmp(name, "google.protobuf.FieldMask")) { - m->well_known_type = UPB_WELLKNOWN_FIELDMASK; - } else if (!strcmp(name, "google.protobuf.Duration")) { - m->well_known_type = UPB_WELLKNOWN_DURATION; - } else if (!strcmp(name, "google.protobuf.Timestamp")) { - m->well_known_type = UPB_WELLKNOWN_TIMESTAMP; - } else if (!strcmp(name, "google.protobuf.DoubleValue")) { - m->well_known_type = UPB_WELLKNOWN_DOUBLEVALUE; - } else if (!strcmp(name, "google.protobuf.FloatValue")) { - m->well_known_type = UPB_WELLKNOWN_FLOATVALUE; - } else if (!strcmp(name, "google.protobuf.Int64Value")) { - m->well_known_type = UPB_WELLKNOWN_INT64VALUE; - } else if (!strcmp(name, "google.protobuf.UInt64Value")) { - m->well_known_type = UPB_WELLKNOWN_UINT64VALUE; - } else if (!strcmp(name, "google.protobuf.Int32Value")) { - m->well_known_type = UPB_WELLKNOWN_INT32VALUE; - } else if (!strcmp(name, "google.protobuf.UInt32Value")) { - m->well_known_type = UPB_WELLKNOWN_UINT32VALUE; - } else if (!strcmp(name, "google.protobuf.BoolValue")) { - m->well_known_type = UPB_WELLKNOWN_BOOLVALUE; - } else if (!strcmp(name, "google.protobuf.StringValue")) { - m->well_known_type = UPB_WELLKNOWN_STRINGVALUE; - } else if (!strcmp(name, "google.protobuf.BytesValue")) { - m->well_known_type = UPB_WELLKNOWN_BYTESVALUE; - } else if (!strcmp(name, "google.protobuf.Value")) { - m->well_known_type = UPB_WELLKNOWN_VALUE; - } else if (!strcmp(name, "google.protobuf.ListValue")) { - m->well_known_type = UPB_WELLKNOWN_LISTVALUE; - } else if (!strcmp(name, "google.protobuf.Struct")) { - m->well_known_type = UPB_WELLKNOWN_STRUCT; - } else { - m->well_known_type = UPB_WELLKNOWN_UNSPECIFIED; - } -} - - -/* upb_enumdef ****************************************************************/ - -const char *upb_enumdef_fullname(const upb_enumdef *e) { - return e->full_name; -} - -const char *upb_enumdef_name(const upb_enumdef *e) { - return shortdefname(e->full_name); -} - -const upb_filedef *upb_enumdef_file(const upb_enumdef *e) { - return e->file; -} - -int32_t upb_enumdef_default(const upb_enumdef *e) { - UPB_ASSERT(upb_enumdef_iton(e, e->defaultval)); - return e->defaultval; -} - -int upb_enumdef_numvals(const upb_enumdef *e) { - return upb_strtable_count(&e->ntoi); -} - -void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) { - /* We iterate over the ntoi table, to account for duplicate numbers. */ - upb_strtable_begin(i, &e->ntoi); -} - -void upb_enum_next(upb_enum_iter *iter) { upb_strtable_next(iter); } -bool upb_enum_done(upb_enum_iter *iter) { return upb_strtable_done(iter); } - -bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name, - size_t len, int32_t *num) { - upb_value v; - if (!upb_strtable_lookup2(&def->ntoi, name, len, &v)) { - return false; - } - if (num) *num = upb_value_getint32(v); - return true; -} - -const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) { - upb_value v; - return upb_inttable_lookup32(&def->iton, num, &v) ? - upb_value_getcstr(v) : NULL; -} - -const char *upb_enum_iter_name(upb_enum_iter *iter) { - return upb_strtable_iter_key(iter); -} - -int32_t upb_enum_iter_number(upb_enum_iter *iter) { - return upb_value_getint32(upb_strtable_iter_value(iter)); -} - - -/* upb_fielddef ***************************************************************/ - -const char *upb_fielddef_fullname(const upb_fielddef *f) { - return f->full_name; -} - -upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f) { - switch (f->type_) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - return UPB_TYPE_DOUBLE; - case UPB_DESCRIPTOR_TYPE_FLOAT: - return UPB_TYPE_FLOAT; - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_SINT64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - return UPB_TYPE_INT64; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - case UPB_DESCRIPTOR_TYPE_SINT32: - return UPB_TYPE_INT32; - case UPB_DESCRIPTOR_TYPE_UINT64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - return UPB_TYPE_UINT64; - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_FIXED32: - return UPB_TYPE_UINT32; - case UPB_DESCRIPTOR_TYPE_ENUM: - return UPB_TYPE_ENUM; - case UPB_DESCRIPTOR_TYPE_BOOL: - return UPB_TYPE_BOOL; - case UPB_DESCRIPTOR_TYPE_STRING: - return UPB_TYPE_STRING; - case UPB_DESCRIPTOR_TYPE_BYTES: - return UPB_TYPE_BYTES; - case UPB_DESCRIPTOR_TYPE_GROUP: - case UPB_DESCRIPTOR_TYPE_MESSAGE: - return UPB_TYPE_MESSAGE; - } - UPB_UNREACHABLE(); -} - -upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f) { - return f->type_; -} - -uint32_t upb_fielddef_index(const upb_fielddef *f) { - return f->index_; -} - -upb_label_t upb_fielddef_label(const upb_fielddef *f) { - return f->label_; -} - -uint32_t upb_fielddef_number(const upb_fielddef *f) { - return f->number_; -} - -bool upb_fielddef_isextension(const upb_fielddef *f) { - return f->is_extension_; -} - -bool upb_fielddef_lazy(const upb_fielddef *f) { - return f->lazy_; -} - -bool upb_fielddef_packed(const upb_fielddef *f) { - return f->packed_; -} - -const char *upb_fielddef_name(const upb_fielddef *f) { - return shortdefname(f->full_name); -} - -uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) { - return f->selector_base; -} - -size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) { - const char *name = upb_fielddef_name(f); - size_t src, dst = 0; - bool ucase_next = false; - -#define WRITE(byte) \ - ++dst; \ - if (dst < len) buf[dst - 1] = byte; \ - else if (dst == len) buf[dst - 1] = '\0' - - if (!name) { - WRITE('\0'); - return 0; - } - - /* Implement the transformation as described in the spec: - * 1. upper case all letters after an underscore. - * 2. remove all underscores. - */ - for (src = 0; name[src]; src++) { - if (name[src] == '_') { - ucase_next = true; - continue; - } - - if (ucase_next) { - WRITE(toupper(name[src])); - ucase_next = false; - } else { - WRITE(name[src]); - } - } - - WRITE('\0'); - return dst; - -#undef WRITE -} - -const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { - return f->msgdef; -} - -const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) { - return f->oneof; -} - -static void chkdefaulttype(const upb_fielddef *f, int ctype) { - UPB_UNUSED(f); - UPB_UNUSED(ctype); -} - -int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_INT64); - return f->defaultval.sint; -} - -int32_t upb_fielddef_defaultint32(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_INT32); - return f->defaultval.sint; -} - -uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT64); - return f->defaultval.uint; -} - -uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_UINT32); - return f->defaultval.uint; -} - -bool upb_fielddef_defaultbool(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_BOOL); - return f->defaultval.boolean; -} - -float upb_fielddef_defaultfloat(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_FLOAT); - return f->defaultval.flt; -} - -double upb_fielddef_defaultdouble(const upb_fielddef *f) { - chkdefaulttype(f, UPB_TYPE_DOUBLE); - return f->defaultval.dbl; -} - -const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len) { - str_t *str = f->defaultval.str; - UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_STRING || - upb_fielddef_type(f) == UPB_TYPE_BYTES || - upb_fielddef_type(f) == UPB_TYPE_ENUM); - if (str) { - if (len) *len = str->len; - return str->str; - } else { - if (len) *len = 0; - return NULL; - } -} - -const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f) { - UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_MESSAGE); - return f->sub.msgdef; -} - -const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) { - UPB_ASSERT(upb_fielddef_type(f) == UPB_TYPE_ENUM); - return f->sub.enumdef; -} - -bool upb_fielddef_issubmsg(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_MESSAGE; -} - -bool upb_fielddef_isstring(const upb_fielddef *f) { - return upb_fielddef_type(f) == UPB_TYPE_STRING || - upb_fielddef_type(f) == UPB_TYPE_BYTES; -} - -bool upb_fielddef_isseq(const upb_fielddef *f) { - return upb_fielddef_label(f) == UPB_LABEL_REPEATED; -} - -bool upb_fielddef_isprimitive(const upb_fielddef *f) { - return !upb_fielddef_isstring(f) && !upb_fielddef_issubmsg(f); -} - -bool upb_fielddef_ismap(const upb_fielddef *f) { - return upb_fielddef_isseq(f) && upb_fielddef_issubmsg(f) && - upb_msgdef_mapentry(upb_fielddef_msgsubdef(f)); -} - -bool upb_fielddef_hassubdef(const upb_fielddef *f) { - return upb_fielddef_issubmsg(f) || upb_fielddef_type(f) == UPB_TYPE_ENUM; -} - -bool upb_fielddef_haspresence(const upb_fielddef *f) { - if (upb_fielddef_isseq(f)) return false; - if (upb_fielddef_issubmsg(f)) return true; - return f->file->syntax == UPB_SYNTAX_PROTO2; -} - -static bool between(int32_t x, int32_t low, int32_t high) { - return x >= low && x <= high; -} - -bool upb_fielddef_checklabel(int32_t label) { return between(label, 1, 3); } -bool upb_fielddef_checktype(int32_t type) { return between(type, 1, 11); } -bool upb_fielddef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); } - -bool upb_fielddef_checkdescriptortype(int32_t type) { - return between(type, 1, 18); -} - -/* upb_msgdef *****************************************************************/ - -const char *upb_msgdef_fullname(const upb_msgdef *m) { - return m->full_name; -} - -const upb_filedef *upb_msgdef_file(const upb_msgdef *m) { - return m->file; -} - -const char *upb_msgdef_name(const upb_msgdef *m) { - return shortdefname(m->full_name); -} - -upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) { - return m->file->syntax; -} - -size_t upb_msgdef_selectorcount(const upb_msgdef *m) { - return m->selector_count; -} - -uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) { - return m->submsg_field_count; -} - -const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) { - upb_value val; - return upb_inttable_lookup32(&m->itof, i, &val) ? - upb_value_getconstptr(val) : NULL; -} - -const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, - size_t len) { - upb_value val; - - if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { - return NULL; - } - - return unpack_def(val, UPB_DEFTYPE_FIELD); -} - -const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, - size_t len) { - upb_value val; - - if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { - return NULL; - } - - return unpack_def(val, UPB_DEFTYPE_ONEOF); -} - -bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, - const upb_fielddef **f, const upb_oneofdef **o) { - upb_value val; - - if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { - return false; - } - - *o = unpack_def(val, UPB_DEFTYPE_ONEOF); - *f = unpack_def(val, UPB_DEFTYPE_FIELD); - UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */ - return true; -} - -int upb_msgdef_numfields(const upb_msgdef *m) { - /* The number table contains only fields. */ - return upb_inttable_count(&m->itof); -} - -int upb_msgdef_numoneofs(const upb_msgdef *m) { - /* The name table includes oneofs, and the number table does not. */ - return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof); -} - -bool upb_msgdef_mapentry(const upb_msgdef *m) { - return m->map_entry; -} - -upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m) { - return m->well_known_type; -} - -bool upb_msgdef_isnumberwrapper(const upb_msgdef *m) { - upb_wellknowntype_t type = upb_msgdef_wellknowntype(m); - return type >= UPB_WELLKNOWN_DOUBLEVALUE && - type <= UPB_WELLKNOWN_UINT32VALUE; -} - -void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m) { - upb_inttable_begin(iter, &m->itof); -} - -void upb_msg_field_next(upb_msg_field_iter *iter) { upb_inttable_next(iter); } - -bool upb_msg_field_done(const upb_msg_field_iter *iter) { - return upb_inttable_done(iter); -} - -upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); -} - -void upb_msg_field_iter_setdone(upb_msg_field_iter *iter) { - upb_inttable_iter_setdone(iter); -} - -bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, - const upb_msg_field_iter * iter2) { - return upb_inttable_iter_isequal(iter1, iter2); -} - -void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) { - upb_strtable_begin(iter, &m->ntof); - /* We need to skip past any initial fields. */ - while (!upb_strtable_done(iter) && - !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)) { - upb_strtable_next(iter); - } -} - -void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { - /* We need to skip past fields to return only oneofs. */ - do { - upb_strtable_next(iter); - } while (!upb_strtable_done(iter) && - !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)); -} - -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { - return upb_strtable_done(iter); -} - -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); -} - -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { - upb_strtable_iter_setdone(iter); -} - -bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, - const upb_msg_oneof_iter *iter2) { - return upb_strtable_iter_isequal(iter1, iter2); -} - -/* upb_oneofdef ***************************************************************/ - -const char *upb_oneofdef_name(const upb_oneofdef *o) { - return shortdefname(o->full_name); -} - -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { - return o->parent; -} - -int upb_oneofdef_numfields(const upb_oneofdef *o) { - return upb_strtable_count(&o->ntof); -} - -uint32_t upb_oneofdef_index(const upb_oneofdef *o) { - return o->index; -} - -const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, - const char *name, size_t length) { - upb_value val; - return upb_strtable_lookup2(&o->ntof, name, length, &val) ? - upb_value_getptr(val) : NULL; -} - -const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) { - upb_value val; - return upb_inttable_lookup32(&o->itof, num, &val) ? - upb_value_getptr(val) : NULL; -} - -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { - upb_inttable_begin(iter, &o->itof); -} - -void upb_oneof_next(upb_oneof_iter *iter) { - upb_inttable_next(iter); -} - -bool upb_oneof_done(upb_oneof_iter *iter) { - return upb_inttable_done(iter); -} - -upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); -} - -void upb_oneof_iter_setdone(upb_oneof_iter *iter) { - upb_inttable_iter_setdone(iter); -} - -/* Code to build defs from descriptor protos. *********************************/ - -/* There is a question of how much validation to do here. It will be difficult - * to perfectly match the amount of validation performed by proto2. But since - * this code is used to directly build defs from Ruby (for example) we do need - * to validate important constraints like uniqueness of names and numbers. */ - -#define CHK(x) if (!(x)) { return false; } -#define CHK_OOM(x) if (!(x)) { upb_status_setoom(ctx->status); return false; } - -typedef struct { - const upb_symtab *symtab; - upb_filedef *file; /* File we are building. */ - upb_alloc *alloc; /* Allocate defs here. */ - upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */ - upb_strtable *addtab; /* full_name -> packed def ptr for new defs. */ - upb_status *status; /* Record errors here. */ -} symtab_addctx; - -static char* strviewdup(const symtab_addctx *ctx, upb_strview view) { - return upb_strdup2(view.data, view.size, ctx->alloc); -} - -static bool streql2(const char *a, size_t n, const char *b) { - return n == strlen(b) && memcmp(a, b, n) == 0; -} - -static bool streql_view(upb_strview view, const char *b) { - return streql2(view.data, view.size, b); -} - -static const char *makefullname(const symtab_addctx *ctx, const char *prefix, - upb_strview name) { - if (prefix) { - /* ret = prefix + '.' + name; */ - size_t n = strlen(prefix); - char *ret = upb_malloc(ctx->alloc, n + name.size + 2); - CHK_OOM(ret); - strcpy(ret, prefix); - ret[n] = '.'; - memcpy(&ret[n + 1], name.data, name.size); - ret[n + 1 + name.size] = '\0'; - return ret; - } else { - return strviewdup(ctx, name); - } -} - -static bool symtab_add(const symtab_addctx *ctx, const char *name, - upb_value v) { - upb_value tmp; - if (upb_strtable_lookup(ctx->addtab, name, &tmp) || - upb_strtable_lookup(&ctx->symtab->syms, name, &tmp)) { - upb_status_seterrf(ctx->status, "duplicate symbol '%s'", name); - return false; - } - - CHK_OOM(upb_strtable_insert3(ctx->addtab, name, strlen(name), v, ctx->tmp)); - return true; -} - -/* Given a symbol and the base symbol inside which it is defined, find the - * symbol's definition in t. */ -static bool resolvename(const upb_strtable *t, const upb_fielddef *f, - const char *base, upb_strview sym, - upb_deftype_t type, upb_status *status, - const void **def) { - if(sym.size == 0) return NULL; - if(sym.data[0] == '.') { - /* Symbols starting with '.' are absolute, so we do a single lookup. - * Slice to omit the leading '.' */ - upb_value v; - if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) { - return false; - } - - *def = unpack_def(v, type); - - if (!*def) { - upb_status_seterrf(status, - "type mismatch when resolving field %s, name %s", - f->full_name, sym.data); - return false; - } - - return true; - } else { - /* Remove components from base until we find an entry or run out. - * TODO: This branch is totally broken, but currently not used. */ - (void)base; - UPB_ASSERT(false); - return false; - } -} - -const void *symtab_resolve(const symtab_addctx *ctx, const upb_fielddef *f, - const char *base, upb_strview sym, - upb_deftype_t type) { - const void *ret; - if (!resolvename(ctx->addtab, f, base, sym, type, ctx->status, &ret) && - !resolvename(&ctx->symtab->syms, f, base, sym, type, ctx->status, &ret)) { - if (upb_ok(ctx->status)) { - upb_status_seterrf(ctx->status, "couldn't resolve name '%s'", sym.data); - } - return false; - } - return ret; -} - -static bool create_oneofdef( - const symtab_addctx *ctx, upb_msgdef *m, - const google_protobuf_OneofDescriptorProto *oneof_proto) { - upb_oneofdef *o; - upb_strview name = google_protobuf_OneofDescriptorProto_name(oneof_proto); - upb_value v; - - o = (upb_oneofdef*)&m->oneofs[m->oneof_count++]; - o->parent = m; - o->full_name = makefullname(ctx, m->full_name, name); - - v = pack_def(o, UPB_DEFTYPE_ONEOF); - CHK_OOM(symtab_add(ctx, o->full_name, v)); - CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc)); - - CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); - CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); - - return true; -} - -static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, - upb_fielddef *f) { - char *end; - char nullz[64]; - errno = 0; - - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT32: - case UPB_TYPE_UINT64: - case UPB_TYPE_DOUBLE: - case UPB_TYPE_FLOAT: - /* Standard C number parsing functions expect null-terminated strings. */ - if (len >= sizeof(nullz) - 1) { - return false; - } - memcpy(nullz, str, len); - nullz[len] = '\0'; - str = nullz; - break; - default: - break; - } - - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: { - long val = strtol(str, &end, 0); - CHK(val <= INT32_MAX && val >= INT32_MIN && errno != ERANGE && !*end); - f->defaultval.sint = val; - break; - } - case UPB_TYPE_ENUM: { - const upb_enumdef *e = f->sub.enumdef; - int32_t val; - CHK(upb_enumdef_ntoi(e, str, len, &val)); - f->defaultval.sint = val; - break; - } - case UPB_TYPE_INT64: { - /* XXX: Need to write our own strtoll, since it's not available in c89. */ - long long val = strtol(str, &end, 0); - CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end); - f->defaultval.sint = val; - break; - } - case UPB_TYPE_UINT32: { - unsigned long val = strtoul(str, &end, 0); - CHK(val <= UINT32_MAX && errno != ERANGE && !*end); - f->defaultval.uint = val; - break; - } - case UPB_TYPE_UINT64: { - /* XXX: Need to write our own strtoull, since it's not available in c89. */ - unsigned long long val = strtoul(str, &end, 0); - CHK(val <= UINT64_MAX && errno != ERANGE && !*end); - f->defaultval.uint = val; - break; - } - case UPB_TYPE_DOUBLE: { - double val = strtod(str, &end); - CHK(errno != ERANGE && !*end); - f->defaultval.dbl = val; - break; - } - case UPB_TYPE_FLOAT: { - /* XXX: Need to write our own strtof, since it's not available in c89. */ - float val = strtod(str, &end); - CHK(errno != ERANGE && !*end); - f->defaultval.flt = val; - break; - } - case UPB_TYPE_BOOL: { - if (streql2(str, len, "false")) { - f->defaultval.boolean = false; - } else if (streql2(str, len, "true")) { - f->defaultval.boolean = true; - } else { - return false; - } - break; - } - case UPB_TYPE_STRING: - f->defaultval.str = newstr(ctx->alloc, str, len); - break; - case UPB_TYPE_BYTES: - /* XXX: need to interpret the C-escaped value. */ - f->defaultval.str = newstr(ctx->alloc, str, len); - break; - case UPB_TYPE_MESSAGE: - /* Should not have a default value. */ - return false; - } - return true; -} - -static void set_default_default(const symtab_addctx *ctx, upb_fielddef *f) { - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: - case UPB_TYPE_INT64: - case UPB_TYPE_ENUM: - f->defaultval.sint = 0; - break; - case UPB_TYPE_UINT64: - case UPB_TYPE_UINT32: - f->defaultval.uint = 0; - break; - case UPB_TYPE_DOUBLE: - case UPB_TYPE_FLOAT: - f->defaultval.dbl = 0; - break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - f->defaultval.str = newstr(ctx->alloc, NULL, 0); - break; - case UPB_TYPE_BOOL: - f->defaultval.boolean = false; - break; - case UPB_TYPE_MESSAGE: - break; - } -} - -static bool create_fielddef( - const symtab_addctx *ctx, const char *prefix, upb_msgdef *m, - const google_protobuf_FieldDescriptorProto *field_proto) { - upb_alloc *alloc = ctx->alloc; - upb_fielddef *f; - const google_protobuf_FieldOptions *options; - upb_strview name; - const char *full_name; - const char *shortname; - uint32_t field_number; - - if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { - upb_status_seterrmsg(ctx->status, "field has no name"); - return false; - } - - name = google_protobuf_FieldDescriptorProto_name(field_proto); - CHK(upb_isident(name, false, ctx->status)); - full_name = makefullname(ctx, prefix, name); - shortname = shortdefname(full_name); - - field_number = google_protobuf_FieldDescriptorProto_number(field_proto); - - if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) { - upb_status_seterrf(ctx->status, "invalid field number (%u)", field_number); - return false; - } - - if (m) { - /* direct message field. */ - upb_value v, packed_v; - - f = (upb_fielddef*)&m->fields[m->field_count++]; - f->msgdef = m; - f->is_extension_ = false; - - packed_v = pack_def(f, UPB_DEFTYPE_FIELD); - v = upb_value_constptr(f); - - if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) { - upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname); - return false; - } - - if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) { - upb_status_seterrf(ctx->status, "duplicate field number (%u)", - field_number); - return false; - } - } else { - /* extension field. */ - f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count]; - f->is_extension_ = true; - CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD))); - } - - f->full_name = full_name; - f->file = ctx->file; - f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); - f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); - f->number_ = field_number; - f->oneof = NULL; - - /* We can't resolve the subdef or (in the case of extensions) the containing - * message yet, because it may not have been defined yet. We stash a pointer - * to the field_proto until later when we can properly resolve it. */ - f->sub.unresolved = field_proto; - - if (f->label_ == UPB_LABEL_REQUIRED && f->file->syntax == UPB_SYNTAX_PROTO3) { - upb_status_seterrf(ctx->status, "proto3 fields cannot be required (%s)", - f->full_name); - return false; - } - - if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { - int oneof_index = - google_protobuf_FieldDescriptorProto_oneof_index(field_proto); - upb_oneofdef *oneof; - upb_value v = upb_value_constptr(f); - - if (upb_fielddef_label(f) != UPB_LABEL_OPTIONAL) { - upb_status_seterrf(ctx->status, - "fields in oneof must have OPTIONAL label (%s)", - f->full_name); - return false; - } - - if (!m) { - upb_status_seterrf(ctx->status, - "oneof_index provided for extension field (%s)", - f->full_name); - return false; - } - - if (oneof_index >= m->oneof_count) { - upb_status_seterrf(ctx->status, "oneof_index out of range (%s)", - f->full_name); - return false; - } - - oneof = (upb_oneofdef*)&m->oneofs[oneof_index]; - f->oneof = oneof; - - CHK(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc)); - CHK(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc)); - } else { - f->oneof = NULL; - } - - if (google_protobuf_FieldDescriptorProto_has_options(field_proto)) { - options = google_protobuf_FieldDescriptorProto_options(field_proto); - f->lazy_ = google_protobuf_FieldOptions_lazy(options); - f->packed_ = google_protobuf_FieldOptions_packed(options); - } else { - f->lazy_ = false; - f->packed_ = false; - } - - return true; -} - -static bool create_enumdef( - const symtab_addctx *ctx, const char *prefix, - const google_protobuf_EnumDescriptorProto *enum_proto) { - upb_enumdef *e; - const google_protobuf_EnumValueDescriptorProto *const *values; - upb_strview name; - size_t i, n; - - name = google_protobuf_EnumDescriptorProto_name(enum_proto); - CHK(upb_isident(name, false, ctx->status)); - - e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++]; - e->full_name = makefullname(ctx, prefix, name); - CHK_OOM(symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM))); - - CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, ctx->alloc)); - CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc)); - - e->file = ctx->file; - e->defaultval = 0; - - values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); - - if (n == 0) { - upb_status_seterrf(ctx->status, - "enums must contain at least one value (%s)", - e->full_name); - return false; - } - - for (i = 0; i < n; i++) { - const google_protobuf_EnumValueDescriptorProto *value = values[i]; - upb_strview name = google_protobuf_EnumValueDescriptorProto_name(value); - char *name2 = strviewdup(ctx, name); - int32_t num = google_protobuf_EnumValueDescriptorProto_number(value); - upb_value v = upb_value_int32(num); - - if (i == 0 && e->file->syntax == UPB_SYNTAX_PROTO3 && num != 0) { - upb_status_seterrf(ctx->status, - "for proto3, the first enum value must be zero (%s)", - e->full_name); - return false; - } - - if (upb_strtable_lookup(&e->ntoi, name2, NULL)) { - upb_status_seterrf(ctx->status, "duplicate enum label '%s'", name2); - return false; - } - - CHK_OOM(name2) - CHK_OOM( - upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc)); - - if (!upb_inttable_lookup(&e->iton, num, NULL)) { - upb_value v = upb_value_cstr(name2); - CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc)); - } - } - - upb_inttable_compact2(&e->iton, ctx->alloc); - - return true; -} - -static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, - const google_protobuf_DescriptorProto *msg_proto) { - upb_msgdef *m; - const google_protobuf_MessageOptions *options; - const google_protobuf_OneofDescriptorProto *const *oneofs; - const google_protobuf_FieldDescriptorProto *const *fields; - const google_protobuf_EnumDescriptorProto *const *enums; - const google_protobuf_DescriptorProto *const *msgs; - size_t i, n; - upb_strview name; - - name = google_protobuf_DescriptorProto_name(msg_proto); - CHK(upb_isident(name, false, ctx->status)); - - m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++]; - m->full_name = makefullname(ctx, prefix, name); - CHK_OOM(symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG))); - - CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc)); - CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, ctx->alloc)); - - m->file = ctx->file; - m->map_entry = false; - - options = google_protobuf_DescriptorProto_options(msg_proto); - - if (options) { - m->map_entry = google_protobuf_MessageOptions_map_entry(options); - } - - oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n); - m->oneof_count = 0; - m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n); - for (i = 0; i < n; i++) { - CHK(create_oneofdef(ctx, m, oneofs[i])); - } - - fields = google_protobuf_DescriptorProto_field(msg_proto, &n); - m->field_count = 0; - m->fields = upb_malloc(ctx->alloc, sizeof(*m->fields) * n); - for (i = 0; i < n; i++) { - CHK(create_fielddef(ctx, m->full_name, m, fields[i])); - } - - CHK(assign_msg_indices(m, ctx->status)); - assign_msg_wellknowntype(m); - upb_inttable_compact2(&m->itof, ctx->alloc); - - /* This message is built. Now build nested messages and enums. */ - - enums = google_protobuf_DescriptorProto_enum_type(msg_proto, &n); - for (i = 0; i < n; i++) { - CHK(create_enumdef(ctx, m->full_name, enums[i])); - } - - msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); - for (i = 0; i < n; i++) { - CHK(create_msgdef(ctx, m->full_name, msgs[i])); - } - - return true; -} - -typedef struct { - int msg_count; - int enum_count; - int ext_count; -} decl_counts; - -static void count_types_in_msg(const google_protobuf_DescriptorProto *msg_proto, - decl_counts *counts) { - const google_protobuf_DescriptorProto *const *msgs; - size_t i, n; - - counts->msg_count++; - - msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n); - for (i = 0; i < n; i++) { - count_types_in_msg(msgs[i], counts); - } - - google_protobuf_DescriptorProto_enum_type(msg_proto, &n); - counts->enum_count += n; - - google_protobuf_DescriptorProto_extension(msg_proto, &n); - counts->ext_count += n; -} - -static void count_types_in_file( - const google_protobuf_FileDescriptorProto *file_proto, - decl_counts *counts) { - const google_protobuf_DescriptorProto *const *msgs; - size_t i, n; - - msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); - for (i = 0; i < n; i++) { - count_types_in_msg(msgs[i], counts); - } - - google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); - counts->enum_count += n; - - google_protobuf_FileDescriptorProto_extension(file_proto, &n); - counts->ext_count += n; -} - -static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, - upb_fielddef *f) { - upb_strview name; - const google_protobuf_FieldDescriptorProto *field_proto = f->sub.unresolved; - - if (f->is_extension_) { - if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { - upb_status_seterrf(ctx->status, - "extension for field '%s' had no extendee", - f->full_name); - return false; - } - - name = google_protobuf_FieldDescriptorProto_extendee(field_proto); - f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); - CHK(f->msgdef); - } - - if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) && - !google_protobuf_FieldDescriptorProto_has_type_name(field_proto)) { - upb_status_seterrf(ctx->status, "field '%s' is missing type name", - f->full_name); - return false; - } - - name = google_protobuf_FieldDescriptorProto_type_name(field_proto); - - if (upb_fielddef_issubmsg(f)) { - f->sub.msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG); - CHK(f->sub.msgdef); - } else if (f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) { - f->sub.enumdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_ENUM); - CHK(f->sub.enumdef); - } - - /* Have to delay resolving of the default value until now because of the enum - * case, since enum defaults are specified with a label. */ - if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { - upb_strview defaultval = - google_protobuf_FieldDescriptorProto_default_value(field_proto); - - if (f->file->syntax == UPB_SYNTAX_PROTO3) { - upb_status_seterrf(ctx->status, - "proto3 fields cannot have explicit defaults (%s)", - f->full_name); - return false; - } - - if (upb_fielddef_issubmsg(f)) { - upb_status_seterrf(ctx->status, - "message fields cannot have explicit defaults (%s)", - f->full_name); - return false; - } - - if (!parse_default(ctx, defaultval.data, defaultval.size, f)) { - upb_status_seterrf(ctx->status, - "couldn't parse default '" UPB_STRVIEW_FORMAT - "' for field (%s)", - UPB_STRVIEW_ARGS(defaultval), f->full_name); - return false; - } - } else { - set_default_default(ctx, f); - } - - return true; -} - -static bool build_filedef( - const symtab_addctx *ctx, upb_filedef *file, - const google_protobuf_FileDescriptorProto *file_proto) { - upb_alloc *alloc = ctx->alloc; - const google_protobuf_FileOptions *file_options_proto; - const google_protobuf_DescriptorProto *const *msgs; - const google_protobuf_EnumDescriptorProto *const *enums; - const google_protobuf_FieldDescriptorProto *const *exts; - const upb_strview* strs; - size_t i, n; - decl_counts counts = {0}; - - count_types_in_file(file_proto, &counts); - - file->msgs = upb_malloc(alloc, sizeof(*file->msgs) * counts.msg_count); - file->enums = upb_malloc(alloc, sizeof(*file->enums) * counts.enum_count); - file->exts = upb_malloc(alloc, sizeof(*file->exts) * counts.ext_count); - - CHK_OOM(counts.msg_count == 0 || file->msgs); - CHK_OOM(counts.enum_count == 0 || file->enums); - CHK_OOM(counts.ext_count == 0 || file->exts); - - /* We increment these as defs are added. */ - file->msg_count = 0; - file->enum_count = 0; - file->ext_count = 0; - - if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) { - upb_status_seterrmsg(ctx->status, "File has no name"); - return false; - } - - file->name = - strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto)); - file->phpprefix = NULL; - file->phpnamespace = NULL; - - if (google_protobuf_FileDescriptorProto_has_package(file_proto)) { - upb_strview package = - google_protobuf_FileDescriptorProto_package(file_proto); - CHK(upb_isident(package, true, ctx->status)); - file->package = strviewdup(ctx, package); - } else { - file->package = NULL; - } - - if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { - upb_strview syntax = - google_protobuf_FileDescriptorProto_syntax(file_proto); - - if (streql_view(syntax, "proto2")) { - file->syntax = UPB_SYNTAX_PROTO2; - } else if (streql_view(syntax, "proto3")) { - file->syntax = UPB_SYNTAX_PROTO3; - } else { - upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax); - return false; - } - } else { - file->syntax = UPB_SYNTAX_PROTO2; - } - - /* Read options. */ - file_options_proto = google_protobuf_FileDescriptorProto_options(file_proto); - if (file_options_proto) { - if (google_protobuf_FileOptions_has_php_class_prefix(file_options_proto)) { - file->phpprefix = strviewdup( - ctx, - google_protobuf_FileOptions_php_class_prefix(file_options_proto)); - } - if (google_protobuf_FileOptions_has_php_namespace(file_options_proto)) { - file->phpnamespace = strviewdup( - ctx, google_protobuf_FileOptions_php_namespace(file_options_proto)); - } - } - - /* Verify dependencies. */ - strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); - file->deps = upb_malloc(alloc, sizeof(*file->deps) * n) ; - CHK_OOM(n == 0 || file->deps); - - for (i = 0; i < n; i++) { - upb_strview dep_name = strs[i]; - upb_value v; - if (!upb_strtable_lookup2(&ctx->symtab->files, dep_name.data, - dep_name.size, &v)) { - upb_status_seterrf(ctx->status, - "Depends on file '" UPB_STRVIEW_FORMAT - "', but it has not been loaded", - UPB_STRVIEW_ARGS(dep_name)); - return false; - } - file->deps[i] = upb_value_getconstptr(v); - } - - /* Create messages. */ - msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); - for (i = 0; i < n; i++) { - CHK(create_msgdef(ctx, file->package, msgs[i])); - } - - /* Create enums. */ - enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); - for (i = 0; i < n; i++) { - CHK(create_enumdef(ctx, file->package, enums[i])); - } - - /* Create extensions. */ - exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); - file->exts = upb_malloc(alloc, sizeof(*file->exts) * n); - CHK_OOM(n == 0 || file->exts); - for (i = 0; i < n; i++) { - CHK(create_fielddef(ctx, file->package, NULL, exts[i])); - } - - /* Now that all names are in the table, resolve references. */ - for (i = 0; i < file->ext_count; i++) { - CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i])); - } - - for (i = 0; i < file->msg_count; i++) { - const upb_msgdef *m = &file->msgs[i]; - int j; - for (j = 0; j < m->field_count; j++) { - CHK(resolve_fielddef(ctx, m->full_name, (upb_fielddef*)&m->fields[j])); - } - } - - return true; - } - -static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, - upb_status *status) { - const upb_filedef *file = ctx->file; - upb_alloc *alloc = upb_arena_alloc(s->arena); - upb_strtable_iter iter; - - CHK_OOM(upb_strtable_insert3(&s->files, file->name, strlen(file->name), - upb_value_constptr(file), alloc)); - - upb_strtable_begin(&iter, ctx->addtab); - for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { - const char *key = upb_strtable_iter_key(&iter); - size_t keylen = upb_strtable_iter_keylength(&iter); - upb_value value = upb_strtable_iter_value(&iter); - CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc)); - } - - return true; -} - -/* upb_filedef ****************************************************************/ - -const char *upb_filedef_name(const upb_filedef *f) { - return f->name; -} - -const char *upb_filedef_package(const upb_filedef *f) { - return f->package; -} - -const char *upb_filedef_phpprefix(const upb_filedef *f) { - return f->phpprefix; -} - -const char *upb_filedef_phpnamespace(const upb_filedef *f) { - return f->phpnamespace; -} - -upb_syntax_t upb_filedef_syntax(const upb_filedef *f) { - return f->syntax; -} - -int upb_filedef_msgcount(const upb_filedef *f) { - return f->msg_count; -} - -int upb_filedef_depcount(const upb_filedef *f) { - return f->dep_count; -} - -int upb_filedef_enumcount(const upb_filedef *f) { - return f->enum_count; -} - -const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i) { - return i < 0 || i >= f->dep_count ? NULL : f->deps[i]; -} - -const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i) { - return i < 0 || i >= f->msg_count ? NULL : &f->msgs[i]; -} - -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i) { - return i < 0 || i >= f->enum_count ? NULL : &f->enums[i]; -} - -void upb_symtab_free(upb_symtab *s) { - upb_arena_free(s->arena); - upb_gfree(s); -} - -upb_symtab *upb_symtab_new(void) { - upb_symtab *s = upb_gmalloc(sizeof(*s)); - upb_alloc *alloc; - - if (!s) { - return NULL; - } - - s->arena = upb_arena_new(); - alloc = upb_arena_alloc(s->arena); - - if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, alloc) || - !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, alloc)) { - upb_arena_free(s->arena); - upb_gfree(s); - s = NULL; - } - return s; -} - -const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) { - upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_MSG) : NULL; -} - -const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym, - size_t len) { - upb_value v; - return upb_strtable_lookup2(&s->syms, sym, len, &v) ? - unpack_def(v, UPB_DEFTYPE_MSG) : NULL; -} - -const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) { - upb_value v; - return upb_strtable_lookup(&s->syms, sym, &v) ? - unpack_def(v, UPB_DEFTYPE_ENUM) : NULL; -} - -const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) { - upb_value v; - return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) - : NULL; -} - -const upb_filedef *upb_symtab_lookupfile2( - const upb_symtab *s, const char *name, size_t len) { - upb_value v; - return upb_strtable_lookup2(&s->files, name, len, &v) ? - upb_value_getconstptr(v) : NULL; -} - -const upb_filedef *upb_symtab_addfile( - upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, - upb_status *status) { - upb_arena *tmparena = upb_arena_new(); - upb_strtable addtab; - upb_alloc *alloc = upb_arena_alloc(s->arena); - upb_filedef *file = upb_malloc(alloc, sizeof(*file)); - bool ok; - symtab_addctx ctx; - - ctx.file = file; - ctx.symtab = s; - ctx.alloc = alloc; - ctx.tmp = upb_arena_alloc(tmparena); - ctx.addtab = &addtab; - ctx.status = status; - - ok = file && - upb_strtable_init2(&addtab, UPB_CTYPE_CONSTPTR, ctx.tmp) && - build_filedef(&ctx, file, file_proto) && - upb_symtab_addtotabs(s, &ctx, status); - - upb_arena_free(tmparena); - return ok ? file : NULL; -} - -/* Include here since we want most of this file to be stdio-free. */ -#include - -bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { - /* Since this function should never fail (it would indicate a bug in upb) we - * print errors to stderr instead of returning error status to the user. */ - upb_def_init **deps = init->deps; - google_protobuf_FileDescriptorProto *file; - upb_arena *arena; - upb_status status; - - upb_status_clear(&status); - - if (upb_strtable_lookup(&s->files, init->filename, NULL)) { - return true; - } - - arena = upb_arena_new(); - - for (; *deps; deps++) { - if (!_upb_symtab_loaddefinit(s, *deps)) goto err; - } - - file = google_protobuf_FileDescriptorProto_parse( - init->descriptor.data, init->descriptor.size, arena); - - if (!file) { - upb_status_seterrf( - &status, - "Failed to parse compiled-in descriptor for file '%s'. This should " - "never happen.", - init->filename); - goto err; - } - - if (!upb_symtab_addfile(s, file, &status)) goto err; - - upb_arena_free(arena); - return true; - -err: - fprintf(stderr, "Error loading compiled-in descriptor: %s\n", - upb_status_errmsg(&status)); - upb_arena_free(arena); - return false; -} - -#undef CHK -#undef CHK_OOM - - - -static bool is_power_of_two(size_t val) { - return (val & (val - 1)) == 0; -} - -/* Align up to the given power of 2. */ -static size_t align_up(size_t val, size_t align) { - UPB_ASSERT(is_power_of_two(align)); - return (val + align - 1) & ~(align - 1); -} - -static size_t div_round_up(size_t n, size_t d) { - return (n + d - 1) / d; -} - -static size_t upb_msgval_sizeof2(upb_fieldtype_t type) { - switch (type) { - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: - return 8; - case UPB_TYPE_ENUM: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_FLOAT: - return 4; - case UPB_TYPE_BOOL: - return 1; - case UPB_TYPE_MESSAGE: - return sizeof(void*); - case UPB_TYPE_BYTES: - case UPB_TYPE_STRING: - return sizeof(upb_strview); - } - UPB_UNREACHABLE(); -} - -static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { - if (upb_fielddef_isseq(f)) { - return sizeof(void*); - } else { - return upb_msgval_sizeof2(upb_fielddef_type(f)); - } -} - - -/** upb_msglayout *************************************************************/ - -static void upb_msglayout_free(upb_msglayout *l) { - upb_gfree(l); -} - -static size_t upb_msglayout_place(upb_msglayout *l, size_t size) { - size_t ret; - - l->size = align_up(l->size, size); - ret = l->size; - l->size += size; - return ret; -} - -static bool upb_msglayout_init(const upb_msgdef *m, - upb_msglayout *l, - upb_msgfactory *factory) { - upb_msg_field_iter it; - upb_msg_oneof_iter oit; - size_t hasbit; - size_t submsg_count = 0; - const upb_msglayout **submsgs; - upb_msglayout_field *fields; - - for (upb_msg_field_begin(&it, m); - !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* f = upb_msg_iter_field(&it); - if (upb_fielddef_issubmsg(f)) { - submsg_count++; - } - } - - memset(l, 0, sizeof(*l)); - - fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields)); - submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs)); - - if ((!fields && upb_msgdef_numfields(m)) || - (!submsgs && submsg_count)) { - /* OOM. */ - upb_gfree(fields); - upb_gfree(submsgs); - return false; - } - - l->field_count = upb_msgdef_numfields(m); - l->fields = fields; - l->submsgs = submsgs; - - /* Allocate data offsets in three stages: - * - * 1. hasbits. - * 2. regular fields. - * 3. oneof fields. - * - * OPT: There is a lot of room for optimization here to minimize the size. - */ - - /* Allocate hasbits and set basic field attributes. */ - submsg_count = 0; - for (upb_msg_field_begin(&it, m), hasbit = 0; - !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* f = upb_msg_iter_field(&it); - upb_msglayout_field *field = &fields[upb_fielddef_index(f)]; - - field->number = upb_fielddef_number(f); - field->descriptortype = upb_fielddef_descriptortype(f); - field->label = upb_fielddef_label(f); - - if (upb_fielddef_issubmsg(f)) { - const upb_msglayout *sub_layout = - upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f)); - field->submsg_index = submsg_count++; - submsgs[field->submsg_index] = sub_layout; - } - - if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) { - field->presence = (hasbit++); - } else { - field->presence = 0; - } - } - - /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit, 8); - - /* Allocate non-oneof fields. */ - for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* f = upb_msg_iter_field(&it); - size_t field_size = upb_msg_fielddefsize(f); - size_t index = upb_fielddef_index(f); - - if (upb_fielddef_containingoneof(f)) { - /* Oneofs are handled separately below. */ - continue; - } - - fields[index].offset = upb_msglayout_place(l, field_size); - } - - /* Allocate oneof fields. Each oneof field consists of a uint32 for the case - * and space for the actual data. */ - for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit); - upb_msg_oneof_next(&oit)) { - const upb_oneofdef* o = upb_msg_iter_oneof(&oit); - upb_oneof_iter fit; - - size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ - size_t field_size = 0; - uint32_t case_offset; - uint32_t data_offset; - - /* Calculate field size: the max of all field sizes. */ - for (upb_oneof_begin(&fit, o); - !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* f = upb_oneof_iter_field(&fit); - field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f)); - } - - /* Align and allocate case offset. */ - case_offset = upb_msglayout_place(l, case_size); - data_offset = upb_msglayout_place(l, field_size); - - for (upb_oneof_begin(&fit, o); - !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* f = upb_oneof_iter_field(&fit); - fields[upb_fielddef_index(f)].offset = data_offset; - fields[upb_fielddef_index(f)].presence = ~case_offset; - } - } - - /* Size of the entire structure should be a multiple of its greatest - * alignment. TODO: track overall alignment for real? */ - l->size = align_up(l->size, 8); - - return true; -} - - -/** upb_msgfactory ************************************************************/ - -struct upb_msgfactory { - const upb_symtab *symtab; /* We own a ref. */ - upb_inttable layouts; -}; - -upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) { - upb_msgfactory *ret = upb_gmalloc(sizeof(*ret)); - - ret->symtab = symtab; - upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR); - - return ret; -} - -void upb_msgfactory_free(upb_msgfactory *f) { - upb_inttable_iter i; - upb_inttable_begin(&i, &f->layouts); - for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i)); - upb_msglayout_free(l); - } - - upb_inttable_uninit(&f->layouts); - upb_gfree(f); -} - -const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) { - return f->symtab; -} - -const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, - const upb_msgdef *m) { - upb_value v; - UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m); - UPB_ASSERT(!upb_msgdef_mapentry(m)); - - if (upb_inttable_lookupptr(&f->layouts, m, &v)) { - UPB_ASSERT(upb_value_getptr(v)); - return upb_value_getptr(v); - } else { - /* In case of circular dependency, layout has to be inserted first. */ - upb_msglayout *l = upb_gmalloc(sizeof(*l)); - upb_msgfactory *mutable_f = (void*)f; - upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l)); - UPB_ASSERT(l); - if (!upb_msglayout_init(m, l, f)) { - upb_msglayout_free(l); - } - return l; - } -} -/* -** TODO(haberman): it's unclear whether a lot of the consistency checks should -** UPB_ASSERT() or return false. -*/ - - -#include - - - -struct upb_handlers { - upb_handlercache *cache; - const upb_msgdef *msg; - const upb_handlers **sub; - const void *top_closure_type; - upb_handlers_tabent table[1]; /* Dynamically-sized field handler array. */ -}; - -static void *upb_calloc(upb_arena *arena, size_t size) { - void *mem = upb_malloc(upb_arena_alloc(arena), size); - if (mem) { - memset(mem, 0, size); - } - return mem; -} - -/* Defined for the sole purpose of having a unique pointer value for - * UPB_NO_CLOSURE. */ -char _upb_noclosure; - -/* Given a selector for a STARTSUBMSG handler, resolves to a pointer to the - * subhandlers for this submessage field. */ -#define SUBH(h, selector) (h->sub[selector]) - -/* The selector for a submessage field is the field index. */ -#define SUBH_F(h, f) SUBH(h, upb_fielddef_index(f)) - -static int32_t trygetsel(upb_handlers *h, const upb_fielddef *f, - upb_handlertype_t type) { - upb_selector_t sel; - bool ok; - - ok = upb_handlers_getselector(f, type, &sel); - - UPB_ASSERT(upb_handlers_msgdef(h) == upb_fielddef_containingtype(f)); - UPB_ASSERT(ok); - - return sel; -} - -static upb_selector_t handlers_getsel(upb_handlers *h, const upb_fielddef *f, - upb_handlertype_t type) { - int32_t sel = trygetsel(h, f, type); - UPB_ASSERT(sel >= 0); - return sel; -} - -static const void **returntype(upb_handlers *h, const upb_fielddef *f, - upb_handlertype_t type) { - return &h->table[handlers_getsel(h, f, type)].attr.return_closure_type; -} - -static bool doset(upb_handlers *h, int32_t sel, const upb_fielddef *f, - upb_handlertype_t type, upb_func *func, - const upb_handlerattr *attr) { - upb_handlerattr set_attr = UPB_HANDLERATTR_INIT; - const void *closure_type; - const void **context_closure_type; - - UPB_ASSERT(!h->table[sel].func); - - if (attr) { - set_attr = *attr; - } - - /* Check that the given closure type matches the closure type that has been - * established for this context (if any). */ - closure_type = set_attr.closure_type; - - if (type == UPB_HANDLER_STRING) { - context_closure_type = returntype(h, f, UPB_HANDLER_STARTSTR); - } else if (f && upb_fielddef_isseq(f) && - type != UPB_HANDLER_STARTSEQ && - type != UPB_HANDLER_ENDSEQ) { - context_closure_type = returntype(h, f, UPB_HANDLER_STARTSEQ); - } else { - context_closure_type = &h->top_closure_type; - } - - if (closure_type && *context_closure_type && - closure_type != *context_closure_type) { - return false; - } - - if (closure_type) - *context_closure_type = closure_type; - - /* If this is a STARTSEQ or STARTSTR handler, check that the returned pointer - * matches any pre-existing expectations about what type is expected. */ - if (type == UPB_HANDLER_STARTSEQ || type == UPB_HANDLER_STARTSTR) { - const void *return_type = set_attr.return_closure_type; - const void *table_return_type = h->table[sel].attr.return_closure_type; - if (return_type && table_return_type && return_type != table_return_type) { - return false; - } - - if (table_return_type && !return_type) { - set_attr.return_closure_type = table_return_type; - } - } - - h->table[sel].func = (upb_func*)func; - h->table[sel].attr = set_attr; - return true; -} - -/* Returns the effective closure type for this handler (which will propagate - * from outer frames if this frame has no START* handler). Not implemented for - * UPB_HANDLER_STRING at the moment since this is not needed. Returns NULL is - * the effective closure type is unspecified (either no handler was registered - * to specify it or the handler that was registered did not specify the closure - * type). */ -const void *effective_closure_type(upb_handlers *h, const upb_fielddef *f, - upb_handlertype_t type) { - const void *ret; - upb_selector_t sel; - - UPB_ASSERT(type != UPB_HANDLER_STRING); - ret = h->top_closure_type; - - if (upb_fielddef_isseq(f) && - type != UPB_HANDLER_STARTSEQ && - type != UPB_HANDLER_ENDSEQ && - h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSEQ)].func) { - ret = h->table[sel].attr.return_closure_type; - } - - if (type == UPB_HANDLER_STRING && - h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSTR)].func) { - ret = h->table[sel].attr.return_closure_type; - } - - /* The effective type of the submessage; not used yet. - * if (type == SUBMESSAGE && - * h->table[sel = handlers_getsel(h, f, UPB_HANDLER_STARTSUBMSG)].func) { - * ret = h->table[sel].attr.return_closure_type; - * } */ - - return ret; -} - -/* Checks whether the START* handler specified by f & type is missing even - * though it is required to convert the established type of an outer frame - * ("closure_type") into the established type of an inner frame (represented in - * the return closure type of this handler's attr. */ -bool checkstart(upb_handlers *h, const upb_fielddef *f, upb_handlertype_t type, - upb_status *status) { - const void *closure_type; - const upb_handlerattr *attr; - const void *return_closure_type; - - upb_selector_t sel = handlers_getsel(h, f, type); - if (h->table[sel].func) return true; - closure_type = effective_closure_type(h, f, type); - attr = &h->table[sel].attr; - return_closure_type = attr->return_closure_type; - if (closure_type && return_closure_type && - closure_type != return_closure_type) { - return false; - } - return true; -} - -static upb_handlers *upb_handlers_new(const upb_msgdef *md, - upb_handlercache *cache, - upb_arena *arena) { - int extra; - upb_handlers *h; - - extra = sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1); - h = upb_calloc(arena, sizeof(*h) + extra); - if (!h) return NULL; - - h->cache = cache; - h->msg = md; - - if (upb_msgdef_submsgfieldcount(md) > 0) { - size_t bytes = upb_msgdef_submsgfieldcount(md) * sizeof(*h->sub); - h->sub = upb_calloc(arena, bytes); - if (!h->sub) return NULL; - } else { - h->sub = 0; - } - - /* calloc() above initialized all handlers to NULL. */ - return h; -} - -/* Public interface ***********************************************************/ - -#define SETTER(name, handlerctype, handlertype) \ - bool upb_handlers_set##name(upb_handlers *h, const upb_fielddef *f, \ - handlerctype func, \ - const upb_handlerattr *attr) { \ - int32_t sel = trygetsel(h, f, handlertype); \ - return doset(h, sel, f, handlertype, (upb_func *)func, attr); \ - } - -SETTER(int32, upb_int32_handlerfunc*, UPB_HANDLER_INT32) -SETTER(int64, upb_int64_handlerfunc*, UPB_HANDLER_INT64) -SETTER(uint32, upb_uint32_handlerfunc*, UPB_HANDLER_UINT32) -SETTER(uint64, upb_uint64_handlerfunc*, UPB_HANDLER_UINT64) -SETTER(float, upb_float_handlerfunc*, UPB_HANDLER_FLOAT) -SETTER(double, upb_double_handlerfunc*, UPB_HANDLER_DOUBLE) -SETTER(bool, upb_bool_handlerfunc*, UPB_HANDLER_BOOL) -SETTER(startstr, upb_startstr_handlerfunc*, UPB_HANDLER_STARTSTR) -SETTER(string, upb_string_handlerfunc*, UPB_HANDLER_STRING) -SETTER(endstr, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSTR) -SETTER(startseq, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSEQ) -SETTER(startsubmsg, upb_startfield_handlerfunc*, UPB_HANDLER_STARTSUBMSG) -SETTER(endsubmsg, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSUBMSG) -SETTER(endseq, upb_endfield_handlerfunc*, UPB_HANDLER_ENDSEQ) - -#undef SETTER - -bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func, - const upb_handlerattr *attr) { - return doset(h, UPB_UNKNOWN_SELECTOR, NULL, UPB_HANDLER_INT32, - (upb_func *)func, attr); -} - -bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func, - const upb_handlerattr *attr) { - return doset(h, UPB_STARTMSG_SELECTOR, NULL, UPB_HANDLER_INT32, - (upb_func *)func, attr); -} - -bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func, - const upb_handlerattr *attr) { - return doset(h, UPB_ENDMSG_SELECTOR, NULL, UPB_HANDLER_INT32, - (upb_func *)func, attr); -} - -bool upb_handlers_setsubhandlers(upb_handlers *h, const upb_fielddef *f, - const upb_handlers *sub) { - UPB_ASSERT(sub); - UPB_ASSERT(upb_fielddef_issubmsg(f)); - if (SUBH_F(h, f)) return false; /* Can't reset. */ - if (upb_handlers_msgdef(sub) != upb_fielddef_msgsubdef(f)) { - return false; - } - SUBH_F(h, f) = sub; - return true; -} - -const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h, - const upb_fielddef *f) { - UPB_ASSERT(upb_fielddef_issubmsg(f)); - return SUBH_F(h, f); -} - -upb_func *upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s, - const void **handler_data) { - upb_func *ret = (upb_func *)h->table[s].func; - if (ret && handler_data) { - *handler_data = h->table[s].attr.handler_data; - } - return ret; -} - -bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t sel, - upb_handlerattr *attr) { - if (!upb_handlers_gethandler(h, sel, NULL)) - return false; - *attr = h->table[sel].attr; - return true; -} - -const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h, - upb_selector_t sel) { - /* STARTSUBMSG selector in sel is the field's selector base. */ - return SUBH(h, sel - UPB_STATIC_SELECTOR_COUNT); -} - -const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h) { return h->msg; } - -bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *func) { - return upb_handlercache_addcleanup(h->cache, p, func); -} - -upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f) { - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: - case UPB_TYPE_ENUM: return UPB_HANDLER_INT32; - case UPB_TYPE_INT64: return UPB_HANDLER_INT64; - case UPB_TYPE_UINT32: return UPB_HANDLER_UINT32; - case UPB_TYPE_UINT64: return UPB_HANDLER_UINT64; - case UPB_TYPE_FLOAT: return UPB_HANDLER_FLOAT; - case UPB_TYPE_DOUBLE: return UPB_HANDLER_DOUBLE; - case UPB_TYPE_BOOL: return UPB_HANDLER_BOOL; - default: UPB_ASSERT(false); return -1; /* Invalid input. */ - } -} - -bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type, - upb_selector_t *s) { - uint32_t selector_base = upb_fielddef_selectorbase(f); - switch (type) { - case UPB_HANDLER_INT32: - case UPB_HANDLER_INT64: - case UPB_HANDLER_UINT32: - case UPB_HANDLER_UINT64: - case UPB_HANDLER_FLOAT: - case UPB_HANDLER_DOUBLE: - case UPB_HANDLER_BOOL: - if (!upb_fielddef_isprimitive(f) || - upb_handlers_getprimitivehandlertype(f) != type) - return false; - *s = selector_base; - break; - case UPB_HANDLER_STRING: - if (upb_fielddef_isstring(f)) { - *s = selector_base; - } else if (upb_fielddef_lazy(f)) { - *s = selector_base + 3; - } else { - return false; - } - break; - case UPB_HANDLER_STARTSTR: - if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) { - *s = selector_base + 1; - } else { - return false; - } - break; - case UPB_HANDLER_ENDSTR: - if (upb_fielddef_isstring(f) || upb_fielddef_lazy(f)) { - *s = selector_base + 2; - } else { - return false; - } - break; - case UPB_HANDLER_STARTSEQ: - if (!upb_fielddef_isseq(f)) return false; - *s = selector_base - 2; - break; - case UPB_HANDLER_ENDSEQ: - if (!upb_fielddef_isseq(f)) return false; - *s = selector_base - 1; - break; - case UPB_HANDLER_STARTSUBMSG: - if (!upb_fielddef_issubmsg(f)) return false; - /* Selectors for STARTSUBMSG are at the beginning of the table so that the - * selector can also be used as an index into the "sub" array of - * subhandlers. The indexes for the two into these two tables are the - * same, except that in the handler table the static selectors come first. */ - *s = upb_fielddef_index(f) + UPB_STATIC_SELECTOR_COUNT; - break; - case UPB_HANDLER_ENDSUBMSG: - if (!upb_fielddef_issubmsg(f)) return false; - *s = selector_base; - break; - } - UPB_ASSERT((size_t)*s < upb_msgdef_selectorcount(upb_fielddef_containingtype(f))); - return true; -} - -/* upb_handlercache ***********************************************************/ - -struct upb_handlercache { - upb_arena *arena; - upb_inttable tab; /* maps upb_msgdef* -> upb_handlers*. */ - upb_handlers_callback *callback; - const void *closure; -}; - -const upb_handlers *upb_handlercache_get(upb_handlercache *c, - const upb_msgdef *md) { - upb_msg_field_iter i; - upb_value v; - upb_handlers *h; - - if (upb_inttable_lookupptr(&c->tab, md, &v)) { - return upb_value_getptr(v); - } - - h = upb_handlers_new(md, c, c->arena); - v = upb_value_ptr(h); - - if (!h) return NULL; - if (!upb_inttable_insertptr(&c->tab, md, v)) return NULL; - - c->callback(c->closure, h); - - /* For each submessage field, get or create a handlers object and set it as - * the subhandlers. */ - 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_handlers *sub_mh = upb_handlercache_get(c, subdef); - - if (!sub_mh) return NULL; - - upb_handlers_setsubhandlers(h, f, sub_mh); - } - } - - return h; -} - - -upb_handlercache *upb_handlercache_new(upb_handlers_callback *callback, - const void *closure) { - upb_handlercache *cache = upb_gmalloc(sizeof(*cache)); - - if (!cache) return NULL; - - cache->arena = upb_arena_new(); - - cache->callback = callback; - cache->closure = closure; - - if (!upb_inttable_init(&cache->tab, UPB_CTYPE_PTR)) goto oom; - - return cache; - -oom: - upb_gfree(cache); - return NULL; -} - -void upb_handlercache_free(upb_handlercache *cache) { - upb_inttable_uninit(&cache->tab); - upb_arena_free(cache->arena); - upb_gfree(cache); -} - -bool upb_handlercache_addcleanup(upb_handlercache *c, void *p, - upb_handlerfree *func) { - return upb_arena_addcleanup(c->arena, p, func); -} - -/* upb_byteshandler ***********************************************************/ - -bool upb_byteshandler_setstartstr(upb_byteshandler *h, - upb_startstr_handlerfunc *func, void *d) { - h->table[UPB_STARTSTR_SELECTOR].func = (upb_func*)func; - h->table[UPB_STARTSTR_SELECTOR].attr.handler_data = d; - return true; -} - -bool upb_byteshandler_setstring(upb_byteshandler *h, - upb_string_handlerfunc *func, void *d) { - h->table[UPB_STRING_SELECTOR].func = (upb_func*)func; - h->table[UPB_STRING_SELECTOR].attr.handler_data = d; - return true; -} - -bool upb_byteshandler_setendstr(upb_byteshandler *h, - upb_endfield_handlerfunc *func, void *d) { - h->table[UPB_ENDSTR_SELECTOR].func = (upb_func*)func; - h->table[UPB_ENDSTR_SELECTOR].attr.handler_data = d; - return true; -} - -/** Handlers for upb_msg ******************************************************/ - -typedef struct { - size_t offset; - int32_t hasbit; -} upb_msg_handlerdata; - -/* Fallback implementation if the handler is not specialized by the producer. */ -#define MSG_WRITER(type, ctype) \ - bool upb_msg_set ## type (void *c, const void *hd, ctype val) { \ - uint8_t *m = c; \ - const upb_msg_handlerdata *d = hd; \ - if (d->hasbit > 0) \ - *(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \ - *(ctype*)&m[d->offset] = val; \ - return true; \ - } \ - -MSG_WRITER(double, double) -MSG_WRITER(float, float) -MSG_WRITER(int32, int32_t) -MSG_WRITER(int64, int64_t) -MSG_WRITER(uint32, uint32_t) -MSG_WRITER(uint64, uint64_t) -MSG_WRITER(bool, bool) - -bool upb_msg_setscalarhandler(upb_handlers *h, const upb_fielddef *f, - size_t offset, int32_t hasbit) { - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - bool ok; - - upb_msg_handlerdata *d = upb_gmalloc(sizeof(*d)); - if (!d) return false; - d->offset = offset; - d->hasbit = hasbit; - - attr.handler_data = d; - attr.alwaysok = true; - upb_handlers_addcleanup(h, d, upb_gfree); - -#define TYPE(u, l) \ - case UPB_TYPE_##u: \ - ok = upb_handlers_set##l(h, f, upb_msg_set##l, &attr); break; - - ok = false; - - switch (upb_fielddef_type(f)) { - TYPE(INT64, int64); - TYPE(INT32, int32); - TYPE(ENUM, int32); - TYPE(UINT64, uint64); - TYPE(UINT32, uint32); - TYPE(DOUBLE, double); - TYPE(FLOAT, float); - TYPE(BOOL, bool); - default: UPB_ASSERT(false); break; - } -#undef TYPE - - return ok; -} - -bool upb_msg_getscalarhandlerdata(const upb_handlers *h, - upb_selector_t s, - upb_fieldtype_t *type, - size_t *offset, - int32_t *hasbit) { - const upb_msg_handlerdata *d; - const void *p; - upb_func *f = upb_handlers_gethandler(h, s, &p); - - if ((upb_int64_handlerfunc*)f == upb_msg_setint64) { - *type = UPB_TYPE_INT64; - } else if ((upb_int32_handlerfunc*)f == upb_msg_setint32) { - *type = UPB_TYPE_INT32; - } else if ((upb_uint64_handlerfunc*)f == upb_msg_setuint64) { - *type = UPB_TYPE_UINT64; - } else if ((upb_uint32_handlerfunc*)f == upb_msg_setuint32) { - *type = UPB_TYPE_UINT32; - } else if ((upb_double_handlerfunc*)f == upb_msg_setdouble) { - *type = UPB_TYPE_DOUBLE; - } else if ((upb_float_handlerfunc*)f == upb_msg_setfloat) { - *type = UPB_TYPE_FLOAT; - } else if ((upb_bool_handlerfunc*)f == upb_msg_setbool) { - *type = UPB_TYPE_BOOL; - } else { - return false; - } - - d = p; - *offset = d->offset; - *hasbit = d->hasbit; - return true; -} - - -bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink) { - void *subc; - bool ret; - upb_bufhandle handle = UPB_BUFHANDLE_INIT; - handle.buf = buf; - ret = upb_bytessink_start(sink, len, &subc); - if (ret && len != 0) { - ret = (upb_bytessink_putbuf(sink, subc, buf, len, &handle) >= len); - } - if (ret) { - ret = upb_bytessink_end(sink); - } - return ret; -} -/* -** protobuf decoder bytecode compiler -** -** Code to compile a upb::Handlers into bytecode for decoding a protobuf -** according to that specific schema and destination handlers. -** -** Bytecode definition is in decoder.int.h. -*/ - -#include - -#ifdef UPB_DUMP_BYTECODE -#include -#endif - - -#define MAXLABEL 5 -#define EMPTYLABEL -1 - -/* upb_pbdecodermethod ********************************************************/ - -static void freemethod(upb_pbdecodermethod *method) { - upb_inttable_uninit(&method->dispatch); - upb_gfree(method); -} - -static upb_pbdecodermethod *newmethod(const upb_handlers *dest_handlers, - mgroup *group) { - upb_pbdecodermethod *ret = upb_gmalloc(sizeof(*ret)); - upb_byteshandler_init(&ret->input_handler_); - - ret->group = group; - ret->dest_handlers_ = dest_handlers; - upb_inttable_init(&ret->dispatch, UPB_CTYPE_UINT64); - - return ret; -} - -const upb_handlers *upb_pbdecodermethod_desthandlers( - const upb_pbdecodermethod *m) { - return m->dest_handlers_; -} - -const upb_byteshandler *upb_pbdecodermethod_inputhandler( - const upb_pbdecodermethod *m) { - return &m->input_handler_; -} - -bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m) { - return m->is_native_; -} - - -/* mgroup *********************************************************************/ - -static void freegroup(mgroup *g) { - upb_inttable_iter i; - - upb_inttable_begin(&i, &g->methods); - for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - freemethod(upb_value_getptr(upb_inttable_iter_value(&i))); - } - - upb_inttable_uninit(&g->methods); - upb_gfree(g->bytecode); - upb_gfree(g); -} - -mgroup *newgroup(void) { - mgroup *g = upb_gmalloc(sizeof(*g)); - upb_inttable_init(&g->methods, UPB_CTYPE_PTR); - g->bytecode = NULL; - g->bytecode_end = NULL; - return g; -} - - -/* bytecode compiler **********************************************************/ - -/* Data used only at compilation time. */ -typedef struct { - mgroup *group; - - uint32_t *pc; - int fwd_labels[MAXLABEL]; - int back_labels[MAXLABEL]; - - /* For fields marked "lazy", parse them lazily or eagerly? */ - bool lazy; -} compiler; - -static compiler *newcompiler(mgroup *group, bool lazy) { - compiler *ret = upb_gmalloc(sizeof(*ret)); - int i; - - ret->group = group; - ret->lazy = lazy; - for (i = 0; i < MAXLABEL; i++) { - ret->fwd_labels[i] = EMPTYLABEL; - ret->back_labels[i] = EMPTYLABEL; - } - return ret; -} - -static void freecompiler(compiler *c) { - upb_gfree(c); -} - -const size_t ptr_words = sizeof(void*) / sizeof(uint32_t); - -/* How many words an instruction is. */ -static int instruction_len(uint32_t instr) { - switch (getop(instr)) { - case OP_SETDISPATCH: return 1 + ptr_words; - case OP_TAGN: return 3; - case OP_SETBIGGROUPNUM: return 2; - default: return 1; - } -} - -bool op_has_longofs(int32_t instruction) { - switch (getop(instruction)) { - case OP_CALL: - case OP_BRANCH: - case OP_CHECKDELIM: - return true; - /* The "tag" instructions only have 8 bytes available for the jump target, - * but that is ok because these opcodes only require short jumps. */ - case OP_TAG1: - case OP_TAG2: - case OP_TAGN: - return false; - default: - UPB_ASSERT(false); - return false; - } -} - -static int32_t getofs(uint32_t instruction) { - if (op_has_longofs(instruction)) { - return (int32_t)instruction >> 8; - } else { - return (int8_t)(instruction >> 8); - } -} - -static void setofs(uint32_t *instruction, int32_t ofs) { - if (op_has_longofs(*instruction)) { - *instruction = getop(*instruction) | (uint32_t)ofs << 8; - } else { - *instruction = (*instruction & ~0xff00) | ((ofs & 0xff) << 8); - } - UPB_ASSERT(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */ -} - -static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; } - -/* Defines a local label at the current PC location. All previous forward - * references are updated to point to this location. The location is noted - * for any future backward references. */ -static void label(compiler *c, unsigned int label) { - int val; - uint32_t *codep; - - UPB_ASSERT(label < MAXLABEL); - val = c->fwd_labels[label]; - codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val; - while (codep) { - int ofs = getofs(*codep); - setofs(codep, c->pc - codep - instruction_len(*codep)); - codep = ofs ? codep + ofs : NULL; - } - c->fwd_labels[label] = EMPTYLABEL; - c->back_labels[label] = pcofs(c); -} - -/* Creates a reference to a numbered label; either a forward reference - * (positive arg) or backward reference (negative arg). For forward references - * the value returned now is actually a "next" pointer into a linked list of all - * instructions that use this label and will be patched later when the label is - * defined with label(). - * - * The returned value is the offset that should be written into the instruction. - */ -static int32_t labelref(compiler *c, int label) { - UPB_ASSERT(label < MAXLABEL); - if (label == LABEL_DISPATCH) { - /* No resolving required. */ - return 0; - } else if (label < 0) { - /* Backward local label. Relative to the next instruction. */ - uint32_t from = (c->pc + 1) - c->group->bytecode; - return c->back_labels[-label] - from; - } else { - /* Forward local label: prepend to (possibly-empty) linked list. */ - int *lptr = &c->fwd_labels[label]; - int32_t ret = (*lptr == EMPTYLABEL) ? 0 : *lptr - pcofs(c); - *lptr = pcofs(c); - return ret; - } -} - -static void put32(compiler *c, uint32_t v) { - mgroup *g = c->group; - if (c->pc == g->bytecode_end) { - int ofs = pcofs(c); - size_t oldsize = g->bytecode_end - g->bytecode; - size_t newsize = UPB_MAX(oldsize * 2, 64); - /* TODO(haberman): handle OOM. */ - g->bytecode = upb_grealloc(g->bytecode, oldsize * sizeof(uint32_t), - newsize * sizeof(uint32_t)); - g->bytecode_end = g->bytecode + newsize; - c->pc = g->bytecode + ofs; - } - *c->pc++ = v; -} - -static void putop(compiler *c, int op, ...) { - va_list ap; - va_start(ap, op); - - switch (op) { - case OP_SETDISPATCH: { - uintptr_t ptr = (uintptr_t)va_arg(ap, void*); - put32(c, OP_SETDISPATCH); - put32(c, ptr); - if (sizeof(uintptr_t) > sizeof(uint32_t)) - put32(c, (uint64_t)ptr >> 32); - break; - } - case OP_STARTMSG: - case OP_ENDMSG: - case OP_PUSHLENDELIM: - case OP_POP: - case OP_SETDELIM: - case OP_HALT: - case OP_RET: - case OP_DISPATCH: - put32(c, op); - break; - case OP_PARSE_DOUBLE: - case OP_PARSE_FLOAT: - case OP_PARSE_INT64: - case OP_PARSE_UINT64: - case OP_PARSE_INT32: - case OP_PARSE_FIXED64: - case OP_PARSE_FIXED32: - case OP_PARSE_BOOL: - case OP_PARSE_UINT32: - case OP_PARSE_SFIXED32: - case OP_PARSE_SFIXED64: - case OP_PARSE_SINT32: - case OP_PARSE_SINT64: - case OP_STARTSEQ: - case OP_ENDSEQ: - case OP_STARTSUBMSG: - case OP_ENDSUBMSG: - case OP_STARTSTR: - case OP_STRING: - case OP_ENDSTR: - case OP_PUSHTAGDELIM: - put32(c, op | va_arg(ap, upb_selector_t) << 8); - break; - case OP_SETBIGGROUPNUM: - put32(c, op); - put32(c, va_arg(ap, int)); - break; - case OP_CALL: { - const upb_pbdecodermethod *method = va_arg(ap, upb_pbdecodermethod *); - put32(c, op | (method->code_base.ofs - (pcofs(c) + 1)) << 8); - break; - } - case OP_CHECKDELIM: - case OP_BRANCH: { - uint32_t instruction = op; - int label = va_arg(ap, int); - setofs(&instruction, labelref(c, label)); - put32(c, instruction); - break; - } - case OP_TAG1: - case OP_TAG2: { - int label = va_arg(ap, int); - uint64_t tag = va_arg(ap, uint64_t); - uint32_t instruction = op | (tag << 16); - UPB_ASSERT(tag <= 0xffff); - setofs(&instruction, labelref(c, label)); - put32(c, instruction); - break; - } - case OP_TAGN: { - int label = va_arg(ap, int); - uint64_t tag = va_arg(ap, uint64_t); - uint32_t instruction = op | (upb_value_size(tag) << 16); - setofs(&instruction, labelref(c, label)); - put32(c, instruction); - put32(c, tag); - put32(c, tag >> 32); - break; - } - } - - va_end(ap); -} - -#if defined(UPB_DUMP_BYTECODE) - -const char *upb_pbdecoder_getopname(unsigned int op) { -#define QUOTE(x) #x -#define EXPAND_AND_QUOTE(x) QUOTE(x) -#define OPNAME(x) OP_##x -#define OP(x) case OPNAME(x): return EXPAND_AND_QUOTE(OPNAME(x)); -#define T(x) OP(PARSE_##x) - /* Keep in sync with list in decoder.int.h. */ - switch ((opcode)op) { - T(DOUBLE) T(FLOAT) T(INT64) T(UINT64) T(INT32) T(FIXED64) T(FIXED32) - T(BOOL) T(UINT32) T(SFIXED32) T(SFIXED64) T(SINT32) T(SINT64) - OP(STARTMSG) OP(ENDMSG) OP(STARTSEQ) OP(ENDSEQ) OP(STARTSUBMSG) - OP(ENDSUBMSG) OP(STARTSTR) OP(STRING) OP(ENDSTR) OP(CALL) OP(RET) - OP(PUSHLENDELIM) OP(PUSHTAGDELIM) OP(SETDELIM) OP(CHECKDELIM) - OP(BRANCH) OP(TAG1) OP(TAG2) OP(TAGN) OP(SETDISPATCH) OP(POP) - OP(SETBIGGROUPNUM) OP(DISPATCH) OP(HALT) - } - return ""; -#undef OP -#undef T -} - -#endif - -#ifdef UPB_DUMP_BYTECODE - -static void dumpbc(uint32_t *p, uint32_t *end, FILE *f) { - - uint32_t *begin = p; - - while (p < end) { - fprintf(f, "%p %8tx", p, p - begin); - uint32_t instr = *p++; - uint8_t op = getop(instr); - fprintf(f, " %s", upb_pbdecoder_getopname(op)); - switch ((opcode)op) { - case OP_SETDISPATCH: { - const upb_inttable *dispatch; - memcpy(&dispatch, p, sizeof(void*)); - p += ptr_words; - const upb_pbdecodermethod *method = - (void *)((char *)dispatch - - offsetof(upb_pbdecodermethod, dispatch)); - fprintf(f, " %s", upb_msgdef_fullname( - upb_handlers_msgdef(method->dest_handlers_))); - break; - } - case OP_DISPATCH: - case OP_STARTMSG: - case OP_ENDMSG: - case OP_PUSHLENDELIM: - case OP_POP: - case OP_SETDELIM: - case OP_HALT: - case OP_RET: - break; - case OP_PARSE_DOUBLE: - case OP_PARSE_FLOAT: - case OP_PARSE_INT64: - case OP_PARSE_UINT64: - case OP_PARSE_INT32: - case OP_PARSE_FIXED64: - case OP_PARSE_FIXED32: - case OP_PARSE_BOOL: - case OP_PARSE_UINT32: - case OP_PARSE_SFIXED32: - case OP_PARSE_SFIXED64: - case OP_PARSE_SINT32: - case OP_PARSE_SINT64: - case OP_STARTSEQ: - case OP_ENDSEQ: - case OP_STARTSUBMSG: - case OP_ENDSUBMSG: - case OP_STARTSTR: - case OP_STRING: - case OP_ENDSTR: - case OP_PUSHTAGDELIM: - fprintf(f, " %d", instr >> 8); - break; - case OP_SETBIGGROUPNUM: - fprintf(f, " %d", *p++); - break; - case OP_CHECKDELIM: - case OP_CALL: - case OP_BRANCH: - fprintf(f, " =>0x%tx", p + getofs(instr) - begin); - break; - case OP_TAG1: - case OP_TAG2: { - fprintf(f, " tag:0x%x", instr >> 16); - if (getofs(instr)) { - fprintf(f, " =>0x%tx", p + getofs(instr) - begin); - } - break; - } - case OP_TAGN: { - uint64_t tag = *p++; - tag |= (uint64_t)*p++ << 32; - fprintf(f, " tag:0x%llx", (long long)tag); - fprintf(f, " n:%d", instr >> 16); - if (getofs(instr)) { - fprintf(f, " =>0x%tx", p + getofs(instr) - begin); - } - break; - } - } - fputs("\n", f); - } -} - -#endif - -static uint64_t get_encoded_tag(const upb_fielddef *f, int wire_type) { - uint32_t tag = (upb_fielddef_number(f) << 3) | wire_type; - uint64_t encoded_tag = upb_vencode32(tag); - /* No tag should be greater than 5 bytes. */ - UPB_ASSERT(encoded_tag <= 0xffffffffff); - return encoded_tag; -} - -static void putchecktag(compiler *c, const upb_fielddef *f, - int wire_type, int dest) { - uint64_t tag = get_encoded_tag(f, wire_type); - switch (upb_value_size(tag)) { - case 1: - putop(c, OP_TAG1, dest, tag); - break; - case 2: - putop(c, OP_TAG2, dest, tag); - break; - default: - putop(c, OP_TAGN, dest, tag); - break; - } -} - -static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) { - upb_selector_t selector; - bool ok = upb_handlers_getselector(f, type, &selector); - UPB_ASSERT(ok); - return selector; -} - -/* Takes an existing, primary dispatch table entry and repacks it with a - * different alternate wire type. Called when we are inserting a secondary - * dispatch table entry for an alternate wire type. */ -static uint64_t repack(uint64_t dispatch, int new_wt2) { - uint64_t ofs; - uint8_t wt1; - uint8_t old_wt2; - upb_pbdecoder_unpackdispatch(dispatch, &ofs, &wt1, &old_wt2); - UPB_ASSERT(old_wt2 == NO_WIRE_TYPE); /* wt2 should not be set yet. */ - return upb_pbdecoder_packdispatch(ofs, wt1, new_wt2); -} - -/* Marks the current bytecode position as the dispatch target for this message, - * field, and wire type. */ -static void dispatchtarget(compiler *c, upb_pbdecodermethod *method, - const upb_fielddef *f, int wire_type) { - /* Offset is relative to msg base. */ - uint64_t ofs = pcofs(c) - method->code_base.ofs; - uint32_t fn = upb_fielddef_number(f); - upb_inttable *d = &method->dispatch; - upb_value v; - if (upb_inttable_remove(d, fn, &v)) { - /* TODO: prioritize based on packed setting in .proto file. */ - uint64_t repacked = repack(upb_value_getuint64(v), wire_type); - upb_inttable_insert(d, fn, upb_value_uint64(repacked)); - upb_inttable_insert(d, fn + UPB_MAX_FIELDNUMBER, upb_value_uint64(ofs)); - } else { - uint64_t val = upb_pbdecoder_packdispatch(ofs, wire_type, NO_WIRE_TYPE); - upb_inttable_insert(d, fn, upb_value_uint64(val)); - } -} - -static void putpush(compiler *c, const upb_fielddef *f) { - if (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE) { - putop(c, OP_PUSHLENDELIM); - } else { - uint32_t fn = upb_fielddef_number(f); - if (fn >= 1 << 24) { - putop(c, OP_PUSHTAGDELIM, 0); - putop(c, OP_SETBIGGROUPNUM, fn); - } else { - putop(c, OP_PUSHTAGDELIM, fn); - } - } -} - -static upb_pbdecodermethod *find_submethod(const compiler *c, - const upb_pbdecodermethod *method, - const upb_fielddef *f) { - const upb_handlers *sub = - upb_handlers_getsubhandlers(method->dest_handlers_, f); - upb_value v; - return upb_inttable_lookupptr(&c->group->methods, sub, &v) - ? upb_value_getptr(v) - : NULL; -} - -static void putsel(compiler *c, opcode op, upb_selector_t sel, - const upb_handlers *h) { - if (upb_handlers_gethandler(h, sel, NULL)) { - putop(c, op, sel); - } -} - -/* Puts an opcode to call a callback, but only if a callback actually exists for - * this field and handler type. */ -static void maybeput(compiler *c, opcode op, const upb_handlers *h, - const upb_fielddef *f, upb_handlertype_t type) { - putsel(c, op, getsel(f, type), h); -} - -static bool haslazyhandlers(const upb_handlers *h, const upb_fielddef *f) { - if (!upb_fielddef_lazy(f)) - return false; - - return upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STARTSTR), NULL) || - upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_STRING), NULL) || - upb_handlers_gethandler(h, getsel(f, UPB_HANDLER_ENDSTR), NULL); -} - - -/* bytecode compiler code generation ******************************************/ - -/* Symbolic names for our local labels. */ -#define LABEL_LOOPSTART 1 /* Top of a repeated field loop. */ -#define LABEL_LOOPBREAK 2 /* To jump out of a repeated loop */ -#define LABEL_FIELD 3 /* Jump backward to find the most recent field. */ -#define LABEL_ENDMSG 4 /* To reach the OP_ENDMSG instr for this msg. */ - -/* Generates bytecode to parse a single non-lazy message field. */ -static void generate_msgfield(compiler *c, const upb_fielddef *f, - upb_pbdecodermethod *method) { - const upb_handlers *h = upb_pbdecodermethod_desthandlers(method); - const upb_pbdecodermethod *sub_m = find_submethod(c, method, f); - int wire_type; - - if (!sub_m) { - /* Don't emit any code for this field at all; it will be parsed as an - * unknown field. - * - * TODO(haberman): we should change this to parse it as a string field - * instead. It will probably be faster, but more importantly, once we - * start vending unknown fields, a field shouldn't be treated as unknown - * just because it doesn't have subhandlers registered. */ - return; - } - - label(c, LABEL_FIELD); - - wire_type = - (upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_MESSAGE) - ? UPB_WIRE_TYPE_DELIMITED - : UPB_WIRE_TYPE_START_GROUP; - - if (upb_fielddef_isseq(f)) { - putop(c, OP_CHECKDELIM, LABEL_ENDMSG); - putchecktag(c, f, wire_type, LABEL_DISPATCH); - dispatchtarget(c, method, f, wire_type); - putop(c, OP_PUSHTAGDELIM, 0); - putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); - label(c, LABEL_LOOPSTART); - putpush(c, f); - putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG)); - putop(c, OP_CALL, sub_m); - putop(c, OP_POP); - maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG); - if (wire_type == UPB_WIRE_TYPE_DELIMITED) { - putop(c, OP_SETDELIM); - } - putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK); - putchecktag(c, f, wire_type, LABEL_LOOPBREAK); - putop(c, OP_BRANCH, -LABEL_LOOPSTART); - label(c, LABEL_LOOPBREAK); - putop(c, OP_POP); - maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ); - } else { - putop(c, OP_CHECKDELIM, LABEL_ENDMSG); - putchecktag(c, f, wire_type, LABEL_DISPATCH); - dispatchtarget(c, method, f, wire_type); - putpush(c, f); - putop(c, OP_STARTSUBMSG, getsel(f, UPB_HANDLER_STARTSUBMSG)); - putop(c, OP_CALL, sub_m); - putop(c, OP_POP); - maybeput(c, OP_ENDSUBMSG, h, f, UPB_HANDLER_ENDSUBMSG); - if (wire_type == UPB_WIRE_TYPE_DELIMITED) { - putop(c, OP_SETDELIM); - } - } -} - -/* Generates bytecode to parse a single string or lazy submessage field. */ -static void generate_delimfield(compiler *c, const upb_fielddef *f, - upb_pbdecodermethod *method) { - const upb_handlers *h = upb_pbdecodermethod_desthandlers(method); - - label(c, LABEL_FIELD); - if (upb_fielddef_isseq(f)) { - putop(c, OP_CHECKDELIM, LABEL_ENDMSG); - putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH); - dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED); - putop(c, OP_PUSHTAGDELIM, 0); - putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); - label(c, LABEL_LOOPSTART); - putop(c, OP_PUSHLENDELIM); - putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR)); - /* Need to emit even if no handler to skip past the string. */ - putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING)); - maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR); - putop(c, OP_POP); - putop(c, OP_SETDELIM); - putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK); - putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_LOOPBREAK); - putop(c, OP_BRANCH, -LABEL_LOOPSTART); - label(c, LABEL_LOOPBREAK); - putop(c, OP_POP); - maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ); - } else { - putop(c, OP_CHECKDELIM, LABEL_ENDMSG); - putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH); - dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED); - putop(c, OP_PUSHLENDELIM); - putop(c, OP_STARTSTR, getsel(f, UPB_HANDLER_STARTSTR)); - putop(c, OP_STRING, getsel(f, UPB_HANDLER_STRING)); - maybeput(c, OP_ENDSTR, h, f, UPB_HANDLER_ENDSTR); - putop(c, OP_POP); - putop(c, OP_SETDELIM); - } -} - -/* Generates bytecode to parse a single primitive field. */ -static void generate_primitivefield(compiler *c, const upb_fielddef *f, - upb_pbdecodermethod *method) { - const upb_handlers *h = upb_pbdecodermethod_desthandlers(method); - upb_descriptortype_t descriptor_type = upb_fielddef_descriptortype(f); - opcode parse_type; - upb_selector_t sel; - int wire_type; - - label(c, LABEL_FIELD); - - /* From a decoding perspective, ENUM is the same as INT32. */ - if (descriptor_type == UPB_DESCRIPTOR_TYPE_ENUM) - descriptor_type = UPB_DESCRIPTOR_TYPE_INT32; - - parse_type = (opcode)descriptor_type; - - /* TODO(haberman): generate packed or non-packed first depending on "packed" - * setting in the fielddef. This will favor (in speed) whichever was - * specified. */ - - UPB_ASSERT((int)parse_type >= 0 && parse_type <= OP_MAX); - sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); - wire_type = upb_pb_native_wire_types[upb_fielddef_descriptortype(f)]; - if (upb_fielddef_isseq(f)) { - putop(c, OP_CHECKDELIM, LABEL_ENDMSG); - putchecktag(c, f, UPB_WIRE_TYPE_DELIMITED, LABEL_DISPATCH); - dispatchtarget(c, method, f, UPB_WIRE_TYPE_DELIMITED); - putop(c, OP_PUSHLENDELIM); - putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Packed */ - label(c, LABEL_LOOPSTART); - putop(c, parse_type, sel); - putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK); - putop(c, OP_BRANCH, -LABEL_LOOPSTART); - dispatchtarget(c, method, f, wire_type); - putop(c, OP_PUSHTAGDELIM, 0); - putop(c, OP_STARTSEQ, getsel(f, UPB_HANDLER_STARTSEQ)); /* Non-packed */ - label(c, LABEL_LOOPSTART); - putop(c, parse_type, sel); - putop(c, OP_CHECKDELIM, LABEL_LOOPBREAK); - putchecktag(c, f, wire_type, LABEL_LOOPBREAK); - putop(c, OP_BRANCH, -LABEL_LOOPSTART); - label(c, LABEL_LOOPBREAK); - putop(c, OP_POP); /* Packed and non-packed join. */ - maybeput(c, OP_ENDSEQ, h, f, UPB_HANDLER_ENDSEQ); - putop(c, OP_SETDELIM); /* Could remove for non-packed by dup ENDSEQ. */ - } else { - putop(c, OP_CHECKDELIM, LABEL_ENDMSG); - putchecktag(c, f, wire_type, LABEL_DISPATCH); - dispatchtarget(c, method, f, wire_type); - putop(c, parse_type, sel); - } -} - -/* Adds bytecode for parsing the given message to the given decoderplan, - * while adding all dispatch targets to this message's dispatch table. */ -static void compile_method(compiler *c, upb_pbdecodermethod *method) { - const upb_handlers *h; - const upb_msgdef *md; - uint32_t* start_pc; - upb_msg_field_iter i; - upb_value val; - - UPB_ASSERT(method); - - /* Clear all entries in the dispatch table. */ - upb_inttable_uninit(&method->dispatch); - upb_inttable_init(&method->dispatch, UPB_CTYPE_UINT64); - - h = upb_pbdecodermethod_desthandlers(method); - md = upb_handlers_msgdef(h); - - method->code_base.ofs = pcofs(c); - putop(c, OP_SETDISPATCH, &method->dispatch); - putsel(c, OP_STARTMSG, UPB_STARTMSG_SELECTOR, h); - label(c, LABEL_FIELD); - start_pc = c->pc; - 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_fieldtype_t type = upb_fielddef_type(f); - - if (type == UPB_TYPE_MESSAGE && !(haslazyhandlers(h, f) && c->lazy)) { - generate_msgfield(c, f, method); - } else if (type == UPB_TYPE_STRING || type == UPB_TYPE_BYTES || - type == UPB_TYPE_MESSAGE) { - generate_delimfield(c, f, method); - } else { - generate_primitivefield(c, f, method); - } - } - - /* If there were no fields, or if no handlers were defined, we need to - * generate a non-empty loop body so that we can at least dispatch for unknown - * fields and check for the end of the message. */ - if (c->pc == start_pc) { - /* Check for end-of-message. */ - putop(c, OP_CHECKDELIM, LABEL_ENDMSG); - /* Unconditionally dispatch. */ - putop(c, OP_DISPATCH, 0); - } - - /* For now we just loop back to the last field of the message (or if none, - * the DISPATCH opcode for the message). */ - putop(c, OP_BRANCH, -LABEL_FIELD); - - /* Insert both a label and a dispatch table entry for this end-of-msg. */ - label(c, LABEL_ENDMSG); - val = upb_value_uint64(pcofs(c) - method->code_base.ofs); - upb_inttable_insert(&method->dispatch, DISPATCH_ENDMSG, val); - - putsel(c, OP_ENDMSG, UPB_ENDMSG_SELECTOR, h); - putop(c, OP_RET); - - upb_inttable_compact(&method->dispatch); -} - -/* Populate "methods" with new upb_pbdecodermethod objects reachable from "h". - * Returns the method for these handlers. - * - * Generates a new method for every destination handlers reachable from "h". */ -static void find_methods(compiler *c, const upb_handlers *h) { - upb_value v; - upb_msg_field_iter i; - const upb_msgdef *md; - upb_pbdecodermethod *method; - - if (upb_inttable_lookupptr(&c->group->methods, h, &v)) - return; - - method = newmethod(h, c->group); - upb_inttable_insertptr(&c->group->methods, h, upb_value_ptr(method)); - - /* Find submethods. */ - md = upb_handlers_msgdef(h); - 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); - const upb_handlers *sub_h; - if (upb_fielddef_type(f) == UPB_TYPE_MESSAGE && - (sub_h = upb_handlers_getsubhandlers(h, f)) != NULL) { - /* We only generate a decoder method for submessages with handlers. - * Others will be parsed as unknown fields. */ - find_methods(c, sub_h); - } - } -} - -/* (Re-)compile bytecode for all messages in "msgs." - * Overwrites any existing bytecode in "c". */ -static void compile_methods(compiler *c) { - upb_inttable_iter i; - - /* Start over at the beginning of the bytecode. */ - c->pc = c->group->bytecode; - - upb_inttable_begin(&i, &c->group->methods); - for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - upb_pbdecodermethod *method = upb_value_getptr(upb_inttable_iter_value(&i)); - compile_method(c, method); - } -} - -static void set_bytecode_handlers(mgroup *g) { - upb_inttable_iter i; - upb_inttable_begin(&i, &g->methods); - for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - upb_pbdecodermethod *m = upb_value_getptr(upb_inttable_iter_value(&i)); - upb_byteshandler *h = &m->input_handler_; - - m->code_base.ptr = g->bytecode + m->code_base.ofs; - - upb_byteshandler_setstartstr(h, upb_pbdecoder_startbc, m->code_base.ptr); - upb_byteshandler_setstring(h, upb_pbdecoder_decode, g); - upb_byteshandler_setendstr(h, upb_pbdecoder_end, m); - } -} - - -/* TODO(haberman): allow this to be constructed for an arbitrary set of dest - * handlers and other mgroups (but verify we have a transitive closure). */ -const mgroup *mgroup_new(const upb_handlers *dest, bool lazy) { - mgroup *g; - compiler *c; - - g = newgroup(); - c = newcompiler(g, lazy); - find_methods(c, dest); - - /* We compile in two passes: - * 1. all messages are assigned relative offsets from the beginning of the - * bytecode (saved in method->code_base). - * 2. forwards OP_CALL instructions can be correctly linked since message - * offsets have been previously assigned. - * - * Could avoid the second pass by linking OP_CALL instructions somehow. */ - compile_methods(c); - compile_methods(c); - g->bytecode_end = c->pc; - freecompiler(c); - -#ifdef UPB_DUMP_BYTECODE - { - FILE *f = fopen("/tmp/upb-bytecode", "w"); - UPB_ASSERT(f); - dumpbc(g->bytecode, g->bytecode_end, stderr); - dumpbc(g->bytecode, g->bytecode_end, f); - fclose(f); - - f = fopen("/tmp/upb-bytecode.bin", "wb"); - UPB_ASSERT(f); - fwrite(g->bytecode, 1, g->bytecode_end - g->bytecode, f); - fclose(f); - } -#endif - - set_bytecode_handlers(g); - return g; -} - - -/* upb_pbcodecache ************************************************************/ - -upb_pbcodecache *upb_pbcodecache_new(upb_handlercache *dest) { - upb_pbcodecache *c = upb_gmalloc(sizeof(*c)); - - if (!c) return NULL; - - c->dest = dest; - c->lazy = false; - - c->arena = upb_arena_new(); - if (!upb_inttable_init(&c->groups, UPB_CTYPE_CONSTPTR)) return NULL; - - return c; -} - -void upb_pbcodecache_free(upb_pbcodecache *c) { - upb_inttable_iter i; - - upb_inttable_begin(&i, &c->groups); - for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - upb_value val = upb_inttable_iter_value(&i); - freegroup((void*)upb_value_getconstptr(val)); - } - - upb_inttable_uninit(&c->groups); - upb_arena_free(c->arena); - upb_gfree(c); -} - -void upb_pbdecodermethodopts_setlazy(upb_pbcodecache *c, bool lazy) { - UPB_ASSERT(upb_inttable_count(&c->groups) == 0); - c->lazy = lazy; -} - -const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c, - const upb_msgdef *md) { - upb_value v; - bool ok; - const upb_handlers *h; - const mgroup *g; - - h = upb_handlercache_get(c->dest, md); - if (upb_inttable_lookupptr(&c->groups, md, &v)) { - g = upb_value_getconstptr(v); - } else { - g = mgroup_new(h, c->lazy); - ok = upb_inttable_insertptr(&c->groups, md, upb_value_constptr(g)); - UPB_ASSERT(ok); - } - - ok = upb_inttable_lookupptr(&g->methods, h, &v); - UPB_ASSERT(ok); - return upb_value_getptr(v); -} -/* -** upb::Decoder (Bytecode Decoder VM) -** -** Bytecode must previously have been generated using the bytecode compiler in -** compile_decoder.c. This decoder then walks through the bytecode op-by-op to -** parse the input. -** -** Decoding is fully resumable; we just keep a pointer to the current bytecode -** instruction and resume from there. A fair amount of the logic here is to -** handle the fact that values can span buffer seams and we have to be able to -** be capable of suspending/resuming from any byte in the stream. This -** sometimes requires keeping a few trailing bytes from the last buffer around -** in the "residual" buffer. -*/ - -#include -#include - -#ifdef UPB_DUMP_BYTECODE -#include -#endif - - -#define CHECK_SUSPEND(x) if (!(x)) return upb_pbdecoder_suspend(d); - -/* Error messages that are shared between the bytecode and JIT decoders. */ -const char *kPbDecoderStackOverflow = "Nesting too deep."; -const char *kPbDecoderSubmessageTooLong = - "Submessage end extends past enclosing submessage."; - -/* Error messages shared within this file. */ -static const char *kUnterminatedVarint = "Unterminated varint."; - -/* upb_pbdecoder **************************************************************/ - -static opcode halt = OP_HALT; - -/* A dummy character we can point to when the user passes us a NULL buffer. - * We need this because in C (NULL + 0) and (NULL - NULL) are undefined - * behavior, which would invalidate functions like curbufleft(). */ -static const char dummy_char; - -/* Whether an op consumes any of the input buffer. */ -static bool consumes_input(opcode op) { - switch (op) { - case OP_SETDISPATCH: - case OP_STARTMSG: - case OP_ENDMSG: - case OP_STARTSEQ: - case OP_ENDSEQ: - case OP_STARTSUBMSG: - case OP_ENDSUBMSG: - case OP_STARTSTR: - case OP_ENDSTR: - case OP_PUSHTAGDELIM: - case OP_POP: - case OP_SETDELIM: - case OP_SETBIGGROUPNUM: - case OP_CHECKDELIM: - case OP_CALL: - case OP_RET: - case OP_BRANCH: - return false; - default: - return true; - } -} - -static size_t stacksize(upb_pbdecoder *d, size_t entries) { - UPB_UNUSED(d); - return entries * sizeof(upb_pbdecoder_frame); -} - -static size_t callstacksize(upb_pbdecoder *d, size_t entries) { - UPB_UNUSED(d); - - return entries * sizeof(uint32_t*); -} - - -static bool in_residual_buf(const upb_pbdecoder *d, const char *p); - -/* It's unfortunate that we have to micro-manage the compiler with - * UPB_FORCEINLINE and UPB_NOINLINE, especially since this tuning is necessarily - * specific to one hardware configuration. But empirically on a Core i7, - * performance increases 30-50% with these annotations. Every instance where - * these appear, gcc 4.2.1 made the wrong decision and degraded performance in - * benchmarks. */ - -static void seterr(upb_pbdecoder *d, const char *msg) { - upb_status_seterrmsg(d->status, msg); -} - -void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg) { - seterr(d, msg); -} - - -/* Buffering ******************************************************************/ - -/* We operate on one buffer at a time, which is either the user's buffer passed - * to our "decode" callback or some residual bytes from the previous buffer. */ - -/* How many bytes can be safely read from d->ptr without reading past end-of-buf - * or past the current delimited end. */ -static size_t curbufleft(const upb_pbdecoder *d) { - UPB_ASSERT(d->data_end >= d->ptr); - return d->data_end - d->ptr; -} - -/* How many bytes are available before end-of-buffer. */ -static size_t bufleft(const upb_pbdecoder *d) { - return d->end - d->ptr; -} - -/* Overall stream offset of d->ptr. */ -uint64_t offset(const upb_pbdecoder *d) { - return d->bufstart_ofs + (d->ptr - d->buf); -} - -/* How many bytes are available before the end of this delimited region. */ -size_t delim_remaining(const upb_pbdecoder *d) { - return d->top->end_ofs - offset(d); -} - -/* Advances d->ptr. */ -static void advance(upb_pbdecoder *d, size_t len) { - UPB_ASSERT(curbufleft(d) >= len); - d->ptr += len; -} - -static bool in_buf(const char *p, const char *buf, const char *end) { - return p >= buf && p <= end; -} - -static bool in_residual_buf(const upb_pbdecoder *d, const char *p) { - return in_buf(p, d->residual, d->residual_end); -} - -/* Calculates the delim_end value, which is affected by both the current buffer - * and the parsing stack, so must be called whenever either is updated. */ -static void set_delim_end(upb_pbdecoder *d) { - size_t delim_ofs = d->top->end_ofs - d->bufstart_ofs; - if (delim_ofs <= (size_t)(d->end - d->buf)) { - d->delim_end = d->buf + delim_ofs; - d->data_end = d->delim_end; - } else { - d->data_end = d->end; - d->delim_end = NULL; - } -} - -static void switchtobuf(upb_pbdecoder *d, const char *buf, const char *end) { - d->ptr = buf; - d->buf = buf; - d->end = end; - set_delim_end(d); -} - -static void advancetobuf(upb_pbdecoder *d, const char *buf, size_t len) { - UPB_ASSERT(curbufleft(d) == 0); - d->bufstart_ofs += (d->end - d->buf); - switchtobuf(d, buf, buf + len); -} - -static void checkpoint(upb_pbdecoder *d) { - /* The assertion here is in the interests of efficiency, not correctness. - * We are trying to ensure that we don't checkpoint() more often than - * necessary. */ - UPB_ASSERT(d->checkpoint != d->ptr); - d->checkpoint = d->ptr; -} - -/* Skips "bytes" bytes in the stream, which may be more than available. If we - * skip more bytes than are available, we return a long read count to the caller - * indicating how many bytes can be skipped over before passing actual data - * again. Skipped bytes can pass a NULL buffer and the decoder guarantees they - * won't actually be read. - */ -static int32_t skip(upb_pbdecoder *d, size_t bytes) { - UPB_ASSERT(!in_residual_buf(d, d->ptr) || d->size_param == 0); - UPB_ASSERT(d->skip == 0); - if (bytes > delim_remaining(d)) { - seterr(d, "Skipped value extended beyond enclosing submessage."); - return upb_pbdecoder_suspend(d); - } else if (bufleft(d) >= bytes) { - /* Skipped data is all in current buffer, and more is still available. */ - advance(d, bytes); - d->skip = 0; - return DECODE_OK; - } else { - /* Skipped data extends beyond currently available buffers. */ - d->pc = d->last; - d->skip = bytes - curbufleft(d); - d->bufstart_ofs += (d->end - d->buf); - d->residual_end = d->residual; - switchtobuf(d, d->residual, d->residual_end); - return d->size_param + d->skip; - } -} - - -/* Resumes the decoder from an initial state or from a previous suspend. */ -int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf, - size_t size, const upb_bufhandle *handle) { - UPB_UNUSED(p); /* Useless; just for the benefit of the JIT. */ - - /* d->skip and d->residual_end could probably elegantly be represented - * as a single variable, to more easily represent this invariant. */ - UPB_ASSERT(!(d->skip && d->residual_end > d->residual)); - - /* We need to remember the original size_param, so that the value we return - * is relative to it, even if we do some skipping first. */ - d->size_param = size; - d->handle = handle; - - /* Have to handle this case specially (ie. not with skip()) because the user - * is allowed to pass a NULL buffer here, which won't allow us to safely - * calculate a d->end or use our normal functions like curbufleft(). */ - if (d->skip && d->skip >= size) { - d->skip -= size; - d->bufstart_ofs += size; - buf = &dummy_char; - size = 0; - - /* We can't just return now, because we might need to execute some ops - * like CHECKDELIM, which could call some callbacks and pop the stack. */ - } - - /* We need to pretend that this was the actual buffer param, since some of the - * calculations assume that d->ptr/d->buf is relative to this. */ - d->buf_param = buf; - - if (!buf) { - /* NULL buf is ok if its entire span is covered by the "skip" above, but - * by this point we know that "skip" doesn't cover the buffer. */ - seterr(d, "Passed NULL buffer over non-skippable region."); - return upb_pbdecoder_suspend(d); - } - - if (d->residual_end > d->residual) { - /* We have residual bytes from the last buffer. */ - UPB_ASSERT(d->ptr == d->residual); - } else { - switchtobuf(d, buf, buf + size); - } - - d->checkpoint = d->ptr; - - /* Handle skips that don't cover the whole buffer (as above). */ - if (d->skip) { - size_t skip_bytes = d->skip; - d->skip = 0; - CHECK_RETURN(skip(d, skip_bytes)); - checkpoint(d); - } - - /* If we're inside an unknown group, continue to parse unknown values. */ - if (d->top->groupnum < 0) { - CHECK_RETURN(upb_pbdecoder_skipunknown(d, -1, 0)); - checkpoint(d); - } - - return DECODE_OK; -} - -/* Suspends the decoder at the last checkpoint, without saving any residual - * bytes. If there are any unconsumed bytes, returns a short byte count. */ -size_t upb_pbdecoder_suspend(upb_pbdecoder *d) { - d->pc = d->last; - if (d->checkpoint == d->residual) { - /* Checkpoint was in residual buf; no user bytes were consumed. */ - d->ptr = d->residual; - return 0; - } else { - size_t ret = d->size_param - (d->end - d->checkpoint); - UPB_ASSERT(!in_residual_buf(d, d->checkpoint)); - UPB_ASSERT(d->buf == d->buf_param || d->buf == &dummy_char); - - d->bufstart_ofs += (d->checkpoint - d->buf); - d->residual_end = d->residual; - switchtobuf(d, d->residual, d->residual_end); - return ret; - } -} - -/* Suspends the decoder at the last checkpoint, and saves any unconsumed - * bytes in our residual buffer. This is necessary if we need more user - * bytes to form a complete value, which might not be contiguous in the - * user's buffers. Always consumes all user bytes. */ -static size_t suspend_save(upb_pbdecoder *d) { - /* We hit end-of-buffer before we could parse a full value. - * Save any unconsumed bytes (if any) to the residual buffer. */ - d->pc = d->last; - - if (d->checkpoint == d->residual) { - /* Checkpoint was in residual buf; append user byte(s) to residual buf. */ - UPB_ASSERT((d->residual_end - d->residual) + d->size_param <= - sizeof(d->residual)); - if (!in_residual_buf(d, d->ptr)) { - d->bufstart_ofs -= (d->residual_end - d->residual); - } - memcpy(d->residual_end, d->buf_param, d->size_param); - d->residual_end += d->size_param; - } else { - /* Checkpoint was in user buf; old residual bytes not needed. */ - size_t save; - UPB_ASSERT(!in_residual_buf(d, d->checkpoint)); - - d->ptr = d->checkpoint; - save = curbufleft(d); - UPB_ASSERT(save <= sizeof(d->residual)); - memcpy(d->residual, d->ptr, save); - d->residual_end = d->residual + save; - d->bufstart_ofs = offset(d); - } - - switchtobuf(d, d->residual, d->residual_end); - return d->size_param; -} - -/* Copies the next "bytes" bytes into "buf" and advances the stream. - * Requires that this many bytes are available in the current buffer. */ -UPB_FORCEINLINE static void consumebytes(upb_pbdecoder *d, void *buf, - size_t bytes) { - UPB_ASSERT(bytes <= curbufleft(d)); - memcpy(buf, d->ptr, bytes); - advance(d, bytes); -} - -/* Slow path for getting the next "bytes" bytes, regardless of whether they are - * available in the current buffer or not. Returns a status code as described - * in decoder.int.h. */ -UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf, - size_t bytes) { - const size_t avail = curbufleft(d); - consumebytes(d, buf, avail); - bytes -= avail; - UPB_ASSERT(bytes > 0); - if (in_residual_buf(d, d->ptr)) { - advancetobuf(d, d->buf_param, d->size_param); - } - if (curbufleft(d) >= bytes) { - consumebytes(d, (char *)buf + avail, bytes); - return DECODE_OK; - } else if (d->data_end == d->delim_end) { - seterr(d, "Submessage ended in the middle of a value or group"); - return upb_pbdecoder_suspend(d); - } else { - return suspend_save(d); - } -} - -/* Gets the next "bytes" bytes, regardless of whether they are available in the - * current buffer or not. Returns a status code as described in decoder.int.h. - */ -UPB_FORCEINLINE static int32_t getbytes(upb_pbdecoder *d, void *buf, - size_t bytes) { - if (curbufleft(d) >= bytes) { - /* Buffer has enough data to satisfy. */ - consumebytes(d, buf, bytes); - return DECODE_OK; - } else { - return getbytes_slow(d, buf, bytes); - } -} - -UPB_NOINLINE static size_t peekbytes_slow(upb_pbdecoder *d, void *buf, - size_t bytes) { - size_t ret = curbufleft(d); - memcpy(buf, d->ptr, ret); - if (in_residual_buf(d, d->ptr)) { - size_t copy = UPB_MIN(bytes - ret, d->size_param); - memcpy((char *)buf + ret, d->buf_param, copy); - ret += copy; - } - return ret; -} - -UPB_FORCEINLINE static size_t peekbytes(upb_pbdecoder *d, void *buf, - size_t bytes) { - if (curbufleft(d) >= bytes) { - memcpy(buf, d->ptr, bytes); - return bytes; - } else { - return peekbytes_slow(d, buf, bytes); - } -} - - -/* Decoding of wire types *****************************************************/ - -/* Slow path for decoding a varint from the current buffer position. - * Returns a status code as described in decoder.int.h. */ -UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d, - uint64_t *u64) { - uint8_t byte = 0x80; - int bitpos; - *u64 = 0; - for(bitpos = 0; bitpos < 70 && (byte & 0x80); bitpos += 7) { - CHECK_RETURN(getbytes(d, &byte, 1)); - *u64 |= (uint64_t)(byte & 0x7F) << bitpos; - } - if(bitpos == 70 && (byte & 0x80)) { - seterr(d, kUnterminatedVarint); - return upb_pbdecoder_suspend(d); - } - return DECODE_OK; -} - -/* Decodes a varint from the current buffer position. - * Returns a status code as described in decoder.int.h. */ -UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) { - if (curbufleft(d) > 0 && !(*d->ptr & 0x80)) { - *u64 = *d->ptr; - advance(d, 1); - return DECODE_OK; - } else if (curbufleft(d) >= 10) { - /* Fast case. */ - upb_decoderet r = upb_vdecode_fast(d->ptr); - if (r.p == NULL) { - seterr(d, kUnterminatedVarint); - return upb_pbdecoder_suspend(d); - } - advance(d, r.p - d->ptr); - *u64 = r.val; - return DECODE_OK; - } else { - /* Slow case -- varint spans buffer seam. */ - return upb_pbdecoder_decode_varint_slow(d, u64); - } -} - -/* Decodes a 32-bit varint from the current buffer position. - * Returns a status code as described in decoder.int.h. */ -UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) { - uint64_t u64; - int32_t ret = decode_varint(d, &u64); - if (ret >= 0) return ret; - if (u64 > UINT32_MAX) { - seterr(d, "Unterminated 32-bit varint"); - /* TODO(haberman) guarantee that this function return is >= 0 somehow, - * so we know this path will always be treated as error by our caller. - * Right now the size_t -> int32_t can overflow and produce negative values. - */ - *u32 = 0; - return upb_pbdecoder_suspend(d); - } - *u32 = u64; - return DECODE_OK; -} - -/* Decodes a fixed32 from the current buffer position. - * Returns a status code as described in decoder.int.h. - * TODO: proper byte swapping for big-endian machines. */ -UPB_FORCEINLINE static int32_t decode_fixed32(upb_pbdecoder *d, uint32_t *u32) { - return getbytes(d, u32, 4); -} - -/* Decodes a fixed64 from the current buffer position. - * Returns a status code as described in decoder.int.h. - * TODO: proper byte swapping for big-endian machines. */ -UPB_FORCEINLINE static int32_t decode_fixed64(upb_pbdecoder *d, uint64_t *u64) { - return getbytes(d, u64, 8); -} - -/* Non-static versions of the above functions. - * These are called by the JIT for fallback paths. */ -int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32) { - return decode_fixed32(d, u32); -} - -int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64) { - return decode_fixed64(d, u64); -} - -static double as_double(uint64_t n) { double d; memcpy(&d, &n, 8); return d; } -static float as_float(uint32_t n) { float f; memcpy(&f, &n, 4); return f; } - -/* Pushes a frame onto the decoder stack. */ -static bool decoder_push(upb_pbdecoder *d, uint64_t end) { - upb_pbdecoder_frame *fr = d->top; - - if (end > fr->end_ofs) { - seterr(d, kPbDecoderSubmessageTooLong); - return false; - } else if (fr == d->limit) { - seterr(d, kPbDecoderStackOverflow); - return false; - } - - fr++; - fr->end_ofs = end; - fr->dispatch = NULL; - fr->groupnum = 0; - d->top = fr; - return true; -} - -static bool pushtagdelim(upb_pbdecoder *d, uint32_t arg) { - /* While we expect to see an "end" tag (either ENDGROUP or a non-sequence - * field number) prior to hitting any enclosing submessage end, pushing our - * existing delim end prevents us from continuing to parse values from a - * corrupt proto that doesn't give us an END tag in time. */ - if (!decoder_push(d, d->top->end_ofs)) - return false; - d->top->groupnum = arg; - return true; -} - -/* Pops a frame from the decoder stack. */ -static void decoder_pop(upb_pbdecoder *d) { d->top--; } - -UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d, - uint64_t expected) { - uint64_t data = 0; - size_t bytes = upb_value_size(expected); - size_t read = peekbytes(d, &data, bytes); - if (read == bytes && data == expected) { - /* Advance past matched bytes. */ - int32_t ok = getbytes(d, &data, read); - UPB_ASSERT(ok < 0); - return DECODE_OK; - } else if (read < bytes && memcmp(&data, &expected, read) == 0) { - return suspend_save(d); - } else { - return DECODE_MISMATCH; - } -} - -int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, - uint8_t wire_type) { - if (fieldnum >= 0) - goto have_tag; - - while (true) { - uint32_t tag; - CHECK_RETURN(decode_v32(d, &tag)); - wire_type = tag & 0x7; - fieldnum = tag >> 3; - -have_tag: - if (fieldnum == 0) { - seterr(d, "Saw invalid field number (0)"); - return upb_pbdecoder_suspend(d); - } - - switch (wire_type) { - case UPB_WIRE_TYPE_32BIT: - CHECK_RETURN(skip(d, 4)); - break; - case UPB_WIRE_TYPE_64BIT: - CHECK_RETURN(skip(d, 8)); - break; - case UPB_WIRE_TYPE_VARINT: { - uint64_t u64; - CHECK_RETURN(decode_varint(d, &u64)); - break; - } - case UPB_WIRE_TYPE_DELIMITED: { - uint32_t len; - CHECK_RETURN(decode_v32(d, &len)); - CHECK_RETURN(skip(d, len)); - break; - } - case UPB_WIRE_TYPE_START_GROUP: - CHECK_SUSPEND(pushtagdelim(d, -fieldnum)); - break; - case UPB_WIRE_TYPE_END_GROUP: - if (fieldnum == -d->top->groupnum) { - decoder_pop(d); - } else if (fieldnum == d->top->groupnum) { - return DECODE_ENDGROUP; - } else { - seterr(d, "Unmatched ENDGROUP tag."); - return upb_pbdecoder_suspend(d); - } - break; - default: - seterr(d, "Invalid wire type"); - return upb_pbdecoder_suspend(d); - } - - if (d->top->groupnum >= 0) { - /* TODO: More code needed for handling unknown groups. */ - upb_sink_putunknown(d->top->sink, d->checkpoint, d->ptr - d->checkpoint); - return DECODE_OK; - } - - /* Unknown group -- continue looping over unknown fields. */ - checkpoint(d); - } -} - -static void goto_endmsg(upb_pbdecoder *d) { - upb_value v; - bool found = upb_inttable_lookup32(d->top->dispatch, DISPATCH_ENDMSG, &v); - UPB_ASSERT(found); - d->pc = d->top->base + upb_value_getuint64(v); -} - -/* Parses a tag and jumps to the corresponding bytecode instruction for this - * field. - * - * If the tag is unknown (or the wire type doesn't match), parses the field as - * unknown. If the tag is a valid ENDGROUP tag, jumps to the bytecode - * instruction for the end of message. */ -static int32_t dispatch(upb_pbdecoder *d) { - upb_inttable *dispatch = d->top->dispatch; - uint32_t tag; - uint8_t wire_type; - uint32_t fieldnum; - upb_value val; - int32_t retval; - - /* Decode tag. */ - CHECK_RETURN(decode_v32(d, &tag)); - wire_type = tag & 0x7; - fieldnum = tag >> 3; - - /* Lookup tag. Because of packed/non-packed compatibility, we have to - * check the wire type against two possibilities. */ - if (fieldnum != DISPATCH_ENDMSG && - upb_inttable_lookup32(dispatch, fieldnum, &val)) { - uint64_t v = upb_value_getuint64(val); - if (wire_type == (v & 0xff)) { - d->pc = d->top->base + (v >> 16); - return DECODE_OK; - } else if (wire_type == ((v >> 8) & 0xff)) { - bool found = - upb_inttable_lookup(dispatch, fieldnum + UPB_MAX_FIELDNUMBER, &val); - UPB_ASSERT(found); - d->pc = d->top->base + upb_value_getuint64(val); - return DECODE_OK; - } - } - - /* We have some unknown fields (or ENDGROUP) to parse. The DISPATCH or TAG - * bytecode that triggered this is preceded by a CHECKDELIM bytecode which - * we need to back up to, so that when we're done skipping unknown data we - * can re-check the delimited end. */ - d->last--; /* Necessary if we get suspended */ - d->pc = d->last; - UPB_ASSERT(getop(*d->last) == OP_CHECKDELIM); - - /* Unknown field or ENDGROUP. */ - retval = upb_pbdecoder_skipunknown(d, fieldnum, wire_type); - - CHECK_RETURN(retval); - - if (retval == DECODE_ENDGROUP) { - goto_endmsg(d); - return DECODE_OK; - } - - return DECODE_OK; -} - -/* Callers know that the stack is more than one deep because the opcodes that - * call this only occur after PUSH operations. */ -upb_pbdecoder_frame *outer_frame(upb_pbdecoder *d) { - UPB_ASSERT(d->top != d->stack); - return d->top - 1; -} - - -/* The main decoding loop *****************************************************/ - -/* The main decoder VM function. Uses traditional bytecode dispatch loop with a - * switch() statement. */ -size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group, - const upb_bufhandle* handle) { - -#define VMCASE(op, code) \ - case op: { code; if (consumes_input(op)) checkpoint(d); break; } -#define PRIMITIVE_OP(type, wt, name, convfunc, ctype) \ - VMCASE(OP_PARSE_ ## type, { \ - ctype val; \ - CHECK_RETURN(decode_ ## wt(d, &val)); \ - upb_sink_put ## name(d->top->sink, arg, (convfunc)(val)); \ - }) - - while(1) { - int32_t instruction; - opcode op; - uint32_t arg; - int32_t longofs; - - d->last = d->pc; - instruction = *d->pc++; - op = getop(instruction); - arg = instruction >> 8; - longofs = arg; - UPB_ASSERT(d->ptr != d->residual_end); - UPB_UNUSED(group); -#ifdef UPB_DUMP_BYTECODE - fprintf(stderr, "s_ofs=%d buf_ofs=%d data_rem=%d buf_rem=%d delim_rem=%d " - "%x %s (%d)\n", - (int)offset(d), - (int)(d->ptr - d->buf), - (int)(d->data_end - d->ptr), - (int)(d->end - d->ptr), - (int)((d->top->end_ofs - d->bufstart_ofs) - (d->ptr - d->buf)), - (int)(d->pc - 1 - group->bytecode), - upb_pbdecoder_getopname(op), - arg); -#endif - switch (op) { - /* Technically, we are losing data if we see a 32-bit varint that is not - * properly sign-extended. We could detect this and error about the data - * loss, but proto2 does not do this, so we pass. */ - PRIMITIVE_OP(INT32, varint, int32, int32_t, uint64_t) - PRIMITIVE_OP(INT64, varint, int64, int64_t, uint64_t) - PRIMITIVE_OP(UINT32, varint, uint32, uint32_t, uint64_t) - PRIMITIVE_OP(UINT64, varint, uint64, uint64_t, uint64_t) - PRIMITIVE_OP(FIXED32, fixed32, uint32, uint32_t, uint32_t) - PRIMITIVE_OP(FIXED64, fixed64, uint64, uint64_t, uint64_t) - PRIMITIVE_OP(SFIXED32, fixed32, int32, int32_t, uint32_t) - PRIMITIVE_OP(SFIXED64, fixed64, int64, int64_t, uint64_t) - PRIMITIVE_OP(BOOL, varint, bool, bool, uint64_t) - PRIMITIVE_OP(DOUBLE, fixed64, double, as_double, uint64_t) - PRIMITIVE_OP(FLOAT, fixed32, float, as_float, uint32_t) - PRIMITIVE_OP(SINT32, varint, int32, upb_zzdec_32, uint64_t) - PRIMITIVE_OP(SINT64, varint, int64, upb_zzdec_64, uint64_t) - - VMCASE(OP_SETDISPATCH, - d->top->base = d->pc - 1; - memcpy(&d->top->dispatch, d->pc, sizeof(void*)); - d->pc += sizeof(void*) / sizeof(uint32_t); - ) - VMCASE(OP_STARTMSG, - CHECK_SUSPEND(upb_sink_startmsg(d->top->sink)); - ) - VMCASE(OP_ENDMSG, - CHECK_SUSPEND(upb_sink_endmsg(d->top->sink, d->status)); - ) - VMCASE(OP_STARTSEQ, - upb_pbdecoder_frame *outer = outer_frame(d); - CHECK_SUSPEND(upb_sink_startseq(outer->sink, arg, &d->top->sink)); - ) - VMCASE(OP_ENDSEQ, - CHECK_SUSPEND(upb_sink_endseq(d->top->sink, arg)); - ) - VMCASE(OP_STARTSUBMSG, - upb_pbdecoder_frame *outer = outer_frame(d); - CHECK_SUSPEND(upb_sink_startsubmsg(outer->sink, arg, &d->top->sink)); - ) - VMCASE(OP_ENDSUBMSG, - upb_sink subsink = (d->top + 1)->sink; - CHECK_SUSPEND(upb_sink_endsubmsg(d->top->sink, subsink, arg)); - ) - VMCASE(OP_STARTSTR, - uint32_t len = delim_remaining(d); - upb_pbdecoder_frame *outer = outer_frame(d); - CHECK_SUSPEND(upb_sink_startstr(outer->sink, arg, len, &d->top->sink)); - if (len == 0) { - d->pc++; /* Skip OP_STRING. */ - } - ) - VMCASE(OP_STRING, - uint32_t len = curbufleft(d); - size_t n = upb_sink_putstring(d->top->sink, arg, d->ptr, len, handle); - if (n > len) { - if (n > delim_remaining(d)) { - seterr(d, "Tried to skip past end of string."); - return upb_pbdecoder_suspend(d); - } else { - int32_t ret = skip(d, n); - /* This shouldn't return DECODE_OK, because n > len. */ - UPB_ASSERT(ret >= 0); - return ret; - } - } - advance(d, n); - if (n < len || d->delim_end == NULL) { - /* We aren't finished with this string yet. */ - d->pc--; /* Repeat OP_STRING. */ - if (n > 0) checkpoint(d); - return upb_pbdecoder_suspend(d); - } - ) - VMCASE(OP_ENDSTR, - CHECK_SUSPEND(upb_sink_endstr(d->top->sink, arg)); - ) - VMCASE(OP_PUSHTAGDELIM, - CHECK_SUSPEND(pushtagdelim(d, arg)); - ) - VMCASE(OP_SETBIGGROUPNUM, - d->top->groupnum = *d->pc++; - ) - VMCASE(OP_POP, - UPB_ASSERT(d->top > d->stack); - decoder_pop(d); - ) - VMCASE(OP_PUSHLENDELIM, - uint32_t len; - CHECK_RETURN(decode_v32(d, &len)); - CHECK_SUSPEND(decoder_push(d, offset(d) + len)); - set_delim_end(d); - ) - VMCASE(OP_SETDELIM, - set_delim_end(d); - ) - VMCASE(OP_CHECKDELIM, - /* We are guaranteed of this assert because we never allow ourselves to - * consume bytes beyond data_end, which covers delim_end when non-NULL. - */ - UPB_ASSERT(!(d->delim_end && d->ptr > d->delim_end)); - if (d->ptr == d->delim_end) - d->pc += longofs; - ) - VMCASE(OP_CALL, - d->callstack[d->call_len++] = d->pc; - d->pc += longofs; - ) - VMCASE(OP_RET, - UPB_ASSERT(d->call_len > 0); - d->pc = d->callstack[--d->call_len]; - ) - VMCASE(OP_BRANCH, - d->pc += longofs; - ) - VMCASE(OP_TAG1, - uint8_t expected; - CHECK_SUSPEND(curbufleft(d) > 0); - expected = (arg >> 8) & 0xff; - if (*d->ptr == expected) { - advance(d, 1); - } else { - int8_t shortofs; - badtag: - shortofs = arg; - if (shortofs == LABEL_DISPATCH) { - CHECK_RETURN(dispatch(d)); - } else { - d->pc += shortofs; - break; /* Avoid checkpoint(). */ - } - } - ) - VMCASE(OP_TAG2, - uint16_t expected; - CHECK_SUSPEND(curbufleft(d) > 0); - expected = (arg >> 8) & 0xffff; - if (curbufleft(d) >= 2) { - uint16_t actual; - memcpy(&actual, d->ptr, 2); - if (expected == actual) { - advance(d, 2); - } else { - goto badtag; - } - } else { - int32_t result = upb_pbdecoder_checktag_slow(d, expected); - if (result == DECODE_MISMATCH) goto badtag; - if (result >= 0) return result; - } - ) - VMCASE(OP_TAGN, { - uint64_t expected; - int32_t result; - memcpy(&expected, d->pc, 8); - d->pc += 2; - result = upb_pbdecoder_checktag_slow(d, expected); - if (result == DECODE_MISMATCH) goto badtag; - if (result >= 0) return result; - }) - VMCASE(OP_DISPATCH, { - CHECK_RETURN(dispatch(d)); - }) - VMCASE(OP_HALT, { - return d->size_param; - }) - } - } -} - - -/* BytesHandler handlers ******************************************************/ - -void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint) { - upb_pbdecoder *d = closure; - UPB_UNUSED(size_hint); - d->top->end_ofs = UINT64_MAX; - d->bufstart_ofs = 0; - d->call_len = 1; - d->callstack[0] = &halt; - d->pc = pc; - d->skip = 0; - return d; -} - -bool upb_pbdecoder_end(void *closure, const void *handler_data) { - upb_pbdecoder *d = closure; - const upb_pbdecodermethod *method = handler_data; - uint64_t end; - char dummy; - - if (d->residual_end > d->residual) { - seterr(d, "Unexpected EOF: decoder still has buffered unparsed data"); - return false; - } - - if (d->skip) { - seterr(d, "Unexpected EOF inside skipped data"); - return false; - } - - if (d->top->end_ofs != UINT64_MAX) { - seterr(d, "Unexpected EOF inside delimited string"); - return false; - } - - /* The user's end() call indicates that the message ends here. */ - end = offset(d); - d->top->end_ofs = end; - - { - const uint32_t *p = d->pc; - d->stack->end_ofs = end; - /* Check the previous bytecode, but guard against beginning. */ - if (p != method->code_base.ptr) p--; - if (getop(*p) == OP_CHECKDELIM) { - /* Rewind from OP_TAG* to OP_CHECKDELIM. */ - UPB_ASSERT(getop(*d->pc) == OP_TAG1 || - getop(*d->pc) == OP_TAG2 || - getop(*d->pc) == OP_TAGN || - getop(*d->pc) == OP_DISPATCH); - d->pc = p; - } - upb_pbdecoder_decode(closure, handler_data, &dummy, 0, NULL); - } - - if (d->call_len != 0) { - seterr(d, "Unexpected EOF inside submessage or group"); - return false; - } - - return true; -} - -size_t upb_pbdecoder_decode(void *decoder, const void *group, const char *buf, - size_t size, const upb_bufhandle *handle) { - int32_t result = upb_pbdecoder_resume(decoder, NULL, buf, size, handle); - - if (result == DECODE_ENDGROUP) goto_endmsg(decoder); - CHECK_RETURN(result); - - return run_decoder_vm(decoder, group, handle); -} - - -/* Public API *****************************************************************/ - -void upb_pbdecoder_reset(upb_pbdecoder *d) { - d->top = d->stack; - d->top->groupnum = 0; - d->ptr = d->residual; - d->buf = d->residual; - d->end = d->residual; - d->residual_end = d->residual; -} - -upb_pbdecoder *upb_pbdecoder_create(upb_arena *a, const upb_pbdecodermethod *m, - upb_sink sink, upb_status *status) { - const size_t default_max_nesting = 64; -#ifndef NDEBUG - size_t size_before = upb_arena_bytesallocated(a); -#endif - - upb_pbdecoder *d = upb_arena_malloc(a, sizeof(upb_pbdecoder)); - if (!d) return NULL; - - d->method_ = m; - d->callstack = upb_arena_malloc(a, callstacksize(d, default_max_nesting)); - d->stack = upb_arena_malloc(a, stacksize(d, default_max_nesting)); - if (!d->stack || !d->callstack) { - return NULL; - } - - d->arena = a; - d->limit = d->stack + default_max_nesting - 1; - d->stack_size = default_max_nesting; - d->status = status; - - upb_pbdecoder_reset(d); - upb_bytessink_reset(&d->input_, &m->input_handler_, d); - - if (d->method_->dest_handlers_) { - if (sink.handlers != d->method_->dest_handlers_) - return NULL; - } - d->top->sink = sink; - - /* If this fails, increase the value in decoder.h. */ - UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(a) - size_before <= - UPB_PB_DECODER_SIZE); - return d; -} - -uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d) { - return offset(d); -} - -const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d) { - return d->method_; -} - -upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d) { - return d->input_; -} - -size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d) { - return d->stack_size; -} - -bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) { - UPB_ASSERT(d->top >= d->stack); - - if (max < (size_t)(d->top - d->stack)) { - /* Can't set a limit smaller than what we are currently at. */ - return false; - } - - if (max > d->stack_size) { - /* Need to reallocate stack and callstack to accommodate. */ - size_t old_size = stacksize(d, d->stack_size); - size_t new_size = stacksize(d, max); - void *p = upb_arena_realloc(d->arena, d->stack, old_size, new_size); - if (!p) { - return false; - } - d->stack = p; - - old_size = callstacksize(d, d->stack_size); - new_size = callstacksize(d, max); - p = upb_arena_realloc(d->arena, d->callstack, old_size, new_size); - if (!p) { - return false; - } - d->callstack = p; - - d->stack_size = max; - } - - d->limit = d->stack + max - 1; - return true; -} -/* -** upb::Encoder -** -** Since we are implementing pure handlers (ie. without any out-of-band access -** to pre-computed lengths), we have to buffer all submessages before we can -** emit even their first byte. -** -** Not knowing the size of submessages also means we can't write a perfect -** zero-copy implementation, even with buffering. Lengths are stored as -** varints, which means that we don't know how many bytes to reserve for the -** length until we know what the length is. -** -** This leaves us with three main choices: -** -** 1. buffer all submessage data in a temporary buffer, then copy it exactly -** once into the output buffer. -** -** 2. attempt to buffer data directly into the output buffer, estimating how -** many bytes each length will take. When our guesses are wrong, use -** memmove() to grow or shrink the allotted space. -** -** 3. buffer directly into the output buffer, allocating a max length -** ahead-of-time for each submessage length. If we overallocated, we waste -** space, but no memcpy() or memmove() is required. This approach requires -** defining a maximum size for submessages and rejecting submessages that -** exceed that size. -** -** (2) and (3) have the potential to have better performance, but they are more -** complicated and subtle to implement: -** -** (3) requires making an arbitrary choice of the maximum message size; it -** wastes space when submessages are shorter than this and fails -** completely when they are longer. This makes it more finicky and -** requires configuration based on the input. It also makes it impossible -** to perfectly match the output of reference encoders that always use the -** optimal amount of space for each length. -** -** (2) requires guessing the the size upfront, and if multiple lengths are -** guessed wrong the minimum required number of memmove() operations may -** be complicated to compute correctly. Implemented properly, it may have -** a useful amortized or average cost, but more investigation is required -** to determine this and what the optimal algorithm is to achieve it. -** -** (1) makes you always pay for exactly one copy, but its implementation is -** the simplest and its performance is predictable. -** -** So for now, we implement (1) only. If we wish to optimize later, we should -** be able to do it without affecting users. -** -** The strategy is to buffer the segments of data that do *not* depend on -** unknown lengths in one buffer, and keep a separate buffer of segment pointers -** and lengths. When the top-level submessage ends, we can go beginning to end, -** alternating the writing of lengths with memcpy() of the rest of the data. -** At the top level though, no buffering is required. -*/ - - - -/* The output buffer is divided into segments; a segment is a string of data - * that is "ready to go" -- it does not need any varint lengths inserted into - * the middle. The seams between segments are where varints will be inserted - * once they are known. - * - * We also use the concept of a "run", which is a range of encoded bytes that - * occur at a single submessage level. Every segment contains one or more runs. - * - * A segment can span messages. Consider: - * - * .--Submessage lengths---------. - * | | | - * | V V - * V | |--------------- | |----------------- - * Submessages: | |----------------------------------------------- - * Top-level msg: ------------------------------------------------------------ - * - * Segments: ----- ------------------- ----------------- - * Runs: *---- *--------------*--- *---------------- - * (* marks the start) - * - * Note that the top-level menssage is not in any segment because it does not - * have any length preceding it. - * - * A segment is only interrupted when another length needs to be inserted. So - * observe how the second segment spans both the inner submessage and part of - * the next enclosing message. */ -typedef struct { - uint32_t msglen; /* The length to varint-encode before this segment. */ - uint32_t seglen; /* Length of the segment. */ -} upb_pb_encoder_segment; - -struct upb_pb_encoder { - upb_arena *arena; - - /* Our input and output. */ - upb_sink input_; - upb_bytessink output_; - - /* The "subclosure" -- used as the inner closure as part of the bytessink - * protocol. */ - void *subc; - - /* The output buffer and limit, and our current write position. "buf" - * initially points to "initbuf", but is dynamically allocated if we need to - * grow beyond the initial size. */ - char *buf, *ptr, *limit; - - /* The beginning of the current run, or undefined if we are at the top - * level. */ - char *runbegin; - - /* The list of segments we are accumulating. */ - upb_pb_encoder_segment *segbuf, *segptr, *seglimit; - - /* The stack of enclosing submessages. Each entry in the stack points to the - * segment where this submessage's length is being accumulated. */ - int *stack, *top, *stacklimit; - - /* Depth of startmsg/endmsg calls. */ - int depth; -}; - -/* low-level buffering ********************************************************/ - -/* Low-level functions for interacting with the output buffer. */ - -/* TODO(haberman): handle pushback */ -static void putbuf(upb_pb_encoder *e, const char *buf, size_t len) { - size_t n = upb_bytessink_putbuf(e->output_, e->subc, buf, len, NULL); - UPB_ASSERT(n == len); -} - -static upb_pb_encoder_segment *top(upb_pb_encoder *e) { - return &e->segbuf[*e->top]; -} - -/* Call to ensure that at least "bytes" bytes are available for writing at - * e->ptr. Returns false if the bytes could not be allocated. */ -static bool reserve(upb_pb_encoder *e, size_t bytes) { - if ((size_t)(e->limit - e->ptr) < bytes) { - /* Grow buffer. */ - char *new_buf; - size_t needed = bytes + (e->ptr - e->buf); - size_t old_size = e->limit - e->buf; - - size_t new_size = old_size; - - while (new_size < needed) { - new_size *= 2; - } - - new_buf = upb_arena_realloc(e->arena, e->buf, old_size, new_size); - - if (new_buf == NULL) { - return false; - } - - e->ptr = new_buf + (e->ptr - e->buf); - e->runbegin = new_buf + (e->runbegin - e->buf); - e->limit = new_buf + new_size; - e->buf = new_buf; - } - - return true; -} - -/* Call when "bytes" bytes have been writte at e->ptr. The caller *must* have - * previously called reserve() with at least this many bytes. */ -static void encoder_advance(upb_pb_encoder *e, size_t bytes) { - UPB_ASSERT((size_t)(e->limit - e->ptr) >= bytes); - e->ptr += bytes; -} - -/* Call when all of the bytes for a handler have been written. Flushes the - * bytes if possible and necessary, returning false if this failed. */ -static bool commit(upb_pb_encoder *e) { - if (!e->top) { - /* We aren't inside a delimited region. Flush our accumulated bytes to - * the output. - * - * TODO(haberman): in the future we may want to delay flushing for - * efficiency reasons. */ - putbuf(e, e->buf, e->ptr - e->buf); - e->ptr = e->buf; - } - - return true; -} - -/* Writes the given bytes to the buffer, handling reserve/advance. */ -static bool encode_bytes(upb_pb_encoder *e, const void *data, size_t len) { - if (!reserve(e, len)) { - return false; - } - - memcpy(e->ptr, data, len); - encoder_advance(e, len); - return true; -} - -/* Finish the current run by adding the run totals to the segment and message - * length. */ -static void accumulate(upb_pb_encoder *e) { - size_t run_len; - UPB_ASSERT(e->ptr >= e->runbegin); - run_len = e->ptr - e->runbegin; - e->segptr->seglen += run_len; - top(e)->msglen += run_len; - e->runbegin = e->ptr; -} - -/* Call to indicate the start of delimited region for which the full length is - * not yet known. All data will be buffered until the length is known. - * Delimited regions may be nested; their lengths will all be tracked properly. */ -static bool start_delim(upb_pb_encoder *e) { - if (e->top) { - /* We are already buffering, advance to the next segment and push it on the - * stack. */ - accumulate(e); - - if (++e->top == e->stacklimit) { - /* TODO(haberman): grow stack? */ - return false; - } - - if (++e->segptr == e->seglimit) { - /* Grow segment buffer. */ - size_t old_size = - (e->seglimit - e->segbuf) * sizeof(upb_pb_encoder_segment); - size_t new_size = old_size * 2; - upb_pb_encoder_segment *new_buf = - upb_arena_realloc(e->arena, e->segbuf, old_size, new_size); - - if (new_buf == NULL) { - return false; - } - - e->segptr = new_buf + (e->segptr - e->segbuf); - e->seglimit = new_buf + (new_size / sizeof(upb_pb_encoder_segment)); - e->segbuf = new_buf; - } - } else { - /* We were previously at the top level, start buffering. */ - e->segptr = e->segbuf; - e->top = e->stack; - e->runbegin = e->ptr; - } - - *e->top = e->segptr - e->segbuf; - e->segptr->seglen = 0; - e->segptr->msglen = 0; - - return true; -} - -/* Call to indicate the end of a delimited region. We now know the length of - * the delimited region. If we are not nested inside any other delimited - * regions, we can now emit all of the buffered data we accumulated. */ -static bool end_delim(upb_pb_encoder *e) { - size_t msglen; - accumulate(e); - msglen = top(e)->msglen; - - if (e->top == e->stack) { - /* All lengths are now available, emit all buffered data. */ - char buf[UPB_PB_VARINT_MAX_LEN]; - upb_pb_encoder_segment *s; - const char *ptr = e->buf; - for (s = e->segbuf; s <= e->segptr; s++) { - size_t lenbytes = upb_vencode64(s->msglen, buf); - putbuf(e, buf, lenbytes); - putbuf(e, ptr, s->seglen); - ptr += s->seglen; - } - - e->ptr = e->buf; - e->top = NULL; - } else { - /* Need to keep buffering; propagate length info into enclosing - * submessages. */ - --e->top; - top(e)->msglen += msglen + upb_varint_size(msglen); - } - - return true; -} - - -/* tag_t **********************************************************************/ - -/* A precomputed (pre-encoded) tag and length. */ - -typedef struct { - uint8_t bytes; - char tag[7]; -} tag_t; - -/* Allocates a new tag for this field, and sets it in these handlerattr. */ -static void new_tag(upb_handlers *h, const upb_fielddef *f, upb_wiretype_t wt, - upb_handlerattr *attr) { - uint32_t n = upb_fielddef_number(f); - - tag_t *tag = upb_gmalloc(sizeof(tag_t)); - tag->bytes = upb_vencode64((n << 3) | wt, tag->tag); - - attr->handler_data = tag; - upb_handlers_addcleanup(h, tag, upb_gfree); -} - -static bool encode_tag(upb_pb_encoder *e, const tag_t *tag) { - return encode_bytes(e, tag->tag, tag->bytes); -} - - -/* encoding of wire types *****************************************************/ - -static bool encode_fixed64(upb_pb_encoder *e, uint64_t val) { - /* TODO(haberman): byte-swap for big endian. */ - return encode_bytes(e, &val, sizeof(uint64_t)); -} - -static bool encode_fixed32(upb_pb_encoder *e, uint32_t val) { - /* TODO(haberman): byte-swap for big endian. */ - return encode_bytes(e, &val, sizeof(uint32_t)); -} - -static bool encode_varint(upb_pb_encoder *e, uint64_t val) { - if (!reserve(e, UPB_PB_VARINT_MAX_LEN)) { - return false; - } - - encoder_advance(e, upb_vencode64(val, e->ptr)); - return true; -} - -static uint64_t dbl2uint64(double d) { - uint64_t ret; - memcpy(&ret, &d, sizeof(uint64_t)); - return ret; -} - -static uint32_t flt2uint32(float d) { - uint32_t ret; - memcpy(&ret, &d, sizeof(uint32_t)); - return ret; -} - - -/* encoding of proto types ****************************************************/ - -static bool startmsg(void *c, const void *hd) { - upb_pb_encoder *e = c; - UPB_UNUSED(hd); - if (e->depth++ == 0) { - upb_bytessink_start(e->output_, 0, &e->subc); - } - return true; -} - -static bool endmsg(void *c, const void *hd, upb_status *status) { - upb_pb_encoder *e = c; - UPB_UNUSED(hd); - UPB_UNUSED(status); - if (--e->depth == 0) { - upb_bytessink_end(e->output_); - } - return true; -} - -static void *encode_startdelimfield(void *c, const void *hd) { - bool ok = encode_tag(c, hd) && commit(c) && start_delim(c); - return ok ? c : UPB_BREAK; -} - -static bool encode_unknown(void *c, const void *hd, const char *buf, - size_t len) { - UPB_UNUSED(hd); - return encode_bytes(c, buf, len) && commit(c); -} - -static bool encode_enddelimfield(void *c, const void *hd) { - UPB_UNUSED(hd); - return end_delim(c); -} - -static void *encode_startgroup(void *c, const void *hd) { - return (encode_tag(c, hd) && commit(c)) ? c : UPB_BREAK; -} - -static bool encode_endgroup(void *c, const void *hd) { - return encode_tag(c, hd) && commit(c); -} - -static void *encode_startstr(void *c, const void *hd, size_t size_hint) { - UPB_UNUSED(size_hint); - return encode_startdelimfield(c, hd); -} - -static size_t encode_strbuf(void *c, const void *hd, const char *buf, - size_t len, const upb_bufhandle *h) { - UPB_UNUSED(hd); - UPB_UNUSED(h); - return encode_bytes(c, buf, len) ? len : 0; -} - -#define T(type, ctype, convert, encode) \ - static bool encode_scalar_##type(void *e, const void *hd, ctype val) { \ - return encode_tag(e, hd) && encode(e, (convert)(val)) && commit(e); \ - } \ - static bool encode_packed_##type(void *e, const void *hd, ctype val) { \ - UPB_UNUSED(hd); \ - return encode(e, (convert)(val)); \ - } - -T(double, double, dbl2uint64, encode_fixed64) -T(float, float, flt2uint32, encode_fixed32) -T(int64, int64_t, uint64_t, encode_varint) -T(int32, int32_t, int64_t, encode_varint) -T(fixed64, uint64_t, uint64_t, encode_fixed64) -T(fixed32, uint32_t, uint32_t, encode_fixed32) -T(bool, bool, bool, encode_varint) -T(uint32, uint32_t, uint32_t, encode_varint) -T(uint64, uint64_t, uint64_t, encode_varint) -T(enum, int32_t, uint32_t, encode_varint) -T(sfixed32, int32_t, uint32_t, encode_fixed32) -T(sfixed64, int64_t, uint64_t, encode_fixed64) -T(sint32, int32_t, upb_zzenc_32, encode_varint) -T(sint64, int64_t, upb_zzenc_64, encode_varint) - -#undef T - - -/* code to build the handlers *************************************************/ - -#include -static void newhandlers_callback(const void *closure, upb_handlers *h) { - const upb_msgdef *m; - upb_msg_field_iter i; - - UPB_UNUSED(closure); - - upb_handlers_setstartmsg(h, startmsg, NULL); - upb_handlers_setendmsg(h, endmsg, NULL); - upb_handlers_setunknown(h, encode_unknown, NULL); - - m = upb_handlers_msgdef(h); - for(upb_msg_field_begin(&i, m); - !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - const upb_fielddef *f = upb_msg_iter_field(&i); - bool packed = upb_fielddef_isseq(f) && upb_fielddef_isprimitive(f) && - upb_fielddef_packed(f); - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - upb_wiretype_t wt = - packed ? UPB_WIRE_TYPE_DELIMITED - : upb_pb_native_wire_types[upb_fielddef_descriptortype(f)]; - - /* Pre-encode the tag for this field. */ - new_tag(h, f, wt, &attr); - - if (packed) { - upb_handlers_setstartseq(h, f, encode_startdelimfield, &attr); - upb_handlers_setendseq(h, f, encode_enddelimfield, &attr); - } - -#define T(upper, lower, upbtype) \ - case UPB_DESCRIPTOR_TYPE_##upper: \ - if (packed) { \ - upb_handlers_set##upbtype(h, f, encode_packed_##lower, &attr); \ - } else { \ - upb_handlers_set##upbtype(h, f, encode_scalar_##lower, &attr); \ - } \ - break; - - switch (upb_fielddef_descriptortype(f)) { - T(DOUBLE, double, double); - T(FLOAT, float, float); - T(INT64, int64, int64); - T(INT32, int32, int32); - T(FIXED64, fixed64, uint64); - T(FIXED32, fixed32, uint32); - T(BOOL, bool, bool); - T(UINT32, uint32, uint32); - T(UINT64, uint64, uint64); - T(ENUM, enum, int32); - T(SFIXED32, sfixed32, int32); - T(SFIXED64, sfixed64, int64); - T(SINT32, sint32, int32); - T(SINT64, sint64, int64); - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: - upb_handlers_setstartstr(h, f, encode_startstr, &attr); - upb_handlers_setendstr(h, f, encode_enddelimfield, &attr); - upb_handlers_setstring(h, f, encode_strbuf, &attr); - break; - case UPB_DESCRIPTOR_TYPE_MESSAGE: - upb_handlers_setstartsubmsg(h, f, encode_startdelimfield, &attr); - upb_handlers_setendsubmsg(h, f, encode_enddelimfield, &attr); - break; - case UPB_DESCRIPTOR_TYPE_GROUP: { - /* Endgroup takes a different tag (wire_type = END_GROUP). */ - upb_handlerattr attr2 = UPB_HANDLERATTR_INIT; - new_tag(h, f, UPB_WIRE_TYPE_END_GROUP, &attr2); - - upb_handlers_setstartsubmsg(h, f, encode_startgroup, &attr); - upb_handlers_setendsubmsg(h, f, encode_endgroup, &attr2); - - break; - } - } - -#undef T - } -} - -void upb_pb_encoder_reset(upb_pb_encoder *e) { - e->segptr = NULL; - e->top = NULL; - e->depth = 0; -} - - -/* public API *****************************************************************/ - -upb_handlercache *upb_pb_encoder_newcache(void) { - return upb_handlercache_new(newhandlers_callback, NULL); -} - -upb_pb_encoder *upb_pb_encoder_create(upb_arena *arena, const upb_handlers *h, - upb_bytessink output) { - const size_t initial_bufsize = 256; - const size_t initial_segbufsize = 16; - /* TODO(haberman): make this configurable. */ - const size_t stack_size = 64; -#ifndef NDEBUG - const size_t size_before = upb_arena_bytesallocated(arena); -#endif - - upb_pb_encoder *e = upb_arena_malloc(arena, sizeof(upb_pb_encoder)); - if (!e) return NULL; - - e->buf = upb_arena_malloc(arena, initial_bufsize); - e->segbuf = upb_arena_malloc(arena, initial_segbufsize * sizeof(*e->segbuf)); - e->stack = upb_arena_malloc(arena, stack_size * sizeof(*e->stack)); - - if (!e->buf || !e->segbuf || !e->stack) { - return NULL; - } - - e->limit = e->buf + initial_bufsize; - e->seglimit = e->segbuf + initial_segbufsize; - e->stacklimit = e->stack + stack_size; - - upb_pb_encoder_reset(e); - upb_sink_reset(&e->input_, h, e); - - e->arena = arena; - e->output_ = output; - e->subc = output.closure; - e->ptr = e->buf; - - /* If this fails, increase the value in encoder.h. */ - UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <= - UPB_PB_ENCODER_SIZE); - return e; -} - -upb_sink upb_pb_encoder_input(upb_pb_encoder *e) { return e->input_; } -/* - * upb::pb::TextPrinter - * - * OPT: This is not optimized at all. It uses printf() which parses the format - * string every time, and it allocates memory for every put. - */ - - -#include -#include -#include -#include -#include -#include - - - -struct upb_textprinter { - upb_sink input_; - upb_bytessink output_; - int indent_depth_; - bool single_line_; - void *subc; -}; - -#define CHECK(x) if ((x) < 0) goto err; - -static const char *shortname(const char *longname) { - const char *last = strrchr(longname, '.'); - return last ? last + 1 : longname; -} - -static int indent(upb_textprinter *p) { - int i; - if (!p->single_line_) - for (i = 0; i < p->indent_depth_; i++) - upb_bytessink_putbuf(p->output_, p->subc, " ", 2, NULL); - return 0; -} - -static int endfield(upb_textprinter *p) { - const char ch = (p->single_line_ ? ' ' : '\n'); - upb_bytessink_putbuf(p->output_, p->subc, &ch, 1, NULL); - return 0; -} - -static int putescaped(upb_textprinter *p, const char *buf, size_t len, - bool preserve_utf8) { - /* Based on CEscapeInternal() from Google's protobuf release. */ - char dstbuf[4096], *dst = dstbuf, *dstend = dstbuf + sizeof(dstbuf); - const char *end = buf + len; - - /* I think hex is prettier and more useful, but proto2 uses octal; should - * investigate whether it can parse hex also. */ - const bool use_hex = false; - bool last_hex_escape = false; /* true if last output char was \xNN */ - - for (; buf < end; buf++) { - bool is_hex_escape; - - if (dstend - dst < 4) { - upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL); - dst = dstbuf; - } - - is_hex_escape = false; - switch (*buf) { - case '\n': *(dst++) = '\\'; *(dst++) = 'n'; break; - case '\r': *(dst++) = '\\'; *(dst++) = 'r'; break; - case '\t': *(dst++) = '\\'; *(dst++) = 't'; break; - case '\"': *(dst++) = '\\'; *(dst++) = '\"'; break; - case '\'': *(dst++) = '\\'; *(dst++) = '\''; break; - case '\\': *(dst++) = '\\'; *(dst++) = '\\'; break; - default: - /* Note that if we emit \xNN and the buf character after that is a hex - * digit then that digit must be escaped too to prevent it being - * interpreted as part of the character code by C. */ - if ((!preserve_utf8 || (uint8_t)*buf < 0x80) && - (!isprint(*buf) || (last_hex_escape && isxdigit(*buf)))) { - sprintf(dst, (use_hex ? "\\x%02x" : "\\%03o"), (uint8_t)*buf); - is_hex_escape = use_hex; - dst += 4; - } else { - *(dst++) = *buf; break; - } - } - last_hex_escape = is_hex_escape; - } - /* Flush remaining data. */ - upb_bytessink_putbuf(p->output_, p->subc, dstbuf, dst - dstbuf, NULL); - return 0; -} - -bool putf(upb_textprinter *p, const char *fmt, ...) { - va_list args; - va_list args_copy; - char *str; - int written; - int len; - bool ok; - - va_start(args, fmt); - - /* Run once to get the length of the string. */ - _upb_va_copy(args_copy, args); - len = _upb_vsnprintf(NULL, 0, fmt, args_copy); - va_end(args_copy); - - /* + 1 for NULL terminator (vsprintf() requires it even if we don't). */ - str = upb_gmalloc(len + 1); - if (!str) return false; - written = vsprintf(str, fmt, args); - va_end(args); - UPB_ASSERT(written == len); - - ok = upb_bytessink_putbuf(p->output_, p->subc, str, len, NULL); - upb_gfree(str); - return ok; -} - - -/* handlers *******************************************************************/ - -static bool textprinter_startmsg(void *c, const void *hd) { - upb_textprinter *p = c; - UPB_UNUSED(hd); - if (p->indent_depth_ == 0) { - upb_bytessink_start(p->output_, 0, &p->subc); - } - return true; -} - -static bool textprinter_endmsg(void *c, const void *hd, upb_status *s) { - upb_textprinter *p = c; - UPB_UNUSED(hd); - UPB_UNUSED(s); - if (p->indent_depth_ == 0) { - upb_bytessink_end(p->output_); - } - return true; -} - -#define TYPE(name, ctype, fmt) \ - static bool textprinter_put ## name(void *closure, const void *handler_data, \ - ctype val) { \ - upb_textprinter *p = closure; \ - const upb_fielddef *f = handler_data; \ - CHECK(indent(p)); \ - putf(p, "%s: " fmt, upb_fielddef_name(f), val); \ - CHECK(endfield(p)); \ - return true; \ - err: \ - return false; \ -} - -static bool textprinter_putbool(void *closure, const void *handler_data, - bool val) { - upb_textprinter *p = closure; - const upb_fielddef *f = handler_data; - CHECK(indent(p)); - putf(p, "%s: %s", upb_fielddef_name(f), val ? "true" : "false"); - CHECK(endfield(p)); - return true; -err: - return false; -} - -#define STRINGIFY_HELPER(x) #x -#define STRINGIFY_MACROVAL(x) STRINGIFY_HELPER(x) - -TYPE(int32, int32_t, "%" PRId32) -TYPE(int64, int64_t, "%" PRId64) -TYPE(uint32, uint32_t, "%" PRIu32) -TYPE(uint64, uint64_t, "%" PRIu64) -TYPE(float, float, "%." STRINGIFY_MACROVAL(FLT_DIG) "g") -TYPE(double, double, "%." STRINGIFY_MACROVAL(DBL_DIG) "g") - -#undef TYPE - -/* Output a symbolic value from the enum if found, else just print as int32. */ -static bool textprinter_putenum(void *closure, const void *handler_data, - int32_t val) { - upb_textprinter *p = closure; - const upb_fielddef *f = handler_data; - const upb_enumdef *enum_def = upb_fielddef_enumsubdef(f); - const char *label = upb_enumdef_iton(enum_def, val); - if (label) { - indent(p); - putf(p, "%s: %s", upb_fielddef_name(f), label); - endfield(p); - } else { - if (!textprinter_putint32(closure, handler_data, val)) - return false; - } - return true; -} - -static void *textprinter_startstr(void *closure, const void *handler_data, - size_t size_hint) { - upb_textprinter *p = closure; - const upb_fielddef *f = handler_data; - UPB_UNUSED(size_hint); - indent(p); - putf(p, "%s: \"", upb_fielddef_name(f)); - return p; -} - -static bool textprinter_endstr(void *closure, const void *handler_data) { - upb_textprinter *p = closure; - UPB_UNUSED(handler_data); - putf(p, "\""); - endfield(p); - return true; -} - -static size_t textprinter_putstr(void *closure, const void *hd, const char *buf, - size_t len, const upb_bufhandle *handle) { - upb_textprinter *p = closure; - const upb_fielddef *f = hd; - UPB_UNUSED(handle); - CHECK(putescaped(p, buf, len, upb_fielddef_type(f) == UPB_TYPE_STRING)); - return len; -err: - return 0; -} - -static void *textprinter_startsubmsg(void *closure, const void *handler_data) { - upb_textprinter *p = closure; - const char *name = handler_data; - CHECK(indent(p)); - putf(p, "%s {%c", name, p->single_line_ ? ' ' : '\n'); - p->indent_depth_++; - return p; -err: - return UPB_BREAK; -} - -static bool textprinter_endsubmsg(void *closure, const void *handler_data) { - upb_textprinter *p = closure; - UPB_UNUSED(handler_data); - p->indent_depth_--; - CHECK(indent(p)); - upb_bytessink_putbuf(p->output_, p->subc, "}", 1, NULL); - CHECK(endfield(p)); - return true; -err: - return false; -} - -static void onmreg(const void *c, upb_handlers *h) { - const upb_msgdef *m = upb_handlers_msgdef(h); - upb_msg_field_iter i; - UPB_UNUSED(c); - - upb_handlers_setstartmsg(h, textprinter_startmsg, NULL); - upb_handlers_setendmsg(h, textprinter_endmsg, NULL); - - for(upb_msg_field_begin(&i, m); - !upb_msg_field_done(&i); - upb_msg_field_next(&i)) { - upb_fielddef *f = upb_msg_iter_field(&i); - upb_handlerattr attr = UPB_HANDLERATTR_INIT; - attr.handler_data = f; - switch (upb_fielddef_type(f)) { - case UPB_TYPE_INT32: - upb_handlers_setint32(h, f, textprinter_putint32, &attr); - break; - case UPB_TYPE_INT64: - upb_handlers_setint64(h, f, textprinter_putint64, &attr); - break; - case UPB_TYPE_UINT32: - upb_handlers_setuint32(h, f, textprinter_putuint32, &attr); - break; - case UPB_TYPE_UINT64: - upb_handlers_setuint64(h, f, textprinter_putuint64, &attr); - break; - case UPB_TYPE_FLOAT: - upb_handlers_setfloat(h, f, textprinter_putfloat, &attr); - break; - case UPB_TYPE_DOUBLE: - upb_handlers_setdouble(h, f, textprinter_putdouble, &attr); - break; - case UPB_TYPE_BOOL: - upb_handlers_setbool(h, f, textprinter_putbool, &attr); - break; - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - upb_handlers_setstartstr(h, f, textprinter_startstr, &attr); - upb_handlers_setstring(h, f, textprinter_putstr, &attr); - upb_handlers_setendstr(h, f, textprinter_endstr, &attr); - break; - case UPB_TYPE_MESSAGE: { - const char *name = - upb_fielddef_descriptortype(f) == UPB_DESCRIPTOR_TYPE_GROUP - ? shortname(upb_msgdef_fullname(upb_fielddef_msgsubdef(f))) - : upb_fielddef_name(f); - attr.handler_data = name; - upb_handlers_setstartsubmsg(h, f, textprinter_startsubmsg, &attr); - upb_handlers_setendsubmsg(h, f, textprinter_endsubmsg, &attr); - break; - } - case UPB_TYPE_ENUM: - upb_handlers_setint32(h, f, textprinter_putenum, &attr); - break; - } - } -} - -static void textprinter_reset(upb_textprinter *p, bool single_line) { - p->single_line_ = single_line; - p->indent_depth_ = 0; -} - - -/* Public API *****************************************************************/ - -upb_textprinter *upb_textprinter_create(upb_arena *arena, const upb_handlers *h, - upb_bytessink output) { - upb_textprinter *p = upb_arena_malloc(arena, sizeof(upb_textprinter)); - if (!p) return NULL; - - p->output_ = output; - upb_sink_reset(&p->input_, h, p); - textprinter_reset(p, false); - - return p; -} - -upb_handlercache *upb_textprinter_newcache(void) { - return upb_handlercache_new(&onmreg, NULL); -} - -upb_sink upb_textprinter_input(upb_textprinter *p) { return p->input_; } - -void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line) { - p->single_line_ = single_line; -} - - -/* Index is descriptor type. */ -const uint8_t upb_pb_native_wire_types[] = { - UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */ - UPB_WIRE_TYPE_64BIT, /* DOUBLE */ - UPB_WIRE_TYPE_32BIT, /* FLOAT */ - UPB_WIRE_TYPE_VARINT, /* INT64 */ - UPB_WIRE_TYPE_VARINT, /* UINT64 */ - UPB_WIRE_TYPE_VARINT, /* INT32 */ - UPB_WIRE_TYPE_64BIT, /* FIXED64 */ - UPB_WIRE_TYPE_32BIT, /* FIXED32 */ - UPB_WIRE_TYPE_VARINT, /* BOOL */ - UPB_WIRE_TYPE_DELIMITED, /* STRING */ - UPB_WIRE_TYPE_START_GROUP, /* GROUP */ - UPB_WIRE_TYPE_DELIMITED, /* MESSAGE */ - UPB_WIRE_TYPE_DELIMITED, /* BYTES */ - UPB_WIRE_TYPE_VARINT, /* UINT32 */ - UPB_WIRE_TYPE_VARINT, /* ENUM */ - UPB_WIRE_TYPE_32BIT, /* SFIXED32 */ - UPB_WIRE_TYPE_64BIT, /* SFIXED64 */ - UPB_WIRE_TYPE_VARINT, /* SINT32 */ - UPB_WIRE_TYPE_VARINT, /* SINT64 */ -}; - -/* A basic branch-based decoder, uses 32-bit values to get good performance - * on 32-bit architectures (but performs well on 64-bits also). - * This scheme comes from the original Google Protobuf implementation - * (proto2). */ -upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r) { - upb_decoderet err = {NULL, 0}; - const char *p = r.p; - uint32_t low = (uint32_t)r.val; - uint32_t high = 0; - uint32_t b; - b = *(p++); low |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done; - b = *(p++); low |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done; - b = *(p++); low |= (b & 0x7fU) << 28; - high = (b & 0x7fU) >> 4; if (!(b & 0x80)) goto done; - b = *(p++); high |= (b & 0x7fU) << 3; if (!(b & 0x80)) goto done; - b = *(p++); high |= (b & 0x7fU) << 10; if (!(b & 0x80)) goto done; - b = *(p++); high |= (b & 0x7fU) << 17; if (!(b & 0x80)) goto done; - b = *(p++); high |= (b & 0x7fU) << 24; if (!(b & 0x80)) goto done; - b = *(p++); high |= (b & 0x7fU) << 31; if (!(b & 0x80)) goto done; - return err; - -done: - r.val = ((uint64_t)high << 32) | low; - r.p = p; - return r; -} - -/* Like the previous, but uses 64-bit values. */ -upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r) { - const char *p = r.p; - uint64_t val = r.val; - uint64_t b; - upb_decoderet err = {NULL, 0}; - b = *(p++); val |= (b & 0x7fU) << 14; if (!(b & 0x80)) goto done; - b = *(p++); val |= (b & 0x7fU) << 21; if (!(b & 0x80)) goto done; - b = *(p++); val |= (b & 0x7fU) << 28; if (!(b & 0x80)) goto done; - b = *(p++); val |= (b & 0x7fU) << 35; if (!(b & 0x80)) goto done; - b = *(p++); val |= (b & 0x7fU) << 42; if (!(b & 0x80)) goto done; - b = *(p++); val |= (b & 0x7fU) << 49; if (!(b & 0x80)) goto done; - b = *(p++); val |= (b & 0x7fU) << 56; if (!(b & 0x80)) goto done; - b = *(p++); val |= (b & 0x7fU) << 63; if (!(b & 0x80)) goto done; - return err; - -done: - r.val = val; - r.p = p; - return r; -} - -// #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 - - - -#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 accumulate 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); -} - -static int div_round_up2(int n, int d) { - return (n + d - 1) / d; -} - -/* epoch_days(1970, 1, 1) == 1970-01-01 == 0. */ -static int epoch_days(int year, int month, int day) { - static const uint16_t month_yday[12] = {0, 31, 59, 90, 120, 151, - 181, 212, 243, 273, 304, 334}; - int febs_since_0 = month > 2 ? year + 1 : year; - int leap_days_since_0 = div_round_up2(febs_since_0, 4) - - div_round_up2(febs_since_0, 100) + - div_round_up2(febs_since_0, 400); - int days_since_0 = - 365 * year + month_yday[month - 1] + (day - 1) + leap_days_since_0; - - /* Convert from 0-epoch (0001-01-01 BC) to Unix Epoch (1970-01-01 AD). - * Since the "BC" system does not have a year zero, 1 BC == year zero. */ - return days_since_0 - 719528; -} - -static int64_t upb_timegm(const struct tm *tp) { - int64_t ret = epoch_days(tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday); - ret = (ret * 24) + tp->tm_hour; - ret = (ret * 60) + tp->tm_min; - ret = (ret * 60) + tp->tm_sec; - return ret; -} - -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_timegm(&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, (p->top + 1)->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, (p->top + 1)->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 2780 "upb/json/parser.rl" - - - -// #line 2583 "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 2783 "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 2861 "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 2588 "upb/json/parser.rl" - { p--; {cs = stack[--top]; goto _again;} } - break; - case 2: -// #line 2590 "upb/json/parser.rl" - { p--; {stack[top++] = cs; cs = 23;goto _again;} } - break; - case 3: -// #line 2594 "upb/json/parser.rl" - { start_text(parser, p); } - break; - case 4: -// #line 2595 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_text(parser, p)); } - break; - case 5: -// #line 2601 "upb/json/parser.rl" - { start_hex(parser); } - break; - case 6: -// #line 2602 "upb/json/parser.rl" - { hexdigit(parser, p); } - break; - case 7: -// #line 2603 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_hex(parser)); } - break; - case 8: -// #line 2609 "upb/json/parser.rl" - { CHECK_RETURN_TOP(escape(parser, p)); } - break; - case 9: -// #line 2615 "upb/json/parser.rl" - { p--; {cs = stack[--top]; goto _again;} } - break; - case 10: -// #line 2620 "upb/json/parser.rl" - { start_year(parser, p); } - break; - case 11: -// #line 2621 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_year(parser, p)); } - break; - case 12: -// #line 2625 "upb/json/parser.rl" - { start_month(parser, p); } - break; - case 13: -// #line 2626 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_month(parser, p)); } - break; - case 14: -// #line 2630 "upb/json/parser.rl" - { start_day(parser, p); } - break; - case 15: -// #line 2631 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_day(parser, p)); } - break; - case 16: -// #line 2635 "upb/json/parser.rl" - { start_hour(parser, p); } - break; - case 17: -// #line 2636 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_hour(parser, p)); } - break; - case 18: -// #line 2640 "upb/json/parser.rl" - { start_minute(parser, p); } - break; - case 19: -// #line 2641 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_minute(parser, p)); } - break; - case 20: -// #line 2645 "upb/json/parser.rl" - { start_second(parser, p); } - break; - case 21: -// #line 2646 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_second(parser, p)); } - break; - case 22: -// #line 2651 "upb/json/parser.rl" - { start_duration_base(parser, p); } - break; - case 23: -// #line 2652 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_duration_base(parser, p)); } - break; - case 24: -// #line 2654 "upb/json/parser.rl" - { p--; {cs = stack[--top]; goto _again;} } - break; - case 25: -// #line 2659 "upb/json/parser.rl" - { start_timestamp_base(parser); } - break; - case 26: -// #line 2661 "upb/json/parser.rl" - { start_timestamp_fraction(parser, p); } - break; - case 27: -// #line 2662 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); } - break; - case 28: -// #line 2664 "upb/json/parser.rl" - { start_timestamp_zone(parser, p); } - break; - case 29: -// #line 2665 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); } - break; - case 30: -// #line 2667 "upb/json/parser.rl" - { p--; {cs = stack[--top]; goto _again;} } - break; - case 31: -// #line 2672 "upb/json/parser.rl" - { start_fieldmask_path_text(parser, p); } - break; - case 32: -// #line 2673 "upb/json/parser.rl" - { end_fieldmask_path_text(parser, p); } - break; - case 33: -// #line 2678 "upb/json/parser.rl" - { start_fieldmask_path(parser); } - break; - case 34: -// #line 2679 "upb/json/parser.rl" - { end_fieldmask_path(parser); } - break; - case 35: -// #line 2685 "upb/json/parser.rl" - { p--; {cs = stack[--top]; goto _again;} } - break; - case 36: -// #line 2690 "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 2703 "upb/json/parser.rl" - { p--; {stack[top++] = cs; cs = 78;goto _again;} } - break; - case 38: -// #line 2708 "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 2715 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_membername(parser)); } - break; - case 40: -// #line 2718 "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 2729 "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 2738 "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 2750 "upb/json/parser.rl" - { CHECK_RETURN_TOP(start_array(parser)); } - break; - case 44: -// #line 2754 "upb/json/parser.rl" - { end_array(parser); } - break; - case 45: -// #line 2759 "upb/json/parser.rl" - { CHECK_RETURN_TOP(start_number(parser, p)); } - break; - case 46: -// #line 2760 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_number(parser, p)); } - break; - case 47: -// #line 2762 "upb/json/parser.rl" - { CHECK_RETURN_TOP(start_stringval(parser)); } - break; - case 48: -// #line 2763 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_stringval(parser)); } - break; - case 49: -// #line 2765 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_bool(parser, true)); } - break; - case 50: -// #line 2767 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_bool(parser, false)); } - break; - case 51: -// #line 2769 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_null(parser)); } - break; - case 52: -// #line 2771 "upb/json/parser.rl" - { CHECK_RETURN_TOP(start_subobject_full(parser)); } - break; - case 53: -// #line 2772 "upb/json/parser.rl" - { end_subobject_full(parser); } - break; - case 54: -// #line 2777 "upb/json/parser.rl" - { p--; {cs = stack[--top]; goto _again;} } - break; -// #line 3185 "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 2586 "upb/json/parser.rl" - { p--; {cs = stack[--top]; if ( p == pe ) - goto _test_eof; -goto _again;} } - break; - case 46: -// #line 2760 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_number(parser, p)); } - break; - case 49: -// #line 2765 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_bool(parser, true)); } - break; - case 50: -// #line 2767 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_bool(parser, false)); } - break; - case 51: -// #line 2769 "upb/json/parser.rl" - { CHECK_RETURN_TOP(end_null(parser)); } - break; - case 53: -// #line 2772 "upb/json/parser.rl" - { end_subobject_full(parser); } - break; -// #line 3227 "upb/json/parser.c" - } - } - } - - _out: {} - } - -// #line 2805 "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 3278 "upb/json/parser.c" - { - cs = json_start; - top = 0; - } - -// #line 2847 "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; -} -/* -** This currently uses snprintf() to format primitives, and could be optimized -** further. -*/ - - -#include -#include -#include -#include - - -struct upb_json_printer { - upb_sink input_; - /* BytesSink closure. */ - void *subc_; - upb_bytessink output_; - - /* We track the depth so that we know when to emit startstr/endstr on the - * output. */ - int depth_; - - /* Have we emitted the first element? This state is necessary to emit commas - * without leaving a trailing comma in arrays/maps. We keep this state per - * frame depth. - * - * Why max_depth * 2? UPB_MAX_HANDLER_DEPTH counts depth as nested messages. - * We count frames (contexts in which we separate elements by commas) as both - * repeated fields and messages (maps), and the worst case is a - * message->repeated field->submessage->repeated field->... nesting. */ - bool first_elem_[UPB_MAX_HANDLER_DEPTH * 2]; - - /* To print timestamp, printer needs to cache its seconds and nanos values - * and convert them when ending timestamp message. See comments of - * printer_sethandlers_timestamp for more detail. */ - int64_t seconds; - int32_t nanos; -}; - -/* StringPiece; a pointer plus a length. */ -typedef struct { - char *ptr; - size_t len; -} strpc; - -void freestrpc(void *ptr) { - strpc *pc = ptr; - upb_gfree(pc->ptr); - upb_gfree(pc); -} - -typedef struct { - bool preserve_fieldnames; -} upb_json_printercache; - -/* Convert fielddef name to JSON name and return as a string piece. */ -strpc *newstrpc(upb_handlers *h, const upb_fielddef *f, - bool preserve_fieldnames) { - /* TODO(haberman): handle malloc failure. */ - strpc *ret = upb_gmalloc(sizeof(*ret)); - if (preserve_fieldnames) { - ret->ptr = upb_gstrdup(upb_fielddef_name(f)); - ret->len = strlen(ret->ptr); - } else { - size_t len; - ret->len = upb_fielddef_getjsonname(f, NULL, 0); - ret->ptr = upb_gmalloc(ret->len); - len = upb_fielddef_getjsonname(f, ret->ptr, ret->len); - UPB_ASSERT(len == ret->len); - ret->len--; /* NULL */ - } - - upb_handlers_addcleanup(h, ret, freestrpc); - return ret; -} - -/* Convert a null-terminated const char* to a string piece. */ -strpc *newstrpc_str(upb_handlers *h, const char * str) { - strpc * ret = upb_gmalloc(sizeof(*ret)); - ret->ptr = upb_gstrdup(str); - ret->len = strlen(str); - upb_handlers_addcleanup(h, ret, freestrpc); - return ret; -} - -/* ------------ JSON string printing: values, maps, arrays ------------------ */ - -static void print_data( - upb_json_printer *p, const char *buf, unsigned int len) { - /* TODO: Will need to change if we support pushback from the sink. */ - size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL); - UPB_ASSERT(n == len); -} - -static void print_comma(upb_json_printer *p) { - if (!p->first_elem_[p->depth_]) { - print_data(p, ",", 1); - } - p->first_elem_[p->depth_] = false; -} - -/* Helpers that print properly formatted elements to the JSON output stream. */ - -/* Used for escaping control chars in strings. */ -static const char kControlCharLimit = 0x20; - -UPB_INLINE bool is_json_escaped(char c) { - /* See RFC 4627. */ - unsigned char uc = (unsigned char)c; - return uc < kControlCharLimit || uc == '"' || uc == '\\'; -} - -UPB_INLINE const char* json_nice_escape(char c) { - switch (c) { - case '"': return "\\\""; - case '\\': return "\\\\"; - case '\b': return "\\b"; - case '\f': return "\\f"; - case '\n': return "\\n"; - case '\r': return "\\r"; - case '\t': return "\\t"; - default: return NULL; - } -} - -/* Write a properly escaped string chunk. The surrounding quotes are *not* - * printed; this is so that the caller has the option of emitting the string - * content in chunks. */ -static void putstring(upb_json_printer *p, const char *buf, unsigned int len) { - const char* unescaped_run = NULL; - unsigned int i; - for (i = 0; i < len; i++) { - char c = buf[i]; - /* Handle escaping. */ - if (is_json_escaped(c)) { - /* Use a "nice" escape, like \n, if one exists for this character. */ - const char* escape = json_nice_escape(c); - /* If we don't have a specific 'nice' escape code, use a \uXXXX-style - * escape. */ - char escape_buf[8]; - if (!escape) { - unsigned char byte = (unsigned char)c; - _upb_snprintf(escape_buf, sizeof(escape_buf), "\\u%04x", (int)byte); - escape = escape_buf; - } - - /* N.B. that we assume that the input encoding is equal to the output - * encoding (both UTF-8 for now), so for chars >= 0x20 and != \, ", we - * can simply pass the bytes through. */ - - /* If there's a current run of unescaped chars, print that run first. */ - if (unescaped_run) { - print_data(p, unescaped_run, &buf[i] - unescaped_run); - unescaped_run = NULL; - } - /* Then print the escape code. */ - print_data(p, escape, strlen(escape)); - } else { - /* Add to the current unescaped run of characters. */ - if (unescaped_run == NULL) { - unescaped_run = &buf[i]; - } - } - } - - /* If the string ended in a run of unescaped characters, print that last run. */ - if (unescaped_run) { - print_data(p, unescaped_run, &buf[len] - unescaped_run); - } -} - -#define CHKLENGTH(x) if (!(x)) return -1; - -/* Helpers that format floating point values according to our custom formats. - * Right now we use %.8g and %.17g for float/double, respectively, to match - * proto2::util::JsonFormat's defaults. May want to change this later. */ - -const char neginf[] = "\"-Infinity\""; -const char inf[] = "\"Infinity\""; - -static size_t fmt_double(double val, char* buf, size_t length) { - if (val == UPB_INFINITY) { - CHKLENGTH(length >= strlen(inf)); - strcpy(buf, inf); - return strlen(inf); - } else if (val == -UPB_INFINITY) { - CHKLENGTH(length >= strlen(neginf)); - strcpy(buf, neginf); - return strlen(neginf); - } else { - size_t n = _upb_snprintf(buf, length, "%.17g", val); - CHKLENGTH(n > 0 && n < length); - return n; - } -} - -static size_t fmt_float(float val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%.8g", val); - CHKLENGTH(n > 0 && n < length); - return n; -} - -static size_t fmt_bool(bool val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%s", (val ? "true" : "false")); - CHKLENGTH(n > 0 && n < length); - return n; -} - -static size_t fmt_int64_as_number(long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%lld", val); - CHKLENGTH(n > 0 && n < length); - return n; -} - -static size_t fmt_uint64_as_number( - unsigned long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%llu", val); - CHKLENGTH(n > 0 && n < length); - return n; -} - -static size_t fmt_int64_as_string(long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "\"%lld\"", val); - CHKLENGTH(n > 0 && n < length); - return n; -} - -static size_t fmt_uint64_as_string( - unsigned long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "\"%llu\"", val); - CHKLENGTH(n > 0 && n < length); - return n; -} - -/* Print a map key given a field name. Called by scalar field handlers and by - * startseq for repeated fields. */ -static bool putkey(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - const strpc *key = handler_data; - print_comma(p); - print_data(p, "\"", 1); - putstring(p, key->ptr, key->len); - print_data(p, "\":", 2); - return true; -} - -#define CHKFMT(val) if ((val) == (size_t)-1) return false; -#define CHK(val) if (!(val)) return false; - -#define TYPE_HANDLERS(type, fmt_func) \ - static bool put##type(void *closure, const void *handler_data, type val) { \ - upb_json_printer *p = closure; \ - char data[64]; \ - size_t length = fmt_func(val, data, sizeof(data)); \ - UPB_UNUSED(handler_data); \ - CHKFMT(length); \ - print_data(p, data, length); \ - return true; \ - } \ - static bool scalar_##type(void *closure, const void *handler_data, \ - type val) { \ - CHK(putkey(closure, handler_data)); \ - CHK(put##type(closure, handler_data, val)); \ - return true; \ - } \ - static bool repeated_##type(void *closure, const void *handler_data, \ - type val) { \ - upb_json_printer *p = closure; \ - print_comma(p); \ - CHK(put##type(closure, handler_data, val)); \ - return true; \ - } - -#define TYPE_HANDLERS_MAPKEY(type, fmt_func) \ - static bool putmapkey_##type(void *closure, const void *handler_data, \ - type val) { \ - upb_json_printer *p = closure; \ - char data[64]; \ - size_t length = fmt_func(val, data, sizeof(data)); \ - UPB_UNUSED(handler_data); \ - print_data(p, "\"", 1); \ - print_data(p, data, length); \ - print_data(p, "\":", 2); \ - return true; \ - } - -TYPE_HANDLERS(double, fmt_double) -TYPE_HANDLERS(float, fmt_float) -TYPE_HANDLERS(bool, fmt_bool) -TYPE_HANDLERS(int32_t, fmt_int64_as_number) -TYPE_HANDLERS(uint32_t, fmt_int64_as_number) -TYPE_HANDLERS(int64_t, fmt_int64_as_string) -TYPE_HANDLERS(uint64_t, fmt_uint64_as_string) - -/* double and float are not allowed to be map keys. */ -TYPE_HANDLERS_MAPKEY(bool, fmt_bool) -TYPE_HANDLERS_MAPKEY(int32_t, fmt_int64_as_number) -TYPE_HANDLERS_MAPKEY(uint32_t, fmt_int64_as_number) -TYPE_HANDLERS_MAPKEY(int64_t, fmt_int64_as_number) -TYPE_HANDLERS_MAPKEY(uint64_t, fmt_uint64_as_number) - -#undef TYPE_HANDLERS -#undef TYPE_HANDLERS_MAPKEY - -typedef struct { - void *keyname; - const upb_enumdef *enumdef; -} EnumHandlerData; - -static bool scalar_enum(void *closure, const void *handler_data, - int32_t val) { - const EnumHandlerData *hd = handler_data; - upb_json_printer *p = closure; - const char *symbolic_name; - - CHK(putkey(closure, hd->keyname)); - - symbolic_name = upb_enumdef_iton(hd->enumdef, val); - if (symbolic_name) { - print_data(p, "\"", 1); - putstring(p, symbolic_name, strlen(symbolic_name)); - print_data(p, "\"", 1); - } else { - putint32_t(closure, NULL, val); - } - - return true; -} - -static void print_enum_symbolic_name(upb_json_printer *p, - const upb_enumdef *def, - int32_t val) { - const char *symbolic_name = upb_enumdef_iton(def, val); - if (symbolic_name) { - print_data(p, "\"", 1); - putstring(p, symbolic_name, strlen(symbolic_name)); - print_data(p, "\"", 1); - } else { - putint32_t(p, NULL, val); - } -} - -static bool repeated_enum(void *closure, const void *handler_data, - int32_t val) { - const EnumHandlerData *hd = handler_data; - upb_json_printer *p = closure; - print_comma(p); - - print_enum_symbolic_name(p, hd->enumdef, val); - - return true; -} - -static bool mapvalue_enum(void *closure, const void *handler_data, - int32_t val) { - const EnumHandlerData *hd = handler_data; - upb_json_printer *p = closure; - - print_enum_symbolic_name(p, hd->enumdef, val); - - return true; -} - -static void *scalar_startsubmsg(void *closure, const void *handler_data) { - return putkey(closure, handler_data) ? closure : UPB_BREAK; -} - -static void *repeated_startsubmsg(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - print_comma(p); - return closure; -} - -static void start_frame(upb_json_printer *p) { - p->depth_++; - p->first_elem_[p->depth_] = true; - print_data(p, "{", 1); -} - -static void end_frame(upb_json_printer *p) { - print_data(p, "}", 1); - p->depth_--; -} - -static bool printer_startmsg(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - if (p->depth_ == 0) { - upb_bytessink_start(p->output_, 0, &p->subc_); - } - start_frame(p); - return true; -} - -static bool printer_endmsg(void *closure, const void *handler_data, upb_status *s) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(s); - end_frame(p); - if (p->depth_ == 0) { - upb_bytessink_end(p->output_); - } - return true; -} - -static void *startseq(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - CHK(putkey(closure, handler_data)); - p->depth_++; - p->first_elem_[p->depth_] = true; - print_data(p, "[", 1); - return closure; -} - -static bool endseq(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - print_data(p, "]", 1); - p->depth_--; - return true; -} - -static void *startmap(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - CHK(putkey(closure, handler_data)); - p->depth_++; - p->first_elem_[p->depth_] = true; - print_data(p, "{", 1); - return closure; -} - -static bool endmap(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - print_data(p, "}", 1); - p->depth_--; - return true; -} - -static size_t putstr(void *closure, const void *handler_data, const char *str, - size_t len, const upb_bufhandle *handle) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(handle); - putstring(p, str, len); - return len; -} - -/* This has to Base64 encode the bytes, because JSON has no "bytes" type. */ -static size_t putbytes(void *closure, const void *handler_data, const char *str, - size_t len, const upb_bufhandle *handle) { - upb_json_printer *p = closure; - - /* This is the regular base64, not the "web-safe" version. */ - static const char base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - /* Base64-encode. */ - char data[16000]; - const char *limit = data + sizeof(data); - const unsigned char *from = (const unsigned char*)str; - char *to = data; - size_t remaining = len; - size_t bytes; - - UPB_UNUSED(handler_data); - UPB_UNUSED(handle); - - print_data(p, "\"", 1); - - while (remaining > 2) { - if (limit - to < 4) { - bytes = to - data; - putstring(p, data, bytes); - to = data; - } - - to[0] = base64[from[0] >> 2]; - to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)]; - to[2] = base64[((from[1] & 0xf) << 2) | (from[2] >> 6)]; - to[3] = base64[from[2] & 0x3f]; - - remaining -= 3; - to += 4; - from += 3; - } - - switch (remaining) { - case 2: - to[0] = base64[from[0] >> 2]; - to[1] = base64[((from[0] & 0x3) << 4) | (from[1] >> 4)]; - to[2] = base64[(from[1] & 0xf) << 2]; - to[3] = '='; - to += 4; - from += 2; - break; - case 1: - to[0] = base64[from[0] >> 2]; - to[1] = base64[((from[0] & 0x3) << 4)]; - to[2] = '='; - to[3] = '='; - to += 4; - from += 1; - break; - } - - bytes = to - data; - putstring(p, data, bytes); - print_data(p, "\"", 1); - return len; -} - -static void *scalar_startstr(void *closure, const void *handler_data, - size_t size_hint) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(size_hint); - CHK(putkey(closure, handler_data)); - print_data(p, "\"", 1); - return p; -} - -static size_t scalar_str(void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - CHK(putstr(closure, handler_data, str, len, handle)); - return len; -} - -static bool scalar_endstr(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - print_data(p, "\"", 1); - return true; -} - -static void *repeated_startstr(void *closure, const void *handler_data, - size_t size_hint) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(size_hint); - print_comma(p); - print_data(p, "\"", 1); - return p; -} - -static size_t repeated_str(void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - CHK(putstr(closure, handler_data, str, len, handle)); - return len; -} - -static bool repeated_endstr(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - print_data(p, "\"", 1); - return true; -} - -static void *mapkeyval_startstr(void *closure, const void *handler_data, - size_t size_hint) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(size_hint); - print_data(p, "\"", 1); - return p; -} - -static size_t mapkey_str(void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - CHK(putstr(closure, handler_data, str, len, handle)); - return len; -} - -static bool mapkey_endstr(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - print_data(p, "\":", 2); - return true; -} - -static bool mapvalue_endstr(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - print_data(p, "\"", 1); - return true; -} - -static size_t scalar_bytes(void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - CHK(putkey(closure, handler_data)); - CHK(putbytes(closure, handler_data, str, len, handle)); - return len; -} - -static size_t repeated_bytes(void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - upb_json_printer *p = closure; - print_comma(p); - CHK(putbytes(closure, handler_data, str, len, handle)); - return len; -} - -static size_t mapkey_bytes(void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - upb_json_printer *p = closure; - CHK(putbytes(closure, handler_data, str, len, handle)); - print_data(p, ":", 1); - return len; -} - -static void set_enum_hd(upb_handlers *h, - const upb_fielddef *f, - bool preserve_fieldnames, - upb_handlerattr *attr) { - EnumHandlerData *hd = upb_gmalloc(sizeof(EnumHandlerData)); - hd->enumdef = upb_fielddef_enumsubdef(f); - hd->keyname = newstrpc(h, f, preserve_fieldnames); - upb_handlers_addcleanup(h, hd, upb_gfree); - attr->handler_data = hd; -} - -/* Set up handlers for a mapentry submessage (i.e., an individual key/value pair - * in a map). - * - * TODO: Handle missing key, missing value, out-of-order key/value, or repeated - * key or value cases properly. The right way to do this is to allocate a - * temporary structure at the start of a mapentry submessage, store key and - * value data in it as key and value handlers are called, and then print the - * key/value pair once at the end of the submessage. If we don't do this, we - * should at least detect the case and throw an error. However, so far all of - * our sources that emit mapentry messages do so canonically (with one key - * field, and then one value field), so this is not a pressing concern at the - * moment. */ -void printer_sethandlers_mapentry(const void *closure, bool preserve_fieldnames, - upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - - /* A mapentry message is printed simply as '"key": value'. Rather than - * special-case key and value for every type below, we just handle both - * fields explicitly here. */ - const upb_fielddef* key_field = upb_msgdef_itof(md, UPB_MAPENTRY_KEY); - const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_MAPENTRY_VALUE); - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - UPB_UNUSED(closure); - - switch (upb_fielddef_type(key_field)) { - case UPB_TYPE_INT32: - upb_handlers_setint32(h, key_field, putmapkey_int32_t, &empty_attr); - break; - case UPB_TYPE_INT64: - upb_handlers_setint64(h, key_field, putmapkey_int64_t, &empty_attr); - break; - case UPB_TYPE_UINT32: - upb_handlers_setuint32(h, key_field, putmapkey_uint32_t, &empty_attr); - break; - case UPB_TYPE_UINT64: - upb_handlers_setuint64(h, key_field, putmapkey_uint64_t, &empty_attr); - break; - case UPB_TYPE_BOOL: - upb_handlers_setbool(h, key_field, putmapkey_bool, &empty_attr); - break; - case UPB_TYPE_STRING: - upb_handlers_setstartstr(h, key_field, mapkeyval_startstr, &empty_attr); - upb_handlers_setstring(h, key_field, mapkey_str, &empty_attr); - upb_handlers_setendstr(h, key_field, mapkey_endstr, &empty_attr); - break; - case UPB_TYPE_BYTES: - upb_handlers_setstring(h, key_field, mapkey_bytes, &empty_attr); - break; - default: - UPB_ASSERT(false); - break; - } - - switch (upb_fielddef_type(value_field)) { - case UPB_TYPE_INT32: - upb_handlers_setint32(h, value_field, putint32_t, &empty_attr); - break; - case UPB_TYPE_INT64: - upb_handlers_setint64(h, value_field, putint64_t, &empty_attr); - break; - case UPB_TYPE_UINT32: - upb_handlers_setuint32(h, value_field, putuint32_t, &empty_attr); - break; - case UPB_TYPE_UINT64: - upb_handlers_setuint64(h, value_field, putuint64_t, &empty_attr); - break; - case UPB_TYPE_BOOL: - upb_handlers_setbool(h, value_field, putbool, &empty_attr); - break; - case UPB_TYPE_FLOAT: - upb_handlers_setfloat(h, value_field, putfloat, &empty_attr); - break; - case UPB_TYPE_DOUBLE: - upb_handlers_setdouble(h, value_field, putdouble, &empty_attr); - break; - case UPB_TYPE_STRING: - upb_handlers_setstartstr(h, value_field, mapkeyval_startstr, &empty_attr); - upb_handlers_setstring(h, value_field, putstr, &empty_attr); - upb_handlers_setendstr(h, value_field, mapvalue_endstr, &empty_attr); - break; - case UPB_TYPE_BYTES: - upb_handlers_setstring(h, value_field, putbytes, &empty_attr); - break; - case UPB_TYPE_ENUM: { - upb_handlerattr enum_attr = UPB_HANDLERATTR_INIT; - set_enum_hd(h, value_field, preserve_fieldnames, &enum_attr); - upb_handlers_setint32(h, value_field, mapvalue_enum, &enum_attr); - break; - } - case UPB_TYPE_MESSAGE: - /* No handler necessary -- the submsg handlers will print the message - * as appropriate. */ - break; - } -} - -static bool putseconds(void *closure, const void *handler_data, - int64_t seconds) { - upb_json_printer *p = closure; - p->seconds = seconds; - UPB_UNUSED(handler_data); - return true; -} - -static bool putnanos(void *closure, const void *handler_data, - int32_t nanos) { - upb_json_printer *p = closure; - p->nanos = nanos; - UPB_UNUSED(handler_data); - return true; -} - -static void *scalar_startstr_nokey(void *closure, const void *handler_data, - size_t size_hint) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(size_hint); - print_data(p, "\"", 1); - return p; -} - -static size_t putstr_nokey(void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(handle); - print_data(p, "\"", 1); - putstring(p, str, len); - print_data(p, "\"", 1); - return len + 2; -} - -static void *startseq_nokey(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - p->depth_++; - p->first_elem_[p->depth_] = true; - print_data(p, "[", 1); - return closure; -} - -static void *startseq_fieldmask(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - p->depth_++; - p->first_elem_[p->depth_] = true; - return closure; -} - -static bool endseq_fieldmask(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - p->depth_--; - return true; -} - -static void *repeated_startstr_fieldmask( - void *closure, const void *handler_data, - size_t size_hint) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(size_hint); - print_comma(p); - return p; -} - -static size_t repeated_str_fieldmask( - void *closure, const void *handler_data, - const char *str, size_t len, - const upb_bufhandle *handle) { - const char* limit = str + len; - bool upper = false; - size_t result_len = 0; - for (; str < limit; str++) { - if (*str == '_') { - upper = true; - continue; - } - if (upper && *str >= 'a' && *str <= 'z') { - char upper_char = toupper(*str); - CHK(putstr(closure, handler_data, &upper_char, 1, handle)); - } else { - CHK(putstr(closure, handler_data, str, 1, handle)); - } - upper = false; - result_len++; - } - return result_len; -} - -static void *startmap_nokey(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - p->depth_++; - p->first_elem_[p->depth_] = true; - print_data(p, "{", 1); - return closure; -} - -static bool putnull(void *closure, const void *handler_data, - int32_t null) { - upb_json_printer *p = closure; - print_data(p, "null", 4); - UPB_UNUSED(handler_data); - UPB_UNUSED(null); - return true; -} - -static bool printer_startdurationmsg(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - if (p->depth_ == 0) { - upb_bytessink_start(p->output_, 0, &p->subc_); - } - return true; -} - -#define UPB_DURATION_MAX_JSON_LEN 23 -#define UPB_DURATION_MAX_NANO_LEN 9 - -static bool printer_enddurationmsg(void *closure, const void *handler_data, - upb_status *s) { - upb_json_printer *p = closure; - char buffer[UPB_DURATION_MAX_JSON_LEN]; - size_t base_len; - size_t curr; - size_t i; - - memset(buffer, 0, UPB_DURATION_MAX_JSON_LEN); - - if (p->seconds < -315576000000) { - upb_status_seterrf(s, "error parsing duration: " - "minimum acceptable value is " - "-315576000000"); - return false; - } - - if (p->seconds > 315576000000) { - upb_status_seterrf(s, "error serializing duration: " - "maximum acceptable value is " - "315576000000"); - return false; - } - - _upb_snprintf(buffer, sizeof(buffer), "%ld", (long)p->seconds); - base_len = strlen(buffer); - - if (p->nanos != 0) { - char nanos_buffer[UPB_DURATION_MAX_NANO_LEN + 3]; - _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f", - p->nanos / 1000000000.0); - /* Remove trailing 0. */ - for (i = UPB_DURATION_MAX_NANO_LEN + 2; - nanos_buffer[i] == '0'; i--) { - nanos_buffer[i] = 0; - } - strcpy(buffer + base_len, nanos_buffer + 1); - } - - curr = strlen(buffer); - strcpy(buffer + curr, "s"); - - p->seconds = 0; - p->nanos = 0; - - print_data(p, "\"", 1); - print_data(p, buffer, strlen(buffer)); - print_data(p, "\"", 1); - - if (p->depth_ == 0) { - upb_bytessink_end(p->output_); - } - - UPB_UNUSED(handler_data); - return true; -} - -static bool printer_starttimestampmsg(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - if (p->depth_ == 0) { - upb_bytessink_start(p->output_, 0, &p->subc_); - } - return true; -} - -#define UPB_TIMESTAMP_MAX_JSON_LEN 31 -#define UPB_TIMESTAMP_BEFORE_NANO_LEN 19 -#define UPB_TIMESTAMP_MAX_NANO_LEN 9 - -static bool printer_endtimestampmsg(void *closure, const void *handler_data, - upb_status *s) { - upb_json_printer *p = closure; - char buffer[UPB_TIMESTAMP_MAX_JSON_LEN]; - time_t time = p->seconds; - size_t curr; - size_t i; - size_t year_length = - strftime(buffer, UPB_TIMESTAMP_MAX_JSON_LEN, "%Y", gmtime(&time)); - - if (p->seconds < -62135596800) { - upb_status_seterrf(s, "error parsing timestamp: " - "minimum acceptable value is " - "0001-01-01T00:00:00Z"); - return false; - } - - if (p->seconds > 253402300799) { - upb_status_seterrf(s, "error parsing timestamp: " - "maximum acceptable value is " - "9999-12-31T23:59:59Z"); - return false; - } - - /* strftime doesn't guarantee 4 digits for year. Prepend 0 by ourselves. */ - for (i = 0; i < 4 - year_length; i++) { - buffer[i] = '0'; - } - - strftime(buffer + (4 - year_length), UPB_TIMESTAMP_MAX_JSON_LEN, - "%Y-%m-%dT%H:%M:%S", gmtime(&time)); - if (p->nanos != 0) { - char nanos_buffer[UPB_TIMESTAMP_MAX_NANO_LEN + 3]; - _upb_snprintf(nanos_buffer, sizeof(nanos_buffer), "%.9f", - p->nanos / 1000000000.0); - /* Remove trailing 0. */ - for (i = UPB_TIMESTAMP_MAX_NANO_LEN + 2; - nanos_buffer[i] == '0'; i--) { - nanos_buffer[i] = 0; - } - strcpy(buffer + UPB_TIMESTAMP_BEFORE_NANO_LEN, nanos_buffer + 1); - } - - curr = strlen(buffer); - strcpy(buffer + curr, "Z"); - - p->seconds = 0; - p->nanos = 0; - - print_data(p, "\"", 1); - print_data(p, buffer, strlen(buffer)); - print_data(p, "\"", 1); - - if (p->depth_ == 0) { - upb_bytessink_end(p->output_); - } - - UPB_UNUSED(handler_data); - UPB_UNUSED(s); - return true; -} - -static bool printer_startmsg_noframe(void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - if (p->depth_ == 0) { - upb_bytessink_start(p->output_, 0, &p->subc_); - } - return true; -} - -static bool printer_endmsg_noframe( - void *closure, const void *handler_data, upb_status *s) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(s); - if (p->depth_ == 0) { - upb_bytessink_end(p->output_); - } - return true; -} - -static bool printer_startmsg_fieldmask( - void *closure, const void *handler_data) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - if (p->depth_ == 0) { - upb_bytessink_start(p->output_, 0, &p->subc_); - } - print_data(p, "\"", 1); - return true; -} - -static bool printer_endmsg_fieldmask( - void *closure, const void *handler_data, upb_status *s) { - upb_json_printer *p = closure; - UPB_UNUSED(handler_data); - UPB_UNUSED(s); - print_data(p, "\"", 1); - if (p->depth_ == 0) { - upb_bytessink_end(p->output_); - } - return true; -} - -static void *scalar_startstr_onlykey( - void *closure, const void *handler_data, size_t size_hint) { - upb_json_printer *p = closure; - UPB_UNUSED(size_hint); - CHK(putkey(closure, handler_data)); - return p; -} - -/* Set up handlers for an Any submessage. */ -void printer_sethandlers_any(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - - const upb_fielddef* type_field = upb_msgdef_itof(md, UPB_ANY_TYPE); - const upb_fielddef* value_field = upb_msgdef_itof(md, UPB_ANY_VALUE); - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - /* type_url's json name is "@type" */ - upb_handlerattr type_name_attr = UPB_HANDLERATTR_INIT; - upb_handlerattr value_name_attr = UPB_HANDLERATTR_INIT; - strpc *type_url_json_name = newstrpc_str(h, "@type"); - strpc *value_json_name = newstrpc_str(h, "value"); - - type_name_attr.handler_data = type_url_json_name; - value_name_attr.handler_data = value_json_name; - - /* Set up handlers. */ - upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr); - upb_handlers_setendmsg(h, printer_endmsg, &empty_attr); - - upb_handlers_setstartstr(h, type_field, scalar_startstr, &type_name_attr); - upb_handlers_setstring(h, type_field, scalar_str, &empty_attr); - upb_handlers_setendstr(h, type_field, scalar_endstr, &empty_attr); - - /* This is not the full and correct JSON encoding for the Any value field. It - * requires further processing by the wrapper code based on the type URL. - */ - upb_handlers_setstartstr(h, value_field, scalar_startstr_onlykey, - &value_name_attr); - - UPB_UNUSED(closure); -} - -/* Set up handlers for a fieldmask submessage. */ -void printer_sethandlers_fieldmask(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - const upb_fielddef* f = upb_msgdef_itof(md, 1); - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - upb_handlers_setstartseq(h, f, startseq_fieldmask, &empty_attr); - upb_handlers_setendseq(h, f, endseq_fieldmask, &empty_attr); - - upb_handlers_setstartmsg(h, printer_startmsg_fieldmask, &empty_attr); - upb_handlers_setendmsg(h, printer_endmsg_fieldmask, &empty_attr); - - upb_handlers_setstartstr(h, f, repeated_startstr_fieldmask, &empty_attr); - upb_handlers_setstring(h, f, repeated_str_fieldmask, &empty_attr); - - UPB_UNUSED(closure); -} - -/* Set up handlers for a duration submessage. */ -void printer_sethandlers_duration(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - - const upb_fielddef* seconds_field = - upb_msgdef_itof(md, UPB_DURATION_SECONDS); - const upb_fielddef* nanos_field = - upb_msgdef_itof(md, UPB_DURATION_NANOS); - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - upb_handlers_setstartmsg(h, printer_startdurationmsg, &empty_attr); - upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr); - upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr); - upb_handlers_setendmsg(h, printer_enddurationmsg, &empty_attr); - - UPB_UNUSED(closure); -} - -/* Set up handlers for a timestamp submessage. Instead of printing fields - * separately, the json representation of timestamp follows RFC 3339 */ -void printer_sethandlers_timestamp(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - - const upb_fielddef* seconds_field = - upb_msgdef_itof(md, UPB_TIMESTAMP_SECONDS); - const upb_fielddef* nanos_field = - upb_msgdef_itof(md, UPB_TIMESTAMP_NANOS); - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - upb_handlers_setstartmsg(h, printer_starttimestampmsg, &empty_attr); - upb_handlers_setint64(h, seconds_field, putseconds, &empty_attr); - upb_handlers_setint32(h, nanos_field, putnanos, &empty_attr); - upb_handlers_setendmsg(h, printer_endtimestampmsg, &empty_attr); - - UPB_UNUSED(closure); -} - -void printer_sethandlers_value(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - upb_msg_field_iter i; - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); - upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); - - upb_msg_field_begin(&i, md); - for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) { - const upb_fielddef *f = upb_msg_iter_field(&i); - - switch (upb_fielddef_type(f)) { - case UPB_TYPE_ENUM: - upb_handlers_setint32(h, f, putnull, &empty_attr); - break; - case UPB_TYPE_DOUBLE: - upb_handlers_setdouble(h, f, putdouble, &empty_attr); - break; - case UPB_TYPE_STRING: - upb_handlers_setstartstr(h, f, scalar_startstr_nokey, &empty_attr); - upb_handlers_setstring(h, f, scalar_str, &empty_attr); - upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr); - break; - case UPB_TYPE_BOOL: - upb_handlers_setbool(h, f, putbool, &empty_attr); - break; - case UPB_TYPE_MESSAGE: - break; - default: - UPB_ASSERT(false); - break; - } - } - - UPB_UNUSED(closure); -} - -#define WRAPPER_SETHANDLERS(wrapper, type, putmethod) \ -void printer_sethandlers_##wrapper(const void *closure, upb_handlers *h) { \ - const upb_msgdef *md = upb_handlers_msgdef(h); \ - const upb_fielddef* f = upb_msgdef_itof(md, 1); \ - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; \ - upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); \ - upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); \ - upb_handlers_set##type(h, f, putmethod, &empty_attr); \ - UPB_UNUSED(closure); \ -} - -WRAPPER_SETHANDLERS(doublevalue, double, putdouble) -WRAPPER_SETHANDLERS(floatvalue, float, putfloat) -WRAPPER_SETHANDLERS(int64value, int64, putint64_t) -WRAPPER_SETHANDLERS(uint64value, uint64, putuint64_t) -WRAPPER_SETHANDLERS(int32value, int32, putint32_t) -WRAPPER_SETHANDLERS(uint32value, uint32, putuint32_t) -WRAPPER_SETHANDLERS(boolvalue, bool, putbool) -WRAPPER_SETHANDLERS(stringvalue, string, putstr_nokey) -WRAPPER_SETHANDLERS(bytesvalue, string, putbytes) - -#undef WRAPPER_SETHANDLERS - -void printer_sethandlers_listvalue(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - const upb_fielddef* f = upb_msgdef_itof(md, 1); - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - upb_handlers_setstartseq(h, f, startseq_nokey, &empty_attr); - upb_handlers_setendseq(h, f, endseq, &empty_attr); - - upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); - upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); - - upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr); - - UPB_UNUSED(closure); -} - -void printer_sethandlers_structvalue(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - const upb_fielddef* f = upb_msgdef_itof(md, 1); - - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - - upb_handlers_setstartseq(h, f, startmap_nokey, &empty_attr); - upb_handlers_setendseq(h, f, endmap, &empty_attr); - - upb_handlers_setstartmsg(h, printer_startmsg_noframe, &empty_attr); - upb_handlers_setendmsg(h, printer_endmsg_noframe, &empty_attr); - - upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &empty_attr); - - UPB_UNUSED(closure); -} - -void printer_sethandlers(const void *closure, upb_handlers *h) { - const upb_msgdef *md = upb_handlers_msgdef(h); - bool is_mapentry = upb_msgdef_mapentry(md); - upb_handlerattr empty_attr = UPB_HANDLERATTR_INIT; - upb_msg_field_iter i; - const upb_json_printercache *cache = closure; - const bool preserve_fieldnames = cache->preserve_fieldnames; - - if (is_mapentry) { - /* mapentry messages are sufficiently different that we handle them - * separately. */ - printer_sethandlers_mapentry(closure, preserve_fieldnames, h); - return; - } - - switch (upb_msgdef_wellknowntype(md)) { - case UPB_WELLKNOWN_UNSPECIFIED: - break; - case UPB_WELLKNOWN_ANY: - printer_sethandlers_any(closure, h); - return; - case UPB_WELLKNOWN_FIELDMASK: - printer_sethandlers_fieldmask(closure, h); - return; - case UPB_WELLKNOWN_DURATION: - printer_sethandlers_duration(closure, h); - return; - case UPB_WELLKNOWN_TIMESTAMP: - printer_sethandlers_timestamp(closure, h); - return; - case UPB_WELLKNOWN_VALUE: - printer_sethandlers_value(closure, h); - return; - case UPB_WELLKNOWN_LISTVALUE: - printer_sethandlers_listvalue(closure, h); - return; - case UPB_WELLKNOWN_STRUCT: - printer_sethandlers_structvalue(closure, h); - return; -#define WRAPPER(wellknowntype, name) \ - case wellknowntype: \ - printer_sethandlers_##name(closure, h); \ - return; \ - - WRAPPER(UPB_WELLKNOWN_DOUBLEVALUE, doublevalue); - WRAPPER(UPB_WELLKNOWN_FLOATVALUE, floatvalue); - WRAPPER(UPB_WELLKNOWN_INT64VALUE, int64value); - WRAPPER(UPB_WELLKNOWN_UINT64VALUE, uint64value); - WRAPPER(UPB_WELLKNOWN_INT32VALUE, int32value); - WRAPPER(UPB_WELLKNOWN_UINT32VALUE, uint32value); - WRAPPER(UPB_WELLKNOWN_BOOLVALUE, boolvalue); - WRAPPER(UPB_WELLKNOWN_STRINGVALUE, stringvalue); - WRAPPER(UPB_WELLKNOWN_BYTESVALUE, bytesvalue); - -#undef WRAPPER - } - - upb_handlers_setstartmsg(h, printer_startmsg, &empty_attr); - upb_handlers_setendmsg(h, printer_endmsg, &empty_attr); - -#define TYPE(type, name, ctype) \ - case type: \ - if (upb_fielddef_isseq(f)) { \ - upb_handlers_set##name(h, f, repeated_##ctype, &empty_attr); \ - } else { \ - upb_handlers_set##name(h, f, scalar_##ctype, &name_attr); \ - } \ - break; - - upb_msg_field_begin(&i, md); - for(; !upb_msg_field_done(&i); upb_msg_field_next(&i)) { - const upb_fielddef *f = upb_msg_iter_field(&i); - - upb_handlerattr name_attr = UPB_HANDLERATTR_INIT; - name_attr.handler_data = newstrpc(h, f, preserve_fieldnames); - - if (upb_fielddef_ismap(f)) { - upb_handlers_setstartseq(h, f, startmap, &name_attr); - upb_handlers_setendseq(h, f, endmap, &name_attr); - } else if (upb_fielddef_isseq(f)) { - upb_handlers_setstartseq(h, f, startseq, &name_attr); - upb_handlers_setendseq(h, f, endseq, &empty_attr); - } - - switch (upb_fielddef_type(f)) { - TYPE(UPB_TYPE_FLOAT, float, float); - TYPE(UPB_TYPE_DOUBLE, double, double); - TYPE(UPB_TYPE_BOOL, bool, bool); - TYPE(UPB_TYPE_INT32, int32, int32_t); - TYPE(UPB_TYPE_UINT32, uint32, uint32_t); - TYPE(UPB_TYPE_INT64, int64, int64_t); - TYPE(UPB_TYPE_UINT64, uint64, uint64_t); - case UPB_TYPE_ENUM: { - /* For now, we always emit symbolic names for enums. We may want an - * option later to control this behavior, but we will wait for a real - * need first. */ - upb_handlerattr enum_attr = UPB_HANDLERATTR_INIT; - set_enum_hd(h, f, preserve_fieldnames, &enum_attr); - - if (upb_fielddef_isseq(f)) { - upb_handlers_setint32(h, f, repeated_enum, &enum_attr); - } else { - upb_handlers_setint32(h, f, scalar_enum, &enum_attr); - } - - break; - } - case UPB_TYPE_STRING: - if (upb_fielddef_isseq(f)) { - upb_handlers_setstartstr(h, f, repeated_startstr, &empty_attr); - upb_handlers_setstring(h, f, repeated_str, &empty_attr); - upb_handlers_setendstr(h, f, repeated_endstr, &empty_attr); - } else { - upb_handlers_setstartstr(h, f, scalar_startstr, &name_attr); - upb_handlers_setstring(h, f, scalar_str, &empty_attr); - upb_handlers_setendstr(h, f, scalar_endstr, &empty_attr); - } - break; - case UPB_TYPE_BYTES: - /* XXX: this doesn't support strings that span buffers yet. The base64 - * encoder will need to be made resumable for this to work properly. */ - if (upb_fielddef_isseq(f)) { - upb_handlers_setstring(h, f, repeated_bytes, &empty_attr); - } else { - upb_handlers_setstring(h, f, scalar_bytes, &name_attr); - } - break; - case UPB_TYPE_MESSAGE: - if (upb_fielddef_isseq(f)) { - upb_handlers_setstartsubmsg(h, f, repeated_startsubmsg, &name_attr); - } else { - upb_handlers_setstartsubmsg(h, f, scalar_startsubmsg, &name_attr); - } - break; - } - } - -#undef TYPE -} - -static void json_printer_reset(upb_json_printer *p) { - p->depth_ = 0; -} - - -/* Public API *****************************************************************/ - -upb_json_printer *upb_json_printer_create(upb_arena *a, const upb_handlers *h, - upb_bytessink output) { -#ifndef NDEBUG - size_t size_before = upb_arena_bytesallocated(a); -#endif - - upb_json_printer *p = upb_arena_malloc(a, sizeof(upb_json_printer)); - if (!p) return NULL; - - p->output_ = output; - json_printer_reset(p); - upb_sink_reset(&p->input_, h, p); - p->seconds = 0; - p->nanos = 0; - - /* If this fails, increase the value in printer.h. */ - UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(a) - size_before <= - UPB_JSON_PRINTER_SIZE); - return p; -} - -upb_sink upb_json_printer_input(upb_json_printer *p) { - return p->input_; -} - -upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames) { - upb_json_printercache *cache = upb_gmalloc(sizeof(*cache)); - upb_handlercache *ret = upb_handlercache_new(printer_sethandlers, cache); - - cache->preserve_fieldnames = preserve_proto_fieldnames; - upb_handlercache_addcleanup(ret, cache, upb_gfree); - - return ret; -} -/* See port_def.inc. This should #undef all macros #defined there. */ - -#undef UPB_SIZE -#undef UPB_FIELD_AT -#undef UPB_READ_ONEOF -#undef UPB_WRITE_ONEOF -#undef UPB_INLINE -#undef UPB_FORCEINLINE -#undef UPB_NOINLINE -#undef UPB_NORETURN -#undef UPB_MAX -#undef UPB_MIN -#undef UPB_UNUSED -#undef UPB_ASSERT -#undef UPB_ASSERT_DEBUGVAR -#undef UPB_UNREACHABLE -#undef UPB_INFINITY -#undef UPB_MSVC_VSNPRINTF -#undef _upb_snprintf -#undef _upb_vsnprintf -#undef _upb_va_copy diff --git a/php/ext/google/protobuf/upb.h b/php/ext/google/protobuf/upb.h deleted file mode 100644 index 6746476c2969..000000000000 --- a/php/ext/google/protobuf/upb.h +++ /dev/null @@ -1,7095 +0,0 @@ -/* Amalgamated source file */ - -// php.h intentionally defined NDEBUG. We have to define this macro in order to -// be used together with php.h -#ifndef NDEBUG -#define NDEBUG -#endif - -#include /* -* This is where we define macros used across upb. -* -* All of these macros are undef'd in port_undef.inc to avoid leaking them to -* users. -* -* The correct usage is: -* -* #include "upb/foobar.h" -* #include "upb/baz.h" -* -* // MUST be last included header. -* #include "upb/port_def.inc" -* -* // Code for this file. -* // <...> -* -* // Can be omitted for .c files, required for .h. -* #include "upb/port_undef.inc" -* -* This file is private and must not be included by users! -*/ -#ifndef UINTPTR_MAX -#error must include stdint.h first -#endif - -#if UINTPTR_MAX == 0xffffffff -#define UPB_SIZE(size32, size64) size32 -#else -#define UPB_SIZE(size32, size64) size64 -#endif - -#define UPB_FIELD_AT(msg, fieldtype, offset) \ - *(fieldtype*)((const char*)(msg) + offset) - -#define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ - UPB_FIELD_AT(msg, int, case_offset) == case_val \ - ? UPB_FIELD_AT(msg, fieldtype, offset) \ - : default - -#define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ - UPB_FIELD_AT(msg, int, case_offset) = case_val; \ - UPB_FIELD_AT(msg, fieldtype, offset) = value; - -/* UPB_INLINE: inline if possible, emit standalone code if required. */ -#ifdef __cplusplus -#define UPB_INLINE inline -#elif defined (__GNUC__) || defined(__clang__) -#define UPB_INLINE static __inline__ -#else -#define UPB_INLINE static -#endif - -/* Hints to the compiler about likely/unlikely branches. */ -#if defined (__GNUC__) || defined(__clang__) -#define UPB_LIKELY(x) __builtin_expect((x),1) -#define UPB_UNLIKELY(x) __builtin_expect((x),0) -#else -#define UPB_LIKELY(x) (x) -#define UPB_UNLIKELY(x) (x) -#endif - -/* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler - * doesn't provide these preprocessor symbols. */ -#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define UPB_BIG_ENDIAN -#endif - -/* Macros for function attributes on compilers that support them. */ -#ifdef __GNUC__ -#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) -#define UPB_NOINLINE __attribute__((noinline)) -#define UPB_NORETURN __attribute__((__noreturn__)) -#else /* !defined(__GNUC__) */ -#define UPB_FORCEINLINE -#define UPB_NOINLINE -#define UPB_NORETURN -#endif - -#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L -/* C99/C++11 versions. */ -#include -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined(_MSC_VER) -/* Microsoft C/C++ versions. */ -#include -#include -#if _MSC_VER < 1900 -int msvc_snprintf(char* s, size_t n, const char* format, ...); -int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); -#define UPB_MSVC_VSNPRINTF -#define _upb_snprintf msvc_snprintf -#define _upb_vsnprintf msvc_vsnprintf -#else -#define _upb_snprintf snprintf -#define _upb_vsnprintf vsnprintf -#endif -#define _upb_va_copy(a, b) va_copy(a, b) -#elif defined __GNUC__ -/* A few hacky workarounds for functions not in C89. - * For internal use only! - * TODO(haberman): fix these by including our own implementations, or finding - * another workaround. - */ -#define _upb_snprintf __builtin_snprintf -#define _upb_vsnprintf __builtin_vsnprintf -#define _upb_va_copy(a, b) __va_copy(a, b) -#else -#error Need implementations of [v]snprintf and va_copy -#endif - -#ifdef __cplusplus -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ - (defined(_MSC_VER) && _MSC_VER >= 1900) -/* C++11 is present */ -#else -#error upb requires C++11 for C++ support -#endif -#endif - -#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) -#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) - -#define UPB_UNUSED(var) (void)var - -/* UPB_ASSERT(): in release mode, we use the expression without letting it be - * evaluated. This prevents "unused variable" warnings. */ -#ifdef NDEBUG -#define UPB_ASSERT(expr) do {} while (false && (expr)) -#else -#define UPB_ASSERT(expr) assert(expr) -#endif - -/* UPB_ASSERT_DEBUGVAR(): assert that uses functions or variables that only - * exist in debug mode. This turns into regular assert. */ -#define UPB_ASSERT_DEBUGVAR(expr) assert(expr) - -#if defined(__GNUC__) || defined(__clang__) -#define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0) -#else -#define UPB_UNREACHABLE() do { assert(0); } while(0) -#endif - -/* UPB_INFINITY representing floating-point positive infinity. */ -#include -#ifdef INFINITY -#define UPB_INFINITY INFINITY -#else -#define UPB_INFINITY (1.0 / 0.0) -#endif -/* -** This file contains shared definitions that are widely used across upb. -** -** This is a mixed C/C++ interface that offers a full API to both languages. -** See the top-level README for more information. -*/ - -#ifndef UPB_H_ -#define UPB_H_ - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -#include -namespace upb { -class Arena; -class Status; -template class InlinedArena; -} -#endif - - -/* upb_status *****************************************************************/ - -/* upb_status represents a success or failure status and error message. - * It owns no resources and allocates no memory, so it should work - * even in OOM situations. */ - -/* The maximum length of an error message before it will get truncated. */ -#define UPB_STATUS_MAX_MESSAGE 127 - -typedef struct { - bool ok; - char msg[UPB_STATUS_MAX_MESSAGE]; /* Error message; NULL-terminated. */ -} upb_status; - -#ifdef __cplusplus -extern "C" { -#endif - -const char *upb_status_errmsg(const upb_status *status); -bool upb_ok(const upb_status *status); - -/* Any of the functions that write to a status object allow status to be NULL, - * to support use cases where the function's caller does not care about the - * status message. */ -void upb_status_clear(upb_status *status); -void upb_status_seterrmsg(upb_status *status, const char *msg); -void upb_status_seterrf(upb_status *status, const char *fmt, ...); -void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args); - -UPB_INLINE void upb_status_setoom(upb_status *status) { - upb_status_seterrmsg(status, "out of memory"); -} - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::Status { - public: - Status() { upb_status_clear(&status_); } - - upb_status* ptr() { return &status_; } - - /* Returns true if there is no error. */ - bool ok() const { return upb_ok(&status_); } - - /* Guaranteed to be NULL-terminated. */ - const char *error_message() const { return upb_status_errmsg(&status_); } - - /* The error message will be truncated if it is longer than - * UPB_STATUS_MAX_MESSAGE-4. */ - void SetErrorMessage(const char *msg) { upb_status_seterrmsg(&status_, msg); } - void SetFormattedErrorMessage(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - upb_status_vseterrf(&status_, fmt, args); - va_end(args); - } - - /* Resets the status to a successful state with no message. */ - void Clear() { upb_status_clear(&status_); } - - private: - upb_status status_; -}; - -#endif /* __cplusplus */ - -/** upb_strview ************************************************************/ - -typedef struct { - const char *data; - size_t size; -} upb_strview; - -UPB_INLINE upb_strview upb_strview_make(const char *data, size_t size) { - upb_strview ret; - ret.data = data; - ret.size = size; - return ret; -} - -UPB_INLINE upb_strview upb_strview_makez(const char *data) { - return upb_strview_make(data, strlen(data)); -} - -UPB_INLINE bool upb_strview_eql(upb_strview a, upb_strview b) { - return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; -} - -#define UPB_STRVIEW_INIT(ptr, len) {ptr, len} - -#define UPB_STRVIEW_FORMAT "%.*s" -#define UPB_STRVIEW_ARGS(view) (int)(view).size, (view).data - -/** upb_alloc *****************************************************************/ - -/* A upb_alloc is a possibly-stateful allocator object. - * - * It could either be an arena allocator (which doesn't require individual - * free() calls) or a regular malloc() (which does). The client must therefore - * free memory unless it knows that the allocator is an arena allocator. */ - -struct upb_alloc; -typedef struct upb_alloc upb_alloc; - -/* A malloc()/free() function. - * If "size" is 0 then the function acts like free(), otherwise it acts like - * realloc(). Only "oldsize" bytes from a previous allocation are preserved. */ -typedef void *upb_alloc_func(upb_alloc *alloc, void *ptr, size_t oldsize, - size_t size); - -struct upb_alloc { - upb_alloc_func *func; -}; - -UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) { - UPB_ASSERT(alloc); - return alloc->func(alloc, NULL, 0, size); -} - -UPB_INLINE void *upb_realloc(upb_alloc *alloc, void *ptr, size_t oldsize, - size_t size) { - UPB_ASSERT(alloc); - return alloc->func(alloc, ptr, oldsize, size); -} - -UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr) { - assert(alloc); - alloc->func(alloc, ptr, 0, 0); -} - -/* The global allocator used by upb. Uses the standard malloc()/free(). */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern upb_alloc upb_alloc_global; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -/* Functions that hard-code the global malloc. - * - * We still get benefit because we can put custom logic into our global - * allocator, like injecting out-of-memory faults in debug/testing builds. */ - -UPB_INLINE void *upb_gmalloc(size_t size) { - return upb_malloc(&upb_alloc_global, size); -} - -UPB_INLINE void *upb_grealloc(void *ptr, size_t oldsize, size_t size) { - return upb_realloc(&upb_alloc_global, ptr, oldsize, size); -} - -UPB_INLINE void upb_gfree(void *ptr) { - upb_free(&upb_alloc_global, ptr); -} - -/* upb_arena ******************************************************************/ - -/* upb_arena is a specific allocator implementation that uses arena allocation. - * The user provides an allocator that will be used to allocate the underlying - * arena blocks. Arenas by nature do not require the individual allocations - * to be freed. However the Arena does allow users to register cleanup - * functions that will run when the arena is destroyed. - * - * A upb_arena is *not* thread-safe. - * - * You could write a thread-safe arena allocator that satisfies the - * upb_alloc interface, but it would not be as efficient for the - * single-threaded case. */ - -typedef void upb_cleanup_func(void *ud); - -struct upb_arena; -typedef struct upb_arena upb_arena; - -#ifdef __cplusplus -extern "C" { -#endif - -/* Creates an arena from the given initial block (if any -- n may be 0). - * Additional blocks will be allocated from |alloc|. If |alloc| is NULL, this - * is a fixed-size arena and cannot grow. */ -upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc); -void upb_arena_free(upb_arena *a); -bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func); -size_t upb_arena_bytesallocated(const upb_arena *a); - -UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; } - -/* Convenience wrappers around upb_alloc functions. */ - -UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { - return upb_malloc(upb_arena_alloc(a), size); -} - -UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, - size_t size) { - return upb_realloc(upb_arena_alloc(a), ptr, oldsize, size); -} - -UPB_INLINE upb_arena *upb_arena_new(void) { - return upb_arena_init(NULL, 0, &upb_alloc_global); -} - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::Arena { - public: - /* A simple arena with no initial memory block and the default allocator. */ - Arena() : ptr_(upb_arena_new(), upb_arena_free) {} - - upb_arena* ptr() { return ptr_.get(); } - - /* Allows this arena to be used as a generic allocator. - * - * The arena does not need free() calls so when using Arena as an allocator - * it is safe to skip them. However they are no-ops so there is no harm in - * calling free() either. */ - upb_alloc *allocator() { return upb_arena_alloc(ptr_.get()); } - - /* Add a cleanup function to run when the arena is destroyed. - * Returns false on out-of-memory. */ - bool AddCleanup(void *ud, upb_cleanup_func* func) { - return upb_arena_addcleanup(ptr_.get(), ud, func); - } - - /* Total number of bytes that have been allocated. It is undefined what - * Realloc() does to &arena_ counter. */ - size_t BytesAllocated() const { return upb_arena_bytesallocated(ptr_.get()); } - - private: - std::unique_ptr ptr_; -}; - -#endif - -/* upb::InlinedArena **********************************************************/ - -/* upb::InlinedArena seeds the arenas with a predefined amount of memory. No - * heap memory will be allocated until the initial block is exceeded. - * - * These types only exist in C++ */ - -#ifdef __cplusplus - -template class upb::InlinedArena : public upb::Arena { - public: - InlinedArena() : ptr_(upb_arena_new(&initial_block_, N, &upb_alloc_global)) {} - - upb_arena* ptr() { return ptr_.get(); } - - private: - InlinedArena(const InlinedArena*) = delete; - InlinedArena& operator=(const InlinedArena*) = delete; - - std::unique_ptr ptr_; - char initial_block_[N]; -}; - -#endif /* __cplusplus */ - -/* Constants ******************************************************************/ - -/* Generic function type. */ -typedef void upb_func(void); - -/* A list of types as they are encoded on-the-wire. */ -typedef enum { - UPB_WIRE_TYPE_VARINT = 0, - UPB_WIRE_TYPE_64BIT = 1, - UPB_WIRE_TYPE_DELIMITED = 2, - UPB_WIRE_TYPE_START_GROUP = 3, - UPB_WIRE_TYPE_END_GROUP = 4, - UPB_WIRE_TYPE_32BIT = 5 -} upb_wiretype_t; - -/* The types a field can have. Note that this list is not identical to the - * types defined in descriptor.proto, which gives INT32 and SINT32 separate - * types (we distinguish the two with the "integer encoding" enum below). */ -typedef enum { - /* Types stored in 1 byte. */ - UPB_TYPE_BOOL = 1, - /* Types stored in 4 bytes. */ - UPB_TYPE_FLOAT = 2, - UPB_TYPE_INT32 = 3, - UPB_TYPE_UINT32 = 4, - UPB_TYPE_ENUM = 5, /* Enum values are int32. */ - /* Types stored as pointers (probably 4 or 8 bytes). */ - UPB_TYPE_STRING = 6, - UPB_TYPE_BYTES = 7, - UPB_TYPE_MESSAGE = 8, - /* Types stored as 8 bytes. */ - UPB_TYPE_DOUBLE = 9, - UPB_TYPE_INT64 = 10, - UPB_TYPE_UINT64 = 11 -} upb_fieldtype_t; - -/* The repeated-ness of each field; this matches descriptor.proto. */ -typedef enum { - UPB_LABEL_OPTIONAL = 1, - UPB_LABEL_REQUIRED = 2, - UPB_LABEL_REPEATED = 3 -} upb_label_t; - -/* Descriptor types, as defined in descriptor.proto. */ -typedef enum { - UPB_DESCRIPTOR_TYPE_DOUBLE = 1, - UPB_DESCRIPTOR_TYPE_FLOAT = 2, - UPB_DESCRIPTOR_TYPE_INT64 = 3, - UPB_DESCRIPTOR_TYPE_UINT64 = 4, - UPB_DESCRIPTOR_TYPE_INT32 = 5, - UPB_DESCRIPTOR_TYPE_FIXED64 = 6, - UPB_DESCRIPTOR_TYPE_FIXED32 = 7, - UPB_DESCRIPTOR_TYPE_BOOL = 8, - UPB_DESCRIPTOR_TYPE_STRING = 9, - UPB_DESCRIPTOR_TYPE_GROUP = 10, - UPB_DESCRIPTOR_TYPE_MESSAGE = 11, - UPB_DESCRIPTOR_TYPE_BYTES = 12, - UPB_DESCRIPTOR_TYPE_UINT32 = 13, - UPB_DESCRIPTOR_TYPE_ENUM = 14, - UPB_DESCRIPTOR_TYPE_SFIXED32 = 15, - UPB_DESCRIPTOR_TYPE_SFIXED64 = 16, - UPB_DESCRIPTOR_TYPE_SINT32 = 17, - UPB_DESCRIPTOR_TYPE_SINT64 = 18 -} upb_descriptortype_t; - -extern const uint8_t upb_desctype_to_fieldtype[]; - - -#endif /* UPB_H_ */ -/* -** upb_decode: parsing into a upb_msg using a upb_msglayout. -*/ - -#ifndef UPB_DECODE_H_ -#define UPB_DECODE_H_ - -/* -** Data structures for message tables, used for parsing and serialization. -** This are much lighter-weight than full reflection, but they are do not -** have enough information to convert to text format, JSON, etc. -** -** The definitions in this file are internal to upb. -**/ - -#ifndef UPB_MSG_H_ -#define UPB_MSG_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void upb_msg; - -/** upb_msglayout *************************************************************/ - -/* upb_msglayout represents the memory layout of a given upb_msgdef. The - * members are public so generated code can initialize them, but users MUST NOT - * read or write any of its members. */ - -typedef struct { - uint32_t number; - uint16_t offset; - int16_t presence; /* If >0, hasbit_index+1. If <0, oneof_index+1. */ - uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */ - uint8_t descriptortype; - uint8_t label; -} upb_msglayout_field; - -typedef struct upb_msglayout { - const struct upb_msglayout *const* submsgs; - const upb_msglayout_field *fields; - /* Must be aligned to sizeof(void*). Doesn't include internal members like - * unknown fields, extension dict, pointer to msglayout, etc. */ - uint16_t size; - uint16_t field_count; - bool extendable; -} upb_msglayout; - -/** Message internal representation *******************************************/ - -/* Our internal representation for repeated fields. */ -typedef struct { - void *data; /* Each element is element_size. */ - size_t len; /* Measured in elements. */ - size_t size; /* Measured in elements. */ -} upb_array; - -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a); -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a); - -void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena); -const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); - -upb_array *upb_array_new(upb_arena *a); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_MSG_H_ */ - -#ifdef __cplusplus -extern "C" { -#endif - -bool upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_DECODE_H_ */ -/* -** upb_encode: parsing into a upb_msg using a upb_msglayout. -*/ - -#ifndef UPB_ENCODE_H_ -#define UPB_ENCODE_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena, - size_t *size); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_ENCODE_H_ */ -/* -** upb_table -** -** This header is INTERNAL-ONLY! Its interfaces are not public or stable! -** This file defines very fast int->upb_value (inttable) and string->upb_value -** (strtable) hash tables. -** -** The table uses chained scatter with Brent's variation (inspired by the Lua -** implementation of hash tables). The hash function for strings is Austin -** Appleby's "MurmurHash." -** -** The inttable uses uintptr_t as its key, which guarantees it can be used to -** store pointers or integers of at least 32 bits (upb isn't really useful on -** systems where sizeof(void*) < 4). -** -** The table must be homogenous (all values of the same type). In debug -** mode, we check this on insert and lookup. -*/ - -#ifndef UPB_TABLE_H_ -#define UPB_TABLE_H_ - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* upb_value ******************************************************************/ - -/* A tagged union (stored untagged inside the table) so that we can check that - * clients calling table accessors are correctly typed without having to have - * an explosion of accessors. */ -typedef enum { - UPB_CTYPE_INT32 = 1, - UPB_CTYPE_INT64 = 2, - UPB_CTYPE_UINT32 = 3, - UPB_CTYPE_UINT64 = 4, - UPB_CTYPE_BOOL = 5, - UPB_CTYPE_CSTR = 6, - UPB_CTYPE_PTR = 7, - UPB_CTYPE_CONSTPTR = 8, - UPB_CTYPE_FPTR = 9, - UPB_CTYPE_FLOAT = 10, - UPB_CTYPE_DOUBLE = 11 -} upb_ctype_t; - -typedef struct { - uint64_t val; -#ifndef NDEBUG - /* In debug mode we carry the value type around also so we can check accesses - * to be sure the right member is being read. */ - upb_ctype_t ctype; -#endif -} upb_value; - -#ifdef NDEBUG -#define SET_TYPE(dest, val) UPB_UNUSED(val) -#else -#define SET_TYPE(dest, val) dest = val -#endif - -/* Like strdup(), which isn't always available since it's not ANSI C. */ -char *upb_strdup(const char *s, upb_alloc *a); -/* Variant that works with a length-delimited rather than NULL-delimited string, - * as supported by strtable. */ -char *upb_strdup2(const char *s, size_t len, upb_alloc *a); - -UPB_INLINE char *upb_gstrdup(const char *s) { - return upb_strdup(s, &upb_alloc_global); -} - -UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val, - upb_ctype_t ctype) { - v->val = val; - SET_TYPE(v->ctype, ctype); -} - -UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) { - upb_value ret; - _upb_value_setval(&ret, val, ctype); - return ret; -} - -/* For each value ctype, define the following set of functions: - * - * // Get/set an int32 from a upb_value. - * int32_t upb_value_getint32(upb_value val); - * void upb_value_setint32(upb_value *val, int32_t cval); - * - * // Construct a new upb_value from an int32. - * upb_value upb_value_int32(int32_t val); */ -#define FUNCS(name, membername, type_t, converter, proto_type) \ - UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \ - val->val = (converter)cval; \ - SET_TYPE(val->ctype, proto_type); \ - } \ - UPB_INLINE upb_value upb_value_ ## name(type_t val) { \ - upb_value ret; \ - upb_value_set ## name(&ret, val); \ - return ret; \ - } \ - UPB_INLINE type_t upb_value_get ## name(upb_value val) { \ - UPB_ASSERT_DEBUGVAR(val.ctype == proto_type); \ - return (type_t)(converter)val.val; \ - } - -FUNCS(int32, int32, int32_t, int32_t, UPB_CTYPE_INT32) -FUNCS(int64, int64, int64_t, int64_t, UPB_CTYPE_INT64) -FUNCS(uint32, uint32, uint32_t, uint32_t, UPB_CTYPE_UINT32) -FUNCS(uint64, uint64, uint64_t, uint64_t, UPB_CTYPE_UINT64) -FUNCS(bool, _bool, bool, bool, UPB_CTYPE_BOOL) -FUNCS(cstr, cstr, char*, uintptr_t, UPB_CTYPE_CSTR) -FUNCS(ptr, ptr, void*, uintptr_t, UPB_CTYPE_PTR) -FUNCS(constptr, constptr, const void*, uintptr_t, UPB_CTYPE_CONSTPTR) -FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR) - -#undef FUNCS - -UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) { - memcpy(&val->val, &cval, sizeof(cval)); - SET_TYPE(val->ctype, UPB_CTYPE_FLOAT); -} - -UPB_INLINE void upb_value_setdouble(upb_value *val, double cval) { - memcpy(&val->val, &cval, sizeof(cval)); - SET_TYPE(val->ctype, UPB_CTYPE_DOUBLE); -} - -UPB_INLINE upb_value upb_value_float(float cval) { - upb_value ret; - upb_value_setfloat(&ret, cval); - return ret; -} - -UPB_INLINE upb_value upb_value_double(double cval) { - upb_value ret; - upb_value_setdouble(&ret, cval); - return ret; -} - -#undef SET_TYPE - - -/* upb_tabkey *****************************************************************/ - -/* Either: - * 1. an actual integer key, or - * 2. a pointer to a string prefixed by its uint32_t length, owned by us. - * - * ...depending on whether this is a string table or an int table. We would - * make this a union of those two types, but C89 doesn't support statically - * initializing a non-first union member. */ -typedef uintptr_t upb_tabkey; - -UPB_INLINE char *upb_tabstr(upb_tabkey key, uint32_t *len) { - char* mem = (char*)key; - if (len) memcpy(len, mem, sizeof(*len)); - return mem + sizeof(*len); -} - - -/* upb_tabval *****************************************************************/ - -typedef struct { - uint64_t val; -} upb_tabval; - -#define UPB_TABVALUE_EMPTY_INIT {-1} - - -/* upb_table ******************************************************************/ - -typedef struct _upb_tabent { - upb_tabkey key; - upb_tabval val; - - /* Internal chaining. This is const so we can create static initializers for - * tables. We cast away const sometimes, but *only* when the containing - * upb_table is known to be non-const. This requires a bit of care, but - * the subtlety is confined to table.c. */ - const struct _upb_tabent *next; -} upb_tabent; - -typedef struct { - size_t count; /* Number of entries in the hash part. */ - size_t mask; /* Mask to turn hash value -> bucket. */ - upb_ctype_t ctype; /* Type of all values. */ - uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */ - - /* Hash table entries. - * Making this const isn't entirely accurate; what we really want is for it to - * have the same const-ness as the table it's inside. But there's no way to - * declare that in C. So we have to make it const so that we can statically - * initialize const hash tables. Then we cast away const when we have to. - */ - const upb_tabent *entries; - -#ifndef NDEBUG - /* This table's allocator. We make the user pass it in to every relevant - * function and only use this to check it in debug mode. We do this solely - * to keep upb_table as small as possible. This might seem slightly paranoid - * but the plan is to use upb_table for all map fields and extension sets in - * a forthcoming message representation, so there could be a lot of these. - * If this turns out to be too annoying later, we can change it (since this - * is an internal-only header file). */ - upb_alloc *alloc; -#endif -} upb_table; - -typedef struct { - upb_table t; -} upb_strtable; - -typedef struct { - upb_table t; /* For entries that don't fit in the array part. */ - const upb_tabval *array; /* Array part of the table. See const note above. */ - size_t array_size; /* Array part size. */ - size_t array_count; /* Array part number of elements. */ -} upb_inttable; - -#define UPB_INTTABLE_INIT(count, mask, ctype, size_lg2, ent, a, asize, acount) \ - {UPB_TABLE_INIT(count, mask, ctype, size_lg2, ent), a, asize, acount} - -#define UPB_EMPTY_INTTABLE_INIT(ctype) \ - UPB_INTTABLE_INIT(0, 0, ctype, 0, NULL, NULL, 0, 0) - -#define UPB_ARRAY_EMPTYENT -1 - -UPB_INLINE size_t upb_table_size(const upb_table *t) { - if (t->size_lg2 == 0) - return 0; - else - return 1 << t->size_lg2; -} - -/* Internal-only functions, in .h file only out of necessity. */ -UPB_INLINE bool upb_tabent_isempty(const upb_tabent *e) { - return e->key == 0; -} - -/* Used by some of the unit tests for generic hashing functionality. */ -uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed); - -UPB_INLINE uintptr_t upb_intkey(uintptr_t key) { - return key; -} - -UPB_INLINE uint32_t upb_inthash(uintptr_t key) { - return (uint32_t)key; -} - -static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) { - return t->entries + (hash & t->mask); -} - -UPB_INLINE bool upb_arrhas(upb_tabval key) { - return key.val != (uint64_t)-1; -} - -/* Initialize and uninitialize a table, respectively. If memory allocation - * failed, false is returned that the table is uninitialized. */ -bool upb_inttable_init2(upb_inttable *table, upb_ctype_t ctype, upb_alloc *a); -bool upb_strtable_init2(upb_strtable *table, upb_ctype_t ctype, upb_alloc *a); -void upb_inttable_uninit2(upb_inttable *table, upb_alloc *a); -void upb_strtable_uninit2(upb_strtable *table, upb_alloc *a); - -UPB_INLINE bool upb_inttable_init(upb_inttable *table, upb_ctype_t ctype) { - return upb_inttable_init2(table, ctype, &upb_alloc_global); -} - -UPB_INLINE bool upb_strtable_init(upb_strtable *table, upb_ctype_t ctype) { - return upb_strtable_init2(table, ctype, &upb_alloc_global); -} - -UPB_INLINE void upb_inttable_uninit(upb_inttable *table) { - upb_inttable_uninit2(table, &upb_alloc_global); -} - -UPB_INLINE void upb_strtable_uninit(upb_strtable *table) { - upb_strtable_uninit2(table, &upb_alloc_global); -} - -/* Returns the number of values in the table. */ -size_t upb_inttable_count(const upb_inttable *t); -UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) { - return t->t.count; -} - -void upb_inttable_packedsize(const upb_inttable *t, size_t *size); -void upb_strtable_packedsize(const upb_strtable *t, size_t *size); -upb_inttable *upb_inttable_pack(const upb_inttable *t, void *p, size_t *ofs, - size_t size); -upb_strtable *upb_strtable_pack(const upb_strtable *t, void *p, size_t *ofs, - size_t size); - -/* Inserts the given key into the hashtable with the given value. The key must - * not already exist in the hash table. For string tables, the key must be - * NULL-terminated, and the table will make an internal copy of the key. - * Inttables must not insert a value of UINTPTR_MAX. - * - * If a table resize was required but memory allocation failed, false is - * returned and the table is unchanged. */ -bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, - upb_alloc *a); -bool upb_strtable_insert3(upb_strtable *t, const char *key, size_t len, - upb_value val, upb_alloc *a); - -UPB_INLINE bool upb_inttable_insert(upb_inttable *t, uintptr_t key, - upb_value val) { - return upb_inttable_insert2(t, key, val, &upb_alloc_global); -} - -UPB_INLINE bool upb_strtable_insert2(upb_strtable *t, const char *key, - size_t len, upb_value val) { - return upb_strtable_insert3(t, key, len, val, &upb_alloc_global); -} - -/* For NULL-terminated strings. */ -UPB_INLINE bool upb_strtable_insert(upb_strtable *t, const char *key, - upb_value val) { - return upb_strtable_insert2(t, key, strlen(key), val); -} - -/* Looks up key in this table, returning "true" if the key was found. - * If v is non-NULL, copies the value for this key into *v. */ -bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v); -bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, - upb_value *v); - -/* For NULL-terminated strings. */ -UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key, - upb_value *v) { - return upb_strtable_lookup2(t, key, strlen(key), v); -} - -/* Removes an item from the table. Returns true if the remove was successful, - * and stores the removed item in *val if non-NULL. */ -bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val); -bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, - upb_value *val, upb_alloc *alloc); - -UPB_INLINE bool upb_strtable_remove2(upb_strtable *t, const char *key, - size_t len, upb_value *val) { - return upb_strtable_remove3(t, key, len, val, &upb_alloc_global); -} - -/* For NULL-terminated strings. */ -UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key, - upb_value *v) { - return upb_strtable_remove2(t, key, strlen(key), v); -} - -/* Updates an existing entry in an inttable. If the entry does not exist, - * returns false and does nothing. Unlike insert/remove, this does not - * invalidate iterators. */ -bool upb_inttable_replace(upb_inttable *t, uintptr_t key, upb_value val); - -/* Handy routines for treating an inttable like a stack. May not be mixed with - * other insert/remove calls. */ -bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a); -upb_value upb_inttable_pop(upb_inttable *t); - -UPB_INLINE bool upb_inttable_push(upb_inttable *t, upb_value val) { - return upb_inttable_push2(t, val, &upb_alloc_global); -} - -/* Convenience routines for inttables with pointer keys. */ -bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, - upb_alloc *a); -bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val); -bool upb_inttable_lookupptr( - const upb_inttable *t, const void *key, upb_value *val); - -UPB_INLINE bool upb_inttable_insertptr(upb_inttable *t, const void *key, - upb_value val) { - return upb_inttable_insertptr2(t, key, val, &upb_alloc_global); -} - -/* Optimizes the table for the current set of entries, for both memory use and - * lookup time. Client should call this after all entries have been inserted; - * inserting more entries is legal, but will likely require a table resize. */ -void upb_inttable_compact2(upb_inttable *t, upb_alloc *a); - -UPB_INLINE void upb_inttable_compact(upb_inttable *t) { - upb_inttable_compact2(t, &upb_alloc_global); -} - -/* A special-case inlinable version of the lookup routine for 32-bit - * integers. */ -UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key, - upb_value *v) { - *v = upb_value_int32(0); /* Silence compiler warnings. */ - if (key < t->array_size) { - upb_tabval arrval = t->array[key]; - if (upb_arrhas(arrval)) { - _upb_value_setval(v, arrval.val, t->t.ctype); - return true; - } else { - return false; - } - } else { - const upb_tabent *e; - if (t->t.entries == NULL) return false; - for (e = upb_getentry(&t->t, upb_inthash(key)); true; e = e->next) { - if ((uint32_t)e->key == key) { - _upb_value_setval(v, e->val.val, t->t.ctype); - return true; - } - if (e->next == NULL) return false; - } - } -} - -/* Exposed for testing only. */ -bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a); - -/* Iterators ******************************************************************/ - -/* Iterators for int and string tables. We are subject to some kind of unusual - * design constraints: - * - * For high-level languages: - * - we must be able to guarantee that we don't crash or corrupt memory even if - * the program accesses an invalidated iterator. - * - * For C++11 range-based for: - * - iterators must be copyable - * - iterators must be comparable - * - it must be possible to construct an "end" value. - * - * Iteration order is undefined. - * - * Modifying the table invalidates iterators. upb_{str,int}table_done() is - * guaranteed to work even on an invalidated iterator, as long as the table it - * is iterating over has not been freed. Calling next() or accessing data from - * an invalidated iterator yields unspecified elements from the table, but it is - * guaranteed not to crash and to return real table elements (except when done() - * is true). */ - - -/* upb_strtable_iter **********************************************************/ - -/* upb_strtable_iter i; - * upb_strtable_begin(&i, t); - * for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { - * const char *key = upb_strtable_iter_key(&i); - * const upb_value val = upb_strtable_iter_value(&i); - * // ... - * } - */ - -typedef struct { - const upb_strtable *t; - size_t index; -} upb_strtable_iter; - -void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t); -void upb_strtable_next(upb_strtable_iter *i); -bool upb_strtable_done(const upb_strtable_iter *i); -const char *upb_strtable_iter_key(const upb_strtable_iter *i); -size_t upb_strtable_iter_keylength(const upb_strtable_iter *i); -upb_value upb_strtable_iter_value(const upb_strtable_iter *i); -void upb_strtable_iter_setdone(upb_strtable_iter *i); -bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, - const upb_strtable_iter *i2); - - -/* upb_inttable_iter **********************************************************/ - -/* upb_inttable_iter i; - * upb_inttable_begin(&i, t); - * for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - * uintptr_t key = upb_inttable_iter_key(&i); - * upb_value val = upb_inttable_iter_value(&i); - * // ... - * } - */ - -typedef struct { - const upb_inttable *t; - size_t index; - bool array_part; -} upb_inttable_iter; - -void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t); -void upb_inttable_next(upb_inttable_iter *i); -bool upb_inttable_done(const upb_inttable_iter *i); -uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i); -upb_value upb_inttable_iter_value(const upb_inttable_iter *i); -void upb_inttable_iter_setdone(upb_inttable_iter *i); -bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, - const upb_inttable_iter *i2); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_TABLE_H_ */ -/* 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_ - -/* -** Functions for use by generated code. These are not public and users must -** not call them directly. -*/ - -#ifndef UPB_GENERATED_UTIL_H_ -#define UPB_GENERATED_UTIL_H_ - -#include - - -#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) - -UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, - size_t *size) { - const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*); - if (arr) { - if (size) *size = arr->len; - return arr->data; - } else { - if (size) *size = 0; - return NULL; - } -} - -UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, - size_t *size) { - upb_array *arr = *PTR_AT(msg, ofs, upb_array*); - if (arr) { - if (size) *size = arr->len; - return arr->data; - } else { - if (size) *size = 0; - return NULL; - } -} - -/* TODO(haberman): this is a mess. It will improve when upb_array no longer - * carries reflective state (type, elem_size). */ -UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, - size_t elem_size, - upb_fieldtype_t type, - upb_arena *arena) { - upb_array *arr = *PTR_AT(msg, ofs, upb_array*); - - if (!arr) { - arr = upb_array_new(arena); - if (!arr) return NULL; - *PTR_AT(msg, ofs, upb_array*) = arr; - } - - if (size > arr->size) { - size_t new_size = UPB_MAX(arr->size, 4); - size_t old_bytes = arr->size * elem_size; - size_t new_bytes; - while (new_size < size) new_size *= 2; - new_bytes = new_size * elem_size; - arr->data = upb_arena_realloc(arena, arr->data, old_bytes, new_bytes); - if (!arr->data) { - return NULL; - } - arr->size = new_size; - } - - arr->len = size; - return arr->data; -} - -UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs, - size_t elem_size, - upb_fieldtype_t type, - const void *value, - upb_arena *arena) { - upb_array *arr = *PTR_AT(msg, ofs, upb_array*); - size_t i = arr ? arr->len : 0; - void *data = - _upb_array_resize_accessor(msg, ofs, i + 1, elem_size, type, arena); - if (!data) return false; - memcpy(PTR_AT(data, i * elem_size, char), value, elem_size); - return true; -} - -UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; -} - -UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); -} - -UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); -} - -UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) { - return *PTR_AT(msg, case_ofs, int32_t) == num; -} - -#undef PTR_AT - - -#endif /* UPB_GENERATED_UTIL_H_ */ - - -#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 - - -#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */ -/* -** Defs are upb's internal representation of the constructs that can appear -** in a .proto file: -** -** - upb::MessageDefPtr (upb_msgdef): describes a "message" construct. -** - upb::FieldDefPtr (upb_fielddef): describes a message field. -** - upb::FileDefPtr (upb_filedef): describes a .proto file and its defs. -** - upb::EnumDefPtr (upb_enumdef): describes an enum. -** - upb::OneofDefPtr (upb_oneofdef): describes a oneof. -** -** TODO: definitions of services. -** -** This is a mixed C/C++ interface that offers a full API to both languages. -** See the top-level README for more information. -*/ - -#ifndef UPB_DEF_H_ -#define UPB_DEF_H_ - - -#ifdef __cplusplus -#include -#include -#include -#include - -namespace upb { -class EnumDefPtr; -class FieldDefPtr; -class FileDefPtr; -class MessageDefPtr; -class OneofDefPtr; -class SymbolTable; -} -#endif - - -struct upb_enumdef; -typedef struct upb_enumdef upb_enumdef; -struct upb_fielddef; -typedef struct upb_fielddef upb_fielddef; -struct upb_filedef; -typedef struct upb_filedef upb_filedef; -struct upb_msgdef; -typedef struct upb_msgdef upb_msgdef; -struct upb_oneofdef; -typedef struct upb_oneofdef upb_oneofdef; -struct upb_symtab; -typedef struct upb_symtab upb_symtab; - -typedef enum { - UPB_SYNTAX_PROTO2 = 2, - UPB_SYNTAX_PROTO3 = 3 -} upb_syntax_t; - -/* All the different kind of well known type messages. For simplicity of check, - * number wrappers and string wrappers are grouped together. Make sure the - * order and merber of these groups are not changed. - */ -typedef enum { - UPB_WELLKNOWN_UNSPECIFIED, - UPB_WELLKNOWN_ANY, - UPB_WELLKNOWN_FIELDMASK, - UPB_WELLKNOWN_DURATION, - UPB_WELLKNOWN_TIMESTAMP, - /* number wrappers */ - UPB_WELLKNOWN_DOUBLEVALUE, - UPB_WELLKNOWN_FLOATVALUE, - UPB_WELLKNOWN_INT64VALUE, - UPB_WELLKNOWN_UINT64VALUE, - UPB_WELLKNOWN_INT32VALUE, - UPB_WELLKNOWN_UINT32VALUE, - /* string wrappers */ - UPB_WELLKNOWN_STRINGVALUE, - UPB_WELLKNOWN_BYTESVALUE, - UPB_WELLKNOWN_BOOLVALUE, - UPB_WELLKNOWN_VALUE, - UPB_WELLKNOWN_LISTVALUE, - UPB_WELLKNOWN_STRUCT -} upb_wellknowntype_t; - -/* upb_fielddef ***************************************************************/ - -/* Maximum field number allowed for FieldDefs. This is an inherent limit of the - * protobuf wire format. */ -#define UPB_MAX_FIELDNUMBER ((1 << 29) - 1) - -#ifdef __cplusplus -extern "C" { -#endif - -const char *upb_fielddef_fullname(const upb_fielddef *f); -upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f); -upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f); -upb_label_t upb_fielddef_label(const upb_fielddef *f); -uint32_t upb_fielddef_number(const upb_fielddef *f); -const char *upb_fielddef_name(const upb_fielddef *f); -bool upb_fielddef_isextension(const upb_fielddef *f); -bool upb_fielddef_lazy(const upb_fielddef *f); -bool upb_fielddef_packed(const upb_fielddef *f); -size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len); -const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f); -const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f); -uint32_t upb_fielddef_index(const upb_fielddef *f); -bool upb_fielddef_issubmsg(const upb_fielddef *f); -bool upb_fielddef_isstring(const upb_fielddef *f); -bool upb_fielddef_isseq(const upb_fielddef *f); -bool upb_fielddef_isprimitive(const upb_fielddef *f); -bool upb_fielddef_ismap(const upb_fielddef *f); -int64_t upb_fielddef_defaultint64(const upb_fielddef *f); -int32_t upb_fielddef_defaultint32(const upb_fielddef *f); -uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f); -uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f); -bool upb_fielddef_defaultbool(const upb_fielddef *f); -float upb_fielddef_defaultfloat(const upb_fielddef *f); -double upb_fielddef_defaultdouble(const upb_fielddef *f); -const char *upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len); -bool upb_fielddef_hassubdef(const upb_fielddef *f); -bool upb_fielddef_haspresence(const upb_fielddef *f); -const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f); -const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f); - -/* Internal only. */ -uint32_t upb_fielddef_selectorbase(const upb_fielddef *f); - -#ifdef __cplusplus -} /* extern "C" */ - -/* A upb_fielddef describes a single field in a message. It is most often - * found as a part of a upb_msgdef, but can also stand alone to represent - * an extension. */ -class upb::FieldDefPtr { - public: - FieldDefPtr() : ptr_(nullptr) {} - explicit FieldDefPtr(const upb_fielddef *ptr) : ptr_(ptr) {} - - const upb_fielddef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - typedef upb_fieldtype_t Type; - typedef upb_label_t Label; - typedef upb_descriptortype_t DescriptorType; - - const char* full_name() const { return upb_fielddef_fullname(ptr_); } - - Type type() const { return upb_fielddef_type(ptr_); } - Label label() const { return upb_fielddef_label(ptr_); } - const char* name() const { return upb_fielddef_name(ptr_); } - uint32_t number() const { return upb_fielddef_number(ptr_); } - bool is_extension() const { return upb_fielddef_isextension(ptr_); } - - /* Copies the JSON name for this field into the given buffer. Returns the - * actual size of the JSON name, including the NULL terminator. If the - * return value is 0, the JSON name is unset. If the return value is - * greater than len, the JSON name was truncated. The buffer is always - * NULL-terminated if len > 0. - * - * The JSON name always defaults to a camelCased version of the regular - * name. However if the regular name is unset, the JSON name will be unset - * also. - */ - size_t GetJsonName(char *buf, size_t len) const { - return upb_fielddef_getjsonname(ptr_, buf, len); - } - - /* Convenience version of the above function which copies the JSON name - * into the given string, returning false if the name is not set. */ - template - bool GetJsonName(T* str) { - str->resize(GetJsonName(NULL, 0)); - GetJsonName(&(*str)[0], str->size()); - return str->size() > 0; - } - - /* For UPB_TYPE_MESSAGE fields only where is_tag_delimited() == false, - * indicates whether this field should have lazy parsing handlers that yield - * the unparsed string for the submessage. - * - * TODO(haberman): I think we want to move this into a FieldOptions container - * when we add support for custom options (the FieldOptions struct will - * contain both regular FieldOptions like "lazy" *and* custom options). */ - bool lazy() const { return upb_fielddef_lazy(ptr_); } - - /* For non-string, non-submessage fields, this indicates whether binary - * protobufs are encoded in packed or non-packed format. - * - * TODO(haberman): see note above about putting options like this into a - * FieldOptions container. */ - bool packed() const { return upb_fielddef_packed(ptr_); } - - /* An integer that can be used as an index into an array of fields for - * whatever message this field belongs to. Guaranteed to be less than - * f->containing_type()->field_count(). May only be accessed once the def has - * been finalized. */ - uint32_t index() const { return upb_fielddef_index(ptr_); } - - /* The MessageDef to which this field belongs. - * - * If this field has been added to a MessageDef, that message can be retrieved - * directly (this is always the case for frozen FieldDefs). - * - * If the field has not yet been added to a MessageDef, you can set the name - * of the containing type symbolically instead. This is mostly useful for - * extensions, where the extension is declared separately from the message. */ - MessageDefPtr containing_type() const; - - /* The OneofDef to which this field belongs, or NULL if this field is not part - * of a oneof. */ - OneofDefPtr containing_oneof() const; - - /* The field's type according to the enum in descriptor.proto. This is not - * the same as UPB_TYPE_*, because it distinguishes between (for example) - * INT32 and SINT32, whereas our "type" enum does not. This return of - * descriptor_type() is a function of type(), integer_format(), and - * is_tag_delimited(). */ - DescriptorType descriptor_type() const { - return upb_fielddef_descriptortype(ptr_); - } - - /* Convenient field type tests. */ - bool IsSubMessage() const { return upb_fielddef_issubmsg(ptr_); } - bool IsString() const { return upb_fielddef_isstring(ptr_); } - bool IsSequence() const { return upb_fielddef_isseq(ptr_); } - bool IsPrimitive() const { return upb_fielddef_isprimitive(ptr_); } - bool IsMap() const { return upb_fielddef_ismap(ptr_); } - - /* Returns the non-string default value for this fielddef, which may either - * be something the client set explicitly or the "default default" (0 for - * numbers, empty for strings). The field's type indicates the type of the - * returned value, except for enum fields that are still mutable. - * - * Requires that the given function matches the field's current type. */ - int64_t default_int64() const { return upb_fielddef_defaultint64(ptr_); } - int32_t default_int32() const { return upb_fielddef_defaultint32(ptr_); } - uint64_t default_uint64() const { return upb_fielddef_defaultuint64(ptr_); } - uint32_t default_uint32() const { return upb_fielddef_defaultuint32(ptr_); } - bool default_bool() const { return upb_fielddef_defaultbool(ptr_); } - float default_float() const { return upb_fielddef_defaultfloat(ptr_); } - double default_double() const { return upb_fielddef_defaultdouble(ptr_); } - - /* The resulting string is always NULL-terminated. If non-NULL, the length - * will be stored in *len. */ - const char *default_string(size_t * len) const { - return upb_fielddef_defaultstr(ptr_, len); - } - - /* Returns the enum or submessage def for this field, if any. The field's - * type must match (ie. you may only call enum_subdef() for fields where - * type() == UPB_TYPE_ENUM). */ - EnumDefPtr enum_subdef() const; - MessageDefPtr message_subdef() const; - - private: - const upb_fielddef *ptr_; -}; - -#endif /* __cplusplus */ - -/* upb_oneofdef ***************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef upb_inttable_iter upb_oneof_iter; - -const char *upb_oneofdef_name(const upb_oneofdef *o); -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o); -int upb_oneofdef_numfields(const upb_oneofdef *o); -uint32_t upb_oneofdef_index(const upb_oneofdef *o); - -/* Oneof lookups: - * - ntof: look up a field by name. - * - ntofz: look up a field by name (as a null-terminated string). - * - itof: look up a field by number. */ -const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, - const char *name, size_t length); -UPB_INLINE const upb_fielddef *upb_oneofdef_ntofz(const upb_oneofdef *o, - const char *name) { - return upb_oneofdef_ntof(o, name, strlen(name)); -} -const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num); - -/* upb_oneof_iter i; - * for(upb_oneof_begin(&i, e); !upb_oneof_done(&i); upb_oneof_next(&i)) { - * // ... - * } - */ -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o); -void upb_oneof_next(upb_oneof_iter *iter); -bool upb_oneof_done(upb_oneof_iter *iter); -upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter); -void upb_oneof_iter_setdone(upb_oneof_iter *iter); -bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1, - const upb_oneof_iter *iter2); - -#ifdef __cplusplus -} /* extern "C" */ - -/* Class that represents a oneof. */ -class upb::OneofDefPtr { - public: - OneofDefPtr() : ptr_(nullptr) {} - explicit OneofDefPtr(const upb_oneofdef *ptr) : ptr_(ptr) {} - - const upb_oneofdef* ptr() const { return ptr_; } - explicit operator bool() { return ptr_ != nullptr; } - - /* Returns the MessageDef that owns this OneofDef. */ - MessageDefPtr containing_type() const; - - /* Returns the name of this oneof. This is the name used to look up the oneof - * by name once added to a message def. */ - const char* name() const { return upb_oneofdef_name(ptr_); } - - /* Returns the number of fields currently defined in the oneof. */ - int field_count() const { return upb_oneofdef_numfields(ptr_); } - - /* Looks up by name. */ - FieldDefPtr FindFieldByName(const char *name, size_t len) const { - return FieldDefPtr(upb_oneofdef_ntof(ptr_, name, len)); - } - FieldDefPtr FindFieldByName(const char* name) const { - return FieldDefPtr(upb_oneofdef_ntofz(ptr_, name)); - } - - template - FieldDefPtr FindFieldByName(const T& str) const { - return FindFieldByName(str.c_str(), str.size()); - } - - /* Looks up by tag number. */ - FieldDefPtr FindFieldByNumber(uint32_t num) const { - return FieldDefPtr(upb_oneofdef_itof(ptr_, num)); - } - - class const_iterator - : public std::iterator { - public: - void operator++() { upb_oneof_next(&iter_); } - - FieldDefPtr operator*() const { - return FieldDefPtr(upb_oneof_iter_field(&iter_)); - } - - bool operator!=(const const_iterator& other) const { - return !upb_oneof_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_iterator& other) const { - return upb_oneof_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class OneofDefPtr; - - const_iterator() {} - explicit const_iterator(OneofDefPtr o) { - upb_oneof_begin(&iter_, o.ptr()); - } - static const_iterator end() { - const_iterator iter; - upb_oneof_iter_setdone(&iter.iter_); - return iter; - } - - upb_oneof_iter iter_; - }; - - const_iterator begin() const { return const_iterator(*this); } - const_iterator end() const { return const_iterator::end(); } - - private: - const upb_oneofdef *ptr_; -}; - -inline upb::OneofDefPtr upb::FieldDefPtr::containing_oneof() const { - return OneofDefPtr(upb_fielddef_containingoneof(ptr_)); -} - -#endif /* __cplusplus */ - -/* upb_msgdef *****************************************************************/ - -typedef upb_inttable_iter upb_msg_field_iter; -typedef upb_strtable_iter upb_msg_oneof_iter; - -/* Well-known field tag numbers for map-entry messages. */ -#define UPB_MAPENTRY_KEY 1 -#define UPB_MAPENTRY_VALUE 2 - -/* Well-known field tag numbers for Any messages. */ -#define UPB_ANY_TYPE 1 -#define UPB_ANY_VALUE 2 - -/* Well-known field tag numbers for timestamp messages. */ -#define UPB_DURATION_SECONDS 1 -#define UPB_DURATION_NANOS 2 - -/* Well-known field tag numbers for duration messages. */ -#define UPB_TIMESTAMP_SECONDS 1 -#define UPB_TIMESTAMP_NANOS 2 - -#ifdef __cplusplus -extern "C" { -#endif - -const char *upb_msgdef_fullname(const upb_msgdef *m); -const upb_filedef *upb_msgdef_file(const upb_msgdef *m); -const char *upb_msgdef_name(const upb_msgdef *m); -int upb_msgdef_numoneofs(const upb_msgdef *m); -upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); -bool upb_msgdef_mapentry(const upb_msgdef *m); -upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); -bool upb_msgdef_isnumberwrapper(const upb_msgdef *m); -bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax); -const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i); -const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, - size_t len); -const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, - size_t len); -int upb_msgdef_numfields(const upb_msgdef *m); -int upb_msgdef_numoneofs(const upb_msgdef *m); - -UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m, - const char *name) { - return upb_msgdef_ntoo(m, name, strlen(name)); -} - -UPB_INLINE const upb_fielddef *upb_msgdef_ntofz(const upb_msgdef *m, - const char *name) { - return upb_msgdef_ntof(m, name, strlen(name)); -} - -/* Internal-only. */ -size_t upb_msgdef_selectorcount(const upb_msgdef *m); -uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m); - -/* Lookup of either field or oneof by name. Returns whether either was found. - * If the return is true, then the found def will be set, and the non-found - * one set to NULL. */ -bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, - const upb_fielddef **f, const upb_oneofdef **o); - -UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name, - const upb_fielddef **f, - const upb_oneofdef **o) { - return upb_msgdef_lookupname(m, name, strlen(name), f, o); -} - -/* Iteration over fields and oneofs. For example: - * - * upb_msg_field_iter i; - * for(upb_msg_field_begin(&i, m); - * !upb_msg_field_done(&i); - * upb_msg_field_next(&i)) { - * upb_fielddef *f = upb_msg_iter_field(&i); - * // ... - * } - * - * For C we don't have separate iterators for const and non-const. - * It is the caller's responsibility to cast the upb_fielddef* to - * const if the upb_msgdef* is const. */ -void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m); -void upb_msg_field_next(upb_msg_field_iter *iter); -bool upb_msg_field_done(const upb_msg_field_iter *iter); -upb_fielddef *upb_msg_iter_field(const upb_msg_field_iter *iter); -void upb_msg_field_iter_setdone(upb_msg_field_iter *iter); -bool upb_msg_field_iter_isequal(const upb_msg_field_iter * iter1, - const upb_msg_field_iter * iter2); - -/* Similar to above, we also support iterating through the oneofs in a - * msgdef. */ -void upb_msg_oneof_begin(upb_msg_oneof_iter * iter, const upb_msgdef *m); -void upb_msg_oneof_next(upb_msg_oneof_iter * iter); -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter); -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter); -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter); -bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, - const upb_msg_oneof_iter *iter2); - -#ifdef __cplusplus -} /* extern "C" */ - -/* Structure that describes a single .proto message type. */ -class upb::MessageDefPtr { - public: - MessageDefPtr() : ptr_(nullptr) {} - explicit MessageDefPtr(const upb_msgdef *ptr) : ptr_(ptr) {} - - const upb_msgdef *ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - const char* full_name() const { return upb_msgdef_fullname(ptr_); } - const char* name() const { return upb_msgdef_name(ptr_); } - - /* The number of fields that belong to the MessageDef. */ - int field_count() const { return upb_msgdef_numfields(ptr_); } - - /* The number of oneofs that belong to the MessageDef. */ - int oneof_count() const { return upb_msgdef_numoneofs(ptr_); } - - upb_syntax_t syntax() const { return upb_msgdef_syntax(ptr_); } - - /* These return null pointers if the field is not found. */ - FieldDefPtr FindFieldByNumber(uint32_t number) const { - return FieldDefPtr(upb_msgdef_itof(ptr_, number)); - } - FieldDefPtr FindFieldByName(const char* name, size_t len) const { - return FieldDefPtr(upb_msgdef_ntof(ptr_, name, len)); - } - FieldDefPtr FindFieldByName(const char *name) const { - return FieldDefPtr(upb_msgdef_ntofz(ptr_, name)); - } - - template - FieldDefPtr FindFieldByName(const T& str) const { - return FindFieldByName(str.c_str(), str.size()); - } - - OneofDefPtr FindOneofByName(const char* name, size_t len) const { - return OneofDefPtr(upb_msgdef_ntoo(ptr_, name, len)); - } - - OneofDefPtr FindOneofByName(const char *name) const { - return OneofDefPtr(upb_msgdef_ntooz(ptr_, name)); - } - - template - OneofDefPtr FindOneofByName(const T &str) const { - return FindOneofByName(str.c_str(), str.size()); - } - - /* Is this message a map entry? */ - bool mapentry() const { return upb_msgdef_mapentry(ptr_); } - - /* Return the type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for - * non-well-known message. */ - upb_wellknowntype_t wellknowntype() const { - return upb_msgdef_wellknowntype(ptr_); - } - - /* Whether is a number wrapper. */ - bool isnumberwrapper() const { return upb_msgdef_isnumberwrapper(ptr_); } - - /* Iteration over fields. The order is undefined. */ - class const_field_iterator - : public std::iterator { - public: - void operator++() { upb_msg_field_next(&iter_); } - - FieldDefPtr operator*() const { - return FieldDefPtr(upb_msg_iter_field(&iter_)); - } - - bool operator!=(const const_field_iterator &other) const { - return !upb_msg_field_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_field_iterator &other) const { - return upb_msg_field_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class MessageDefPtr; - - explicit const_field_iterator() {} - - explicit const_field_iterator(MessageDefPtr msg) { - upb_msg_field_begin(&iter_, msg.ptr()); - } - - static const_field_iterator end() { - const_field_iterator iter; - upb_msg_field_iter_setdone(&iter.iter_); - return iter; - } - - upb_msg_field_iter iter_; - }; - - /* Iteration over oneofs. The order is undefined. */ - class const_oneof_iterator - : public std::iterator { - public: - - void operator++() { upb_msg_oneof_next(&iter_); } - - OneofDefPtr operator*() const { - return OneofDefPtr(upb_msg_iter_oneof(&iter_)); - } - - bool operator!=(const const_oneof_iterator& other) const { - return !upb_msg_oneof_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_oneof_iterator &other) const { - return upb_msg_oneof_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class MessageDefPtr; - - const_oneof_iterator() {} - - explicit const_oneof_iterator(MessageDefPtr msg) { - upb_msg_oneof_begin(&iter_, msg.ptr()); - } - - static const_oneof_iterator end() { - const_oneof_iterator iter; - upb_msg_oneof_iter_setdone(&iter.iter_); - return iter; - } - - upb_msg_oneof_iter iter_; - }; - - class ConstFieldAccessor { - public: - explicit ConstFieldAccessor(const upb_msgdef* md) : md_(md) {} - const_field_iterator begin() { return MessageDefPtr(md_).field_begin(); } - const_field_iterator end() { return MessageDefPtr(md_).field_end(); } - private: - const upb_msgdef* md_; - }; - - class ConstOneofAccessor { - public: - explicit ConstOneofAccessor(const upb_msgdef* md) : md_(md) {} - const_oneof_iterator begin() { return MessageDefPtr(md_).oneof_begin(); } - const_oneof_iterator end() { return MessageDefPtr(md_).oneof_end(); } - private: - const upb_msgdef* md_; - }; - - const_field_iterator field_begin() const { - return const_field_iterator(*this); - } - - const_field_iterator field_end() const { return const_field_iterator::end(); } - - const_oneof_iterator oneof_begin() const { - return const_oneof_iterator(*this); - } - - const_oneof_iterator oneof_end() const { return const_oneof_iterator::end(); } - - ConstFieldAccessor fields() const { return ConstFieldAccessor(ptr()); } - ConstOneofAccessor oneofs() const { return ConstOneofAccessor(ptr()); } - - private: - const upb_msgdef* ptr_; -}; - -inline upb::MessageDefPtr upb::FieldDefPtr::message_subdef() const { - return MessageDefPtr(upb_fielddef_msgsubdef(ptr_)); -} - -inline upb::MessageDefPtr upb::FieldDefPtr::containing_type() const { - return MessageDefPtr(upb_fielddef_containingtype(ptr_)); -} - -inline upb::MessageDefPtr upb::OneofDefPtr::containing_type() const { - return MessageDefPtr(upb_oneofdef_containingtype(ptr_)); -} - -#endif /* __cplusplus */ - -/* upb_enumdef ****************************************************************/ - -typedef upb_strtable_iter upb_enum_iter; - -const char *upb_enumdef_fullname(const upb_enumdef *e); -const char *upb_enumdef_name(const upb_enumdef *e); -const upb_filedef *upb_enumdef_file(const upb_enumdef *e); -int32_t upb_enumdef_default(const upb_enumdef *e); -int upb_enumdef_numvals(const upb_enumdef *e); - -/* Enum lookups: - * - ntoi: look up a name with specified length. - * - ntoiz: look up a name provided as a null-terminated string. - * - iton: look up an integer, returning the name as a null-terminated - * string. */ -bool upb_enumdef_ntoi(const upb_enumdef *e, const char *name, size_t len, - int32_t *num); -UPB_INLINE bool upb_enumdef_ntoiz(const upb_enumdef *e, - const char *name, int32_t *num) { - return upb_enumdef_ntoi(e, name, strlen(name), num); -} -const char *upb_enumdef_iton(const upb_enumdef *e, int32_t num); - -/* upb_enum_iter i; - * for(upb_enum_begin(&i, e); !upb_enum_done(&i); upb_enum_next(&i)) { - * // ... - * } - */ -void upb_enum_begin(upb_enum_iter *iter, const upb_enumdef *e); -void upb_enum_next(upb_enum_iter *iter); -bool upb_enum_done(upb_enum_iter *iter); -const char *upb_enum_iter_name(upb_enum_iter *iter); -int32_t upb_enum_iter_number(upb_enum_iter *iter); - -#ifdef __cplusplus - -class upb::EnumDefPtr { - public: - EnumDefPtr() : ptr_(nullptr) {} - explicit EnumDefPtr(const upb_enumdef* ptr) : ptr_(ptr) {} - - const upb_enumdef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - const char* full_name() const { return upb_enumdef_fullname(ptr_); } - const char* name() const { return upb_enumdef_name(ptr_); } - - /* The value that is used as the default when no field default is specified. - * If not set explicitly, the first value that was added will be used. - * The default value must be a member of the enum. - * Requires that value_count() > 0. */ - int32_t default_value() const { return upb_enumdef_default(ptr_); } - - /* Returns the number of values currently defined in the enum. Note that - * multiple names can refer to the same number, so this may be greater than - * the total number of unique numbers. */ - int value_count() const { return upb_enumdef_numvals(ptr_); } - - /* Lookups from name to integer, returning true if found. */ - bool FindValueByName(const char *name, int32_t *num) const { - return upb_enumdef_ntoiz(ptr_, name, num); - } - - /* Finds the name corresponding to the given number, or NULL if none was - * found. If more than one name corresponds to this number, returns the - * first one that was added. */ - const char *FindValueByNumber(int32_t num) const { - return upb_enumdef_iton(ptr_, num); - } - - /* Iteration over name/value pairs. The order is undefined. - * Adding an enum val invalidates any iterators. - * - * TODO: make compatible with range-for, with elements as pairs? */ - class Iterator { - public: - explicit Iterator(EnumDefPtr e) { upb_enum_begin(&iter_, e.ptr()); } - - int32_t number() { return upb_enum_iter_number(&iter_); } - const char *name() { return upb_enum_iter_name(&iter_); } - bool Done() { return upb_enum_done(&iter_); } - void Next() { return upb_enum_next(&iter_); } - - private: - upb_enum_iter iter_; - }; - - private: - const upb_enumdef *ptr_; -}; - -inline upb::EnumDefPtr upb::FieldDefPtr::enum_subdef() const { - return EnumDefPtr(upb_fielddef_enumsubdef(ptr_)); -} - -#endif /* __cplusplus */ - -/* upb_filedef ****************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -const char *upb_filedef_name(const upb_filedef *f); -const char *upb_filedef_package(const upb_filedef *f); -const char *upb_filedef_phpprefix(const upb_filedef *f); -const char *upb_filedef_phpnamespace(const upb_filedef *f); -upb_syntax_t upb_filedef_syntax(const upb_filedef *f); -int upb_filedef_depcount(const upb_filedef *f); -int upb_filedef_msgcount(const upb_filedef *f); -int upb_filedef_enumcount(const upb_filedef *f); -const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i); -const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i); -const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i); - -#ifdef __cplusplus -} /* extern "C" */ - -/* Class that represents a .proto file with some things defined in it. - * - * Many users won't care about FileDefs, but they are necessary if you want to - * read the values of file-level options. */ -class upb::FileDefPtr { - public: - explicit FileDefPtr(const upb_filedef *ptr) : ptr_(ptr) {} - - const upb_filedef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - /* Get/set name of the file (eg. "foo/bar.proto"). */ - const char* name() const { return upb_filedef_name(ptr_); } - - /* Package name for definitions inside the file (eg. "foo.bar"). */ - const char* package() const { return upb_filedef_package(ptr_); } - - /* Sets the php class prefix which is prepended to all php generated classes - * from this .proto. Default is empty. */ - const char* phpprefix() const { return upb_filedef_phpprefix(ptr_); } - - /* Use this option to change the namespace of php generated classes. Default - * is empty. When this option is empty, the package name will be used for - * determining the namespace. */ - const char* phpnamespace() const { return upb_filedef_phpnamespace(ptr_); } - - /* Syntax for the file. Defaults to proto2. */ - upb_syntax_t syntax() const { return upb_filedef_syntax(ptr_); } - - /* Get the list of dependencies from the file. These are returned in the - * order that they were added to the FileDefPtr. */ - int dependency_count() const { return upb_filedef_depcount(ptr_); } - const FileDefPtr dependency(int index) const { - return FileDefPtr(upb_filedef_dep(ptr_, index)); - } - - private: - const upb_filedef* ptr_; -}; - -#endif /* __cplusplus */ - -/* upb_symtab *****************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -upb_symtab *upb_symtab_new(void); -void upb_symtab_free(upb_symtab* s); -const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym); -const upb_msgdef *upb_symtab_lookupmsg2( - const upb_symtab *s, const char *sym, size_t len); -const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym); -const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name); -const upb_filedef *upb_symtab_lookupfile2( - const upb_symtab *s, const char *name, size_t len); -int upb_symtab_filecount(const upb_symtab *s); -const upb_filedef *upb_symtab_addfile( - upb_symtab *s, const google_protobuf_FileDescriptorProto *file, - upb_status *status); - -/* For generated code only: loads a generated descriptor. */ -typedef struct upb_def_init { - struct upb_def_init **deps; - const char *filename; - upb_strview descriptor; -} upb_def_init; - -bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); - -#ifdef __cplusplus -} /* extern "C" */ - -/* Non-const methods in upb::SymbolTable are NOT thread-safe. */ -class upb::SymbolTable { - public: - SymbolTable() : ptr_(upb_symtab_new(), upb_symtab_free) {} - explicit SymbolTable(upb_symtab* s) : ptr_(s, upb_symtab_free) {} - - const upb_symtab* ptr() const { return ptr_.get(); } - upb_symtab* ptr() { return ptr_.get(); } - - /* Finds an entry in the symbol table with this exact name. If not found, - * returns NULL. */ - MessageDefPtr LookupMessage(const char *sym) const { - return MessageDefPtr(upb_symtab_lookupmsg(ptr_.get(), sym)); - } - - EnumDefPtr LookupEnum(const char *sym) const { - return EnumDefPtr(upb_symtab_lookupenum(ptr_.get(), sym)); - } - - FileDefPtr LookupFile(const char *name) const { - return FileDefPtr(upb_symtab_lookupfile(ptr_.get(), name)); - } - - /* TODO: iteration? */ - - /* Adds the given serialized FileDescriptorProto to the pool. */ - FileDefPtr AddFile(const google_protobuf_FileDescriptorProto *file_proto, - Status *status) { - return FileDefPtr( - upb_symtab_addfile(ptr_.get(), file_proto, status->ptr())); - } - - private: - std::unique_ptr ptr_; -}; - -UPB_INLINE const char* upb_safecstr(const std::string& str) { - UPB_ASSERT(str.size() == std::strlen(str.c_str())); - return str.c_str(); -} - -#endif /* __cplusplus */ - - -#endif /* UPB_DEF_H_ */ - - -#ifndef UPB_MSGFACTORY_H_ -#define UPB_MSGFACTORY_H_ - -/** upb_msgfactory ************************************************************/ - -struct upb_msgfactory; -typedef struct upb_msgfactory upb_msgfactory; - -#ifdef __cplusplus -extern "C" { -#endif - -/* A upb_msgfactory contains a cache of upb_msglayout, upb_handlers, and - * upb_visitorplan objects. These are the objects necessary to represent, - * populate, and and visit upb_msg objects. - * - * These caches are all populated by upb_msgdef, and lazily created on demand. - */ - -/* Creates and destroys a msgfactory, respectively. The messages for this - * msgfactory must come from |symtab| (which should outlive the msgfactory). */ -upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab); -void upb_msgfactory_free(upb_msgfactory *f); - -const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f); - -/* The functions to get cached objects, lazily creating them on demand. These - * all require: - * - * - m is in upb_msgfactory_symtab(f) - * - upb_msgdef_mapentry(m) == false (since map messages can't have layouts). - * - * The returned objects will live for as long as the msgfactory does. - * - * TODO(haberman): consider making this thread-safe and take a const - * upb_msgfactory. */ -const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, - const upb_msgdef *m); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_MSGFACTORY_H_ */ -/* -** upb::Handlers (upb_handlers) -** -** A upb_handlers is like a virtual table for a upb_msgdef. Each field of the -** message can have associated functions that will be called when we are -** parsing or visiting a stream of data. This is similar to how handlers work -** in SAX (the Simple API for XML). -** -** The handlers have no idea where the data is coming from, so a single set of -** handlers could be used with two completely different data sources (for -** example, a parser and a visitor over in-memory objects). This decoupling is -** the most important feature of upb, because it allows parsers and serializers -** to be highly reusable. -** -** This is a mixed C/C++ interface that offers a full API to both languages. -** See the top-level README for more information. -*/ - -#ifndef UPB_HANDLERS_H -#define UPB_HANDLERS_H - - - -#ifdef __cplusplus -namespace upb { -class HandlersPtr; -class HandlerCache; -template class Handler; -template struct CanonicalType; -} /* namespace upb */ -#endif - - -/* The maximum depth that the handler graph can have. This is a resource limit - * for the C stack since we sometimes need to recursively traverse the graph. - * Cycles are ok; the traversal will stop when it detects a cycle, but we must - * hit the cycle before the maximum depth is reached. - * - * If having a single static limit is too inflexible, we can add another variant - * of Handlers::Freeze that allows specifying this as a parameter. */ -#define UPB_MAX_HANDLER_DEPTH 64 - -/* All the different types of handlers that can be registered. - * Only needed for the advanced functions in upb::Handlers. */ -typedef enum { - UPB_HANDLER_INT32, - UPB_HANDLER_INT64, - UPB_HANDLER_UINT32, - UPB_HANDLER_UINT64, - UPB_HANDLER_FLOAT, - UPB_HANDLER_DOUBLE, - UPB_HANDLER_BOOL, - UPB_HANDLER_STARTSTR, - UPB_HANDLER_STRING, - UPB_HANDLER_ENDSTR, - UPB_HANDLER_STARTSUBMSG, - UPB_HANDLER_ENDSUBMSG, - UPB_HANDLER_STARTSEQ, - UPB_HANDLER_ENDSEQ -} upb_handlertype_t; - -#define UPB_HANDLER_MAX (UPB_HANDLER_ENDSEQ+1) - -#define UPB_BREAK NULL - -/* A convenient definition for when no closure is needed. */ -extern char _upb_noclosure; -#define UPB_NO_CLOSURE &_upb_noclosure - -/* A selector refers to a specific field handler in the Handlers object - * (for example: the STARTSUBMSG handler for field "field15"). */ -typedef int32_t upb_selector_t; - -/* Static selectors for upb::Handlers. */ -#define UPB_STARTMSG_SELECTOR 0 -#define UPB_ENDMSG_SELECTOR 1 -#define UPB_UNKNOWN_SELECTOR 2 -#define UPB_STATIC_SELECTOR_COUNT 3 /* Warning: also in upb/def.c. */ - -/* Static selectors for upb::BytesHandler. */ -#define UPB_STARTSTR_SELECTOR 0 -#define UPB_STRING_SELECTOR 1 -#define UPB_ENDSTR_SELECTOR 2 - -#ifdef __cplusplus -template const void *UniquePtrForType() { - static const char ch = 0; - return &ch; -} -#endif - -/* upb_handlers ************************************************************/ - -/* Handler attributes, to be registered with the handler itself. */ -typedef struct { - const void *handler_data; - const void *closure_type; - const void *return_closure_type; - bool alwaysok; -} upb_handlerattr; - -#define UPB_HANDLERATTR_INIT {NULL, NULL, NULL, false} - -/* Bufhandle, data passed along with a buffer to indicate its provenance. */ -typedef struct { - /* The beginning of the buffer. This may be different than the pointer - * passed to a StringBuf handler because the handler may receive data - * that is from the middle or end of a larger buffer. */ - const char *buf; - - /* The offset within the attached object where this buffer begins. Only - * meaningful if there is an attached object. */ - size_t objofs; - - /* The attached object (if any) and a pointer representing its type. */ - const void *obj; - const void *objtype; - -#ifdef __cplusplus - template - void SetAttachedObject(const T* _obj) { - obj = _obj; - objtype = UniquePtrForType(); - } - - template - const T *GetAttachedObject() const { - return objtype == UniquePtrForType() ? static_cast(obj) - : NULL; - } -#endif -} upb_bufhandle; - -#define UPB_BUFHANDLE_INIT {NULL, 0, NULL, NULL} - -/* Handler function typedefs. */ -typedef void upb_handlerfree(void *d); -typedef bool upb_unknown_handlerfunc(void *c, const void *hd, const char *buf, - size_t n); -typedef bool upb_startmsg_handlerfunc(void *c, const void*); -typedef bool upb_endmsg_handlerfunc(void *c, const void *, upb_status *status); -typedef void* upb_startfield_handlerfunc(void *c, const void *hd); -typedef bool upb_endfield_handlerfunc(void *c, const void *hd); -typedef bool upb_int32_handlerfunc(void *c, const void *hd, int32_t val); -typedef bool upb_int64_handlerfunc(void *c, const void *hd, int64_t val); -typedef bool upb_uint32_handlerfunc(void *c, const void *hd, uint32_t val); -typedef bool upb_uint64_handlerfunc(void *c, const void *hd, uint64_t val); -typedef bool upb_float_handlerfunc(void *c, const void *hd, float val); -typedef bool upb_double_handlerfunc(void *c, const void *hd, double val); -typedef bool upb_bool_handlerfunc(void *c, const void *hd, bool val); -typedef void *upb_startstr_handlerfunc(void *c, const void *hd, - size_t size_hint); -typedef size_t upb_string_handlerfunc(void *c, const void *hd, const char *buf, - size_t n, const upb_bufhandle* handle); - -struct upb_handlers; -typedef struct upb_handlers upb_handlers; - -#ifdef __cplusplus -extern "C" { -#endif - -/* Mutating accessors. */ -const upb_status *upb_handlers_status(upb_handlers *h); -void upb_handlers_clearerr(upb_handlers *h); -const upb_msgdef *upb_handlers_msgdef(const upb_handlers *h); -bool upb_handlers_addcleanup(upb_handlers *h, void *p, upb_handlerfree *hfree); -bool upb_handlers_setunknown(upb_handlers *h, upb_unknown_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setstartmsg(upb_handlers *h, upb_startmsg_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setendmsg(upb_handlers *h, upb_endmsg_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setint32(upb_handlers *h, const upb_fielddef *f, - upb_int32_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setint64(upb_handlers *h, const upb_fielddef *f, - upb_int64_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setuint32(upb_handlers *h, const upb_fielddef *f, - upb_uint32_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setuint64(upb_handlers *h, const upb_fielddef *f, - upb_uint64_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setfloat(upb_handlers *h, const upb_fielddef *f, - upb_float_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setdouble(upb_handlers *h, const upb_fielddef *f, - upb_double_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setbool(upb_handlers *h, const upb_fielddef *f, - upb_bool_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setstartstr(upb_handlers *h, const upb_fielddef *f, - upb_startstr_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setstring(upb_handlers *h, const upb_fielddef *f, - upb_string_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setendstr(upb_handlers *h, const upb_fielddef *f, - upb_endfield_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setstartseq(upb_handlers *h, const upb_fielddef *f, - upb_startfield_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setstartsubmsg(upb_handlers *h, const upb_fielddef *f, - upb_startfield_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setendsubmsg(upb_handlers *h, const upb_fielddef *f, - upb_endfield_handlerfunc *func, - const upb_handlerattr *attr); -bool upb_handlers_setendseq(upb_handlers *h, const upb_fielddef *f, - upb_endfield_handlerfunc *func, - const upb_handlerattr *attr); - -/* Read-only accessors. */ -const upb_handlers *upb_handlers_getsubhandlers(const upb_handlers *h, - const upb_fielddef *f); -const upb_handlers *upb_handlers_getsubhandlers_sel(const upb_handlers *h, - upb_selector_t sel); -upb_func *upb_handlers_gethandler(const upb_handlers *h, upb_selector_t s, - const void **handler_data); -bool upb_handlers_getattr(const upb_handlers *h, upb_selector_t s, - upb_handlerattr *attr); - -/* "Static" methods */ -upb_handlertype_t upb_handlers_getprimitivehandlertype(const upb_fielddef *f); -bool upb_handlers_getselector(const upb_fielddef *f, upb_handlertype_t type, - upb_selector_t *s); -UPB_INLINE upb_selector_t upb_handlers_getendselector(upb_selector_t start) { - return start + 1; -} - -#ifdef __cplusplus -} /* extern "C" */ - -namespace upb { -typedef upb_handlers Handlers; -} - -/* Convenience macros for creating a Handler object that is wrapped with a - * type-safe wrapper function that converts the "void*" parameters/returns - * of the underlying C API into nice C++ function. - * - * Sample usage: - * void OnValue1(MyClosure* c, const MyHandlerData* d, int32_t val) { - * // do stuff ... - * } - * - * // Handler that doesn't need any data bound to it. - * void OnValue2(MyClosure* c, int32_t val) { - * // do stuff ... - * } - * - * // Handler that returns bool so it can return failure if necessary. - * bool OnValue3(MyClosure* c, int32_t val) { - * // do stuff ... - * return ok; - * } - * - * // Member function handler. - * class MyClosure { - * public: - * void OnValue(int32_t val) { - * // do stuff ... - * } - * }; - * - * // Takes ownership of the MyHandlerData. - * handlers->SetInt32Handler(f1, UpbBind(OnValue1, new MyHandlerData(...))); - * handlers->SetInt32Handler(f2, UpbMakeHandler(OnValue2)); - * handlers->SetInt32Handler(f1, UpbMakeHandler(OnValue3)); - * handlers->SetInt32Handler(f2, UpbMakeHandler(&MyClosure::OnValue)); - */ - -/* In C++11, the "template" disambiguator can appear even outside templates, - * so all calls can safely use this pair of macros. */ - -#define UpbMakeHandler(f) upb::MatchFunc(f).template GetFunc() - -/* We have to be careful to only evaluate "d" once. */ -#define UpbBind(f, d) upb::MatchFunc(f).template GetFunc((d)) - -/* Handler: a struct that contains the (handler, data, deleter) tuple that is - * used to register all handlers. Users can Make() these directly but it's - * more convenient to use the UpbMakeHandler/UpbBind macros above. */ -template class upb::Handler { - public: - /* The underlying, handler function signature that upb uses internally. */ - typedef T FuncPtr; - - /* Intentionally implicit. */ - template Handler(F func); - ~Handler() { UPB_ASSERT(registered_); } - - void AddCleanup(upb_handlers* h) const; - FuncPtr handler() const { return handler_; } - const upb_handlerattr& attr() const { return attr_; } - - private: - Handler(const Handler&) = delete; - Handler& operator=(const Handler&) = delete; - - FuncPtr handler_; - mutable upb_handlerattr attr_; - mutable bool registered_; - void *cleanup_data_; - upb_handlerfree *cleanup_func_; -}; - -/* A upb::Handlers object represents the set of handlers associated with a - * message in the graph of messages. You can think of it as a big virtual - * table with functions corresponding to all the events that can fire while - * parsing or visiting a message of a specific type. - * - * Any handlers that are not set behave as if they had successfully consumed - * the value. Any unset Start* handlers will propagate their closure to the - * inner frame. - * - * The easiest way to create the *Handler objects needed by the Set* methods is - * with the UpbBind() and UpbMakeHandler() macros; see below. */ -class upb::HandlersPtr { - public: - HandlersPtr(upb_handlers* ptr) : ptr_(ptr) {} - - upb_handlers* ptr() const { return ptr_; } - - typedef upb_selector_t Selector; - typedef upb_handlertype_t Type; - - typedef Handler StartFieldHandler; - typedef Handler EndFieldHandler; - typedef Handler StartMessageHandler; - typedef Handler - EndMessageHandler; - typedef Handler StartStringHandler; - typedef Handler - StringHandler; - - template struct ValueHandler { - typedef Handler H; - }; - - typedef ValueHandler::H Int32Handler; - typedef ValueHandler::H Int64Handler; - typedef ValueHandler::H UInt32Handler; - typedef ValueHandler::H UInt64Handler; - typedef ValueHandler::H FloatHandler; - typedef ValueHandler::H DoubleHandler; - typedef ValueHandler::H BoolHandler; - - /* Any function pointer can be converted to this and converted back to its - * correct type. */ - typedef void GenericFunction(); - - typedef void HandlersCallback(const void *closure, upb_handlers *h); - - /* Returns the msgdef associated with this handlers object. */ - MessageDefPtr message_def() const { - return MessageDefPtr(upb_handlers_msgdef(ptr())); - } - - /* Adds the given pointer and function to the list of cleanup functions that - * will be run when these handlers are freed. If this pointer has previously - * been registered, the function returns false and does nothing. */ - bool AddCleanup(void *ptr, upb_handlerfree *cleanup) { - return upb_handlers_addcleanup(ptr_, ptr, cleanup); - } - - /* Sets the startmsg handler for the message, which is defined as follows: - * - * bool startmsg(MyType* closure) { - * // Called when the message begins. Returns true if processing should - * // continue. - * return true; - * } - */ - bool SetStartMessageHandler(const StartMessageHandler &h) { - h.AddCleanup(ptr()); - return upb_handlers_setstartmsg(ptr(), h.handler(), &h.attr()); - } - - /* Sets the endmsg handler for the message, which is defined as follows: - * - * bool endmsg(MyType* closure, upb_status *status) { - * // Called when processing of this message ends, whether in success or - * // failure. "status" indicates the final status of processing, and - * // can also be modified in-place to update the final status. - * } - */ - bool SetEndMessageHandler(const EndMessageHandler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setendmsg(ptr(), h.handler(), &h.attr()); - } - - /* Sets the value handler for the given field, which is defined as follows - * (this is for an int32 field; other field types will pass their native - * C/C++ type for "val"): - * - * bool OnValue(MyClosure* c, const MyHandlerData* d, int32_t val) { - * // Called when the field's value is encountered. "d" contains - * // whatever data was bound to this field when it was registered. - * // Returns true if processing should continue. - * return true; - * } - * - * handers->SetInt32Handler(f, UpbBind(OnValue, new MyHandlerData(...))); - * - * The value type must exactly match f->type(). - * For example, a handler that takes an int32_t parameter may only be used for - * fields of type UPB_TYPE_INT32 and UPB_TYPE_ENUM. - * - * Returns false if the handler failed to register; in this case the cleanup - * handler (if any) will be called immediately. - */ - bool SetInt32Handler(FieldDefPtr f, const Int32Handler &h) { - h.AddCleanup(ptr()); - return upb_handlers_setint32(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetInt64Handler (FieldDefPtr f, const Int64Handler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setint64(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetUInt32Handler(FieldDefPtr f, const UInt32Handler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setuint32(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetUInt64Handler(FieldDefPtr f, const UInt64Handler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setuint64(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetFloatHandler (FieldDefPtr f, const FloatHandler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setfloat(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetDoubleHandler(FieldDefPtr f, const DoubleHandler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setdouble(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetBoolHandler(FieldDefPtr f, const BoolHandler &h) { - h.AddCleanup(ptr()); - return upb_handlers_setbool(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - /* Like the previous, but templated on the type on the value (ie. int32). - * This is mostly useful to call from other templates. To call this you must - * specify the template parameter explicitly, ie: - * h->SetValueHandler(f, UpbBind(MyHandler, MyData)); */ - template - bool SetValueHandler( - FieldDefPtr f, - const typename ValueHandler::Type>::H &handler); - - /* Sets handlers for a string field, which are defined as follows: - * - * MySubClosure* startstr(MyClosure* c, const MyHandlerData* d, - * size_t size_hint) { - * // Called when a string value begins. The return value indicates the - * // closure for the string. "size_hint" indicates the size of the - * // string if it is known, however if the string is length-delimited - * // and the end-of-string is not available size_hint will be zero. - * // This case is indistinguishable from the case where the size is - * // known to be zero. - * // - * // TODO(haberman): is it important to distinguish these cases? - * // If we had ssize_t as a type we could make -1 "unknown", but - * // ssize_t is POSIX (not ANSI) and therefore less portable. - * // In practice I suspect it won't be important to distinguish. - * return closure; - * } - * - * size_t str(MyClosure* closure, const MyHandlerData* d, - * const char *str, size_t len) { - * // Called for each buffer of string data; the multiple physical buffers - * // are all part of the same logical string. The return value indicates - * // how many bytes were consumed. If this number is less than "len", - * // this will also indicate that processing should be halted for now, - * // like returning false or UPB_BREAK from any other callback. If - * // number is greater than "len", the excess bytes will be skipped over - * // and not passed to the callback. - * return len; - * } - * - * bool endstr(MyClosure* c, const MyHandlerData* d) { - * // Called when a string value ends. Return value indicates whether - * // processing should continue. - * return true; - * } - */ - bool SetStartStringHandler(FieldDefPtr f, const StartStringHandler &h) { - h.AddCleanup(ptr()); - return upb_handlers_setstartstr(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetStringHandler(FieldDefPtr f, const StringHandler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setstring(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - bool SetEndStringHandler(FieldDefPtr f, const EndFieldHandler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setendstr(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - /* Sets the startseq handler, which is defined as follows: - * - * MySubClosure *startseq(MyClosure* c, const MyHandlerData* d) { - * // Called when a sequence (repeated field) begins. The returned - * // pointer indicates the closure for the sequence (or UPB_BREAK - * // to interrupt processing). - * return closure; - * } - * - * h->SetStartSequenceHandler(f, UpbBind(startseq, new MyHandlerData(...))); - * - * Returns "false" if "f" does not belong to this message or is not a - * repeated field. - */ - bool SetStartSequenceHandler(FieldDefPtr f, const StartFieldHandler &h) { - h.AddCleanup(ptr()); - return upb_handlers_setstartseq(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - /* Sets the startsubmsg handler for the given field, which is defined as - * follows: - * - * MySubClosure* startsubmsg(MyClosure* c, const MyHandlerData* d) { - * // Called when a submessage begins. The returned pointer indicates the - * // closure for the sequence (or UPB_BREAK to interrupt processing). - * return closure; - * } - * - * h->SetStartSubMessageHandler(f, UpbBind(startsubmsg, - * new MyHandlerData(...))); - * - * Returns "false" if "f" does not belong to this message or is not a - * submessage/group field. - */ - bool SetStartSubMessageHandler(FieldDefPtr f, const StartFieldHandler& h) { - h.AddCleanup(ptr()); - return upb_handlers_setstartsubmsg(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - /* Sets the endsubmsg handler for the given field, which is defined as - * follows: - * - * bool endsubmsg(MyClosure* c, const MyHandlerData* d) { - * // Called when a submessage ends. Returns true to continue processing. - * return true; - * } - * - * Returns "false" if "f" does not belong to this message or is not a - * submessage/group field. - */ - bool SetEndSubMessageHandler(FieldDefPtr f, const EndFieldHandler &h) { - h.AddCleanup(ptr()); - return upb_handlers_setendsubmsg(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - /* Starts the endsubseq handler for the given field, which is defined as - * follows: - * - * bool endseq(MyClosure* c, const MyHandlerData* d) { - * // Called when a sequence ends. Returns true continue processing. - * return true; - * } - * - * Returns "false" if "f" does not belong to this message or is not a - * repeated field. - */ - bool SetEndSequenceHandler(FieldDefPtr f, const EndFieldHandler &h) { - h.AddCleanup(ptr()); - return upb_handlers_setendseq(ptr(), f.ptr(), h.handler(), &h.attr()); - } - - private: - upb_handlers* ptr_; -}; - -#endif /* __cplusplus */ - -/* upb_handlercache ***********************************************************/ - -/* A upb_handlercache lazily builds and caches upb_handlers. You pass it a - * function (with optional closure) that can build handlers for a given - * message on-demand, and the cache maintains a map of msgdef->handlers. */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct upb_handlercache; -typedef struct upb_handlercache upb_handlercache; - -typedef void upb_handlers_callback(const void *closure, upb_handlers *h); - -upb_handlercache *upb_handlercache_new(upb_handlers_callback *callback, - const void *closure); -void upb_handlercache_free(upb_handlercache *cache); -const upb_handlers *upb_handlercache_get(upb_handlercache *cache, - const upb_msgdef *md); -bool upb_handlercache_addcleanup(upb_handlercache *h, void *p, - upb_handlerfree *hfree); - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::HandlerCache { - public: - HandlerCache(upb_handlers_callback *callback, const void *closure) - : ptr_(upb_handlercache_new(callback, closure), upb_handlercache_free) {} - HandlerCache(HandlerCache&&) = default; - HandlerCache& operator=(HandlerCache&&) = default; - HandlerCache(upb_handlercache* c) : ptr_(c, upb_handlercache_free) {} - - upb_handlercache* ptr() { return ptr_.get(); } - - const upb_handlers *Get(MessageDefPtr md) { - return upb_handlercache_get(ptr_.get(), md.ptr()); - } - - private: - std::unique_ptr ptr_; -}; - -#endif /* __cplusplus */ - -/* upb_byteshandler ***********************************************************/ - -typedef struct { - upb_func *func; - - /* It is wasteful to include the entire attributes here: - * - * * Some of the information is redundant (like storing the closure type - * separately for each handler that must match). - * * Some of the info is only needed prior to freeze() (like closure types). - * * alignment padding wastes a lot of space for alwaysok_. - * - * If/when the size and locality of handlers is an issue, we can optimize this - * not to store the entire attr like this. We do not expose the table's - * layout to allow this optimization in the future. */ - upb_handlerattr attr; -} upb_handlers_tabent; - -#define UPB_TABENT_INIT {NULL, UPB_HANDLERATTR_INIT} - -typedef struct { - upb_handlers_tabent table[3]; -} upb_byteshandler; - -#define UPB_BYTESHANDLER_INIT \ - { \ - { UPB_TABENT_INIT, UPB_TABENT_INIT, UPB_TABENT_INIT } \ - } - -UPB_INLINE void upb_byteshandler_init(upb_byteshandler *handler) { - upb_byteshandler init = UPB_BYTESHANDLER_INIT; - *handler = init; -} - -#ifdef __cplusplus -extern "C" { -#endif - -/* Caller must ensure that "d" outlives the handlers. */ -bool upb_byteshandler_setstartstr(upb_byteshandler *h, - upb_startstr_handlerfunc *func, void *d); -bool upb_byteshandler_setstring(upb_byteshandler *h, - upb_string_handlerfunc *func, void *d); -bool upb_byteshandler_setendstr(upb_byteshandler *h, - upb_endfield_handlerfunc *func, void *d); - -#ifdef __cplusplus -} /* extern "C" */ - -namespace upb { -typedef upb_byteshandler BytesHandler; -} -#endif - -/** Message handlers ******************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* These are the handlers used internally by upb_msgfactory_getmergehandlers(). - * They write scalar data to a known offset from the message pointer. - * - * These would be trivial for anyone to implement themselves, but it's better - * to use these because some JITs will recognize and specialize these instead - * of actually calling the function. */ - -/* Sets a handler for the given primitive field that will write the data at the - * given offset. If hasbit > 0, also sets a hasbit at the given bit offset - * (addressing each byte low to high). */ -bool upb_msg_setscalarhandler(upb_handlers *h, - const upb_fielddef *f, - size_t offset, - int32_t hasbit); - -/* If the given handler is a msghandlers_primitive field, returns true and sets - * *type, *offset and *hasbit. Otherwise returns false. */ -bool upb_msg_getscalarhandlerdata(const upb_handlers *h, - upb_selector_t s, - upb_fieldtype_t *type, - size_t *offset, - int32_t *hasbit); - - - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -/* -** Inline definitions for handlers.h, which are particularly long and a bit -** tricky. -*/ - -#ifndef UPB_HANDLERS_INL_H_ -#define UPB_HANDLERS_INL_H_ - -#include -#include - - -#ifdef __cplusplus - -/* Type detection and typedefs for integer types. - * For platforms where there are multiple 32-bit or 64-bit types, we need to be - * able to enumerate them so we can properly create overloads for all variants. - * - * If any platform existed where there were three integer types with the same - * size, this would have to become more complicated. For example, short, int, - * and long could all be 32-bits. Even more diabolically, short, int, long, - * and long long could all be 64 bits and still be standard-compliant. - * However, few platforms are this strange, and it's unlikely that upb will be - * used on the strangest ones. */ - -/* Can't count on stdint.h limits like INT32_MAX, because in C++ these are - * only defined when __STDC_LIMIT_MACROS are defined before the *first* include - * of stdint.h. We can't guarantee that someone else didn't include these first - * without defining __STDC_LIMIT_MACROS. */ -#define UPB_INT32_MAX 0x7fffffffLL -#define UPB_INT32_MIN (-UPB_INT32_MAX - 1) -#define UPB_INT64_MAX 0x7fffffffffffffffLL -#define UPB_INT64_MIN (-UPB_INT64_MAX - 1) - -#if INT_MAX == UPB_INT32_MAX && INT_MIN == UPB_INT32_MIN -#define UPB_INT_IS_32BITS 1 -#endif - -#if LONG_MAX == UPB_INT32_MAX && LONG_MIN == UPB_INT32_MIN -#define UPB_LONG_IS_32BITS 1 -#endif - -#if LONG_MAX == UPB_INT64_MAX && LONG_MIN == UPB_INT64_MIN -#define UPB_LONG_IS_64BITS 1 -#endif - -#if LLONG_MAX == UPB_INT64_MAX && LLONG_MIN == UPB_INT64_MIN -#define UPB_LLONG_IS_64BITS 1 -#endif - -/* We use macros instead of typedefs so we can undefine them later and avoid - * leaking them outside this header file. */ -#if UPB_INT_IS_32BITS -#define UPB_INT32_T int -#define UPB_UINT32_T unsigned int - -#if UPB_LONG_IS_32BITS -#define UPB_TWO_32BIT_TYPES 1 -#define UPB_INT32ALT_T long -#define UPB_UINT32ALT_T unsigned long -#endif /* UPB_LONG_IS_32BITS */ - -#elif UPB_LONG_IS_32BITS /* && !UPB_INT_IS_32BITS */ -#define UPB_INT32_T long -#define UPB_UINT32_T unsigned long -#endif /* UPB_INT_IS_32BITS */ - - -#if UPB_LONG_IS_64BITS -#define UPB_INT64_T long -#define UPB_UINT64_T unsigned long - -#if UPB_LLONG_IS_64BITS -#define UPB_TWO_64BIT_TYPES 1 -#define UPB_INT64ALT_T long long -#define UPB_UINT64ALT_T unsigned long long -#endif /* UPB_LLONG_IS_64BITS */ - -#elif UPB_LLONG_IS_64BITS /* && !UPB_LONG_IS_64BITS */ -#define UPB_INT64_T long long -#define UPB_UINT64_T unsigned long long -#endif /* UPB_LONG_IS_64BITS */ - -#undef UPB_INT32_MAX -#undef UPB_INT32_MIN -#undef UPB_INT64_MAX -#undef UPB_INT64_MIN -#undef UPB_INT_IS_32BITS -#undef UPB_LONG_IS_32BITS -#undef UPB_LONG_IS_64BITS -#undef UPB_LLONG_IS_64BITS - - -namespace upb { - -typedef void CleanupFunc(void *ptr); - -/* Template to remove "const" from "const T*" and just return "T*". - * - * We define a nonsense default because otherwise it will fail to instantiate as - * a function parameter type even in cases where we don't expect any caller to - * actually match the overload. */ -class CouldntRemoveConst {}; -template struct remove_constptr { typedef CouldntRemoveConst type; }; -template struct remove_constptr { typedef T *type; }; - -/* Template that we use below to remove a template specialization from - * consideration if it matches a specific type. */ -template struct disable_if_same { typedef void Type; }; -template struct disable_if_same {}; - -template void DeletePointer(void *p) { delete static_cast(p); } - -template -struct FirstUnlessVoidOrBool { - typedef T1 value; -}; - -template -struct FirstUnlessVoidOrBool { - typedef T2 value; -}; - -template -struct FirstUnlessVoidOrBool { - typedef T2 value; -}; - -template -struct is_same { - static bool value; -}; - -template -struct is_same { - static bool value; -}; - -template -bool is_same::value = false; - -template -bool is_same::value = true; - -/* FuncInfo *******************************************************************/ - -/* Info about the user's original, pre-wrapped function. */ -template -struct FuncInfo { - /* The type of the closure that the function takes (its first param). */ - typedef C Closure; - - /* The return type. */ - typedef R Return; -}; - -/* Func ***********************************************************************/ - -/* Func1, Func2, Func3: Template classes representing a function and its - * signature. - * - * Since the function is a template parameter, calling the function can be - * inlined at compile-time and does not require a function pointer at runtime. - * These functions are not bound to a handler data so have no data or cleanup - * handler. */ -struct UnboundFunc { - CleanupFunc *GetCleanup() { return nullptr; } - void *GetData() { return nullptr; } -}; - -template -struct Func1 : public UnboundFunc { - typedef R Return; - typedef I FuncInfo; - static R Call(P1 p1) { return F(p1); } -}; - -template -struct Func2 : public UnboundFunc { - typedef R Return; - typedef I FuncInfo; - static R Call(P1 p1, P2 p2) { return F(p1, p2); } -}; - -template -struct Func3 : public UnboundFunc { - typedef R Return; - typedef I FuncInfo; - static R Call(P1 p1, P2 p2, P3 p3) { return F(p1, p2, p3); } -}; - -template -struct Func4 : public UnboundFunc { - typedef R Return; - typedef I FuncInfo; - static R Call(P1 p1, P2 p2, P3 p3, P4 p4) { return F(p1, p2, p3, p4); } -}; - -template -struct Func5 : public UnboundFunc { - typedef R Return; - typedef I FuncInfo; - static R Call(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { - return F(p1, p2, p3, p4, p5); - } -}; - -/* BoundFunc ******************************************************************/ - -/* BoundFunc2, BoundFunc3: Like Func2/Func3 except also contains a value that - * shall be bound to the function's second parameter. - * - * Note that the second parameter is a const pointer, but our stored bound value - * is non-const so we can free it when the handlers are destroyed. */ -template -struct BoundFunc { - typedef typename remove_constptr::type MutableP2; - explicit BoundFunc(MutableP2 data_) : data(data_) {} - CleanupFunc *GetCleanup() { return &DeletePointer; } - MutableP2 GetData() { return data; } - MutableP2 data; -}; - -template -struct BoundFunc2 : public BoundFunc { - typedef BoundFunc Base; - typedef I FuncInfo; - explicit BoundFunc2(typename Base::MutableP2 arg) : Base(arg) {} -}; - -template -struct BoundFunc3 : public BoundFunc { - typedef BoundFunc Base; - typedef I FuncInfo; - explicit BoundFunc3(typename Base::MutableP2 arg) : Base(arg) {} -}; - -template -struct BoundFunc4 : public BoundFunc { - typedef BoundFunc Base; - typedef I FuncInfo; - explicit BoundFunc4(typename Base::MutableP2 arg) : Base(arg) {} -}; - -template -struct BoundFunc5 : public BoundFunc { - typedef BoundFunc Base; - typedef I FuncInfo; - explicit BoundFunc5(typename Base::MutableP2 arg) : Base(arg) {} -}; - -/* FuncSig ********************************************************************/ - -/* FuncSig1, FuncSig2, FuncSig3: template classes reflecting a function - * *signature*, but without a specific function attached. - * - * These classes contain member functions that can be invoked with a - * specific function to return a Func/BoundFunc class. */ -template -struct FuncSig1 { - template - Func1 > GetFunc() { - return Func1 >(); - } -}; - -template -struct FuncSig2 { - template - Func2 > GetFunc() { - return Func2 >(); - } - - template - BoundFunc2 > GetFunc( - typename remove_constptr::type param2) { - return BoundFunc2 >(param2); - } -}; - -template -struct FuncSig3 { - template - Func3 > GetFunc() { - return Func3 >(); - } - - template - BoundFunc3 > GetFunc( - typename remove_constptr::type param2) { - return BoundFunc3 >(param2); - } -}; - -template -struct FuncSig4 { - template - Func4 > GetFunc() { - return Func4 >(); - } - - template - BoundFunc4 > GetFunc( - typename remove_constptr::type param2) { - return BoundFunc4 >(param2); - } -}; - -template -struct FuncSig5 { - template - Func5 > GetFunc() { - return Func5 >(); - } - - template - BoundFunc5 > GetFunc( - typename remove_constptr::type param2) { - return BoundFunc5 >(param2); - } -}; - -/* Overloaded template function that can construct the appropriate FuncSig* - * class given a function pointer by deducing the template parameters. */ -template -inline FuncSig1 MatchFunc(R (*f)(P1)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return FuncSig1(); -} - -template -inline FuncSig2 MatchFunc(R (*f)(P1, P2)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return FuncSig2(); -} - -template -inline FuncSig3 MatchFunc(R (*f)(P1, P2, P3)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return FuncSig3(); -} - -template -inline FuncSig4 MatchFunc(R (*f)(P1, P2, P3, P4)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return FuncSig4(); -} - -template -inline FuncSig5 MatchFunc(R (*f)(P1, P2, P3, P4, P5)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return FuncSig5(); -} - -/* MethodSig ******************************************************************/ - -/* CallMethod*: a function template that calls a given method. */ -template -R CallMethod0(C *obj) { - return ((*obj).*F)(); -} - -template -R CallMethod1(C *obj, P1 arg1) { - return ((*obj).*F)(arg1); -} - -template -R CallMethod2(C *obj, P1 arg1, P2 arg2) { - return ((*obj).*F)(arg1, arg2); -} - -template -R CallMethod3(C *obj, P1 arg1, P2 arg2, P3 arg3) { - return ((*obj).*F)(arg1, arg2, arg3); -} - -template -R CallMethod4(C *obj, P1 arg1, P2 arg2, P3 arg3, P4 arg4) { - return ((*obj).*F)(arg1, arg2, arg3, arg4); -} - -/* MethodSig: like FuncSig, but for member functions. - * - * GetFunc() returns a normal FuncN object, so after calling GetFunc() no - * more logic is required to special-case methods. */ -template -struct MethodSig0 { - template - Func1, FuncInfo > GetFunc() { - return Func1, FuncInfo >(); - } -}; - -template -struct MethodSig1 { - template - Func2, FuncInfo > GetFunc() { - return Func2, FuncInfo >(); - } - - template - BoundFunc2, FuncInfo > GetFunc( - typename remove_constptr::type param1) { - return BoundFunc2, FuncInfo >( - param1); - } -}; - -template -struct MethodSig2 { - template - Func3, FuncInfo > - GetFunc() { - return Func3, - FuncInfo >(); - } - - template - BoundFunc3, FuncInfo > - GetFunc(typename remove_constptr::type param1) { - return BoundFunc3, - FuncInfo >(param1); - } -}; - -template -struct MethodSig3 { - template - Func4, FuncInfo > - GetFunc() { - return Func4, - FuncInfo >(); - } - - template - BoundFunc4, - FuncInfo > - GetFunc(typename remove_constptr::type param1) { - return BoundFunc4, - FuncInfo >(param1); - } -}; - -template -struct MethodSig4 { - template - Func5, - FuncInfo > - GetFunc() { - return Func5, - FuncInfo >(); - } - - template - BoundFunc5, - FuncInfo > - GetFunc(typename remove_constptr::type param1) { - return BoundFunc5, FuncInfo >( - param1); - } -}; - -template -inline MethodSig0 MatchFunc(R (C::*f)()) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return MethodSig0(); -} - -template -inline MethodSig1 MatchFunc(R (C::*f)(P1)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return MethodSig1(); -} - -template -inline MethodSig2 MatchFunc(R (C::*f)(P1, P2)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return MethodSig2(); -} - -template -inline MethodSig3 MatchFunc(R (C::*f)(P1, P2, P3)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return MethodSig3(); -} - -template -inline MethodSig4 MatchFunc(R (C::*f)(P1, P2, P3, P4)) { - UPB_UNUSED(f); /* Only used for template parameter deduction. */ - return MethodSig4(); -} - -/* MaybeWrapReturn ************************************************************/ - -/* Template class that attempts to wrap the return value of the function so it - * matches the expected type. There are two main adjustments it may make: - * - * 1. If the function returns void, make it return the expected type and with - * a value that always indicates success. - * 2. If the function returns bool, make it return the expected type with a - * value that indicates success or failure. - * - * The "expected type" for return is: - * 1. void* for start handlers. If the closure parameter has a different type - * we will cast it to void* for the return in the success case. - * 2. size_t for string buffer handlers. - * 3. bool for everything else. */ - -/* Template parameters are FuncN type and desired return type. */ -template -struct MaybeWrapReturn; - -/* If the return type matches, return the given function unwrapped. */ -template -struct MaybeWrapReturn { - typedef F Func; -}; - -/* Function wrapper that munges the return value from void to (bool)true. */ -template -bool ReturnTrue2(P1 p1, P2 p2) { - F(p1, p2); - return true; -} - -template -bool ReturnTrue3(P1 p1, P2 p2, P3 p3) { - F(p1, p2, p3); - return true; -} - -/* Function wrapper that munges the return value from void to (void*)arg1 */ -template -void *ReturnClosure2(P1 p1, P2 p2) { - F(p1, p2); - return p1; -} - -template -void *ReturnClosure3(P1 p1, P2 p2, P3 p3) { - F(p1, p2, p3); - return p1; -} - -/* Function wrapper that munges the return value from R to void*. */ -template -void *CastReturnToVoidPtr2(P1 p1, P2 p2) { - return F(p1, p2); -} - -template -void *CastReturnToVoidPtr3(P1 p1, P2 p2, P3 p3) { - return F(p1, p2, p3); -} - -/* Function wrapper that munges the return value from bool to void*. */ -template -void *ReturnClosureOrBreak2(P1 p1, P2 p2) { - return F(p1, p2) ? p1 : UPB_BREAK; -} - -template -void *ReturnClosureOrBreak3(P1 p1, P2 p2, P3 p3) { - return F(p1, p2, p3) ? p1 : UPB_BREAK; -} - -/* For the string callback, which takes five params, returns the size param. */ -template -size_t ReturnStringLen(P1 p1, P2 p2, const char *p3, size_t p4, - const upb_bufhandle *p5) { - F(p1, p2, p3, p4, p5); - return p4; -} - -/* For the string callback, which takes five params, returns the size param or - * zero. */ -template -size_t ReturnNOr0(P1 p1, P2 p2, const char *p3, size_t p4, - const upb_bufhandle *p5) { - return F(p1, p2, p3, p4, p5) ? p4 : 0; -} - -/* If we have a function returning void but want a function returning bool, wrap - * it in a function that returns true. */ -template -struct MaybeWrapReturn, bool> { - typedef Func2, I> Func; -}; - -template -struct MaybeWrapReturn, bool> { - typedef Func3, I> Func; -}; - -/* If our function returns void but we want one returning void*, wrap it in a - * function that returns the first argument. */ -template -struct MaybeWrapReturn, void *> { - typedef Func2, I> Func; -}; - -template -struct MaybeWrapReturn, void *> { - typedef Func3, I> Func; -}; - -/* If our function returns R* but we want one returning void*, wrap it in a - * function that casts to void*. */ -template -struct MaybeWrapReturn, void *, - typename disable_if_same::Type> { - typedef Func2, I> Func; -}; - -template -struct MaybeWrapReturn, void *, - typename disable_if_same::Type> { - typedef Func3, I> - Func; -}; - -/* If our function returns bool but we want one returning void*, wrap it in a - * function that returns either the first param or UPB_BREAK. */ -template -struct MaybeWrapReturn, void *> { - typedef Func2, I> Func; -}; - -template -struct MaybeWrapReturn, void *> { - typedef Func3, I> - Func; -}; - -/* If our function returns void but we want one returning size_t, wrap it in a - * function that returns the size argument. */ -template -struct MaybeWrapReturn< - Func5, - size_t> { - typedef Func5, I> Func; -}; - -/* If our function returns bool but we want one returning size_t, wrap it in a - * function that returns either 0 or the buf size. */ -template -struct MaybeWrapReturn< - Func5, - size_t> { - typedef Func5, I> Func; -}; - -/* ConvertParams **************************************************************/ - -/* Template class that converts the function parameters if necessary, and - * ignores the HandlerData parameter if appropriate. - * - * Template parameter is the are FuncN function type. */ -template -struct ConvertParams; - -/* Function that discards the handler data parameter. */ -template -R IgnoreHandlerData2(void *p1, const void *hd) { - UPB_UNUSED(hd); - return F(static_cast(p1)); -} - -template -R IgnoreHandlerData3(void *p1, const void *hd, P2Wrapper p2) { - UPB_UNUSED(hd); - return F(static_cast(p1), p2); -} - -template -R IgnoreHandlerData4(void *p1, const void *hd, P2 p2, P3 p3) { - UPB_UNUSED(hd); - return F(static_cast(p1), p2, p3); -} - -template -R IgnoreHandlerData5(void *p1, const void *hd, P2 p2, P3 p3, P4 p4) { - UPB_UNUSED(hd); - return F(static_cast(p1), p2, p3, p4); -} - -template -R IgnoreHandlerDataIgnoreHandle(void *p1, const void *hd, const char *p2, - size_t p3, const upb_bufhandle *handle) { - UPB_UNUSED(hd); - UPB_UNUSED(handle); - return F(static_cast(p1), p2, p3); -} - -/* Function that casts the handler data parameter. */ -template -R CastHandlerData2(void *c, const void *hd) { - return F(static_cast(c), static_cast(hd)); -} - -template -R CastHandlerData3(void *c, const void *hd, P3Wrapper p3) { - return F(static_cast(c), static_cast(hd), p3); -} - -template -R CastHandlerData5(void *c, const void *hd, P3 p3, P4 p4, P5 p5) { - return F(static_cast(c), static_cast(hd), p3, p4, p5); -} - -template -R CastHandlerDataIgnoreHandle(void *c, const void *hd, const char *p3, - size_t p4, const upb_bufhandle *handle) { - UPB_UNUSED(handle); - return F(static_cast(c), static_cast(hd), p3, p4); -} - -/* For unbound functions, ignore the handler data. */ -template -struct ConvertParams, T> { - typedef Func2, I> Func; -}; - -template -struct ConvertParams, - R2 (*)(P1_2, P2_2, P3_2)> { - typedef Func3, I> Func; -}; - -/* For StringBuffer only; this ignores both the handler data and the - * upb_bufhandle. */ -template -struct ConvertParams, T> { - typedef Func5, - I> Func; -}; - -template -struct ConvertParams, T> { - typedef Func5, I> Func; -}; - -/* For bound functions, cast the handler data. */ -template -struct ConvertParams, T> { - typedef Func2, I> - Func; -}; - -template -struct ConvertParams, - R2 (*)(P1_2, P2_2, P3_2)> { - typedef Func3, I> Func; -}; - -/* For StringBuffer only; this ignores the upb_bufhandle. */ -template -struct ConvertParams, T> { - typedef Func5, I> - Func; -}; - -template -struct ConvertParams, T> { - typedef Func5, I> Func; -}; - -/* utype/ltype are upper/lower-case, ctype is canonical C type, vtype is - * variant C type. */ -#define TYPE_METHODS(utype, ltype, ctype, vtype) \ - template <> \ - struct CanonicalType { \ - typedef ctype Type; \ - }; \ - template <> \ - inline bool HandlersPtr::SetValueHandler( \ - FieldDefPtr f, const HandlersPtr::utype##Handler &handler) { \ - handler.AddCleanup(ptr()); \ - return upb_handlers_set##ltype(ptr(), f.ptr(), handler.handler(), \ - &handler.attr()); \ - } - -TYPE_METHODS(Double, double, double, double) -TYPE_METHODS(Float, float, float, float) -TYPE_METHODS(UInt64, uint64, uint64_t, UPB_UINT64_T) -TYPE_METHODS(UInt32, uint32, uint32_t, UPB_UINT32_T) -TYPE_METHODS(Int64, int64, int64_t, UPB_INT64_T) -TYPE_METHODS(Int32, int32, int32_t, UPB_INT32_T) -TYPE_METHODS(Bool, bool, bool, bool) - -#ifdef UPB_TWO_32BIT_TYPES -TYPE_METHODS(Int32, int32, int32_t, UPB_INT32ALT_T) -TYPE_METHODS(UInt32, uint32, uint32_t, UPB_UINT32ALT_T) -#endif - -#ifdef UPB_TWO_64BIT_TYPES -TYPE_METHODS(Int64, int64, int64_t, UPB_INT64ALT_T) -TYPE_METHODS(UInt64, uint64, uint64_t, UPB_UINT64ALT_T) -#endif -#undef TYPE_METHODS - -template <> struct CanonicalType { - typedef Status* Type; -}; - -template struct ReturnOf; - -template -struct ReturnOf { - typedef R Return; -}; - -template -struct ReturnOf { - typedef R Return; -}; - -template -struct ReturnOf { - typedef R Return; -}; - -template -struct ReturnOf { - typedef R Return; -}; - - -template -template -inline Handler::Handler(F func) - : registered_(false), - cleanup_data_(func.GetData()), - cleanup_func_(func.GetCleanup()) { - attr_.handler_data = func.GetData(); - typedef typename ReturnOf::Return Return; - typedef typename ConvertParams::Func ConvertedParamsFunc; - typedef typename MaybeWrapReturn::Func - ReturnWrappedFunc; - handler_ = ReturnWrappedFunc().Call; - - /* Set attributes based on what templates can statically tell us about the - * user's function. */ - - /* If the original function returns void, then we know that we wrapped it to - * always return ok. */ - bool always_ok = is_same::value; - attr_.alwaysok = always_ok; - - /* Closure parameter and return type. */ - attr_.closure_type = UniquePtrForType(); - - /* We use the closure type (from the first parameter) if the return type is - * void or bool, since these are the two cases we wrap to return the closure's - * type anyway. - * - * This is all nonsense for non START* handlers, but it doesn't matter because - * in that case the value will be ignored. */ - typedef typename FirstUnlessVoidOrBool::value - EffectiveReturn; - attr_.return_closure_type = UniquePtrForType(); -} - -template -inline void Handler::AddCleanup(upb_handlers* h) const { - UPB_ASSERT(!registered_); - registered_ = true; - if (cleanup_func_) { - bool ok = upb_handlers_addcleanup(h, cleanup_data_, cleanup_func_); - UPB_ASSERT(ok); - } -} - -} /* namespace upb */ - -#endif /* __cplusplus */ - - -#undef UPB_TWO_32BIT_TYPES -#undef UPB_TWO_64BIT_TYPES -#undef UPB_INT32_T -#undef UPB_UINT32_T -#undef UPB_INT32ALT_T -#undef UPB_UINT32ALT_T -#undef UPB_INT64_T -#undef UPB_UINT64_T -#undef UPB_INT64ALT_T -#undef UPB_UINT64ALT_T - - -#endif /* UPB_HANDLERS_INL_H_ */ - -#endif /* UPB_HANDLERS_H */ -/* -** upb::Sink (upb_sink) -** upb::BytesSink (upb_bytessink) -** -** A upb_sink is an object that binds a upb_handlers object to some runtime -** state. It is the object that can actually receive data via the upb_handlers -** interface. -** -** Unlike upb_def and upb_handlers, upb_sink is never frozen, immutable, or -** thread-safe. You can create as many of them as you want, but each one may -** only be used in a single thread at a time. -** -** If we compare with class-based OOP, a you can think of a upb_def as an -** abstract base class, a upb_handlers as a concrete derived class, and a -** upb_sink as an object (class instance). -*/ - -#ifndef UPB_SINK_H -#define UPB_SINK_H - - - -#ifdef __cplusplus -namespace upb { -class BytesSink; -class Sink; -} -#endif - -/* upb_sink *******************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - const upb_handlers *handlers; - void *closure; -} upb_sink; - -#define PUTVAL(type, ctype) \ - UPB_INLINE bool upb_sink_put##type(upb_sink s, upb_selector_t sel, \ - ctype val) { \ - typedef upb_##type##_handlerfunc functype; \ - functype *func; \ - const void *hd; \ - if (!s.handlers) return true; \ - func = (functype *)upb_handlers_gethandler(s.handlers, sel, &hd); \ - if (!func) return true; \ - return func(s.closure, hd, val); \ - } - -PUTVAL(int32, int32_t) -PUTVAL(int64, int64_t) -PUTVAL(uint32, uint32_t) -PUTVAL(uint64, uint64_t) -PUTVAL(float, float) -PUTVAL(double, double) -PUTVAL(bool, bool) -#undef PUTVAL - -UPB_INLINE void upb_sink_reset(upb_sink *s, const upb_handlers *h, void *c) { - s->handlers = h; - s->closure = c; -} - -UPB_INLINE size_t upb_sink_putstring(upb_sink s, upb_selector_t sel, - const char *buf, size_t n, - const upb_bufhandle *handle) { - typedef upb_string_handlerfunc func; - func *handler; - const void *hd; - if (!s.handlers) return n; - handler = (func *)upb_handlers_gethandler(s.handlers, sel, &hd); - - if (!handler) return n; - return handler(s.closure, hd, buf, n, handle); -} - -UPB_INLINE bool upb_sink_putunknown(upb_sink s, const char *buf, size_t n) { - typedef upb_unknown_handlerfunc func; - func *handler; - const void *hd; - if (!s.handlers) return true; - handler = - (func *)upb_handlers_gethandler(s.handlers, UPB_UNKNOWN_SELECTOR, &hd); - - if (!handler) return n; - return handler(s.closure, hd, buf, n); -} - -UPB_INLINE bool upb_sink_startmsg(upb_sink s) { - typedef upb_startmsg_handlerfunc func; - func *startmsg; - const void *hd; - if (!s.handlers) return true; - startmsg = - (func *)upb_handlers_gethandler(s.handlers, UPB_STARTMSG_SELECTOR, &hd); - - if (!startmsg) return true; - return startmsg(s.closure, hd); -} - -UPB_INLINE bool upb_sink_endmsg(upb_sink s, upb_status *status) { - typedef upb_endmsg_handlerfunc func; - func *endmsg; - const void *hd; - if (!s.handlers) return true; - endmsg = - (func *)upb_handlers_gethandler(s.handlers, UPB_ENDMSG_SELECTOR, &hd); - - if (!endmsg) return true; - return endmsg(s.closure, hd, status); -} - -UPB_INLINE bool upb_sink_startseq(upb_sink s, upb_selector_t sel, - upb_sink *sub) { - typedef upb_startfield_handlerfunc func; - func *startseq; - const void *hd; - sub->closure = s.closure; - sub->handlers = s.handlers; - if (!s.handlers) return true; - startseq = (func*)upb_handlers_gethandler(s.handlers, sel, &hd); - - if (!startseq) return true; - sub->closure = startseq(s.closure, hd); - return sub->closure ? true : false; -} - -UPB_INLINE bool upb_sink_endseq(upb_sink s, upb_selector_t sel) { - typedef upb_endfield_handlerfunc func; - func *endseq; - const void *hd; - if (!s.handlers) return true; - endseq = (func*)upb_handlers_gethandler(s.handlers, sel, &hd); - - if (!endseq) return true; - return endseq(s.closure, hd); -} - -UPB_INLINE bool upb_sink_startstr(upb_sink s, upb_selector_t sel, - size_t size_hint, upb_sink *sub) { - typedef upb_startstr_handlerfunc func; - func *startstr; - const void *hd; - sub->closure = s.closure; - sub->handlers = s.handlers; - if (!s.handlers) return true; - startstr = (func*)upb_handlers_gethandler(s.handlers, sel, &hd); - - if (!startstr) return true; - sub->closure = startstr(s.closure, hd, size_hint); - return sub->closure ? true : false; -} - -UPB_INLINE bool upb_sink_endstr(upb_sink s, upb_selector_t sel) { - typedef upb_endfield_handlerfunc func; - func *endstr; - const void *hd; - if (!s.handlers) return true; - endstr = (func*)upb_handlers_gethandler(s.handlers, sel, &hd); - - if (!endstr) return true; - return endstr(s.closure, hd); -} - -UPB_INLINE bool upb_sink_startsubmsg(upb_sink s, upb_selector_t sel, - upb_sink *sub) { - typedef upb_startfield_handlerfunc func; - func *startsubmsg; - const void *hd; - sub->closure = s.closure; - if (!s.handlers) { - sub->handlers = NULL; - return true; - } - sub->handlers = upb_handlers_getsubhandlers_sel(s.handlers, sel); - startsubmsg = (func*)upb_handlers_gethandler(s.handlers, sel, &hd); - - if (!startsubmsg) return true; - sub->closure = startsubmsg(s.closure, hd); - return sub->closure ? true : false; -} - -UPB_INLINE bool upb_sink_endsubmsg(upb_sink s, upb_sink sub, - upb_selector_t sel) { - typedef upb_endfield_handlerfunc func; - func *endsubmsg; - const void *hd; - if (!s.handlers) return true; - endsubmsg = (func*)upb_handlers_gethandler(s.handlers, sel, &hd); - - if (!endsubmsg) return true; - return endsubmsg(sub.closure, hd); -} - -#ifdef __cplusplus -} /* extern "C" */ - -/* A upb::Sink is an object that binds a upb::Handlers object to some runtime - * state. It represents an endpoint to which data can be sent. - * - * TODO(haberman): right now all of these functions take selectors. Should they - * take selectorbase instead? - * - * ie. instead of calling: - * sink->StartString(FOO_FIELD_START_STRING, ...) - * a selector base would let you say: - * sink->StartString(FOO_FIELD, ...) - * - * This would make call sites a little nicer and require emitting fewer selector - * definitions in .h files. - * - * But the current scheme has the benefit that you can retrieve a function - * pointer for any handler with handlers->GetHandler(selector), without having - * to have a separate GetHandler() function for each handler type. The JIT - * compiler uses this. To accommodate we'd have to expose a separate - * GetHandler() for every handler type. - * - * Also to ponder: selectors right now are independent of a specific Handlers - * instance. In other words, they allocate a number to every possible handler - * that *could* be registered, without knowing anything about what handlers - * *are* registered. That means that using selectors as table offsets prohibits - * us from compacting the handler table at Freeze() time. If the table is very - * sparse, this could be wasteful. - * - * Having another selector-like thing that is specific to a Handlers instance - * would allow this compacting, but then it would be impossible to write code - * ahead-of-time that can be bound to any Handlers instance at runtime. For - * example, a .proto file parser written as straight C will not know what - * Handlers it will be bound to, so when it calls sink->StartString() what - * selector will it pass? It needs a selector like we have today, that is - * independent of any particular upb::Handlers. - * - * Is there a way then to allow Handlers table compaction? */ -class upb::Sink { - public: - /* Constructor with no initialization; must be Reset() before use. */ - Sink() {} - - Sink(const Sink&) = default; - Sink& operator=(const Sink&) = default; - - Sink(const upb_sink& sink) : sink_(sink) {} - Sink &operator=(const upb_sink &sink) { - sink_ = sink; - return *this; - } - - upb_sink sink() { return sink_; } - - /* Constructs a new sink for the given frozen handlers and closure. - * - * TODO: once the Handlers know the expected closure type, verify that T - * matches it. */ - template Sink(const upb_handlers* handlers, T* closure) { - Reset(handlers, closure); - } - - upb_sink* ptr() { return &sink_; } - - /* Resets the value of the sink. */ - template void Reset(const upb_handlers* handlers, T* closure) { - upb_sink_reset(&sink_, handlers, closure); - } - - /* Returns the top-level object that is bound to this sink. - * - * TODO: once the Handlers know the expected closure type, verify that T - * matches it. */ - template T* GetObject() const { - return static_cast(sink_.closure); - } - - /* Functions for pushing data into the sink. - * - * These return false if processing should stop (either due to error or just - * to suspend). - * - * These may not be called from within one of the same sink's handlers (in - * other words, handlers are not re-entrant). */ - - /* Should be called at the start and end of every message; both the top-level - * message and submessages. This means that submessages should use the - * following sequence: - * sink->StartSubMessage(startsubmsg_selector); - * sink->StartMessage(); - * // ... - * sink->EndMessage(&status); - * sink->EndSubMessage(endsubmsg_selector); */ - bool StartMessage() { return upb_sink_startmsg(sink_); } - bool EndMessage(upb_status *status) { - return upb_sink_endmsg(sink_, status); - } - - /* Putting of individual values. These work for both repeated and - * non-repeated fields, but for repeated fields you must wrap them in - * calls to StartSequence()/EndSequence(). */ - bool PutInt32(HandlersPtr::Selector s, int32_t val) { - return upb_sink_putint32(sink_, s, val); - } - - bool PutInt64(HandlersPtr::Selector s, int64_t val) { - return upb_sink_putint64(sink_, s, val); - } - - bool PutUInt32(HandlersPtr::Selector s, uint32_t val) { - return upb_sink_putuint32(sink_, s, val); - } - - bool PutUInt64(HandlersPtr::Selector s, uint64_t val) { - return upb_sink_putuint64(sink_, s, val); - } - - bool PutFloat(HandlersPtr::Selector s, float val) { - return upb_sink_putfloat(sink_, s, val); - } - - bool PutDouble(HandlersPtr::Selector s, double val) { - return upb_sink_putdouble(sink_, s, val); - } - - bool PutBool(HandlersPtr::Selector s, bool val) { - return upb_sink_putbool(sink_, s, val); - } - - /* Putting of string/bytes values. Each string can consist of zero or more - * non-contiguous buffers of data. - * - * For StartString(), the function will write a sink for the string to "sub." - * The sub-sink must be used for any/all PutStringBuffer() calls. */ - bool StartString(HandlersPtr::Selector s, size_t size_hint, Sink* sub) { - upb_sink sub_c; - bool ret = upb_sink_startstr(sink_, s, size_hint, &sub_c); - *sub = sub_c; - return ret; - } - - size_t PutStringBuffer(HandlersPtr::Selector s, const char *buf, size_t len, - const upb_bufhandle *handle) { - return upb_sink_putstring(sink_, s, buf, len, handle); - } - - bool EndString(HandlersPtr::Selector s) { - return upb_sink_endstr(sink_, s); - } - - /* For submessage fields. - * - * For StartSubMessage(), the function will write a sink for the string to - * "sub." The sub-sink must be used for any/all handlers called within the - * submessage. */ - bool StartSubMessage(HandlersPtr::Selector s, Sink* sub) { - upb_sink sub_c; - bool ret = upb_sink_startsubmsg(sink_, s, &sub_c); - *sub = sub_c; - return ret; - } - - bool EndSubMessage(HandlersPtr::Selector s, Sink sub) { - return upb_sink_endsubmsg(sink_, sub.sink_, s); - } - - /* For repeated fields of any type, the sequence of values must be wrapped in - * these calls. - * - * For StartSequence(), the function will write a sink for the string to - * "sub." The sub-sink must be used for any/all handlers called within the - * sequence. */ - bool StartSequence(HandlersPtr::Selector s, Sink* sub) { - upb_sink sub_c; - bool ret = upb_sink_startseq(sink_, s, &sub_c); - *sub = sub_c; - return ret; - } - - bool EndSequence(HandlersPtr::Selector s) { - return upb_sink_endseq(sink_, s); - } - - /* Copy and assign specifically allowed. - * We don't even bother making these members private because so many - * functions need them and this is mainly just a dumb data container anyway. - */ - - private: - upb_sink sink_; -}; - -#endif /* __cplusplus */ - -/* upb_bytessink **************************************************************/ - -typedef struct { - const upb_byteshandler *handler; - void *closure; -} upb_bytessink ; - -UPB_INLINE void upb_bytessink_reset(upb_bytessink* s, const upb_byteshandler *h, - void *closure) { - s->handler = h; - s->closure = closure; -} - -UPB_INLINE bool upb_bytessink_start(upb_bytessink s, size_t size_hint, - void **subc) { - typedef upb_startstr_handlerfunc func; - func *start; - *subc = s.closure; - if (!s.handler) return true; - start = (func *)s.handler->table[UPB_STARTSTR_SELECTOR].func; - - if (!start) return true; - *subc = start(s.closure, - s.handler->table[UPB_STARTSTR_SELECTOR].attr.handler_data, - size_hint); - return *subc != NULL; -} - -UPB_INLINE size_t upb_bytessink_putbuf(upb_bytessink s, void *subc, - const char *buf, size_t size, - const upb_bufhandle* handle) { - typedef upb_string_handlerfunc func; - func *putbuf; - if (!s.handler) return true; - putbuf = (func *)s.handler->table[UPB_STRING_SELECTOR].func; - - if (!putbuf) return true; - return putbuf(subc, s.handler->table[UPB_STRING_SELECTOR].attr.handler_data, - buf, size, handle); -} - -UPB_INLINE bool upb_bytessink_end(upb_bytessink s) { - typedef upb_endfield_handlerfunc func; - func *end; - if (!s.handler) return true; - end = (func *)s.handler->table[UPB_ENDSTR_SELECTOR].func; - - if (!end) return true; - return end(s.closure, - s.handler->table[UPB_ENDSTR_SELECTOR].attr.handler_data); -} - -#ifdef __cplusplus - -class upb::BytesSink { - public: - BytesSink() {} - - BytesSink(const BytesSink&) = default; - BytesSink& operator=(const BytesSink&) = default; - - BytesSink(const upb_bytessink& sink) : sink_(sink) {} - BytesSink &operator=(const upb_bytessink &sink) { - sink_ = sink; - return *this; - } - - upb_bytessink sink() { return sink_; } - - /* Constructs a new sink for the given frozen handlers and closure. - * - * TODO(haberman): once the Handlers know the expected closure type, verify - * that T matches it. */ - template BytesSink(const upb_byteshandler* handler, T* closure) { - upb_bytessink_reset(sink_, handler, closure); - } - - /* Resets the value of the sink. */ - template void Reset(const upb_byteshandler* handler, T* closure) { - upb_bytessink_reset(&sink_, handler, closure); - } - - bool Start(size_t size_hint, void **subc) { - return upb_bytessink_start(sink_, size_hint, subc); - } - - size_t PutBuffer(void *subc, const char *buf, size_t len, - const upb_bufhandle *handle) { - return upb_bytessink_putbuf(sink_, subc, buf, len, handle); - } - - bool End() { - return upb_bytessink_end(sink_); - } - - private: - upb_bytessink sink_; -}; - -#endif /* __cplusplus */ - -/* upb_bufsrc *****************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink); - -#ifdef __cplusplus -} /* extern "C" */ - -namespace upb { -template bool PutBuffer(const T& str, BytesSink sink) { - return upb_bufsrc_putbuf(str.data(), str.size(), sink.sink()); -} -} - -#endif /* __cplusplus */ - - -#endif -/* -** Internal-only definitions for the decoder. -*/ - -#ifndef UPB_DECODER_INT_H_ -#define UPB_DECODER_INT_H_ - -/* -** upb::pb::Decoder -** -** A high performance, streaming, resumable decoder for the binary protobuf -** format. -** -** This interface works the same regardless of what decoder backend is being -** used. A client of this class does not need to know whether decoding is using -** a JITted decoder (DynASM, LLVM, etc) or an interpreted decoder. By default, -** it will always use the fastest available decoder. However, you can call -** set_allow_jit(false) to disable any JIT decoder that might be available. -** This is primarily useful for testing purposes. -*/ - -#ifndef UPB_DECODER_H_ -#define UPB_DECODER_H_ - - -#ifdef __cplusplus -namespace upb { -namespace pb { -class CodeCache; -class DecoderPtr; -class DecoderMethodPtr; -class DecoderMethodOptions; -} /* namespace pb */ -} /* namespace upb */ -#endif - -/* The maximum number of bytes we are required to buffer internally between - * calls to the decoder. The value is 14: a 5 byte unknown tag plus ten-byte - * varint, less one because we are buffering an incomplete value. - * - * Should only be used by unit tests. */ -#define UPB_DECODER_MAX_RESIDUAL_BYTES 14 - -/* upb_pbdecodermethod ********************************************************/ - -struct upb_pbdecodermethod; -typedef struct upb_pbdecodermethod upb_pbdecodermethod; - -#ifdef __cplusplus -extern "C" { -#endif - -const upb_handlers *upb_pbdecodermethod_desthandlers( - const upb_pbdecodermethod *m); -const upb_byteshandler *upb_pbdecodermethod_inputhandler( - const upb_pbdecodermethod *m); -bool upb_pbdecodermethod_isnative(const upb_pbdecodermethod *m); - -#ifdef __cplusplus -} /* extern "C" */ - -/* Represents the code to parse a protobuf according to a destination - * Handlers. */ -class upb::pb::DecoderMethodPtr { - public: - DecoderMethodPtr() : ptr_(nullptr) {} - DecoderMethodPtr(const upb_pbdecodermethod* ptr) : ptr_(ptr) {} - - const upb_pbdecodermethod* ptr() { return ptr_; } - - /* The destination handlers that are statically bound to this method. - * This method is only capable of outputting to a sink that uses these - * handlers. */ - const Handlers *dest_handlers() const { - return upb_pbdecodermethod_desthandlers(ptr_); - } - - /* The input handlers for this decoder method. */ - const BytesHandler* input_handler() const { - return upb_pbdecodermethod_inputhandler(ptr_); - } - - /* Whether this method is native. */ - bool is_native() const { - return upb_pbdecodermethod_isnative(ptr_); - } - - private: - const upb_pbdecodermethod* ptr_; -}; - -#endif - -/* upb_pbdecoder **************************************************************/ - -/* Preallocation hint: decoder won't allocate more bytes than this when first - * constructed. This hint may be an overestimate for some build configurations. - * But if the decoder library is upgraded without recompiling the application, - * it may be an underestimate. */ -#define UPB_PB_DECODER_SIZE 4416 - -struct upb_pbdecoder; -typedef struct upb_pbdecoder upb_pbdecoder; - -#ifdef __cplusplus -extern "C" { -#endif - -upb_pbdecoder *upb_pbdecoder_create(upb_arena *arena, - const upb_pbdecodermethod *method, - upb_sink output, upb_status *status); -const upb_pbdecodermethod *upb_pbdecoder_method(const upb_pbdecoder *d); -upb_bytessink upb_pbdecoder_input(upb_pbdecoder *d); -uint64_t upb_pbdecoder_bytesparsed(const upb_pbdecoder *d); -size_t upb_pbdecoder_maxnesting(const upb_pbdecoder *d); -bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max); -void upb_pbdecoder_reset(upb_pbdecoder *d); - -#ifdef __cplusplus -} /* extern "C" */ - -/* A Decoder receives binary protobuf data on its input sink and pushes the - * decoded data to its output sink. */ -class upb::pb::DecoderPtr { - public: - DecoderPtr() : ptr_(nullptr) {} - DecoderPtr(upb_pbdecoder* ptr) : ptr_(ptr) {} - - upb_pbdecoder* ptr() { return ptr_; } - - /* Constructs a decoder instance for the given method, which must outlive this - * decoder. Any errors during parsing will be set on the given status, which - * must also outlive this decoder. - * - * The sink must match the given method. */ - static DecoderPtr Create(Arena *arena, DecoderMethodPtr method, - upb::Sink output, Status *status) { - return DecoderPtr(upb_pbdecoder_create(arena->ptr(), method.ptr(), - output.sink(), status->ptr())); - } - - /* Returns the DecoderMethod this decoder is parsing from. */ - const DecoderMethodPtr method() const { - return DecoderMethodPtr(upb_pbdecoder_method(ptr_)); - } - - /* The sink on which this decoder receives input. */ - BytesSink input() { return BytesSink(upb_pbdecoder_input(ptr())); } - - /* Returns number of bytes successfully parsed. - * - * This can be useful for determining the stream position where an error - * occurred. - * - * This value may not be up-to-date when called from inside a parsing - * callback. */ - uint64_t BytesParsed() { return upb_pbdecoder_bytesparsed(ptr()); } - - /* Gets/sets the parsing nexting limit. If the total number of nested - * submessages and repeated fields hits this limit, parsing will fail. This - * is a resource limit that controls the amount of memory used by the parsing - * stack. - * - * Setting the limit will fail if the parser is currently suspended at a depth - * greater than this, or if memory allocation of the stack fails. */ - size_t max_nesting() { return upb_pbdecoder_maxnesting(ptr()); } - bool set_max_nesting(size_t max) { return upb_pbdecoder_maxnesting(ptr()); } - - void Reset() { upb_pbdecoder_reset(ptr()); } - - static const size_t kSize = UPB_PB_DECODER_SIZE; - - private: - upb_pbdecoder *ptr_; -}; - -#endif /* __cplusplus */ - -/* upb_pbcodecache ************************************************************/ - -/* Lazily builds and caches decoder methods that will push data to the given - * handlers. The destination handlercache must outlive this object. */ - -struct upb_pbcodecache; -typedef struct upb_pbcodecache upb_pbcodecache; - -#ifdef __cplusplus -extern "C" { -#endif - -upb_pbcodecache *upb_pbcodecache_new(upb_handlercache *dest); -void upb_pbcodecache_free(upb_pbcodecache *c); -bool upb_pbcodecache_allowjit(const upb_pbcodecache *c); -void upb_pbcodecache_setallowjit(upb_pbcodecache *c, bool allow); -void upb_pbcodecache_setlazy(upb_pbcodecache *c, bool lazy); -const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c, - const upb_msgdef *md); - -#ifdef __cplusplus -} /* extern "C" */ - -/* A class for caching protobuf processing code, whether bytecode for the - * interpreted decoder or machine code for the JIT. - * - * This class is not thread-safe. */ -class upb::pb::CodeCache { - public: - CodeCache(upb::HandlerCache *dest) - : ptr_(upb_pbcodecache_new(dest->ptr()), upb_pbcodecache_free) {} - CodeCache(CodeCache&&) = default; - CodeCache& operator=(CodeCache&&) = default; - - upb_pbcodecache* ptr() { return ptr_.get(); } - const upb_pbcodecache* ptr() const { return ptr_.get(); } - - /* Whether the cache is allowed to generate machine code. Defaults to true. - * There is no real reason to turn it off except for testing or if you are - * having a specific problem with the JIT. - * - * Note that allow_jit = true does not *guarantee* that the code will be JIT - * compiled. If this platform is not supported or the JIT was not compiled - * in, the code may still be interpreted. */ - bool allow_jit() const { return upb_pbcodecache_allowjit(ptr()); } - - /* This may only be called when the object is first constructed, and prior to - * any code generation. */ - void set_allow_jit(bool allow) { upb_pbcodecache_setallowjit(ptr(), allow); } - - /* Should the decoder push submessages to lazy handlers for fields that have - * them? The caller should set this iff the lazy handlers expect data that is - * in protobuf binary format and the caller wishes to lazy parse it. */ - void set_lazy(bool lazy) { upb_pbcodecache_setlazy(ptr(), lazy); } - - /* Returns a DecoderMethod that can push data to the given handlers. - * If a suitable method already exists, it will be returned from the cache. */ - const DecoderMethodPtr Get(MessageDefPtr md) { - return DecoderMethodPtr(upb_pbcodecache_get(ptr(), md.ptr())); - } - - private: - std::unique_ptr ptr_; -}; - -#endif /* __cplusplus */ - -#endif /* UPB_DECODER_H_ */ - - -/* Opcode definitions. The canonical meaning of each opcode is its - * implementation in the interpreter (the JIT is written to match this). - * - * All instructions have the opcode in the low byte. - * Instruction format for most instructions is: - * - * +-------------------+--------+ - * | arg (24) | op (8) | - * +-------------------+--------+ - * - * Exceptions are indicated below. A few opcodes are multi-word. */ -typedef enum { - /* Opcodes 1-8, 13, 15-18 parse their respective descriptor types. - * Arg for all of these is the upb selector for this field. */ -#define T(type) OP_PARSE_ ## type = UPB_DESCRIPTOR_TYPE_ ## type - T(DOUBLE), T(FLOAT), T(INT64), T(UINT64), T(INT32), T(FIXED64), T(FIXED32), - T(BOOL), T(UINT32), T(SFIXED32), T(SFIXED64), T(SINT32), T(SINT64), -#undef T - OP_STARTMSG = 9, /* No arg. */ - OP_ENDMSG = 10, /* No arg. */ - OP_STARTSEQ = 11, - OP_ENDSEQ = 12, - OP_STARTSUBMSG = 14, - OP_ENDSUBMSG = 19, - OP_STARTSTR = 20, - OP_STRING = 21, - OP_ENDSTR = 22, - - OP_PUSHTAGDELIM = 23, /* No arg. */ - OP_PUSHLENDELIM = 24, /* No arg. */ - OP_POP = 25, /* No arg. */ - OP_SETDELIM = 26, /* No arg. */ - OP_SETBIGGROUPNUM = 27, /* two words: - * | unused (24) | opc (8) | - * | groupnum (32) | */ - OP_CHECKDELIM = 28, - OP_CALL = 29, - OP_RET = 30, - OP_BRANCH = 31, - - /* Different opcodes depending on how many bytes expected. */ - OP_TAG1 = 32, /* | match tag (16) | jump target (8) | opc (8) | */ - OP_TAG2 = 33, /* | match tag (16) | jump target (8) | opc (8) | */ - OP_TAGN = 34, /* three words: */ - /* | unused (16) | jump target(8) | opc (8) | */ - /* | match tag 1 (32) | */ - /* | match tag 2 (32) | */ - - OP_SETDISPATCH = 35, /* N words: */ - /* | unused (24) | opc | */ - /* | upb_inttable* (32 or 64) | */ - - OP_DISPATCH = 36, /* No arg. */ - - OP_HALT = 37 /* No arg. */ -} opcode; - -#define OP_MAX OP_HALT - -UPB_INLINE opcode getop(uint32_t instr) { return (opcode)(instr & 0xff); } - -struct upb_pbcodecache { - upb_arena *arena; - upb_handlercache *dest; - bool allow_jit; - bool lazy; - - /* Map of upb_msgdef -> mgroup. */ - upb_inttable groups; -}; - -/* Method group; represents a set of decoder methods that had their code - * emitted together. Immutable once created. */ -typedef struct { - /* Maps upb_msgdef/upb_handlers -> upb_pbdecodermethod. Owned by us. - * - * Ideally this would be on pbcodecache (if we were actually caching code). - * Right now we don't actually cache anything, which is wasteful. */ - upb_inttable methods; - - /* The bytecode for our methods, if any exists. Owned by us. */ - uint32_t *bytecode; - uint32_t *bytecode_end; -} mgroup; - -/* The maximum that any submessages can be nested. Matches proto2's limit. - * This specifies the size of the decoder's statically-sized array and therefore - * setting it high will cause the upb::pb::Decoder object to be larger. - * - * If necessary we can add a runtime-settable property to Decoder that allow - * this to be larger than the compile-time setting, but this would add - * complexity, particularly since we would have to decide how/if to give users - * the ability to set a custom memory allocation function. */ -#define UPB_DECODER_MAX_NESTING 64 - -/* Internal-only struct used by the decoder. */ -typedef struct { - /* Space optimization note: we store two pointers here that the JIT - * doesn't need at all; the upb_handlers* inside the sink and - * the dispatch table pointer. We can optimize so that the JIT uses - * smaller stack frames than the interpreter. The only thing we need - * to guarantee is that the fallback routines can find end_ofs. */ - upb_sink sink; - - /* The absolute stream offset of the end-of-frame delimiter. - * Non-delimited frames (groups and non-packed repeated fields) reuse the - * delimiter of their parent, even though the frame may not end there. - * - * NOTE: the JIT stores a slightly different value here for non-top frames. - * It stores the value relative to the end of the enclosed message. But the - * top frame is still stored the same way, which is important for ensuring - * that calls from the JIT into C work correctly. */ - uint64_t end_ofs; - const uint32_t *base; - - /* 0 indicates a length-delimited field. - * A positive number indicates a known group. - * A negative number indicates an unknown group. */ - int32_t groupnum; - upb_inttable *dispatch; /* Not used by the JIT. */ -} upb_pbdecoder_frame; - -struct upb_pbdecodermethod { - /* While compiling, the base is relative in "ofs", after compiling it is - * absolute in "ptr". */ - union { - uint32_t ofs; /* PC offset of method. */ - void *ptr; /* Pointer to bytecode or machine code for this method. */ - } code_base; - - /* The decoder method group to which this method belongs. */ - const mgroup *group; - - /* Whether this method is native code or bytecode. */ - bool is_native_; - - /* The handler one calls to invoke this method. */ - upb_byteshandler input_handler_; - - /* The destination handlers this method is bound to. We own a ref. */ - const upb_handlers *dest_handlers_; - - /* Dispatch table -- used by both bytecode decoder and JIT when encountering a - * field number that wasn't the one we were expecting to see. See - * decoder.int.h for the layout of this table. */ - upb_inttable dispatch; -}; - -struct upb_pbdecoder { - upb_arena *arena; - - /* Our input sink. */ - upb_bytessink input_; - - /* The decoder method we are parsing with (owned). */ - const upb_pbdecodermethod *method_; - - size_t call_len; - const uint32_t *pc, *last; - - /* Current input buffer and its stream offset. */ - const char *buf, *ptr, *end, *checkpoint; - - /* End of the delimited region, relative to ptr, NULL if not in this buf. */ - const char *delim_end; - - /* End of the delimited region, relative to ptr, end if not in this buf. */ - const char *data_end; - - /* Overall stream offset of "buf." */ - uint64_t bufstart_ofs; - - /* Buffer for residual bytes not parsed from the previous buffer. */ - char residual[UPB_DECODER_MAX_RESIDUAL_BYTES]; - char *residual_end; - - /* Bytes of data that should be discarded from the input before we start - * parsing again. We set this when we internally determine that we can - * safely skip the next N bytes, but this region extends past the current - * user buffer. */ - size_t skip; - - /* Stores the user buffer passed to our decode function. */ - const char *buf_param; - size_t size_param; - const upb_bufhandle *handle; - - /* Our internal stack. */ - upb_pbdecoder_frame *stack, *top, *limit; - const uint32_t **callstack; - size_t stack_size; - - upb_status *status; -}; - -/* Decoder entry points; used as handlers. */ -void *upb_pbdecoder_startbc(void *closure, const void *pc, size_t size_hint); -size_t upb_pbdecoder_decode(void *closure, const void *hd, const char *buf, - size_t size, const upb_bufhandle *handle); -bool upb_pbdecoder_end(void *closure, const void *handler_data); - -/* Decoder-internal functions that the JIT calls to handle fallback paths. */ -int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf, - size_t size, const upb_bufhandle *handle); -size_t upb_pbdecoder_suspend(upb_pbdecoder *d); -int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, - uint8_t wire_type); -int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d, uint64_t expected); -int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d, uint64_t *u64); -int32_t upb_pbdecoder_decode_f32(upb_pbdecoder *d, uint32_t *u32); -int32_t upb_pbdecoder_decode_f64(upb_pbdecoder *d, uint64_t *u64); -void upb_pbdecoder_seterr(upb_pbdecoder *d, const char *msg); - -/* Error messages that are shared between the bytecode and JIT decoders. */ -extern const char *kPbDecoderStackOverflow; -extern const char *kPbDecoderSubmessageTooLong; - -/* Access to decoderplan members needed by the decoder. */ -const char *upb_pbdecoder_getopname(unsigned int op); - -/* A special label that means "do field dispatch for this message and branch to - * wherever that takes you." */ -#define LABEL_DISPATCH 0 - -/* A special slot in the dispatch table that stores the epilogue (ENDMSG and/or - * RET) for branching to when we find an appropriate ENDGROUP tag. */ -#define DISPATCH_ENDMSG 0 - -/* It's important to use this invalid wire type instead of 0 (which is a valid - * wire type). */ -#define NO_WIRE_TYPE 0xff - -/* The dispatch table layout is: - * [field number] -> [ 48-bit offset ][ 8-bit wt2 ][ 8-bit wt1 ] - * - * If wt1 matches, jump to the 48-bit offset. If wt2 matches, lookup - * (UPB_MAX_FIELDNUMBER + fieldnum) and jump there. - * - * We need two wire types because of packed/non-packed compatibility. A - * primitive repeated field can use either wire type and be valid. While we - * could key the table on fieldnum+wiretype, the table would be 8x sparser. - * - * Storing two wire types in the primary value allows us to quickly rule out - * the second wire type without needing to do a separate lookup (this case is - * less common than an unknown field). */ -UPB_INLINE uint64_t upb_pbdecoder_packdispatch(uint64_t ofs, uint8_t wt1, - uint8_t wt2) { - return (ofs << 16) | (wt2 << 8) | wt1; -} - -UPB_INLINE void upb_pbdecoder_unpackdispatch(uint64_t dispatch, uint64_t *ofs, - uint8_t *wt1, uint8_t *wt2) { - *wt1 = (uint8_t)dispatch; - *wt2 = (uint8_t)(dispatch >> 8); - *ofs = dispatch >> 16; -} - -/* All of the functions in decoder.c that return int32_t return values according - * to the following scheme: - * 1. negative values indicate a return code from the following list. - * 2. positive values indicate that error or end of buffer was hit, and - * that the decode function should immediately return the given value - * (the decoder state has already been suspended and is ready to be - * resumed). */ -#define DECODE_OK -1 -#define DECODE_MISMATCH -2 /* Used only from checktag_slow(). */ -#define DECODE_ENDGROUP -3 /* Used only from checkunknown(). */ - -#define CHECK_RETURN(x) { int32_t ret = x; if (ret >= 0) return ret; } - - -#endif /* UPB_DECODER_INT_H_ */ -/* -** A number of routines for varint manipulation (we keep them all around to -** have multiple approaches available for benchmarking). -*/ - -#ifndef UPB_VARINT_DECODER_H_ -#define UPB_VARINT_DECODER_H_ - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -#define UPB_MAX_WIRE_TYPE 5 - -/* The maximum number of bytes that it takes to encode a 64-bit varint. */ -#define UPB_PB_VARINT_MAX_LEN 10 - -/* Array of the "native" (ie. non-packed-repeated) wire type for the given a - * descriptor type (upb_descriptortype_t). */ -extern const uint8_t upb_pb_native_wire_types[]; - -UPB_INLINE uint64_t byteswap64(uint64_t val) -{ - return ((((val) & 0xff00000000000000ull) >> 56) - | (((val) & 0x00ff000000000000ull) >> 40) - | (((val) & 0x0000ff0000000000ull) >> 24) - | (((val) & 0x000000ff00000000ull) >> 8) - | (((val) & 0x00000000ff000000ull) << 8) - | (((val) & 0x0000000000ff0000ull) << 24) - | (((val) & 0x000000000000ff00ull) << 40) - | (((val) & 0x00000000000000ffull) << 56)); -} - -/* Zig-zag encoding/decoding **************************************************/ - -UPB_INLINE int32_t upb_zzdec_32(uint32_t n) { - return (n >> 1) ^ -(int32_t)(n & 1); -} -UPB_INLINE int64_t upb_zzdec_64(uint64_t n) { - return (n >> 1) ^ -(int64_t)(n & 1); -} -UPB_INLINE uint32_t upb_zzenc_32(int32_t n) { - return ((uint32_t)n << 1) ^ (n >> 31); -} -UPB_INLINE uint64_t upb_zzenc_64(int64_t n) { - return ((uint64_t)n << 1) ^ (n >> 63); -} - -/* Decoding *******************************************************************/ - -/* All decoding functions return this struct by value. */ -typedef struct { - const char *p; /* NULL if the varint was unterminated. */ - uint64_t val; -} upb_decoderet; - -UPB_INLINE upb_decoderet upb_decoderet_make(const char *p, uint64_t val) { - upb_decoderet ret; - ret.p = p; - ret.val = val; - return ret; -} - -upb_decoderet upb_vdecode_max8_branch32(upb_decoderet r); -upb_decoderet upb_vdecode_max8_branch64(upb_decoderet r); - -/* Template for a function that checks the first two bytes with branching - * and dispatches 2-10 bytes with a separate function. Note that this may read - * up to 10 bytes, so it must not be used unless there are at least ten bytes - * left in the buffer! */ -#define UPB_VARINT_DECODER_CHECK2(name, decode_max8_function) \ -UPB_INLINE upb_decoderet upb_vdecode_check2_ ## name(const char *_p) { \ - uint8_t *p = (uint8_t*)_p; \ - upb_decoderet r; \ - if ((*p & 0x80) == 0) { \ - /* Common case: one-byte varint. */ \ - return upb_decoderet_make(_p + 1, *p & 0x7fU); \ - } \ - r = upb_decoderet_make(_p + 2, (*p & 0x7fU) | ((*(p + 1) & 0x7fU) << 7)); \ - if ((*(p + 1) & 0x80) == 0) { \ - /* Two-byte varint. */ \ - return r; \ - } \ - /* Longer varint, fallback to out-of-line function. */ \ - return decode_max8_function(r); \ -} - -UPB_VARINT_DECODER_CHECK2(branch32, upb_vdecode_max8_branch32) -UPB_VARINT_DECODER_CHECK2(branch64, upb_vdecode_max8_branch64) -#undef UPB_VARINT_DECODER_CHECK2 - -/* Our canonical functions for decoding varints, based on the currently - * favored best-performing implementations. */ -UPB_INLINE upb_decoderet upb_vdecode_fast(const char *p) { - if (sizeof(long) == 8) - return upb_vdecode_check2_branch64(p); - else - return upb_vdecode_check2_branch32(p); -} - - -/* Encoding *******************************************************************/ - -UPB_INLINE int upb_value_size(uint64_t val) { -#ifdef __GNUC__ - int high_bit = 63 - __builtin_clzll(val); /* 0-based, undef if val == 0. */ -#else - int high_bit = 0; - uint64_t tmp = val; - while(tmp >>= 1) high_bit++; -#endif - return val == 0 ? 1 : high_bit / 8 + 1; -} - -/* Encodes a 64-bit varint into buf (which must be >=UPB_PB_VARINT_MAX_LEN - * bytes long), returning how many bytes were used. - * - * TODO: benchmark and optimize if necessary. */ -UPB_INLINE size_t upb_vencode64(uint64_t val, char *buf) { - size_t i; - if (val == 0) { buf[0] = 0; return 1; } - i = 0; - while (val) { - uint8_t byte = val & 0x7fU; - val >>= 7; - if (val) byte |= 0x80U; - buf[i++] = byte; - } - return i; -} - -UPB_INLINE size_t upb_varint_size(uint64_t val) { - char buf[UPB_PB_VARINT_MAX_LEN]; - return upb_vencode64(val, buf); -} - -/* Encodes a 32-bit varint, *not* sign-extended. */ -UPB_INLINE uint64_t upb_vencode32(uint32_t val) { - char buf[UPB_PB_VARINT_MAX_LEN]; - size_t bytes = upb_vencode64(val, buf); - uint64_t ret = 0; - UPB_ASSERT(bytes <= 5); - memcpy(&ret, buf, bytes); -#ifdef UPB_BIG_ENDIAN - ret = byteswap64(ret); -#endif - UPB_ASSERT(ret <= 0xffffffffffU); - return ret; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_VARINT_DECODER_H_ */ -/* -** upb::pb::Encoder (upb_pb_encoder) -** -** Implements a set of upb_handlers that write protobuf data to the binary wire -** format. -** -** This encoder implementation does not have any access to any out-of-band or -** precomputed lengths for submessages, so it must buffer submessages internally -** before it can emit the first byte. -*/ - -#ifndef UPB_ENCODER_H_ -#define UPB_ENCODER_H_ - - -#ifdef __cplusplus -namespace upb { -namespace pb { -class EncoderPtr; -} /* namespace pb */ -} /* namespace upb */ -#endif - -#define UPB_PBENCODER_MAX_NESTING 100 - -/* upb_pb_encoder *************************************************************/ - -/* Preallocation hint: decoder won't allocate more bytes than this when first - * constructed. This hint may be an overestimate for some build configurations. - * But if the decoder library is upgraded without recompiling the application, - * it may be an underestimate. */ -#define UPB_PB_ENCODER_SIZE 784 - -struct upb_pb_encoder; -typedef struct upb_pb_encoder upb_pb_encoder; - -#ifdef __cplusplus -extern "C" { -#endif - -upb_sink upb_pb_encoder_input(upb_pb_encoder *p); -upb_pb_encoder* upb_pb_encoder_create(upb_arena* a, const upb_handlers* h, - upb_bytessink output); - -/* Lazily builds and caches handlers that will push encoded data to a bytessink. - * Any msgdef objects used with this object must outlive it. */ -upb_handlercache *upb_pb_encoder_newcache(void); - -#ifdef __cplusplus -} /* extern "C" { */ - -class upb::pb::EncoderPtr { - public: - EncoderPtr(upb_pb_encoder* ptr) : ptr_(ptr) {} - - upb_pb_encoder* ptr() { return ptr_; } - - /* Creates a new encoder in the given environment. The Handlers must have - * come from NewHandlers() below. */ - static EncoderPtr Create(Arena* arena, const Handlers* handlers, - BytesSink output) { - return EncoderPtr( - upb_pb_encoder_create(arena->ptr(), handlers, output.sink())); - } - - /* The input to the encoder. */ - upb::Sink input() { return upb_pb_encoder_input(ptr()); } - - /* Creates a new set of handlers for this MessageDef. */ - static HandlerCache NewCache() { - return HandlerCache(upb_pb_encoder_newcache()); - } - - static const size_t kSize = UPB_PB_ENCODER_SIZE; - - private: - upb_pb_encoder* ptr_; -}; - -#endif /* __cplusplus */ - -#endif /* UPB_ENCODER_H_ */ -/* -** upb::pb::TextPrinter (upb_textprinter) -** -** Handlers for writing to protobuf text format. -*/ - -#ifndef UPB_TEXT_H_ -#define UPB_TEXT_H_ - - -#ifdef __cplusplus -namespace upb { -namespace pb { -class TextPrinterPtr; -} /* namespace pb */ -} /* namespace upb */ -#endif - -/* upb_textprinter ************************************************************/ - -struct upb_textprinter; -typedef struct upb_textprinter upb_textprinter; - -#ifdef __cplusplus -extern "C" { -#endif - -/* C API. */ -upb_textprinter *upb_textprinter_create(upb_arena *arena, const upb_handlers *h, - upb_bytessink output); -void upb_textprinter_setsingleline(upb_textprinter *p, bool single_line); -upb_sink upb_textprinter_input(upb_textprinter *p); -upb_handlercache *upb_textprinter_newcache(void); - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::pb::TextPrinterPtr { - public: - TextPrinterPtr(upb_textprinter* ptr) : ptr_(ptr) {} - - /* The given handlers must have come from NewHandlers(). It must outlive the - * TextPrinter. */ - static TextPrinterPtr Create(Arena *arena, upb::HandlersPtr *handlers, - BytesSink output) { - return TextPrinterPtr( - upb_textprinter_create(arena->ptr(), handlers->ptr(), output.sink())); - } - - void SetSingleLineMode(bool single_line) { - upb_textprinter_setsingleline(ptr_, single_line); - } - - Sink input() { return upb_textprinter_input(ptr_); } - - /* If handler caching becomes a requirement we can add a code cache as in - * decoder.h */ - static HandlerCache NewCache() { - return HandlerCache(upb_textprinter_newcache()); - } - - private: - upb_textprinter* ptr_; -}; - -#endif - -#endif /* UPB_TEXT_H_ */ -/* -** upb::json::Parser (upb_json_parser) -** -** Parses JSON according to a specific schema. -** Support for parsing arbitrary JSON (schema-less) will be added later. -*/ - -#ifndef UPB_JSON_PARSER_H_ -#define UPB_JSON_PARSER_H_ - - -#ifdef __cplusplus -namespace upb { -namespace json { -class CodeCache; -class ParserPtr; -class ParserMethodPtr; -} /* namespace json */ -} /* namespace upb */ -#endif - -/* upb_json_parsermethod ******************************************************/ - -struct upb_json_parsermethod; -typedef struct upb_json_parsermethod upb_json_parsermethod; - -#ifdef __cplusplus -extern "C" { -#endif - -const upb_byteshandler* upb_json_parsermethod_inputhandler( - const upb_json_parsermethod* m); - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::json::ParserMethodPtr { - public: - ParserMethodPtr() : ptr_(nullptr) {} - ParserMethodPtr(const upb_json_parsermethod* ptr) : ptr_(ptr) {} - - const upb_json_parsermethod* ptr() const { return ptr_; } - - const BytesHandler* input_handler() const { - return upb_json_parsermethod_inputhandler(ptr()); - } - - private: - const upb_json_parsermethod* ptr_; -}; - -#endif /* __cplusplus */ - -/* upb_json_parser ************************************************************/ - -/* Preallocation hint: parser won't allocate more bytes than this when first - * constructed. This hint may be an overestimate for some build configurations. - * But if the parser library is upgraded without recompiling the application, - * it may be an underestimate. */ -#define UPB_JSON_PARSER_SIZE 5712 - -struct upb_json_parser; -typedef struct upb_json_parser upb_json_parser; - -#ifdef __cplusplus -extern "C" { -#endif - -upb_json_parser* upb_json_parser_create(upb_arena* a, - const upb_json_parsermethod* m, - const upb_symtab* symtab, - upb_sink output, - upb_status *status, - bool ignore_json_unknown); -upb_bytessink upb_json_parser_input(upb_json_parser* p); - -#ifdef __cplusplus -} /* extern "C" */ - -/* Parses an incoming BytesStream, pushing the results to the destination - * sink. */ -class upb::json::ParserPtr { - public: - ParserPtr(upb_json_parser* ptr) : ptr_(ptr) {} - - static ParserPtr Create(Arena* arena, ParserMethodPtr method, - SymbolTable* symtab, Sink output, Status* status, - bool ignore_json_unknown) { - upb_symtab* symtab_ptr = symtab ? symtab->ptr() : nullptr; - return ParserPtr(upb_json_parser_create( - arena->ptr(), method.ptr(), symtab_ptr, output.sink(), status->ptr(), - ignore_json_unknown)); - } - - BytesSink input() { return upb_json_parser_input(ptr_); } - - private: - upb_json_parser* ptr_; -}; - -#endif /* __cplusplus */ - -/* upb_json_codecache *********************************************************/ - -/* Lazily builds and caches decoder methods that will push data to the given - * handlers. The upb_symtab object(s) must outlive this object. */ - -struct upb_json_codecache; -typedef struct upb_json_codecache upb_json_codecache; - -#ifdef __cplusplus -extern "C" { -#endif - -upb_json_codecache *upb_json_codecache_new(void); -void upb_json_codecache_free(upb_json_codecache *cache); -const upb_json_parsermethod* upb_json_codecache_get(upb_json_codecache* cache, - const upb_msgdef* md); - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::json::CodeCache { - public: - CodeCache() : ptr_(upb_json_codecache_new(), upb_json_codecache_free) {} - - /* Returns a DecoderMethod that can push data to the given handlers. - * If a suitable method already exists, it will be returned from the cache. */ - ParserMethodPtr Get(MessageDefPtr md) { - return upb_json_codecache_get(ptr_.get(), md.ptr()); - } - - private: - std::unique_ptr ptr_; -}; - -#endif - -#endif /* UPB_JSON_PARSER_H_ */ -/* -** upb::json::Printer -** -** Handlers that emit JSON according to a specific protobuf schema. -*/ - -#ifndef UPB_JSON_TYPED_PRINTER_H_ -#define UPB_JSON_TYPED_PRINTER_H_ - - -#ifdef __cplusplus -namespace upb { -namespace json { -class PrinterPtr; -} /* namespace json */ -} /* namespace upb */ -#endif - -/* upb_json_printer ***********************************************************/ - -#define UPB_JSON_PRINTER_SIZE 192 - -struct upb_json_printer; -typedef struct upb_json_printer upb_json_printer; - -#ifdef __cplusplus -extern "C" { -#endif - -/* Native C API. */ -upb_json_printer *upb_json_printer_create(upb_arena *a, const upb_handlers *h, - upb_bytessink output); -upb_sink upb_json_printer_input(upb_json_printer *p); -const upb_handlers *upb_json_printer_newhandlers(const upb_msgdef *md, - bool preserve_fieldnames, - const void *owner); - -/* Lazily builds and caches handlers that will push encoded data to a bytessink. - * Any msgdef objects used with this object must outlive it. */ -upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames); - -#ifdef __cplusplus -} /* extern "C" */ - -/* Prints an incoming stream of data to a BytesSink in JSON format. */ -class upb::json::PrinterPtr { - public: - PrinterPtr(upb_json_printer* ptr) : ptr_(ptr) {} - - static PrinterPtr Create(Arena *arena, const upb::Handlers *handlers, - BytesSink output) { - return PrinterPtr( - upb_json_printer_create(arena->ptr(), handlers, output.sink())); - } - - /* The input to the printer. */ - Sink input() { return upb_json_printer_input(ptr_); } - - static const size_t kSize = UPB_JSON_PRINTER_SIZE; - - static HandlerCache NewCache(bool preserve_proto_fieldnames) { - return upb_json_printer_newcache(preserve_proto_fieldnames); - } - - private: - upb_json_printer* ptr_; -}; - -#endif /* __cplusplus */ - -#endif /* UPB_JSON_TYPED_PRINTER_H_ */ -/* See port_def.inc. This should #undef all macros #defined there. */ - -#undef UPB_SIZE -#undef UPB_FIELD_AT -#undef UPB_READ_ONEOF -#undef UPB_WRITE_ONEOF -#undef UPB_INLINE -#undef UPB_FORCEINLINE -#undef UPB_NOINLINE -#undef UPB_NORETURN -#undef UPB_MAX -#undef UPB_MIN -#undef UPB_UNUSED -#undef UPB_ASSERT -#undef UPB_ASSERT_DEBUGVAR -#undef UPB_UNREACHABLE -#undef UPB_INFINITY -#undef UPB_MSVC_VSNPRINTF -#undef _upb_snprintf -#undef _upb_vsnprintf -#undef _upb_va_copy diff --git a/php/ext/google/protobuf/wkt.inc b/php/ext/google/protobuf/wkt.inc new file mode 100644 index 000000000000..573ff30c1478 --- /dev/null +++ b/php/ext/google/protobuf/wkt.inc @@ -0,0 +1,3232 @@ +// This file is generated from the .proto files for the well-known +// types. Do not edit! +static void google_protobuf_any_proto_AddDescriptor(); +static void google_protobuf_api_proto_AddDescriptor(); +static void google_protobuf_duration_proto_AddDescriptor(); +static void google_protobuf_empty_proto_AddDescriptor(); +static void google_protobuf_field_mask_proto_AddDescriptor(); +static void google_protobuf_source_context_proto_AddDescriptor(); +static void google_protobuf_struct_proto_AddDescriptor(); +static void google_protobuf_type_proto_AddDescriptor(); +static void google_protobuf_timestamp_proto_AddDescriptor(); +static void google_protobuf_wrappers_proto_AddDescriptor(); +/* google/protobuf/any.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Any_ce; + +const char google_protobuf_any_proto_descriptor [212] = { +'\n', '\031', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'n', 'y', '.', 'p', 'r', 'o', +'t', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '&', '\n', '\003', 'A', 'n', +'y', '\022', '\020', '\n', '\010', 't', 'y', 'p', 'e', '_', 'u', 'r', 'l', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\r', '\n', '\005', 'v', 'a', +'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\014', 'B', 'v', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\010', 'A', 'n', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', ',', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', +'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'a', 'n', 'y', 'p', 'b', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', +'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', +'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_any_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/any.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/any.proto", google_protobuf_any_proto_descriptor, + sizeof(google_protobuf_any_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Any, initOnce) { + google_protobuf_any_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Any_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Any, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Any_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Any", + GPBMetadata_Google_Protobuf_Any_methods); + + GPBMetadata_Google_Protobuf_Any_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Any */ + +zend_class_entry* google_protobuf_Any_ce; + +static PHP_METHOD(google_protobuf_Any, __construct) { + google_protobuf_any_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Any, getTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Any, setTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Any, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Any, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Any_phpmethods[] = { + PHP_ME(google_protobuf_Any, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, getTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, setTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, setValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, is, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, pack, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Any, unpack, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Any_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Any", + google_protobuf_Any_phpmethods); + + google_protobuf_Any_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Any_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Any_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Any_ce, message_ce); +} + +/* google/protobuf/api.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Api_ce; + +const char google_protobuf_api_proto_descriptor [751] = { +'\n', '\031', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'p', 'i', '.', 'p', 'r', 'o', +'t', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\032', '$', 'g', 'o', 'o', 'g', +'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', +'t', '.', 'p', 'r', 'o', 't', 'o', '\032', '\032', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', +'t', 'y', 'p', 'e', '.', 'p', 'r', 'o', 't', 'o', '\"', '\201', '\002', '\n', '\003', 'A', 'p', 'i', '\022', '\014', '\n', '\004', 'n', 'a', 'm', +'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '(', '\n', '\007', 'm', 'e', 't', 'h', 'o', 'd', 's', '\030', '\002', ' ', '\003', '(', '\013', '2', +'\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', '\022', +'(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\017', '\n', '\007', 'v', 'e', 'r', 's', 'i', +'o', 'n', '\030', '\004', ' ', '\001', '(', '\t', '\022', '6', '\n', '\016', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', +'t', '\030', '\005', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', '&', '\n', '\006', 'm', 'i', 'x', 'i', 'n', 's', '\030', +'\006', ' ', '\003', '(', '\013', '2', '\026', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', +'i', 'x', 'i', 'n', '\022', '\'', '\n', '\006', 's', 'y', 'n', 't', 'a', 'x', '\030', '\007', ' ', '\001', '(', '\016', '2', '\027', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', 't', 'a', 'x', '\"', '\325', '\001', '\n', '\006', +'M', 'e', 't', 'h', 'o', 'd', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\030', '\n', '\020', 'r', +'e', 'q', 'u', 'e', 's', 't', '_', 't', 'y', 'p', 'e', '_', 'u', 'r', 'l', '\030', '\002', ' ', '\001', '(', '\t', '\022', '\031', '\n', '\021', +'r', 'e', 'q', 'u', 'e', 's', 't', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\003', ' ', '\001', '(', '\010', '\022', '\031', +'\n', '\021', 'r', 'e', 's', 'p', 'o', 'n', 's', 'e', '_', 't', 'y', 'p', 'e', '_', 'u', 'r', 'l', '\030', '\004', ' ', '\001', '(', '\t', +'\022', '\032', '\n', '\022', 'r', 'e', 's', 'p', 'o', 'n', 's', 'e', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\005', ' ', +'\001', '(', '\010', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\006', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\'', '\n', '\006', 's', +'y', 'n', 't', 'a', 'x', '\030', '\007', ' ', '\001', '(', '\016', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', +'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', 't', 'a', 'x', '\"', '#', '\n', '\005', 'M', 'i', 'x', 'i', 'n', '\022', '\014', '\n', '\004', 'n', +'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\014', '\n', '\004', 'r', 'o', 'o', 't', '\030', '\002', ' ', '\001', '(', '\t', 'B', 'v', +'\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\010', 'A', 'p', +'i', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', ',', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', +'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'a', +'p', 'i', 'p', 'b', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', +'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', +'3', +}; + +static void google_protobuf_api_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/api.proto")) return; + google_protobuf_source_context_proto_AddDescriptor(); + google_protobuf_type_proto_AddDescriptor(); + DescriptorPool_AddDescriptor("google/protobuf/api.proto", google_protobuf_api_proto_descriptor, + sizeof(google_protobuf_api_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Api, initOnce) { + google_protobuf_api_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Api_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Api, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Api_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Api", + GPBMetadata_Google_Protobuf_Api_methods); + + GPBMetadata_Google_Protobuf_Api_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Api */ + +zend_class_entry* google_protobuf_Api_ce; + +static PHP_METHOD(google_protobuf_Api, __construct) { + google_protobuf_api_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Api, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getMethods) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "methods"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setMethods) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "methods"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getVersion) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "version"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setVersion) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "version"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getMixins) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "mixins"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setMixins) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "mixins"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Api, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Api_phpmethods[] = { + PHP_ME(google_protobuf_Api, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getMethods, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setMethods, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getVersion, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setVersion, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getMixins, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setMixins, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Api, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Api_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Api", + google_protobuf_Api_phpmethods); + + google_protobuf_Api_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Api_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Api_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Api_ce, message_ce); +} + +/* google_protobuf_Method */ + +zend_class_entry* google_protobuf_Method_ce; + +static PHP_METHOD(google_protobuf_Method, __construct) { + google_protobuf_api_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Method, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getRequestTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setRequestTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getRequestStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_streaming"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setRequestStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "request_streaming"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getResponseTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setResponseTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getResponseStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_streaming"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setResponseStreaming) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "response_streaming"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Method, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Method_phpmethods[] = { + PHP_ME(google_protobuf_Method, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getRequestTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setRequestTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getRequestStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setRequestStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getResponseTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setResponseTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getResponseStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setResponseStreaming, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Method, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Method_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Method", + google_protobuf_Method_phpmethods); + + google_protobuf_Method_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Method_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Method_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Method_ce, message_ce); +} + +/* google_protobuf_Mixin */ + +zend_class_entry* google_protobuf_Mixin_ce; + +static PHP_METHOD(google_protobuf_Mixin, __construct) { + google_protobuf_api_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Mixin, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Mixin, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Mixin, getRoot) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "root"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Mixin, setRoot) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "root"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Mixin_phpmethods[] = { + PHP_ME(google_protobuf_Mixin, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, getRoot, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Mixin, setRoot, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Mixin_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Mixin", + google_protobuf_Mixin_phpmethods); + + google_protobuf_Mixin_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Mixin_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Mixin_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Mixin_ce, message_ce); +} + +/* google/protobuf/duration.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Duration_ce; + +const char google_protobuf_duration_proto_descriptor [235] = { +'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', +'n', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', +'*', '\n', '\010', 'D', 'u', 'r', 'a', 't', 'i', 'o', 'n', '\022', '\017', '\n', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\030', '\001', ' ', +'\001', '(', '\003', '\022', '\r', '\n', '\005', 'n', 'a', 'n', 'o', 's', '\030', '\002', ' ', '\001', '(', '\005', 'B', '\203', '\001', '\n', '\023', 'c', 'o', +'m', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\r', 'D', 'u', 'r', 'a', 't', 'i', +'o', 'n', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '1', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', +'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', +'d', 'u', 'r', 'a', 't', 'i', 'o', 'n', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', +'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', +'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_duration_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/duration.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/duration.proto", google_protobuf_duration_proto_descriptor, + sizeof(google_protobuf_duration_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Duration, initOnce) { + google_protobuf_duration_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Duration_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Duration, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Duration_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Duration", + GPBMetadata_Google_Protobuf_Duration_methods); + + GPBMetadata_Google_Protobuf_Duration_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Duration */ + +zend_class_entry* google_protobuf_Duration_ce; + +static PHP_METHOD(google_protobuf_Duration, __construct) { + google_protobuf_duration_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Duration, getSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Duration, setSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Duration, getNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Duration, setNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Duration_phpmethods[] = { + PHP_ME(google_protobuf_Duration, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, getSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, setSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, getNanos, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Duration, setNanos, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Duration_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Duration", + google_protobuf_Duration_phpmethods); + + google_protobuf_Duration_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Duration_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Duration_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Duration_ce, message_ce); +} + +/* google/protobuf/empty.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_GPBEmpty_ce; + +const char google_protobuf_empty_proto_descriptor [190] = { +'\n', '\033', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'e', 'm', 'p', 't', 'y', '.', 'p', +'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '\007', '\n', '\005', +'E', 'm', 'p', 't', 'y', 'B', '}', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', 'B', '\n', 'E', 'm', 'p', 't', 'y', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', +'s', '/', 'k', 'n', 'o', 'w', 'n', '/', 'e', 'm', 'p', 't', 'y', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', +'\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', +'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_empty_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/empty.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/empty.proto", google_protobuf_empty_proto_descriptor, + sizeof(google_protobuf_empty_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_GPBEmpty, initOnce) { + google_protobuf_empty_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_GPBEmpty_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_GPBEmpty, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_GPBEmpty_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\GPBEmpty", + GPBMetadata_Google_Protobuf_GPBEmpty_methods); + + GPBMetadata_Google_Protobuf_GPBEmpty_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Empty */ + +zend_class_entry* google_protobuf_Empty_ce; + +static PHP_METHOD(google_protobuf_Empty, __construct) { + google_protobuf_empty_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static zend_function_entry google_protobuf_Empty_phpmethods[] = { + PHP_ME(google_protobuf_Empty, __construct, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Empty_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\GPBEmpty", + google_protobuf_Empty_phpmethods); + + google_protobuf_Empty_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Empty_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Empty_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Empty_ce, message_ce); +} + +/* google/protobuf/field_mask.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_FieldMask_ce; + +const char google_protobuf_field_mask_proto_descriptor [223] = { +'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'f', 'i', 'e', 'l', 'd', '_', 'm', +'a', 's', 'k', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', +'f', '\"', '\032', '\n', '\t', 'F', 'i', 'e', 'l', 'd', 'M', 'a', 's', 'k', '\022', '\r', '\n', '\005', 'p', 'a', 't', 'h', 's', '\030', '\001', +' ', '\003', '(', '\t', 'B', '\205', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', 'B', '\016', 'F', 'i', 'e', 'l', 'd', 'M', 'a', 's', 'k', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '2', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', +'t', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'f', 'i', 'e', 'l', 'd', 'm', 'a', 's', 'k', 'p', 'b', '\370', '\001', +'\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_field_mask_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/field_mask.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/field_mask.proto", google_protobuf_field_mask_proto_descriptor, + sizeof(google_protobuf_field_mask_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_FieldMask, initOnce) { + google_protobuf_field_mask_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_FieldMask_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_FieldMask, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_FieldMask_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\FieldMask", + GPBMetadata_Google_Protobuf_FieldMask_methods); + + GPBMetadata_Google_Protobuf_FieldMask_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_FieldMask */ + +zend_class_entry* google_protobuf_FieldMask_ce; + +static PHP_METHOD(google_protobuf_FieldMask, __construct) { + google_protobuf_field_mask_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_FieldMask, getPaths) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "paths"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_FieldMask, setPaths) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "paths"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_FieldMask_phpmethods[] = { + PHP_ME(google_protobuf_FieldMask, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FieldMask, getPaths, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FieldMask, setPaths, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_FieldMask_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\FieldMask", + google_protobuf_FieldMask_phpmethods); + + google_protobuf_FieldMask_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_FieldMask_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_FieldMask_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_FieldMask_ce, message_ce); +} + +/* google/protobuf/source_context.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_SourceContext_ce; + +const char google_protobuf_source_context_proto_descriptor [240] = { +'\n', '$', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 'o', 'u', 'r', 'c', 'e', '_', +'c', 'o', 'n', 't', 'e', 'x', 't', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '\"', '\"', '\n', '\r', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', '\021', '\n', +'\t', 'f', 'i', 'l', 'e', '_', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'B', '\212', '\001', '\n', '\023', 'c', 'o', 'm', '.', +'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\022', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', +'n', 't', 'e', 'x', 't', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '6', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', +'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', +'w', 'n', '/', 's', 'o', 'u', 'r', 'c', 'e', 'c', 'o', 'n', 't', 'e', 'x', 't', 'p', 'b', '\242', '\002', '\003', 'G', 'P', 'B', '\252', +'\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', +'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_source_context_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/source_context.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/source_context.proto", google_protobuf_source_context_proto_descriptor, + sizeof(google_protobuf_source_context_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_SourceContext, initOnce) { + google_protobuf_source_context_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_SourceContext_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_SourceContext, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_SourceContext_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\SourceContext", + GPBMetadata_Google_Protobuf_SourceContext_methods); + + GPBMetadata_Google_Protobuf_SourceContext_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_SourceContext */ + +zend_class_entry* google_protobuf_SourceContext_ce; + +static PHP_METHOD(google_protobuf_SourceContext, __construct) { + google_protobuf_source_context_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_SourceContext, getFileName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "file_name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_SourceContext, setFileName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "file_name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_SourceContext_phpmethods[] = { + PHP_ME(google_protobuf_SourceContext, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_SourceContext, getFileName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_SourceContext, setFileName, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_SourceContext_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\SourceContext", + google_protobuf_SourceContext_phpmethods); + + google_protobuf_SourceContext_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_SourceContext_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_SourceContext_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_SourceContext_ce, message_ce); +} + +/* google/protobuf/struct.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Struct_ce; + +const char google_protobuf_struct_proto_descriptor [638] = { +'\n', '\034', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 't', 'r', 'u', 'c', 't', '.', +'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', '\204', '\001', +'\n', '\006', 'S', 't', 'r', 'u', 'c', 't', '\022', '3', '\n', '\006', 'f', 'i', 'e', 'l', 'd', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', +'#', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 't', 'r', 'u', 'c', 't', '.', +'F', 'i', 'e', 'l', 'd', 's', 'E', 'n', 't', 'r', 'y', '\032', 'E', '\n', '\013', 'F', 'i', 'e', 'l', 'd', 's', 'E', 'n', 't', 'r', +'y', '\022', '\013', '\n', '\003', 'k', 'e', 'y', '\030', '\001', ' ', '\001', '(', '\t', '\022', '%', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', +' ', '\001', '(', '\013', '2', '\026', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'V', 'a', +'l', 'u', 'e', ':', '\002', '8', '\001', '\"', '\352', '\001', '\n', '\005', 'V', 'a', 'l', 'u', 'e', '\022', '0', '\n', '\n', 'n', 'u', 'l', 'l', +'_', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '\032', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '.', 'N', 'u', 'l', 'l', 'V', 'a', 'l', 'u', 'e', 'H', '\000', '\022', '\026', '\n', '\014', 'n', 'u', 'm', 'b', +'e', 'r', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\001', 'H', '\000', '\022', '\026', '\n', '\014', 's', 't', 'r', 'i', 'n', +'g', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'H', '\000', '\022', '\024', '\n', '\n', 'b', 'o', 'o', 'l', '_', 'v', +'a', 'l', 'u', 'e', '\030', '\004', ' ', '\001', '(', '\010', 'H', '\000', '\022', '/', '\n', '\014', 's', 't', 'r', 'u', 'c', 't', '_', 'v', 'a', +'l', 'u', 'e', '\030', '\005', ' ', '\001', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'S', 't', 'r', 'u', 'c', 't', 'H', '\000', '\022', '0', '\n', '\n', 'l', 'i', 's', 't', '_', 'v', 'a', 'l', 'u', 'e', +'\030', '\006', ' ', '\001', '(', '\013', '2', '\032', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'L', 'i', 's', 't', 'V', 'a', 'l', 'u', 'e', 'H', '\000', 'B', '\006', '\n', '\004', 'k', 'i', 'n', 'd', '\"', '3', '\n', '\t', 'L', 'i', +'s', 't', 'V', 'a', 'l', 'u', 'e', '\022', '&', '\n', '\006', 'v', 'a', 'l', 'u', 'e', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', '\026', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'V', 'a', 'l', 'u', 'e', '*', '\033', '\n', +'\t', 'N', 'u', 'l', 'l', 'V', 'a', 'l', 'u', 'e', '\022', '\016', '\n', '\n', 'N', 'U', 'L', 'L', '_', 'V', 'A', 'L', 'U', 'E', '\020', +'\000', 'B', '\177', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', +'\013', 'S', 't', 'r', 'u', 'c', 't', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '/', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', +'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', +'n', 'o', 'w', 'n', '/', 's', 't', 'r', 'u', 'c', 't', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', +'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', +'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_struct_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/struct.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/struct.proto", google_protobuf_struct_proto_descriptor, + sizeof(google_protobuf_struct_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Struct, initOnce) { + google_protobuf_struct_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Struct_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Struct, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Struct_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Struct", + GPBMetadata_Google_Protobuf_Struct_methods); + + GPBMetadata_Google_Protobuf_Struct_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Struct */ + +zend_class_entry* google_protobuf_Struct_ce; + +static PHP_METHOD(google_protobuf_Struct, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Struct, getFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct, setFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Struct_phpmethods[] = { + PHP_ME(google_protobuf_Struct, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct, getFields, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct, setFields, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Struct_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Struct", + google_protobuf_Struct_phpmethods); + + google_protobuf_Struct_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Struct_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Struct_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Struct_ce, message_ce); +} + +/* google_protobuf_Struct_FieldsEntry */ + +zend_class_entry* google_protobuf_Struct_FieldsEntry_ce; + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getKey) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "key"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setKey) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "key"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Struct_FieldsEntry, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Struct_FieldsEntry_phpmethods[] = { + PHP_ME(google_protobuf_Struct_FieldsEntry, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, getKey, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, setKey, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Struct_FieldsEntry, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Struct_FieldsEntry_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Struct\\FieldsEntry", + google_protobuf_Struct_FieldsEntry_phpmethods); + + google_protobuf_Struct_FieldsEntry_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Struct_FieldsEntry_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Struct_FieldsEntry_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Struct_FieldsEntry_ce, message_ce); +} + +/* google_protobuf_Value */ + +zend_class_entry* google_protobuf_Value_ce; + +static PHP_METHOD(google_protobuf_Value, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Value, getNullValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "null_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setNullValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "null_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getNumberValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setNumberValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getStringValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "string_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setStringValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "string_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getBoolValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "bool_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setBoolValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "bool_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getStructValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "struct_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setStructValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "struct_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getListValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "list_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, setListValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "list_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Value, getKind) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef, + "kind"); + const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof); + RETURN_STRING(field ? upb_fielddef_name(field) : ""); +} +static zend_function_entry google_protobuf_Value_phpmethods[] = { + PHP_ME(google_protobuf_Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getNullValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setNullValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getNumberValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setNumberValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getStringValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setStringValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getBoolValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setBoolValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getStructValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setStructValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getListValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, setListValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Value, getKind, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Value", + google_protobuf_Value_phpmethods); + + google_protobuf_Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Value_ce, message_ce); +} + +/* google_protobuf_ListValue */ + +zend_class_entry* google_protobuf_ListValue_ce; + +static PHP_METHOD(google_protobuf_ListValue, __construct) { + google_protobuf_struct_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_ListValue, getValues) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "values"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_ListValue, setValues) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "values"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_ListValue_phpmethods[] = { + PHP_ME(google_protobuf_ListValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_ListValue, getValues, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_ListValue, setValues, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_ListValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\ListValue", + google_protobuf_ListValue_phpmethods); + + google_protobuf_ListValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_ListValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_ListValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_ListValue_ce, message_ce); +} + +/* google_protobuf_NullValue */ + +zend_class_entry* google_protobuf_NullValue_ce; + +PHP_METHOD(google_protobuf_NullValue, name) { + google_protobuf_struct_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\NullValue has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_NullValue, value) { + google_protobuf_struct_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.NullValue"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\NullValue has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_NullValue_phpmethods[] = { + PHP_ME(google_protobuf_NullValue, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_NullValue, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_NullValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\NullValue", + google_protobuf_NullValue_phpmethods); + + google_protobuf_NullValue_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_NullValue_ce, "NULL_VALUE", + strlen("NULL_VALUE"), 0); +} + +/* google/protobuf/type.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Type_ce; + +const char google_protobuf_type_proto_descriptor [1592] = { +'\n', '\032', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', '.', 'p', 'r', +'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\032', '\031', 'g', 'o', 'o', +'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'a', 'n', 'y', '.', 'p', 'r', 'o', 't', 'o', '\032', '$', 'g', +'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', +'t', 'e', 'x', 't', '.', 'p', 'r', 'o', 't', 'o', '\"', '\327', '\001', '\n', '\004', 'T', 'y', 'p', 'e', '\022', '\014', '\n', '\004', 'n', 'a', +'m', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '&', '\n', '\006', 'f', 'i', 'e', 'l', 'd', 's', '\030', '\002', ' ', '\003', '(', '\013', '2', +'\026', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', '\022', '\016', +'\n', '\006', 'o', 'n', 'e', 'o', 'f', 's', '\030', '\003', ' ', '\003', '(', '\t', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', +'\030', '\004', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'O', 'p', 't', 'i', 'o', 'n', '\022', '6', '\n', '\016', 's', 'o', 'u', 'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '\030', +'\005', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', +'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', '\'', '\n', '\006', 's', 'y', 'n', 't', 'a', 'x', '\030', '\006', ' ', +'\001', '(', '\016', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', +'t', 'a', 'x', '\"', '\325', '\005', '\n', '\005', 'F', 'i', 'e', 'l', 'd', '\022', ')', '\n', '\004', 'k', 'i', 'n', 'd', '\030', '\001', ' ', '\001', +'(', '\016', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', +'d', '.', 'K', 'i', 'n', 'd', '\022', '7', '\n', '\013', 'c', 'a', 'r', 'd', 'i', 'n', 'a', 'l', 'i', 't', 'y', '\030', '\002', ' ', '\001', +'(', '\016', '2', '\"', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', +'d', '.', 'C', 'a', 'r', 'd', 'i', 'n', 'a', 'l', 'i', 't', 'y', '\022', '\016', '\n', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\030', '\003', +' ', '\001', '(', '\005', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\004', ' ', '\001', '(', '\t', '\022', '\020', '\n', '\010', 't', 'y', 'p', +'e', '_', 'u', 'r', 'l', '\030', '\006', ' ', '\001', '(', '\t', '\022', '\023', '\n', '\013', 'o', 'n', 'e', 'o', 'f', '_', 'i', 'n', 'd', 'e', +'x', '\030', '\007', ' ', '\001', '(', '\005', '\022', '\016', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\010', ' ', '\001', '(', '\010', '\022', '(', +'\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\t', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\021', '\n', '\t', 'j', 's', 'o', 'n', '_', 'n', +'a', 'm', 'e', '\030', '\n', ' ', '\001', '(', '\t', '\022', '\025', '\n', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', +'e', '\030', '\013', ' ', '\001', '(', '\t', '\"', '\310', '\002', '\n', '\004', 'K', 'i', 'n', 'd', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', +'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B', 'L', 'E', '\020', +'\001', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', +'_', 'I', 'N', 'T', '6', '4', '\020', '\003', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6', '4', '\020', '\004', +'\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', +'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\006', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '3', '2', +'\020', '\007', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', +'_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\t', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U', 'P', '\020', '\n', +'\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', +'E', '_', 'B', 'Y', 'T', 'E', 'S', '\020', '\014', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '3', '2', '\020', +'\r', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', +'S', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\017', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', +'6', '4', '\020', '\020', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022', '\017', '\n', '\013', +'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '6', '4', '\020', '\022', '\"', 't', '\n', '\013', 'C', 'a', 'r', 'd', 'i', 'n', 'a', 'l', +'i', 't', 'y', '\022', '\027', '\n', '\023', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', +'N', '\020', '\000', '\022', '\030', '\n', '\024', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'O', 'P', 'T', 'I', 'O', 'N', +'A', 'L', '\020', '\001', '\022', '\030', '\n', '\024', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'R', 'E', 'Q', 'U', 'I', +'R', 'E', 'D', '\020', '\002', '\022', '\030', '\n', '\024', 'C', 'A', 'R', 'D', 'I', 'N', 'A', 'L', 'I', 'T', 'Y', '_', 'R', 'E', 'P', 'E', +'A', 'T', 'E', 'D', '\020', '\003', '\"', '\316', '\001', '\n', '\004', 'E', 'n', 'u', 'm', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', +' ', '\001', '(', '\t', '\022', '-', '\n', '\t', 'e', 'n', 'u', 'm', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '\032', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', +'e', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\003', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', '\022', '6', '\n', '\016', 's', 'o', 'u', +'r', 'c', 'e', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '\030', '\004', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', +'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'n', 't', 'e', 'x', 't', '\022', +'\'', '\n', '\006', 's', 'y', 'n', 't', 'a', 'x', '\030', '\005', ' ', '\001', '(', '\016', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'y', 'n', 't', 'a', 'x', '\"', 'S', '\n', '\t', 'E', 'n', 'u', 'm', 'V', 'a', +'l', 'u', 'e', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', '\016', '\n', '\006', 'n', 'u', 'm', 'b', +'e', 'r', '\030', '\002', ' ', '\001', '(', '\005', '\022', '(', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\003', '(', '\013', +'2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'p', 't', 'i', 'o', 'n', +'\"', ';', '\n', '\006', 'O', 'p', 't', 'i', 'o', 'n', '\022', '\014', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\022', +'#', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\013', '2', '\024', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'A', 'n', 'y', '*', '.', '\n', '\006', 'S', 'y', 'n', 't', 'a', 'x', '\022', '\021', '\n', '\r', +'S', 'Y', 'N', 'T', 'A', 'X', '_', 'P', 'R', 'O', 'T', 'O', '2', '\020', '\000', '\022', '\021', '\n', '\r', 'S', 'Y', 'N', 'T', 'A', 'X', +'_', 'P', 'R', 'O', 'T', 'O', '3', '\020', '\001', 'B', '{', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\t', 'T', 'y', 'p', 'e', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '-', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', +'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 't', 'y', 'p', 'e', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', +'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', +'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_type_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/type.proto")) return; + google_protobuf_any_proto_AddDescriptor(); + google_protobuf_source_context_proto_AddDescriptor(); + DescriptorPool_AddDescriptor("google/protobuf/type.proto", google_protobuf_type_proto_descriptor, + sizeof(google_protobuf_type_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Type, initOnce) { + google_protobuf_type_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Type_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Type, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Type_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Type", + GPBMetadata_Google_Protobuf_Type_methods); + + GPBMetadata_Google_Protobuf_Type_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Type */ + +zend_class_entry* google_protobuf_Type_ce; + +static PHP_METHOD(google_protobuf_Type, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Type, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setFields) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "fields"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getOneofs) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneofs"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setOneofs) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneofs"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Type, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Type_phpmethods[] = { + PHP_ME(google_protobuf_Type, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getFields, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setFields, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getOneofs, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setOneofs, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Type, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Type_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Type", + google_protobuf_Type_phpmethods); + + google_protobuf_Type_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Type_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Type_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Type_ce, message_ce); +} + +/* google_protobuf_Field */ + +zend_class_entry* google_protobuf_Field_ce; + +static PHP_METHOD(google_protobuf_Field, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Field, getKind) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "kind"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setKind) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "kind"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getCardinality) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "cardinality"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setCardinality) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "cardinality"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setTypeUrl) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "type_url"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getOneofIndex) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneof_index"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setOneofIndex) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "oneof_index"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getPacked) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "packed"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setPacked) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "packed"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getJsonName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "json_name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setJsonName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "json_name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, getDefaultValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "default_value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Field, setDefaultValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "default_value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Field_phpmethods[] = { + PHP_ME(google_protobuf_Field, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getKind, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setKind, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getCardinality, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setCardinality, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setTypeUrl, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getOneofIndex, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setOneofIndex, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getPacked, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setPacked, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getJsonName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setJsonName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, getDefaultValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Field, setDefaultValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Field_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field", + google_protobuf_Field_phpmethods); + + google_protobuf_Field_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Field_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Field_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Field_ce, message_ce); +} + +/* google_protobuf_Field_Kind */ + +zend_class_entry* google_protobuf_Field_Kind_ce; + +PHP_METHOD(google_protobuf_Field_Kind, name) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Kind has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_Field_Kind, value) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Kind"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Kind has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_Field_Kind_phpmethods[] = { + PHP_ME(google_protobuf_Field_Kind, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_Field_Kind, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_Field_Kind_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field\\Kind", + google_protobuf_Field_Kind_phpmethods); + + google_protobuf_Field_Kind_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UNKNOWN", + strlen("TYPE_UNKNOWN"), 0); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_DOUBLE", + strlen("TYPE_DOUBLE"), 1); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FLOAT", + strlen("TYPE_FLOAT"), 2); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_INT64", + strlen("TYPE_INT64"), 3); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UINT64", + strlen("TYPE_UINT64"), 4); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_INT32", + strlen("TYPE_INT32"), 5); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FIXED64", + strlen("TYPE_FIXED64"), 6); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_FIXED32", + strlen("TYPE_FIXED32"), 7); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_BOOL", + strlen("TYPE_BOOL"), 8); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_STRING", + strlen("TYPE_STRING"), 9); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_GROUP", + strlen("TYPE_GROUP"), 10); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_MESSAGE", + strlen("TYPE_MESSAGE"), 11); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_BYTES", + strlen("TYPE_BYTES"), 12); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_UINT32", + strlen("TYPE_UINT32"), 13); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_ENUM", + strlen("TYPE_ENUM"), 14); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SFIXED32", + strlen("TYPE_SFIXED32"), 15); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SFIXED64", + strlen("TYPE_SFIXED64"), 16); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SINT32", + strlen("TYPE_SINT32"), 17); + zend_declare_class_constant_long(google_protobuf_Field_Kind_ce, "TYPE_SINT64", + strlen("TYPE_SINT64"), 18); +} + +/* google_protobuf_Field_Cardinality */ + +zend_class_entry* google_protobuf_Field_Cardinality_ce; + +PHP_METHOD(google_protobuf_Field_Cardinality, name) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Cardinality has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_Field_Cardinality, value) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Field.Cardinality"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Field\\Cardinality has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_Field_Cardinality_phpmethods[] = { + PHP_ME(google_protobuf_Field_Cardinality, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_Field_Cardinality, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_Field_Cardinality_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Field\\Cardinality", + google_protobuf_Field_Cardinality_phpmethods); + + google_protobuf_Field_Cardinality_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_UNKNOWN", + strlen("CARDINALITY_UNKNOWN"), 0); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_OPTIONAL", + strlen("CARDINALITY_OPTIONAL"), 1); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_REQUIRED", + strlen("CARDINALITY_REQUIRED"), 2); + zend_declare_class_constant_long(google_protobuf_Field_Cardinality_ce, "CARDINALITY_REPEATED", + strlen("CARDINALITY_REPEATED"), 3); +} + +/* google_protobuf_Enum */ + +zend_class_entry* google_protobuf_Enum_ce; + +static PHP_METHOD(google_protobuf_Enum, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Enum, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getEnumvalue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "enumvalue"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setEnumvalue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "enumvalue"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setSourceContext) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "source_context"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, getSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Enum, setSyntax) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "syntax"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Enum_phpmethods[] = { + PHP_ME(google_protobuf_Enum, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getEnumvalue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setEnumvalue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setSourceContext, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, getSyntax, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Enum, setSyntax, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Enum_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Enum", + google_protobuf_Enum_phpmethods); + + google_protobuf_Enum_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Enum_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Enum_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Enum_ce, message_ce); +} + +/* google_protobuf_EnumValue */ + +zend_class_entry* google_protobuf_EnumValue_ce; + +static PHP_METHOD(google_protobuf_EnumValue, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_EnumValue, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, getNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, setNumber) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "number"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, getOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_EnumValue, setOptions) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "options"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_EnumValue_phpmethods[] = { + PHP_ME(google_protobuf_EnumValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, getNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, setNumber, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, getOptions, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_EnumValue, setOptions, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_EnumValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\EnumValue", + google_protobuf_EnumValue_phpmethods); + + google_protobuf_EnumValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_EnumValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_EnumValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_EnumValue_ce, message_ce); +} + +/* google_protobuf_Option */ + +zend_class_entry* google_protobuf_Option_ce; + +static PHP_METHOD(google_protobuf_Option, __construct) { + google_protobuf_type_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Option, getName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Option, setName) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "name"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Option, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Option, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Option_phpmethods[] = { + PHP_ME(google_protobuf_Option, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, getName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, setName, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Option, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Option_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Option", + google_protobuf_Option_phpmethods); + + google_protobuf_Option_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Option_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Option_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Option_ce, message_ce); +} + +/* google_protobuf_Syntax */ + +zend_class_entry* google_protobuf_Syntax_ce; + +PHP_METHOD(google_protobuf_Syntax, name) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax"); + const char *name; + zend_long value; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) == + FAILURE) { + return; + } + name = upb_enumdef_iton(e, value); + if (!name) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Syntax has no name " + "defined for value " ZEND_LONG_FMT ".", + value); + return; + } + RETURN_STRING(name); +} + +PHP_METHOD(google_protobuf_Syntax, value) { + google_protobuf_type_proto_AddDescriptor(); + const upb_symtab *symtab = DescriptorPool_GetSymbolTable(); + const upb_enumdef *e = upb_symtab_lookupenum(symtab, "google.protobuf.Syntax"); + char *name = NULL; + size_t name_len; + int32_t num; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, + &name_len) == FAILURE) { + return; + } + if (!upb_enumdef_ntoi(e, name, name_len, &num)) { + zend_throw_exception_ex(NULL, 0, + "Google\\Protobuf\\Syntax has no value " + "defined for name %s.", + name); + return; + } + RETURN_LONG(num); +} + +static zend_function_entry google_protobuf_Syntax_phpmethods[] = { + PHP_ME(google_protobuf_Syntax, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(google_protobuf_Syntax, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void google_protobuf_Syntax_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Syntax", + google_protobuf_Syntax_phpmethods); + + google_protobuf_Syntax_ce = zend_register_internal_class(&tmp_ce); + zend_declare_class_constant_long(google_protobuf_Syntax_ce, "SYNTAX_PROTO2", + strlen("SYNTAX_PROTO2"), 0); + zend_declare_class_constant_long(google_protobuf_Syntax_ce, "SYNTAX_PROTO3", + strlen("SYNTAX_PROTO3"), 1); +} + +/* google/protobuf/timestamp.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Timestamp_ce; + +const char google_protobuf_timestamp_proto_descriptor [239] = { +'\n', '\037', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'i', 'm', 'e', 's', 't', 'a', +'m', 'p', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'\"', '+', '\n', '\t', 'T', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', '\022', '\017', '\n', '\007', 's', 'e', 'c', 'o', 'n', 'd', 's', '\030', +'\001', ' ', '\001', '(', '\003', '\022', '\r', '\n', '\005', 'n', 'a', 'n', 'o', 's', '\030', '\002', ' ', '\001', '(', '\005', 'B', '\205', '\001', '\n', '\023', +'c', 'o', 'm', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\016', 'T', 'i', 'm', 'e', +'s', 't', 'a', 'm', 'p', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', '2', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', +'n', 'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', +'w', 'n', '/', 't', 'i', 'm', 'e', 's', 't', 'a', 'm', 'p', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', +'\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', +'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_timestamp_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/timestamp.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/timestamp.proto", google_protobuf_timestamp_proto_descriptor, + sizeof(google_protobuf_timestamp_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Timestamp, initOnce) { + google_protobuf_timestamp_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Timestamp_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Timestamp, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Timestamp_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Timestamp", + GPBMetadata_Google_Protobuf_Timestamp_methods); + + GPBMetadata_Google_Protobuf_Timestamp_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_Timestamp */ + +zend_class_entry* google_protobuf_Timestamp_ce; + +static PHP_METHOD(google_protobuf_Timestamp, __construct) { + google_protobuf_timestamp_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Timestamp, getSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Timestamp, setSeconds) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "seconds"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static PHP_METHOD(google_protobuf_Timestamp, getNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Timestamp, setNanos) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "nanos"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Timestamp_phpmethods[] = { + PHP_ME(google_protobuf_Timestamp, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, getSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, setSeconds, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, getNanos, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, setNanos, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, fromDateTime, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Timestamp, toDateTime, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Timestamp_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Timestamp", + google_protobuf_Timestamp_phpmethods); + + google_protobuf_Timestamp_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Timestamp_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Timestamp_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Timestamp_ce, message_ce); +} + +/* google/protobuf/wrappers.proto */ + +zend_class_entry* GPBMetadata_Google_Protobuf_Wrappers_ce; + +const char google_protobuf_wrappers_proto_descriptor [455] = { +'\n', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'w', 'r', 'a', 'p', 'p', 'e', 'r', +'s', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', +'\034', '\n', '\013', 'D', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', +' ', '\001', '(', '\001', '\"', '\033', '\n', '\n', 'F', 'l', 'o', 'a', 't', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', +'u', 'e', '\030', '\001', ' ', '\001', '(', '\002', '\"', '\033', '\n', '\n', 'I', 'n', 't', '6', '4', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', +'\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\003', '\"', '\034', '\n', '\013', 'U', 'I', 'n', 't', '6', '4', 'V', 'a', 'l', +'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\004', '\"', '\033', '\n', '\n', 'I', 'n', 't', '3', +'2', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\005', '\"', '\034', '\n', '\013', +'U', 'I', 'n', 't', '3', '2', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', +'\r', '\"', '\032', '\n', '\t', 'B', 'o', 'o', 'l', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', +' ', '\001', '(', '\010', '\"', '\034', '\n', '\013', 'S', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\r', '\n', '\005', 'v', 'a', +'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\t', '\"', '\033', '\n', '\n', 'B', 'y', 't', 'e', 's', 'V', 'a', 'l', 'u', 'e', '\022', '\r', +'\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\001', ' ', '\001', '(', '\014', 'B', '\203', '\001', '\n', '\023', 'c', 'o', 'm', '.', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\r', 'W', 'r', 'a', 'p', 'p', 'e', 'r', 's', 'P', 'r', 'o', +'t', 'o', 'P', '\001', 'Z', '1', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', '.', 'o', 'r', 'g', '/', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'k', 'n', 'o', 'w', 'n', '/', 'w', 'r', 'a', 'p', 'p', +'e', 'r', 's', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\036', 'G', 'o', 'o', 'g', 'l', 'e', '.', 'P', +'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'W', 'e', 'l', 'l', 'K', 'n', 'o', 'w', 'n', 'T', 'y', 'p', 'e', 's', 'b', '\006', 'p', +'r', 'o', 't', 'o', '3', +}; + +static void google_protobuf_wrappers_proto_AddDescriptor() { + if (DescriptorPool_HasFile("google/protobuf/wrappers.proto")) return; + DescriptorPool_AddDescriptor("google/protobuf/wrappers.proto", google_protobuf_wrappers_proto_descriptor, + sizeof(google_protobuf_wrappers_proto_descriptor)); +} + +static PHP_METHOD(GPBMetadata_Google_Protobuf_Wrappers, initOnce) { + google_protobuf_wrappers_proto_AddDescriptor(); +} + +static zend_function_entry GPBMetadata_Google_Protobuf_Wrappers_methods[] = { + PHP_ME(GPBMetadata_Google_Protobuf_Wrappers, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + ZEND_FE_END +}; + +static void GPBMetadata_Google_Protobuf_Wrappers_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "GPBMetadata\\Google\\Protobuf\\Wrappers", + GPBMetadata_Google_Protobuf_Wrappers_methods); + + GPBMetadata_Google_Protobuf_Wrappers_ce = zend_register_internal_class(&tmp_ce); +} + +/* google_protobuf_DoubleValue */ + +zend_class_entry* google_protobuf_DoubleValue_ce; + +static PHP_METHOD(google_protobuf_DoubleValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_DoubleValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_DoubleValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_DoubleValue_phpmethods[] = { + PHP_ME(google_protobuf_DoubleValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_DoubleValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_DoubleValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_DoubleValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\DoubleValue", + google_protobuf_DoubleValue_phpmethods); + + google_protobuf_DoubleValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_DoubleValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_DoubleValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_DoubleValue_ce, message_ce); +} + +/* google_protobuf_FloatValue */ + +zend_class_entry* google_protobuf_FloatValue_ce; + +static PHP_METHOD(google_protobuf_FloatValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_FloatValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_FloatValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_FloatValue_phpmethods[] = { + PHP_ME(google_protobuf_FloatValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FloatValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_FloatValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_FloatValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\FloatValue", + google_protobuf_FloatValue_phpmethods); + + google_protobuf_FloatValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_FloatValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_FloatValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_FloatValue_ce, message_ce); +} + +/* google_protobuf_Int64Value */ + +zend_class_entry* google_protobuf_Int64Value_ce; + +static PHP_METHOD(google_protobuf_Int64Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Int64Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Int64Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Int64Value_phpmethods[] = { + PHP_ME(google_protobuf_Int64Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int64Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int64Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Int64Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Int64Value", + google_protobuf_Int64Value_phpmethods); + + google_protobuf_Int64Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Int64Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Int64Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Int64Value_ce, message_ce); +} + +/* google_protobuf_UInt64Value */ + +zend_class_entry* google_protobuf_UInt64Value_ce; + +static PHP_METHOD(google_protobuf_UInt64Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_UInt64Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_UInt64Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_UInt64Value_phpmethods[] = { + PHP_ME(google_protobuf_UInt64Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt64Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt64Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_UInt64Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\UInt64Value", + google_protobuf_UInt64Value_phpmethods); + + google_protobuf_UInt64Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_UInt64Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_UInt64Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_UInt64Value_ce, message_ce); +} + +/* google_protobuf_Int32Value */ + +zend_class_entry* google_protobuf_Int32Value_ce; + +static PHP_METHOD(google_protobuf_Int32Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_Int32Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_Int32Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_Int32Value_phpmethods[] = { + PHP_ME(google_protobuf_Int32Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int32Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_Int32Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_Int32Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\Int32Value", + google_protobuf_Int32Value_phpmethods); + + google_protobuf_Int32Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_Int32Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_Int32Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_Int32Value_ce, message_ce); +} + +/* google_protobuf_UInt32Value */ + +zend_class_entry* google_protobuf_UInt32Value_ce; + +static PHP_METHOD(google_protobuf_UInt32Value, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_UInt32Value, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_UInt32Value, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_UInt32Value_phpmethods[] = { + PHP_ME(google_protobuf_UInt32Value, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt32Value, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_UInt32Value, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_UInt32Value_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\UInt32Value", + google_protobuf_UInt32Value_phpmethods); + + google_protobuf_UInt32Value_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_UInt32Value_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_UInt32Value_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_UInt32Value_ce, message_ce); +} + +/* google_protobuf_BoolValue */ + +zend_class_entry* google_protobuf_BoolValue_ce; + +static PHP_METHOD(google_protobuf_BoolValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_BoolValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_BoolValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_BoolValue_phpmethods[] = { + PHP_ME(google_protobuf_BoolValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BoolValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BoolValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_BoolValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\BoolValue", + google_protobuf_BoolValue_phpmethods); + + google_protobuf_BoolValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_BoolValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_BoolValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_BoolValue_ce, message_ce); +} + +/* google_protobuf_StringValue */ + +zend_class_entry* google_protobuf_StringValue_ce; + +static PHP_METHOD(google_protobuf_StringValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_StringValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_StringValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_StringValue_phpmethods[] = { + PHP_ME(google_protobuf_StringValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_StringValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_StringValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_StringValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\StringValue", + google_protobuf_StringValue_phpmethods); + + google_protobuf_StringValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_StringValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_StringValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_StringValue_ce, message_ce); +} + +/* google_protobuf_BytesValue */ + +zend_class_entry* google_protobuf_BytesValue_ce; + +static PHP_METHOD(google_protobuf_BytesValue, __construct) { + google_protobuf_wrappers_proto_AddDescriptor(); + zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +static PHP_METHOD(google_protobuf_BytesValue, getValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval ret; + Message_get(intern, f, &ret); + RETURN_ZVAL(&ret, 1, 0); +} + +static PHP_METHOD(google_protobuf_BytesValue, setValue) { + Message* intern = (Message*)Z_OBJ_P(getThis()); + const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef, + "value"); + zval *val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) + == FAILURE) { + return; + } + Message_set(intern, f, val); + RETURN_ZVAL(getThis(), 1, 0); +} + +static zend_function_entry google_protobuf_BytesValue_phpmethods[] = { + PHP_ME(google_protobuf_BytesValue, __construct, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BytesValue, getValue, NULL, ZEND_ACC_PUBLIC) + PHP_ME(google_protobuf_BytesValue, setValue, NULL, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static void google_protobuf_BytesValue_ModuleInit() { + zend_class_entry tmp_ce; + + INIT_CLASS_ENTRY(tmp_ce, "Google\\Protobuf\\BytesValue", + google_protobuf_BytesValue_phpmethods); + + google_protobuf_BytesValue_ce = zend_register_internal_class(&tmp_ce); + google_protobuf_BytesValue_ce->ce_flags |= ZEND_ACC_FINAL; + google_protobuf_BytesValue_ce->create_object = Message_create; + zend_do_inheritance(google_protobuf_BytesValue_ce, message_ce); +} + +static void WellKnownTypes_ModuleInit() { + GPBMetadata_Google_Protobuf_Any_ModuleInit(); + google_protobuf_Any_ModuleInit(); + GPBMetadata_Google_Protobuf_Api_ModuleInit(); + google_protobuf_Api_ModuleInit(); + google_protobuf_Method_ModuleInit(); + google_protobuf_Mixin_ModuleInit(); + GPBMetadata_Google_Protobuf_Duration_ModuleInit(); + google_protobuf_Duration_ModuleInit(); + GPBMetadata_Google_Protobuf_GPBEmpty_ModuleInit(); + google_protobuf_Empty_ModuleInit(); + GPBMetadata_Google_Protobuf_FieldMask_ModuleInit(); + google_protobuf_FieldMask_ModuleInit(); + GPBMetadata_Google_Protobuf_SourceContext_ModuleInit(); + google_protobuf_SourceContext_ModuleInit(); + GPBMetadata_Google_Protobuf_Struct_ModuleInit(); + google_protobuf_Struct_ModuleInit(); + google_protobuf_Struct_FieldsEntry_ModuleInit(); + google_protobuf_Value_ModuleInit(); + google_protobuf_ListValue_ModuleInit(); + google_protobuf_NullValue_ModuleInit(); + GPBMetadata_Google_Protobuf_Type_ModuleInit(); + google_protobuf_Type_ModuleInit(); + google_protobuf_Field_ModuleInit(); + google_protobuf_Field_Kind_ModuleInit(); + google_protobuf_Field_Cardinality_ModuleInit(); + google_protobuf_Enum_ModuleInit(); + google_protobuf_EnumValue_ModuleInit(); + google_protobuf_Option_ModuleInit(); + google_protobuf_Syntax_ModuleInit(); + GPBMetadata_Google_Protobuf_Timestamp_ModuleInit(); + google_protobuf_Timestamp_ModuleInit(); + GPBMetadata_Google_Protobuf_Wrappers_ModuleInit(); + google_protobuf_DoubleValue_ModuleInit(); + google_protobuf_FloatValue_ModuleInit(); + google_protobuf_Int64Value_ModuleInit(); + google_protobuf_UInt64Value_ModuleInit(); + google_protobuf_Int32Value_ModuleInit(); + google_protobuf_UInt32Value_ModuleInit(); + google_protobuf_BoolValue_ModuleInit(); + google_protobuf_StringValue_ModuleInit(); + google_protobuf_BytesValue_ModuleInit(); +} diff --git a/php/generate_descriptor_protos.sh b/php/generate_descriptor_protos.sh index f636cc0ebb48..9feaa96c8b51 100755 --- a/php/generate_descriptor_protos.sh +++ b/php/generate_descriptor_protos.sh @@ -3,6 +3,8 @@ # Run this script to regenerate descriptor protos after the protocol compiler # changes. +set -e + if test ! -e src/google/protobuf/stubs/common.h; then cat >&2 << __EOF__ Could not find source code. Make sure you are running this script from the @@ -13,4 +15,15 @@ fi pushd src ./protoc --php_out=internal:../php/src google/protobuf/descriptor.proto +./protoc --php_out=internal_generate_c_wkt:../php/src \ + google/protobuf/any.proto \ + google/protobuf/api.proto \ + google/protobuf/duration.proto \ + google/protobuf/empty.proto \ + google/protobuf/field_mask.proto \ + google/protobuf/source_context.proto \ + google/protobuf/struct.proto \ + google/protobuf/type.proto \ + google/protobuf/timestamp.proto \ + google/protobuf/wrappers.proto popd diff --git a/php/phpunit.xml b/php/phpunit.xml index 769037cf9ac4..8e7583596bfb 100644 --- a/php/phpunit.xml +++ b/php/phpunit.xml @@ -3,16 +3,16 @@ colors="true"> - tests/php_implementation_test.php - tests/array_test.php - tests/encode_decode_test.php - tests/generated_class_test.php - tests/generated_phpdoc_test.php - tests/map_field_test.php - tests/well_known_test.php - tests/descriptors_test.php - tests/generated_service_test.php - tests/wrapper_type_setters_test.php + tests/PhpImplementationTest.php + tests/ArrayTest.php + tests/EncodeDecodeTest.php + tests/GeneratedClassTest.php + tests/GeneratedPhpdocTest.php + tests/MapFieldTest.php + tests/WellKnownTest.php + tests/DescriptorsTest.php + tests/GeneratedServiceTest.php + tests/WrapperTypeSettersTest.php diff --git a/php/prepare_c_extension.sh b/php/prepare_c_extension.sh new file mode 100755 index 000000000000..84cd1aa3d155 --- /dev/null +++ b/php/prepare_c_extension.sh @@ -0,0 +1,6 @@ + +# wyhash has to live in the base third_party directory. +# We copy it into the ext/google/protobuf directory for the build +# (and for the release to PECL). +mkdir -p ../ext/google/protobuf/third_party/wyhash +cp ../../third_party/wyhash/* ../ext/google/protobuf/third_party/wyhash diff --git a/php/src/GPBMetadata/Google/Protobuf/Any.php b/php/src/GPBMetadata/Google/Protobuf/Any.php index 22cc25008fc8..fbce4bfdb10f 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Any.php +++ b/php/src/GPBMetadata/Google/Protobuf/Any.php @@ -14,15 +14,15 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0acd010a19676f6f676c652f70726f746f6275662f616e792e70726f746f" . - "120f676f6f676c652e70726f746f62756622260a03416e7912100a087479" . - "70655f75726c180120012809120d0a0576616c756518022001280c426f0a" . - "13636f6d2e676f6f676c652e70726f746f6275664208416e7950726f746f" . - "50015a256769746875622e636f6d2f676f6c616e672f70726f746f627566" . - "2f7074797065732f616e79a20203475042aa021e476f6f676c652e50726f" . - "746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/any.protogoogle.protobuf"& +Any +type_url (  +value ( Bv +com.google.protobufBAnyProtoPZ,google.golang.org/protobuf/types/known/anypbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Api.php b/php/src/GPBMetadata/Google/Protobuf/Api.php index b18e0d33ac03..75e0ec631805 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Api.php +++ b/php/src/GPBMetadata/Google/Protobuf/Api.php @@ -16,32 +16,31 @@ public static function initOnce() { } \GPBMetadata\Google\Protobuf\SourceContext::initOnce(); \GPBMetadata\Google\Protobuf\Type::initOnce(); - $pool->internalAddGeneratedFile(hex2bin( - "0ac8050a19676f6f676c652f70726f746f6275662f6170692e70726f746f" . - "120f676f6f676c652e70726f746f6275661a1a676f6f676c652f70726f74" . - "6f6275662f747970652e70726f746f2281020a03417069120c0a046e616d" . - "6518012001280912280a076d6574686f647318022003280b32172e676f6f" . - "676c652e70726f746f6275662e4d6574686f6412280a076f7074696f6e73" . - "18032003280b32172e676f6f676c652e70726f746f6275662e4f7074696f" . - "6e120f0a0776657273696f6e18042001280912360a0e736f757263655f63" . - "6f6e7465787418052001280b321e2e676f6f676c652e70726f746f627566" . - "2e536f75726365436f6e7465787412260a066d6978696e7318062003280b" . - "32162e676f6f676c652e70726f746f6275662e4d6978696e12270a067379" . - "6e74617818072001280e32172e676f6f676c652e70726f746f6275662e53" . - "796e74617822d5010a064d6574686f64120c0a046e616d65180120012809" . - "12180a10726571756573745f747970655f75726c18022001280912190a11" . - "726571756573745f73747265616d696e6718032001280812190a11726573" . - "706f6e73655f747970655f75726c180420012809121a0a12726573706f6e" . - "73655f73747265616d696e6718052001280812280a076f7074696f6e7318" . - "062003280b32172e676f6f676c652e70726f746f6275662e4f7074696f6e" . - "12270a0673796e74617818072001280e32172e676f6f676c652e70726f74" . - "6f6275662e53796e74617822230a054d6978696e120c0a046e616d651801" . - "20012809120c0a04726f6f7418022001280942750a13636f6d2e676f6f67" . - "6c652e70726f746f627566420841706950726f746f50015a2b676f6f676c" . - "652e676f6c616e672e6f72672f67656e70726f746f2f70726f746f627566" . - "2f6170693b617069a20203475042aa021e476f6f676c652e50726f746f62" . - "75662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/api.protogoogle.protobufgoogle/protobuf/type.proto" +Api +name ( ( +methods ( 2.google.protobuf.Method( +options ( 2.google.protobuf.Option +version ( 6 +source_context ( 2.google.protobuf.SourceContext& +mixins ( 2.google.protobuf.Mixin\' +syntax (2.google.protobuf.Syntax" +Method +name (  +request_type_url (  +request_streaming ( +response_type_url (  +response_streaming (( +options ( 2.google.protobuf.Option\' +syntax (2.google.protobuf.Syntax"# +Mixin +name (  +root ( Bv +com.google.protobufBApiProtoPZ,google.golang.org/protobuf/types/known/apipbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Duration.php b/php/src/GPBMetadata/Google/Protobuf/Duration.php index b1c85ad8894e..5d8023e4db9e 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Duration.php +++ b/php/src/GPBMetadata/Google/Protobuf/Duration.php @@ -14,16 +14,15 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ae3010a1e676f6f676c652f70726f746f6275662f6475726174696f6e2e" . - "70726f746f120f676f6f676c652e70726f746f627566222a0a0844757261" . - "74696f6e120f0a077365636f6e6473180120012803120d0a056e616e6f73" . - "180220012805427c0a13636f6d2e676f6f676c652e70726f746f62756642" . - "0d4475726174696f6e50726f746f50015a2a6769746875622e636f6d2f67" . - "6f6c616e672f70726f746f6275662f7074797065732f6475726174696f6e" . - "f80101a20203475042aa021e476f6f676c652e50726f746f6275662e5765" . - "6c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/duration.protogoogle.protobuf"* +Duration +seconds ( +nanos (B +com.google.protobufB DurationProtoPZ1google.golang.org/protobuf/types/known/durationpbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/FieldMask.php b/php/src/GPBMetadata/Google/Protobuf/FieldMask.php index 5812be1e2447..f31bcc001245 100644 --- a/php/src/GPBMetadata/Google/Protobuf/FieldMask.php +++ b/php/src/GPBMetadata/Google/Protobuf/FieldMask.php @@ -14,16 +14,14 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ae3010a20676f6f676c652f70726f746f6275662f6669656c645f6d6173" . - "6b2e70726f746f120f676f6f676c652e70726f746f627566221a0a094669" . - "656c644d61736b120d0a0570617468731801200328094289010a13636f6d" . - "2e676f6f676c652e70726f746f627566420e4669656c644d61736b50726f" . - "746f50015a39676f6f676c652e676f6c616e672e6f72672f67656e70726f" . - "746f2f70726f746f6275662f6669656c645f6d61736b3b6669656c645f6d" . - "61736ba20203475042aa021e476f6f676c652e50726f746f6275662e5765" . - "6c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + + google/protobuf/field_mask.protogoogle.protobuf" + FieldMask +paths ( B +com.google.protobufBFieldMaskProtoPZ2google.golang.org/protobuf/types/known/fieldmaskpbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php b/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php index 88f42a11a462..5e42536f270c 100644 --- a/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php +++ b/php/src/GPBMetadata/Google/Protobuf/GPBEmpty.php @@ -14,15 +14,14 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f" . - "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276" . - "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072" . - "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f" . - "6275662f7074797065732f656d707479f80101a20203475042aa021e476f" . - "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206" . - "70726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/empty.protogoogle.protobuf" +EmptyB} +com.google.protobufB +EmptyProtoPZ.google.golang.org/protobuf/types/known/emptypbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php index e6362f2bfb51..ea0edc55575a 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php @@ -72,6 +72,7 @@ public static function initOnce() { ->optional('oneof_index', \Google\Protobuf\Internal\GPBType::INT32, 9) ->optional('json_name', \Google\Protobuf\Internal\GPBType::STRING, 10) ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 8, 'google.protobuf.internal.FieldOptions') + ->optional('proto3_optional', \Google\Protobuf\Internal\GPBType::BOOL, 17) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FieldDescriptorProto.Type', \Google\Protobuf\Internal\Type::class) diff --git a/php/src/GPBMetadata/Google/Protobuf/SourceContext.php b/php/src/GPBMetadata/Google/Protobuf/SourceContext.php index 495c6de410ec..797732d9f326 100644 --- a/php/src/GPBMetadata/Google/Protobuf/SourceContext.php +++ b/php/src/GPBMetadata/Google/Protobuf/SourceContext.php @@ -14,17 +14,14 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0afb010a24676f6f676c652f70726f746f6275662f736f757263655f636f" . - "6e746578742e70726f746f120f676f6f676c652e70726f746f6275662222" . - "0a0d536f75726365436f6e7465787412110a0966696c655f6e616d651801" . - "200128094295010a13636f6d2e676f6f676c652e70726f746f6275664212" . - "536f75726365436f6e7465787450726f746f50015a41676f6f676c652e67" . - "6f6c616e672e6f72672f67656e70726f746f2f70726f746f6275662f736f" . - "757263655f636f6e746578743b736f757263655f636f6e74657874a20203" . - "475042aa021e476f6f676c652e50726f746f6275662e57656c6c4b6e6f77" . - "6e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +$google/protobuf/source_context.protogoogle.protobuf"" + SourceContext + file_name ( B +com.google.protobufBSourceContextProtoPZ6google.golang.org/protobuf/types/known/sourcecontextpbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Struct.php b/php/src/GPBMetadata/Google/Protobuf/Struct.php index 96b42af41d52..888a81adee40 100644 Binary files a/php/src/GPBMetadata/Google/Protobuf/Struct.php and b/php/src/GPBMetadata/Google/Protobuf/Struct.php differ diff --git a/php/src/GPBMetadata/Google/Protobuf/Timestamp.php b/php/src/GPBMetadata/Google/Protobuf/Timestamp.php index 373665c977c0..09437271a91c 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Timestamp.php +++ b/php/src/GPBMetadata/Google/Protobuf/Timestamp.php @@ -14,16 +14,15 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0ae7010a1f676f6f676c652f70726f746f6275662f74696d657374616d70" . - "2e70726f746f120f676f6f676c652e70726f746f627566222b0a0954696d" . - "657374616d70120f0a077365636f6e6473180120012803120d0a056e616e" . - "6f73180220012805427e0a13636f6d2e676f6f676c652e70726f746f6275" . - "66420e54696d657374616d7050726f746f50015a2b6769746875622e636f" . - "6d2f676f6c616e672f70726f746f6275662f7074797065732f74696d6573" . - "74616d70f80101a20203475042aa021e476f6f676c652e50726f746f6275" . - "662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/timestamp.protogoogle.protobuf"+ + Timestamp +seconds ( +nanos (B +com.google.protobufBTimestampProtoPZ2google.golang.org/protobuf/types/known/timestamppbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/GPBMetadata/Google/Protobuf/Type.php b/php/src/GPBMetadata/Google/Protobuf/Type.php index 8fbe8cbfe0d4..7d0bfbb533a2 100644 Binary files a/php/src/GPBMetadata/Google/Protobuf/Type.php and b/php/src/GPBMetadata/Google/Protobuf/Type.php differ diff --git a/php/src/GPBMetadata/Google/Protobuf/Wrappers.php b/php/src/GPBMetadata/Google/Protobuf/Wrappers.php index dd72ff48ce0e..e7ea1a3b9516 100644 --- a/php/src/GPBMetadata/Google/Protobuf/Wrappers.php +++ b/php/src/GPBMetadata/Google/Protobuf/Wrappers.php @@ -14,23 +14,34 @@ public static function initOnce() { if (static::$is_initialized == true) { return; } - $pool->internalAddGeneratedFile(hex2bin( - "0abf030a1e676f6f676c652f70726f746f6275662f77726170706572732e" . - "70726f746f120f676f6f676c652e70726f746f627566221c0a0b446f7562" . - "6c6556616c7565120d0a0576616c7565180120012801221b0a0a466c6f61" . - "7456616c7565120d0a0576616c7565180120012802221b0a0a496e743634" . - "56616c7565120d0a0576616c7565180120012803221c0a0b55496e743634" . - "56616c7565120d0a0576616c7565180120012804221b0a0a496e74333256" . - "616c7565120d0a0576616c7565180120012805221c0a0b55496e74333256" . - "616c7565120d0a0576616c756518012001280d221a0a09426f6f6c56616c" . - "7565120d0a0576616c7565180120012808221c0a0b537472696e6756616c" . - "7565120d0a0576616c7565180120012809221b0a0a427974657356616c75" . - "65120d0a0576616c756518012001280c427c0a13636f6d2e676f6f676c65" . - "2e70726f746f627566420d577261707065727350726f746f50015a2a6769" . - "746875622e636f6d2f676f6c616e672f70726f746f6275662f7074797065" . - "732f7772617070657273f80101a20203475042aa021e476f6f676c652e50" . - "726f746f6275662e57656c6c4b6e6f776e5479706573620670726f746f33" - )); + $pool->internalAddGeneratedFile( + ' + +google/protobuf/wrappers.protogoogle.protobuf" + DoubleValue +value (" + +FloatValue +value (" + +Int64Value +value (" + UInt64Value +value (" + +Int32Value +value (" + UInt32Value +value ( " + BoolValue +value (" + StringValue +value ( " + +BytesValue +value ( B +com.google.protobufB WrappersProtoPZ1google.golang.org/protobuf/types/known/wrapperspbGPBGoogle.Protobuf.WellKnownTypesbproto3' + , true); static::$is_initialized = true; } diff --git a/php/src/Google/Protobuf/Any.php b/php/src/Google/Protobuf/Any.php index 166c66a49e56..8fdc3c483d22 100644 --- a/php/src/Google/Protobuf/Any.php +++ b/php/src/Google/Protobuf/Any.php @@ -5,7 +5,6 @@ namespace Google\Protobuf; use Google\Protobuf\Internal\GPBType; -use Google\Protobuf\Internal\Message; use Google\Protobuf\Internal\RepeatedField; use Google\Protobuf\Internal\GPBUtil; @@ -39,10 +38,13 @@ * ... * Example 4: Pack and unpack a message in Go * foo := &pb.Foo{...} - * any, err := ptypes.MarshalAny(foo) + * any, err := anypb.New(foo) + * if err != nil { + * ... + * } * ... * foo := &pb.Foo{} - * if err := ptypes.UnmarshalAny(any, foo); err != nil { + * if err := any.UnmarshalTo(foo); err != nil { * ... * } * The pack methods provided by protobuf library will by default use @@ -76,11 +78,12 @@ * * Generated from protobuf message google.protobuf.Any */ -class Any extends \Google\Protobuf\Internal\Message +class Any extends \Google\Protobuf\Internal\AnyBase { /** * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -104,15 +107,13 @@ class Any extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string type_url = 1; */ - private $type_url = ''; + protected $type_url = ''; /** * Must be a valid serialized protocol buffer of the above specified type. * * Generated from protobuf field bytes value = 2; */ - private $value = ''; - - const TYPE_URL_PREFIX = 'type.googleapis.com/'; + protected $value = ''; /** * Constructor. @@ -122,7 +123,8 @@ class Any extends \Google\Protobuf\Internal\Message * * @type string $type_url * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -154,7 +156,8 @@ public function __construct($data = NULL) { /** * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -186,7 +189,8 @@ public function getTypeUrl() /** * A URL/resource name that uniquely identifies the type of the serialized - * protocol buffer message. The last segment of the URL's path must represent + * protocol buffer message. This string must contain at least + * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). @@ -246,80 +250,5 @@ public function setValue($var) return $this; } - /** - * This method will try to resolve the type_url in Any message to get the - * targeted message type. If failed, an error will be thrown. Otherwise, - * the method will create a message of the targeted type and fill it with - * the decoded value in Any. - * @return Message unpacked message - * @throws \Exception Type url needs to be type.googleapis.com/fully-qualified. - * @throws \Exception Class hasn't been added to descriptor pool. - * @throws \Exception cannot decode data in value field. - */ - public function unpack() - { - // Get fully qualified name from type url. - $url_prifix_len = strlen(GPBUtil::TYPE_URL_PREFIX); - if (substr($this->type_url, 0, $url_prifix_len) != - GPBUtil::TYPE_URL_PREFIX) { - throw new \Exception( - "Type url needs to be type.googleapis.com/fully-qulified"); - } - $fully_qualifed_name = - substr($this->type_url, $url_prifix_len); - - // Create message according to fully qualified name. - $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); - $desc = $pool->getDescriptorByProtoName( ".".$fully_qualifed_name); - if (is_null($desc)) { - throw new \Exception("Class ".$fully_qualifed_name - ." hasn't been added to descriptor pool"); - } - $klass = $desc->getClass(); - $msg = new $klass(); - - // Merge data into message. - $msg->mergeFromString($this->value); - return $msg; - } - - /** - * The type_url will be created according to the given message’s type and - * the value is encoded data from the given message.. - * @param message: A proto message. - */ - public function pack($msg) - { - if (!$msg instanceof Message) { - trigger_error("Given parameter is not a message instance.", - E_USER_ERROR); - return; - } - - // Set value using serialized message. - $this->value = $msg->serializeToString(); - - // Set type url. - $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); - $desc = $pool->getDescriptorByClassName(get_class($msg)); - $fully_qualifed_name = $desc->getFullName(); - $this->type_url = GPBUtil::TYPE_URL_PREFIX.substr( - $fully_qualifed_name, 1, strlen($fully_qualifed_name)); - } - - /** - * This method returns whether the type_url in any_message is corresponded - * to the given class. - * @param klass: The fully qualified PHP class name of a proto message type. - */ - public function is($klass) - { - $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); - $desc = $pool->getDescriptorByClassName($klass); - $fully_qualifed_name = $desc->getFullName(); - $type_url = GPBUtil::TYPE_URL_PREFIX.substr( - $fully_qualifed_name, 1, strlen($fully_qualifed_name)); - return $this->type_url === $type_url; - } } diff --git a/php/src/Google/Protobuf/Api.php b/php/src/Google/Protobuf/Api.php index db37ffb0194e..773397565c08 100644 --- a/php/src/Google/Protobuf/Api.php +++ b/php/src/Google/Protobuf/Api.php @@ -28,7 +28,7 @@ class Api extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * The methods of this interface, in unspecified order. * @@ -62,14 +62,14 @@ class Api extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string version = 4; */ - private $version = ''; + protected $version = ''; /** * Source context for the protocol buffer service represented by this * message. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; */ - private $source_context = null; + protected $source_context = null; /** * Included interfaces. See [Mixin][]. * @@ -81,7 +81,7 @@ class Api extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Syntax syntax = 7; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. @@ -275,7 +275,17 @@ public function setVersion($var) */ public function getSourceContext() { - return $this->source_context; + return isset($this->source_context) ? $this->source_context : null; + } + + public function hasSourceContext() + { + return isset($this->source_context); + } + + public function clearSourceContext() + { + unset($this->source_context); } /** diff --git a/php/src/Google/Protobuf/BoolValue.php b/php/src/Google/Protobuf/BoolValue.php index 13872eb1e464..ecdbf4dcc265 100644 --- a/php/src/Google/Protobuf/BoolValue.php +++ b/php/src/Google/Protobuf/BoolValue.php @@ -21,7 +21,7 @@ class BoolValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field bool value = 1; */ - private $value = false; + protected $value = false; /** * Constructor. diff --git a/php/src/Google/Protobuf/BytesValue.php b/php/src/Google/Protobuf/BytesValue.php index f1b381718564..1582e14acd90 100644 --- a/php/src/Google/Protobuf/BytesValue.php +++ b/php/src/Google/Protobuf/BytesValue.php @@ -21,7 +21,7 @@ class BytesValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field bytes value = 1; */ - private $value = ''; + protected $value = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/Descriptor.php b/php/src/Google/Protobuf/Descriptor.php index 986b81e12d61..36436e2b70b5 100644 --- a/php/src/Google/Protobuf/Descriptor.php +++ b/php/src/Google/Protobuf/Descriptor.php @@ -97,4 +97,12 @@ public function getOneofDeclCount() { return count($this->internal_desc->getOneofDecl()); } + + /** + * @return int Number of real oneofs in message + */ + public function getRealOneofDeclCount() + { + return $this->internal_desc->getRealOneofDeclCount(); + } } diff --git a/php/src/Google/Protobuf/DoubleValue.php b/php/src/Google/Protobuf/DoubleValue.php index 236d91822354..b72399f460d6 100644 --- a/php/src/Google/Protobuf/DoubleValue.php +++ b/php/src/Google/Protobuf/DoubleValue.php @@ -21,7 +21,7 @@ class DoubleValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field double value = 1; */ - private $value = 0.0; + protected $value = 0.0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Duration.php b/php/src/Google/Protobuf/Duration.php index 414a1868b748..531cd50b5791 100644 --- a/php/src/Google/Protobuf/Duration.php +++ b/php/src/Google/Protobuf/Duration.php @@ -25,7 +25,7 @@ * if (duration.seconds < 0 && duration.nanos > 0) { * duration.seconds += 1; * duration.nanos -= 1000000000; - * } else if (durations.seconds > 0 && duration.nanos < 0) { + * } else if (duration.seconds > 0 && duration.nanos < 0) { * duration.seconds -= 1; * duration.nanos += 1000000000; * } @@ -66,7 +66,7 @@ class Duration extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int64 seconds = 1; */ - private $seconds = 0; + protected $seconds = 0; /** * Signed fractions of a second at nanosecond resolution of the span * of time. Durations less than one second are represented with a 0 @@ -77,7 +77,7 @@ class Duration extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int32 nanos = 2; */ - private $nanos = 0; + protected $nanos = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Enum.php b/php/src/Google/Protobuf/Enum.php index 243c40d2899d..ed5afc447fec 100644 --- a/php/src/Google/Protobuf/Enum.php +++ b/php/src/Google/Protobuf/Enum.php @@ -20,7 +20,7 @@ class Enum extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * Enum value definitions. * @@ -38,13 +38,13 @@ class Enum extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.SourceContext source_context = 4; */ - private $source_context = null; + protected $source_context = null; /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 5; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. @@ -155,7 +155,17 @@ public function setOptions($var) */ public function getSourceContext() { - return $this->source_context; + return isset($this->source_context) ? $this->source_context : null; + } + + public function hasSourceContext() + { + return isset($this->source_context); + } + + public function clearSourceContext() + { + unset($this->source_context); } /** diff --git a/php/src/Google/Protobuf/EnumValue.php b/php/src/Google/Protobuf/EnumValue.php index 1dc3c7a6eee0..905f4ad14b29 100644 --- a/php/src/Google/Protobuf/EnumValue.php +++ b/php/src/Google/Protobuf/EnumValue.php @@ -20,13 +20,13 @@ class EnumValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * Enum value number. * * Generated from protobuf field int32 number = 2; */ - private $number = 0; + protected $number = 0; /** * Protocol buffer options. * diff --git a/php/src/Google/Protobuf/Field.php b/php/src/Google/Protobuf/Field.php index 8da43e34da4f..76a505ea567d 100644 --- a/php/src/Google/Protobuf/Field.php +++ b/php/src/Google/Protobuf/Field.php @@ -20,45 +20,45 @@ class Field extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Field.Kind kind = 1; */ - private $kind = 0; + protected $kind = 0; /** * The field cardinality. * * Generated from protobuf field .google.protobuf.Field.Cardinality cardinality = 2; */ - private $cardinality = 0; + protected $cardinality = 0; /** * The field number. * * Generated from protobuf field int32 number = 3; */ - private $number = 0; + protected $number = 0; /** * The field name. * * Generated from protobuf field string name = 4; */ - private $name = ''; + protected $name = ''; /** * The field type URL, without the scheme, for message or enumeration * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. * * Generated from protobuf field string type_url = 6; */ - private $type_url = ''; + protected $type_url = ''; /** * The index of the field type in `Type.oneofs`, for message or enumeration * types. The first type has index 1; zero means the type is not in the list. * * Generated from protobuf field int32 oneof_index = 7; */ - private $oneof_index = 0; + protected $oneof_index = 0; /** * Whether to use alternative packed wire representation. * * Generated from protobuf field bool packed = 8; */ - private $packed = false; + protected $packed = false; /** * The protocol buffer options. * @@ -70,13 +70,13 @@ class Field extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string json_name = 10; */ - private $json_name = ''; + protected $json_name = ''; /** * The string value of the default value of this field. Proto2 syntax only. * * Generated from protobuf field string default_value = 11; */ - private $default_value = ''; + protected $default_value = ''; /** * Constructor. @@ -133,7 +133,7 @@ public function getKind() */ public function setKind($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Field_Kind::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Field\Kind::class); $this->kind = $var; return $this; @@ -159,7 +159,7 @@ public function getCardinality() */ public function setCardinality($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Field_Cardinality::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Field\Cardinality::class); $this->cardinality = $var; return $this; diff --git a/php/src/Google/Protobuf/Field/Cardinality.php b/php/src/Google/Protobuf/Field/Cardinality.php index 479dc0bfc2db..a42219957696 100644 --- a/php/src/Google/Protobuf/Field/Cardinality.php +++ b/php/src/Google/Protobuf/Field/Cardinality.php @@ -54,6 +54,7 @@ public static function name($value) return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/Field/Kind.php b/php/src/Google/Protobuf/Field/Kind.php index f30bd2f59bdf..2d8dd77c1cb4 100644 --- a/php/src/Google/Protobuf/Field/Kind.php +++ b/php/src/Google/Protobuf/Field/Kind.php @@ -159,6 +159,7 @@ public static function name($value) return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/FieldDescriptor.php b/php/src/Google/Protobuf/FieldDescriptor.php index ac9271f98b25..6d08cea9da97 100644 --- a/php/src/Google/Protobuf/FieldDescriptor.php +++ b/php/src/Google/Protobuf/FieldDescriptor.php @@ -114,4 +114,12 @@ public function isMap() { return $this->internal_desc->isMap(); } + + /** + * @return boolean + */ + public function hasOptionalKeyword() + { + return $this->internal_desc->hasOptionalKeyword(); + } } diff --git a/php/src/Google/Protobuf/FieldMask.php b/php/src/Google/Protobuf/FieldMask.php index 8fb38cbfb22c..0b9659d38f5c 100644 --- a/php/src/Google/Protobuf/FieldMask.php +++ b/php/src/Google/Protobuf/FieldMask.php @@ -62,45 +62,39 @@ * and leave the others untouched. If a resource is passed in to * describe the updated values, the API ignores the values of all * fields not covered by the mask. - * If a repeated field is specified for an update operation, the existing - * repeated values in the target resource will be overwritten by the new values. - * Note that a repeated field is only allowed in the last position of a `paths` - * string. + * If a repeated field is specified for an update operation, new values will + * be appended to the existing repeated field in the target resource. Note that + * a repeated field is only allowed in the last position of a `paths` string. * If a sub-message is specified in the last position of the field mask for an - * update operation, then the existing sub-message in the target resource is - * overwritten. Given the target message: + * update operation, then new value will be merged into the existing sub-message + * in the target resource. + * For example, given the target message: * f { * b { - * d : 1 - * x : 2 + * d: 1 + * x: 2 * } - * c : 1 + * c: [1] * } * And an update message: * f { * b { - * d : 10 + * d: 10 * } + * c: [2] * } * then if the field mask is: - * paths: "f.b" + * paths: ["f.b", "f.c"] * then the result will be: * f { * b { - * d : 10 - * } - * c : 1 - * } - * However, if the update mask was: - * paths: "f.b.d" - * then the result would be: - * f { - * b { - * d : 10 - * x : 2 + * d: 10 + * x: 2 * } - * c : 1 + * c: [1, 2] * } + * An implementation may provide options to override this default behavior for + * repeated and message fields. * In order to reset a field's value to the default, the field must * be in the mask and set to the default value in the provided resource. * Hence, in order to reset all fields of a resource, provide a default @@ -165,7 +159,7 @@ * ## Field Mask Verification * The implementation of any API method which has a FieldMask type field in the * request should verify the included field paths, and return an - * `INVALID_ARGUMENT` error if any path is duplicated or unmappable. + * `INVALID_ARGUMENT` error if any path is unmappable. * * Generated from protobuf message google.protobuf.FieldMask */ diff --git a/php/src/Google/Protobuf/FloatValue.php b/php/src/Google/Protobuf/FloatValue.php index 47ba52e6af3a..4285358d5e8c 100644 --- a/php/src/Google/Protobuf/FloatValue.php +++ b/php/src/Google/Protobuf/FloatValue.php @@ -21,7 +21,7 @@ class FloatValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field float value = 1; */ - private $value = 0.0; + protected $value = 0.0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Int32Value.php b/php/src/Google/Protobuf/Int32Value.php index d7fd528d21bf..cfd73cdc90f5 100644 --- a/php/src/Google/Protobuf/Int32Value.php +++ b/php/src/Google/Protobuf/Int32Value.php @@ -21,7 +21,7 @@ class Int32Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int32 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Int64Value.php b/php/src/Google/Protobuf/Int64Value.php index ca663055839c..143474fcd7cf 100644 --- a/php/src/Google/Protobuf/Int64Value.php +++ b/php/src/Google/Protobuf/Int64Value.php @@ -21,7 +21,7 @@ class Int64Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int64 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Internal/AnyBase.php b/php/src/Google/Protobuf/Internal/AnyBase.php new file mode 100644 index 000000000000..cba922d47547 --- /dev/null +++ b/php/src/Google/Protobuf/Internal/AnyBase.php @@ -0,0 +1,86 @@ +type_url, 0, $url_prifix_len) != + GPBUtil::TYPE_URL_PREFIX) { + throw new \Exception( + "Type url needs to be type.googleapis.com/fully-qulified"); + } + $fully_qualifed_name = + substr($this->type_url, $url_prifix_len); + + // Create message according to fully qualified name. + $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByProtoName($fully_qualifed_name); + if (is_null($desc)) { + throw new \Exception("Class ".$fully_qualifed_name + ." hasn't been added to descriptor pool"); + } + $klass = $desc->getClass(); + $msg = new $klass(); + + // Merge data into message. + $msg->mergeFromString($this->value); + return $msg; + } + + /** + * The type_url will be created according to the given message’s type and + * the value is encoded data from the given message.. + * @param message: A proto message. + */ + public function pack($msg) + { + if (!$msg instanceof Message) { + trigger_error("Given parameter is not a message instance.", + E_USER_ERROR); + return; + } + + // Set value using serialized message. + $this->value = $msg->serializeToString(); + + // Set type url. + $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByClassName(get_class($msg)); + $fully_qualifed_name = $desc->getFullName(); + $this->type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name; + } + + /** + * This method returns whether the type_url in any_message is corresponded + * to the given class. + * @param klass: The fully qualified PHP class name of a proto message type. + */ + public function is($klass) + { + $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); + $desc = $pool->getDescriptorByClassName($klass); + $fully_qualifed_name = $desc->getFullName(); + $type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualifed_name; + return $this->type_url === $type_url; + } +} diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php index 21ac5de364fb..a7f80d534e01 100644 --- a/php/src/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/Google/Protobuf/Internal/Descriptor.php @@ -185,8 +185,8 @@ public static function buildFromProto($proto, $file_proto, $containing) $containing, $file_proto, $message_name_without_package, - $legacy_classname, $classname, + $legacy_classname, $fullname); $desc->setFullName($fullname); $desc->setClass($classname); diff --git a/php/src/Google/Protobuf/Internal/DescriptorPool.php b/php/src/Google/Protobuf/Internal/DescriptorPool.php index 419bbf4dca17..2880cee641b2 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorPool.php +++ b/php/src/Google/Protobuf/Internal/DescriptorPool.php @@ -59,22 +59,25 @@ public function internalAddGeneratedFile($data, $use_nested = false) { $files = new FileDescriptorSet(); $files->mergeFromString($data); - $file = FileDescriptor::buildFromProto($files->getFile()[0]); - foreach ($file->getMessageType() as $desc) { - $this->addDescriptor($desc); - } - unset($desc); + foreach($files->getFile() as $file_proto) { + $file = FileDescriptor::buildFromProto($file_proto); - foreach ($file->getEnumType() as $desc) { - $this->addEnumDescriptor($desc); - } - unset($desc); + foreach ($file->getMessageType() as $desc) { + $this->addDescriptor($desc); + } + unset($desc); - foreach ($file->getMessageType() as $desc) { - $this->crossLink($desc); + foreach ($file->getEnumType() as $desc) { + $this->addEnumDescriptor($desc); + } + unset($desc); + + foreach ($file->getMessageType() as $desc) { + $this->crossLink($desc); + } + unset($desc); } - unset($desc); } public function addMessage($name, $klass) @@ -149,11 +152,22 @@ private function crossLink(Descriptor $desc) switch ($field->getType()) { case GPBType::MESSAGE: $proto = $field->getMessageType(); - $field->setMessageType( - $this->getDescriptorByProtoName($proto)); + if ($proto[0] == '.') { + $proto = substr($proto, 1); + } + $subdesc = $this->getDescriptorByProtoName($proto); + if (is_null($subdesc)) { + trigger_error( + 'proto not added: ' . $proto + . " for " . $desc->getFullName(), E_ERROR); + } + $field->setMessageType($subdesc); break; case GPBType::ENUM: $proto = $field->getEnumType(); + if ($proto[0] == '.') { + $proto = substr($proto, 1); + } $field->setEnumType( $this->getEnumDescriptorByProtoName($proto)); break; diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto.php b/php/src/Google/Protobuf/Internal/DescriptorProto.php index 7cc689d0282e..e0822d779bb2 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto.php @@ -20,48 +20,39 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto field = 2; */ private $field; - private $has_field = false; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 6; */ private $extension; - private $has_extension = false; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto nested_type = 3; */ private $nested_type; - private $has_nested_type = false; /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 4; */ private $enum_type; - private $has_enum_type = false; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; */ private $extension_range; - private $has_extension_range = false; /** * Generated from protobuf field repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; */ private $oneof_decl; - private $has_oneof_decl = false; /** * Generated from protobuf field optional .google.protobuf.MessageOptions options = 7; */ protected $options = null; - private $has_options = false; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; */ private $reserved_range; - private $has_reserved_range = false; /** * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. @@ -69,7 +60,6 @@ class DescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated string reserved_name = 10; */ private $reserved_name; - private $has_reserved_name = false; /** * Constructor. @@ -102,7 +92,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -114,16 +114,10 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto field = 2; * @return \Google\Protobuf\Internal\RepeatedField @@ -142,16 +136,10 @@ public function setField($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->field = $arr; - $this->has_field = true; return $this; } - public function hasField() - { - return $this->has_field; - } - /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 6; * @return \Google\Protobuf\Internal\RepeatedField @@ -170,16 +158,10 @@ public function setExtension($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->extension = $arr; - $this->has_extension = true; return $this; } - public function hasExtension() - { - return $this->has_extension; - } - /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto nested_type = 3; * @return \Google\Protobuf\Internal\RepeatedField @@ -198,16 +180,10 @@ public function setNestedType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); $this->nested_type = $arr; - $this->has_nested_type = true; return $this; } - public function hasNestedType() - { - return $this->has_nested_type; - } - /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 4; * @return \Google\Protobuf\Internal\RepeatedField @@ -226,16 +202,10 @@ public function setEnumType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); $this->enum_type = $arr; - $this->has_enum_type = true; return $this; } - public function hasEnumType() - { - return $this->has_enum_type; - } - /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; * @return \Google\Protobuf\Internal\RepeatedField @@ -254,16 +224,10 @@ public function setExtensionRange($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class); $this->extension_range = $arr; - $this->has_extension_range = true; return $this; } - public function hasExtensionRange() - { - return $this->has_extension_range; - } - /** * Generated from protobuf field repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; * @return \Google\Protobuf\Internal\RepeatedField @@ -282,23 +246,27 @@ public function setOneofDecl($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\OneofDescriptorProto::class); $this->oneof_decl = $arr; - $this->has_oneof_decl = true; return $this; } - public function hasOneofDecl() - { - return $this->has_oneof_decl; - } - /** * Generated from protobuf field optional .google.protobuf.MessageOptions options = 7; * @return \Google\Protobuf\Internal\MessageOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -310,16 +278,10 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MessageOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; * @return \Google\Protobuf\Internal\RepeatedField @@ -338,16 +300,10 @@ public function setReservedRange($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class); $this->reserved_range = $arr; - $this->has_reserved_range = true; return $this; } - public function hasReservedRange() - { - return $this->has_reserved_range; - } - /** * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. @@ -372,15 +328,9 @@ public function setReservedName($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->reserved_name = $arr; - $this->has_reserved_name = true; return $this; } - public function hasReservedName() - { - return $this->has_reserved_name; - } - } diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php index 82b5695efe49..1594913996b1 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php @@ -20,20 +20,17 @@ class ExtensionRange extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 start = 1; */ - protected $start = 0; - private $has_start = false; + protected $start = null; /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -61,7 +58,17 @@ public function __construct($data = NULL) { */ public function getStart() { - return $this->start; + return isset($this->start) ? $this->start : 0; + } + + public function hasStart() + { + return isset($this->start); + } + + public function clearStart() + { + unset($this->start); } /** @@ -75,16 +82,10 @@ public function setStart($var) { GPBUtil::checkInt32($var); $this->start = $var; - $this->has_start = true; return $this; } - public function hasStart() - { - return $this->has_start; - } - /** * Exclusive. * @@ -93,7 +94,17 @@ public function hasStart() */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -107,23 +118,27 @@ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - /** * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions options = 3; * @return \Google\Protobuf\Internal\ExtensionRangeOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -135,16 +150,10 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ExtensionRangeOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php index 8022151abfc6..f099cc345abe 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php +++ b/php/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php @@ -24,15 +24,13 @@ class ReservedRange extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 start = 1; */ - protected $start = 0; - private $has_start = false; + protected $start = null; /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Constructor. @@ -59,7 +57,17 @@ public function __construct($data = NULL) { */ public function getStart() { - return $this->start; + return isset($this->start) ? $this->start : 0; + } + + public function hasStart() + { + return isset($this->start); + } + + public function clearStart() + { + unset($this->start); } /** @@ -73,16 +81,10 @@ public function setStart($var) { GPBUtil::checkInt32($var); $this->start = $var; - $this->has_start = true; return $this; } - public function hasStart() - { - return $this->has_start; - } - /** * Exclusive. * @@ -91,7 +93,17 @@ public function hasStart() */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -105,16 +117,10 @@ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php index f5c7fe148281..85dc246634fd 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto.php @@ -20,18 +20,15 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.EnumValueDescriptorProto value = 2; */ private $value; - private $has_value = false; /** * Generated from protobuf field optional .google.protobuf.EnumOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not @@ -40,7 +37,6 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; */ private $reserved_range; - private $has_reserved_range = false; /** * Reserved enum value names, which may not be reused. A given name may only * be reserved once. @@ -48,7 +44,6 @@ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated string reserved_name = 5; */ private $reserved_name; - private $has_reserved_name = false; /** * Constructor. @@ -79,7 +74,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -91,16 +96,10 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field repeated .google.protobuf.EnumValueDescriptorProto value = 2; * @return \Google\Protobuf\Internal\RepeatedField @@ -119,23 +118,27 @@ public function setValue($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumValueDescriptorProto::class); $this->value = $arr; - $this->has_value = true; return $this; } - public function hasValue() - { - return $this->has_value; - } - /** * Generated from protobuf field optional .google.protobuf.EnumOptions options = 3; * @return \Google\Protobuf\Internal\EnumOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -147,16 +150,10 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not @@ -183,16 +180,10 @@ public function setReservedRange($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class); $this->reserved_range = $arr; - $this->has_reserved_range = true; return $this; } - public function hasReservedRange() - { - return $this->has_reserved_range; - } - /** * Reserved enum value names, which may not be reused. A given name may only * be reserved once. @@ -217,15 +208,9 @@ public function setReservedName($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->reserved_name = $arr; - $this->has_reserved_name = true; return $this; } - public function hasReservedName() - { - return $this->has_reserved_name; - } - } diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php index 949dd891071f..7282fccb0788 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php @@ -26,15 +26,13 @@ class EnumReservedRange extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 start = 1; */ - protected $start = 0; - private $has_start = false; + protected $start = null; /** * Inclusive. * * Generated from protobuf field optional int32 end = 2; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Constructor. @@ -61,7 +59,17 @@ public function __construct($data = NULL) { */ public function getStart() { - return $this->start; + return isset($this->start) ? $this->start : 0; + } + + public function hasStart() + { + return isset($this->start); + } + + public function clearStart() + { + unset($this->start); } /** @@ -75,16 +83,10 @@ public function setStart($var) { GPBUtil::checkInt32($var); $this->start = $var; - $this->has_start = true; return $this; } - public function hasStart() - { - return $this->has_start; - } - /** * Inclusive. * @@ -93,7 +95,17 @@ public function hasStart() */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -107,16 +119,10 @@ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/EnumOptions.php b/php/src/Google/Protobuf/Internal/EnumOptions.php index e6500423b194..7a6967605974 100644 --- a/php/src/Google/Protobuf/Internal/EnumOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumOptions.php @@ -21,8 +21,7 @@ class EnumOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool allow_alias = 2; */ - protected $allow_alias = false; - private $has_allow_alias = false; + protected $allow_alias = null; /** * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -31,15 +30,13 @@ class EnumOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -73,7 +70,17 @@ public function __construct($data = NULL) { */ public function getAllowAlias() { - return $this->allow_alias; + return isset($this->allow_alias) ? $this->allow_alias : false; + } + + public function hasAllowAlias() + { + return isset($this->allow_alias); + } + + public function clearAllowAlias() + { + unset($this->allow_alias); } /** @@ -88,16 +95,10 @@ public function setAllowAlias($var) { GPBUtil::checkBool($var); $this->allow_alias = $var; - $this->has_allow_alias = true; return $this; } - public function hasAllowAlias() - { - return $this->has_allow_alias; - } - /** * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -109,7 +110,17 @@ public function hasAllowAlias() */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -126,16 +137,10 @@ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -158,15 +163,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php index 3dd95583ac55..01097b669d5b 100644 --- a/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php @@ -20,18 +20,15 @@ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field optional int32 number = 2; */ - protected $number = 0; - private $has_number = false; + protected $number = null; /** * Generated from protobuf field optional .google.protobuf.EnumValueOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -55,7 +52,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -67,23 +74,27 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field optional int32 number = 2; * @return int */ public function getNumber() { - return $this->number; + return isset($this->number) ? $this->number : 0; + } + + public function hasNumber() + { + return isset($this->number); + } + + public function clearNumber() + { + unset($this->number); } /** @@ -95,23 +106,27 @@ public function setNumber($var) { GPBUtil::checkInt32($var); $this->number = $var; - $this->has_number = true; return $this; } - public function hasNumber() - { - return $this->has_number; - } - /** * Generated from protobuf field optional .google.protobuf.EnumValueOptions options = 3; * @return \Google\Protobuf\Internal\EnumValueOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -123,15 +138,9 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumValueOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } diff --git a/php/src/Google/Protobuf/Internal/EnumValueOptions.php b/php/src/Google/Protobuf/Internal/EnumValueOptions.php index 9f9fb3bec1bc..84ba7bc85bfc 100644 --- a/php/src/Google/Protobuf/Internal/EnumValueOptions.php +++ b/php/src/Google/Protobuf/Internal/EnumValueOptions.php @@ -23,15 +23,13 @@ class EnumValueOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 1 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -64,7 +62,17 @@ public function __construct($data = NULL) { */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -81,16 +89,10 @@ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -113,15 +115,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php index 00fbebecaf6a..b5e27c3e2783 100644 --- a/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php +++ b/php/src/Google/Protobuf/Internal/ExtensionRangeOptions.php @@ -21,7 +21,6 @@ class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -60,15 +59,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php index 98b516fecc52..ce83f63a2b26 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php @@ -229,7 +229,17 @@ public static function getFieldDescriptor($proto) } $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1; - $packed = false; + // TODO: once proto2 is supported, this default should be false + // for proto2. + if ($proto->getLabel() === GPBLabel::REPEATED && + $proto->getType() !== GPBType::MESSAGE && + $proto->getType() !== GPBType::GROUP && + $proto->getType() !== GPBType::STRING && + $proto->getType() !== GPBType::BYTES) { + $packed = true; + } else { + $packed = false; + } $options = $proto->getOptions(); if ($options !== null) { $packed = $options->getPacked(); diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php index b231c9e1021e..5c8823f8dc7f 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto.php @@ -20,26 +20,22 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field optional int32 number = 3; */ - protected $number = 0; - private $has_number = false; + protected $number = null; /** * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Label label = 4; */ - protected $label = 0; - private $has_label = false; + protected $label = null; /** * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. * * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Type type = 5; */ - protected $type = 0; - private $has_type = false; + protected $type = null; /** * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping @@ -49,16 +45,14 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string type_name = 6; */ - protected $type_name = ''; - private $has_type_name = false; + protected $type_name = null; /** * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. * * Generated from protobuf field optional string extendee = 2; */ - protected $extendee = ''; - private $has_extendee = false; + protected $extendee = null; /** * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". @@ -68,16 +62,14 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string default_value = 7; */ - protected $default_value = ''; - private $has_default_value = false; + protected $default_value = null; /** * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. * * Generated from protobuf field optional int32 oneof_index = 9; */ - protected $oneof_index = 0; - private $has_oneof_index = false; + protected $oneof_index = null; /** * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value @@ -86,13 +78,34 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string json_name = 10; */ - protected $json_name = ''; - private $has_json_name = false; + protected $json_name = null; /** * Generated from protobuf field optional .google.protobuf.FieldOptions options = 8; */ protected $options = null; - private $has_options = false; + /** + * If true, this is a proto3 "optional". When a proto3 field is optional, it + * tracks presence regardless of field type. + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still + * indicates the semantic detail of whether the user wrote "optional" or not. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. + * Proto2 optional fields do not set this flag, because they already indicate + * optional with `LABEL_OPTIONAL`. + * + * Generated from protobuf field optional bool proto3_optional = 17; + */ + protected $proto3_optional = null; /** * Constructor. @@ -130,6 +143,25 @@ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message * will be used. Otherwise, it's deduced from the field's name by converting * it to camelCase. * @type \Google\Protobuf\Internal\FieldOptions $options + * @type bool $proto3_optional + * If true, this is a proto3 "optional". When a proto3 field is optional, it + * tracks presence regardless of field type. + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still + * indicates the semantic detail of whether the user wrote "optional" or not. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. + * Proto2 optional fields do not set this flag, because they already indicate + * optional with `LABEL_OPTIONAL`. * } */ public function __construct($data = NULL) { @@ -143,7 +175,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -155,23 +197,27 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field optional int32 number = 3; * @return int */ public function getNumber() { - return $this->number; + return isset($this->number) ? $this->number : 0; + } + + public function hasNumber() + { + return isset($this->number); + } + + public function clearNumber() + { + unset($this->number); } /** @@ -183,23 +229,27 @@ public function setNumber($var) { GPBUtil::checkInt32($var); $this->number = $var; - $this->has_number = true; return $this; } - public function hasNumber() - { - return $this->has_number; - } - /** * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Label label = 4; * @return int */ public function getLabel() { - return $this->label; + return isset($this->label) ? $this->label : 0; + } + + public function hasLabel() + { + return isset($this->label); + } + + public function clearLabel() + { + unset($this->label); } /** @@ -209,18 +259,12 @@ public function getLabel() */ public function setLabel($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto_Label::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Label::class); $this->label = $var; - $this->has_label = true; return $this; } - public function hasLabel() - { - return $this->has_label; - } - /** * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. @@ -230,7 +274,17 @@ public function hasLabel() */ public function getType() { - return $this->type; + return isset($this->type) ? $this->type : 0; + } + + public function hasType() + { + return isset($this->type); + } + + public function clearType() + { + unset($this->type); } /** @@ -243,18 +297,12 @@ public function getType() */ public function setType($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto_Type::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Type::class); $this->type = $var; - $this->has_type = true; return $this; } - public function hasType() - { - return $this->has_type; - } - /** * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping @@ -267,7 +315,17 @@ public function hasType() */ public function getTypeName() { - return $this->type_name; + return isset($this->type_name) ? $this->type_name : ''; + } + + public function hasTypeName() + { + return isset($this->type_name); + } + + public function clearTypeName() + { + unset($this->type_name); } /** @@ -285,16 +343,10 @@ public function setTypeName($var) { GPBUtil::checkString($var, True); $this->type_name = $var; - $this->has_type_name = true; return $this; } - public function hasTypeName() - { - return $this->has_type_name; - } - /** * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. @@ -304,7 +356,17 @@ public function hasTypeName() */ public function getExtendee() { - return $this->extendee; + return isset($this->extendee) ? $this->extendee : ''; + } + + public function hasExtendee() + { + return isset($this->extendee); + } + + public function clearExtendee() + { + unset($this->extendee); } /** @@ -319,16 +381,10 @@ public function setExtendee($var) { GPBUtil::checkString($var, True); $this->extendee = $var; - $this->has_extendee = true; return $this; } - public function hasExtendee() - { - return $this->has_extendee; - } - /** * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". @@ -341,7 +397,17 @@ public function hasExtendee() */ public function getDefaultValue() { - return $this->default_value; + return isset($this->default_value) ? $this->default_value : ''; + } + + public function hasDefaultValue() + { + return isset($this->default_value); + } + + public function clearDefaultValue() + { + unset($this->default_value); } /** @@ -359,16 +425,10 @@ public function setDefaultValue($var) { GPBUtil::checkString($var, True); $this->default_value = $var; - $this->has_default_value = true; return $this; } - public function hasDefaultValue() - { - return $this->has_default_value; - } - /** * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. @@ -378,7 +438,17 @@ public function hasDefaultValue() */ public function getOneofIndex() { - return $this->oneof_index; + return isset($this->oneof_index) ? $this->oneof_index : 0; + } + + public function hasOneofIndex() + { + return isset($this->oneof_index); + } + + public function clearOneofIndex() + { + unset($this->oneof_index); } /** @@ -393,16 +463,10 @@ public function setOneofIndex($var) { GPBUtil::checkInt32($var); $this->oneof_index = $var; - $this->has_oneof_index = true; return $this; } - public function hasOneofIndex() - { - return $this->has_oneof_index; - } - /** * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value @@ -414,7 +478,17 @@ public function hasOneofIndex() */ public function getJsonName() { - return $this->json_name; + return isset($this->json_name) ? $this->json_name : ''; + } + + public function hasJsonName() + { + return isset($this->json_name); + } + + public function clearJsonName() + { + unset($this->json_name); } /** @@ -431,23 +505,27 @@ public function setJsonName($var) { GPBUtil::checkString($var, True); $this->json_name = $var; - $this->has_json_name = true; return $this; } - public function hasJsonName() - { - return $this->has_json_name; - } - /** * Generated from protobuf field optional .google.protobuf.FieldOptions options = 8; * @return \Google\Protobuf\Internal\FieldOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -459,14 +537,78 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FieldOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() + /** + * If true, this is a proto3 "optional". When a proto3 field is optional, it + * tracks presence regardless of field type. + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still + * indicates the semantic detail of whether the user wrote "optional" or not. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. + * Proto2 optional fields do not set this flag, because they already indicate + * optional with `LABEL_OPTIONAL`. + * + * Generated from protobuf field optional bool proto3_optional = 17; + * @return bool + */ + public function getProto3Optional() + { + return isset($this->proto3_optional) ? $this->proto3_optional : false; + } + + public function hasProto3Optional() + { + return isset($this->proto3_optional); + } + + public function clearProto3Optional() + { + unset($this->proto3_optional); + } + + /** + * If true, this is a proto3 "optional". When a proto3 field is optional, it + * tracks presence regardless of field type. + * When proto3_optional is true, this field must be belong to a oneof to + * signal to old proto3 clients that presence is tracked for this field. This + * oneof is known as a "synthetic" oneof, and this field must be its sole + * member (each proto3 optional field gets its own synthetic oneof). Synthetic + * oneofs exist in the descriptor only, and do not generate any API. Synthetic + * oneofs must be ordered after all "real" oneofs. + * For message fields, proto3_optional doesn't create any semantic change, + * since non-repeated message fields always track presence. However it still + * indicates the semantic detail of whether the user wrote "optional" or not. + * This can be useful for round-tripping the .proto file. For consistency we + * give message fields a synthetic oneof also, even though it is not required + * to track presence. This is especially important because the parser can't + * tell if a field is a message or an enum, so it must always create a + * synthetic oneof. + * Proto2 optional fields do not set this flag, because they already indicate + * optional with `LABEL_OPTIONAL`. + * + * Generated from protobuf field optional bool proto3_optional = 17; + * @param bool $var + * @return $this + */ + public function setProto3Optional($var) { - return $this->has_options; + GPBUtil::checkBool($var); + $this->proto3_optional = $var; + + return $this; } } diff --git a/php/src/Google/Protobuf/Internal/FieldOptions.php b/php/src/Google/Protobuf/Internal/FieldOptions.php index 2ccc41825c48..c6c63a9665ac 100644 --- a/php/src/Google/Protobuf/Internal/FieldOptions.php +++ b/php/src/Google/Protobuf/Internal/FieldOptions.php @@ -23,8 +23,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; */ - protected $ctype = 0; - private $has_ctype = false; + protected $ctype = null; /** * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly @@ -34,8 +33,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool packed = 2; */ - protected $packed = false; - private $has_packed = false; + protected $packed = null; /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types @@ -50,8 +48,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; */ - protected $jstype = 0; - private $has_jstype = false; + protected $jstype = null; /** * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the @@ -80,8 +77,7 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool lazy = 5 [default = false]; */ - protected $lazy = false; - private $has_lazy = false; + protected $lazy = null; /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -90,22 +86,19 @@ class FieldOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * For Google-internal migration only. Do not use. * * Generated from protobuf field optional bool weak = 10 [default = false]; */ - protected $weak = false; - private $has_weak = false; + protected $weak = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -187,7 +180,17 @@ public function __construct($data = NULL) { */ public function getCtype() { - return $this->ctype; + return isset($this->ctype) ? $this->ctype : 0; + } + + public function hasCtype() + { + return isset($this->ctype); + } + + public function clearCtype() + { + unset($this->ctype); } /** @@ -202,18 +205,12 @@ public function getCtype() */ public function setCtype($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions_CType::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\CType::class); $this->ctype = $var; - $this->has_ctype = true; return $this; } - public function hasCtype() - { - return $this->has_ctype; - } - /** * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly @@ -226,7 +223,17 @@ public function hasCtype() */ public function getPacked() { - return $this->packed; + return isset($this->packed) ? $this->packed : false; + } + + public function hasPacked() + { + return isset($this->packed); + } + + public function clearPacked() + { + unset($this->packed); } /** @@ -244,16 +251,10 @@ public function setPacked($var) { GPBUtil::checkBool($var); $this->packed = $var; - $this->has_packed = true; return $this; } - public function hasPacked() - { - return $this->has_packed; - } - /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types @@ -271,7 +272,17 @@ public function hasPacked() */ public function getJstype() { - return $this->jstype; + return isset($this->jstype) ? $this->jstype : 0; + } + + public function hasJstype() + { + return isset($this->jstype); + } + + public function clearJstype() + { + unset($this->jstype); } /** @@ -292,18 +303,12 @@ public function getJstype() */ public function setJstype($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions_JSType::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\JSType::class); $this->jstype = $var; - $this->has_jstype = true; return $this; } - public function hasJstype() - { - return $this->has_jstype; - } - /** * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the @@ -335,7 +340,17 @@ public function hasJstype() */ public function getLazy() { - return $this->lazy; + return isset($this->lazy) ? $this->lazy : false; + } + + public function hasLazy() + { + return isset($this->lazy); + } + + public function clearLazy() + { + unset($this->lazy); } /** @@ -372,16 +387,10 @@ public function setLazy($var) { GPBUtil::checkBool($var); $this->lazy = $var; - $this->has_lazy = true; return $this; } - public function hasLazy() - { - return $this->has_lazy; - } - /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -393,7 +402,17 @@ public function hasLazy() */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -410,16 +429,10 @@ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * For Google-internal migration only. Do not use. * @@ -428,7 +441,17 @@ public function hasDeprecated() */ public function getWeak() { - return $this->weak; + return isset($this->weak) ? $this->weak : false; + } + + public function hasWeak() + { + return isset($this->weak); + } + + public function clearWeak() + { + unset($this->weak); } /** @@ -442,16 +465,10 @@ public function setWeak($var) { GPBUtil::checkBool($var); $this->weak = $var; - $this->has_weak = true; return $this; } - public function hasWeak() - { - return $this->has_weak; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -474,15 +491,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php index c9e3648c2374..96e2c6a6e747 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorProto.php @@ -22,29 +22,25 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * e.g. "foo", "foo.bar", etc. * * Generated from protobuf field optional string package = 2; */ - protected $package = ''; - private $has_package = false; + protected $package = null; /** * Names of files imported by this file. * * Generated from protobuf field repeated string dependency = 3; */ private $dependency; - private $has_dependency = false; /** * Indexes of the public imported files in the dependency list above. * * Generated from protobuf field repeated int32 public_dependency = 10; */ private $public_dependency; - private $has_public_dependency = false; /** * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. @@ -52,34 +48,28 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 weak_dependency = 11; */ private $weak_dependency; - private $has_weak_dependency = false; /** * All top-level definitions in this file. * * Generated from protobuf field repeated .google.protobuf.DescriptorProto message_type = 4; */ private $message_type; - private $has_message_type = false; /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 5; */ private $enum_type; - private $has_enum_type = false; /** * Generated from protobuf field repeated .google.protobuf.ServiceDescriptorProto service = 6; */ private $service; - private $has_service = false; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 7; */ private $extension; - private $has_extension = false; /** * Generated from protobuf field optional .google.protobuf.FileOptions options = 8; */ protected $options = null; - private $has_options = false; /** * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime @@ -89,15 +79,13 @@ class FileDescriptorProto extends \Google\Protobuf\Internal\Message * Generated from protobuf field optional .google.protobuf.SourceCodeInfo source_code_info = 9; */ protected $source_code_info = null; - private $has_source_code_info = false; /** * The syntax of the proto file. * The supported values are "proto2" and "proto3". * * Generated from protobuf field optional string syntax = 12; */ - protected $syntax = ''; - private $has_syntax = false; + protected $syntax = null; /** * Constructor. @@ -145,7 +133,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -159,16 +157,10 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * e.g. "foo", "foo.bar", etc. * @@ -177,7 +169,17 @@ public function hasName() */ public function getPackage() { - return $this->package; + return isset($this->package) ? $this->package : ''; + } + + public function hasPackage() + { + return isset($this->package); + } + + public function clearPackage() + { + unset($this->package); } /** @@ -191,16 +193,10 @@ public function setPackage($var) { GPBUtil::checkString($var, True); $this->package = $var; - $this->has_package = true; return $this; } - public function hasPackage() - { - return $this->has_package; - } - /** * Names of files imported by this file. * @@ -223,16 +219,10 @@ public function setDependency($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->dependency = $arr; - $this->has_dependency = true; return $this; } - public function hasDependency() - { - return $this->has_dependency; - } - /** * Indexes of the public imported files in the dependency list above. * @@ -255,16 +245,10 @@ public function setPublicDependency($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->public_dependency = $arr; - $this->has_public_dependency = true; return $this; } - public function hasPublicDependency() - { - return $this->has_public_dependency; - } - /** * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. @@ -289,16 +273,10 @@ public function setWeakDependency($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->weak_dependency = $arr; - $this->has_weak_dependency = true; return $this; } - public function hasWeakDependency() - { - return $this->has_weak_dependency; - } - /** * All top-level definitions in this file. * @@ -321,16 +299,10 @@ public function setMessageType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); $this->message_type = $arr; - $this->has_message_type = true; return $this; } - public function hasMessageType() - { - return $this->has_message_type; - } - /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 5; * @return \Google\Protobuf\Internal\RepeatedField @@ -349,16 +321,10 @@ public function setEnumType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); $this->enum_type = $arr; - $this->has_enum_type = true; return $this; } - public function hasEnumType() - { - return $this->has_enum_type; - } - /** * Generated from protobuf field repeated .google.protobuf.ServiceDescriptorProto service = 6; * @return \Google\Protobuf\Internal\RepeatedField @@ -377,16 +343,10 @@ public function setService($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\ServiceDescriptorProto::class); $this->service = $arr; - $this->has_service = true; return $this; } - public function hasService() - { - return $this->has_service; - } - /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 7; * @return \Google\Protobuf\Internal\RepeatedField @@ -405,23 +365,27 @@ public function setExtension($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->extension = $arr; - $this->has_extension = true; return $this; } - public function hasExtension() - { - return $this->has_extension; - } - /** * Generated from protobuf field optional .google.protobuf.FileOptions options = 8; * @return \Google\Protobuf\Internal\FileOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -433,16 +397,10 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FileOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime @@ -454,7 +412,17 @@ public function hasOptions() */ public function getSourceCodeInfo() { - return $this->source_code_info; + return isset($this->source_code_info) ? $this->source_code_info : null; + } + + public function hasSourceCodeInfo() + { + return isset($this->source_code_info); + } + + public function clearSourceCodeInfo() + { + unset($this->source_code_info); } /** @@ -471,16 +439,10 @@ public function setSourceCodeInfo($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\SourceCodeInfo::class); $this->source_code_info = $var; - $this->has_source_code_info = true; return $this; } - public function hasSourceCodeInfo() - { - return $this->has_source_code_info; - } - /** * The syntax of the proto file. * The supported values are "proto2" and "proto3". @@ -490,7 +452,17 @@ public function hasSourceCodeInfo() */ public function getSyntax() { - return $this->syntax; + return isset($this->syntax) ? $this->syntax : ''; + } + + public function hasSyntax() + { + return isset($this->syntax); + } + + public function clearSyntax() + { + unset($this->syntax); } /** @@ -505,15 +477,9 @@ public function setSyntax($var) { GPBUtil::checkString($var, True); $this->syntax = $var; - $this->has_syntax = true; return $this; } - public function hasSyntax() - { - return $this->has_syntax; - } - } diff --git a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php index 9907b17d73c5..794e6347a35f 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptorSet.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptorSet.php @@ -22,7 +22,6 @@ class FileDescriptorSet extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.FileDescriptorProto file = 1; */ private $file; - private $has_file = false; /** * Constructor. @@ -56,15 +55,9 @@ public function setFile($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FileDescriptorProto::class); $this->file = $arr; - $this->has_file = true; return $this; } - public function hasFile() - { - return $this->has_file; - } - } diff --git a/php/src/Google/Protobuf/Internal/FileOptions.php b/php/src/Google/Protobuf/Internal/FileOptions.php index 605d92bfda74..f415b07f2c55 100644 --- a/php/src/Google/Protobuf/Internal/FileOptions.php +++ b/php/src/Google/Protobuf/Internal/FileOptions.php @@ -23,8 +23,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string java_package = 1; */ - protected $java_package = ''; - private $has_java_package = false; + protected $java_package = null; /** * If set, all the classes from the .proto file are wrapped in a single * outer class with the given name. This applies to both Proto1 @@ -34,8 +33,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string java_outer_classname = 8; */ - protected $java_outer_classname = ''; - private $has_java_outer_classname = false; + protected $java_outer_classname = null; /** * If set true, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto @@ -46,15 +44,13 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool java_multiple_files = 10 [default = false]; */ - protected $java_multiple_files = false; - private $has_java_multiple_files = false; + protected $java_multiple_files = null; /** * This option does nothing. * * Generated from protobuf field optional bool java_generate_equals_and_hash = 20 [deprecated = true]; */ - protected $java_generate_equals_and_hash = false; - private $has_java_generate_equals_and_hash = false; + protected $java_generate_equals_and_hash = null; /** * If set true, then the Java2 code generator will generate code that * throws an exception whenever an attempt is made to assign a non-UTF-8 @@ -65,13 +61,11 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool java_string_check_utf8 = 27 [default = false]; */ - protected $java_string_check_utf8 = false; - private $has_java_string_check_utf8 = false; + protected $java_string_check_utf8 = null; /** * Generated from protobuf field optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; */ - protected $optimize_for = 0; - private $has_optimize_for = false; + protected $optimize_for = null; /** * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: @@ -81,8 +75,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string go_package = 11; */ - protected $go_package = ''; - private $has_go_package = false; + protected $go_package = null; /** * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the @@ -96,23 +89,19 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool cc_generic_services = 16 [default = false]; */ - protected $cc_generic_services = false; - private $has_cc_generic_services = false; + protected $cc_generic_services = null; /** * Generated from protobuf field optional bool java_generic_services = 17 [default = false]; */ - protected $java_generic_services = false; - private $has_java_generic_services = false; + protected $java_generic_services = null; /** * Generated from protobuf field optional bool py_generic_services = 18 [default = false]; */ - protected $py_generic_services = false; - private $has_py_generic_services = false; + protected $py_generic_services = null; /** * Generated from protobuf field optional bool php_generic_services = 42 [default = false]; */ - protected $php_generic_services = false; - private $has_php_generic_services = false; + protected $php_generic_services = null; /** * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -121,31 +110,27 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 23 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * - * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = false]; + * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = true]; */ - protected $cc_enable_arenas = false; - private $has_cc_enable_arenas = false; + protected $cc_enable_arenas = null; /** * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. * * Generated from protobuf field optional string objc_class_prefix = 36; */ - protected $objc_class_prefix = ''; - private $has_objc_class_prefix = false; + protected $objc_class_prefix = null; /** * Namespace for generated classes; defaults to the package. * * Generated from protobuf field optional string csharp_namespace = 37; */ - protected $csharp_namespace = ''; - private $has_csharp_namespace = false; + protected $csharp_namespace = null; /** * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols @@ -154,16 +139,14 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string swift_prefix = 39; */ - protected $swift_prefix = ''; - private $has_swift_prefix = false; + protected $swift_prefix = null; /** * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. * * Generated from protobuf field optional string php_class_prefix = 40; */ - protected $php_class_prefix = ''; - private $has_php_class_prefix = false; + protected $php_class_prefix = null; /** * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for @@ -171,8 +154,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string php_namespace = 41; */ - protected $php_namespace = ''; - private $has_php_namespace = false; + protected $php_namespace = null; /** * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be @@ -180,8 +162,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string php_metadata_namespace = 44; */ - protected $php_metadata_namespace = ''; - private $has_php_metadata_namespace = false; + protected $php_metadata_namespace = null; /** * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for @@ -189,8 +170,7 @@ class FileOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string ruby_package = 45; */ - protected $ruby_package = ''; - private $has_ruby_package = false; + protected $ruby_package = null; /** * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. @@ -198,7 +178,6 @@ class FileOptions extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -307,7 +286,17 @@ public function __construct($data = NULL) { */ public function getJavaPackage() { - return $this->java_package; + return isset($this->java_package) ? $this->java_package : ''; + } + + public function hasJavaPackage() + { + return isset($this->java_package); + } + + public function clearJavaPackage() + { + unset($this->java_package); } /** @@ -324,16 +313,10 @@ public function setJavaPackage($var) { GPBUtil::checkString($var, True); $this->java_package = $var; - $this->has_java_package = true; return $this; } - public function hasJavaPackage() - { - return $this->has_java_package; - } - /** * If set, all the classes from the .proto file are wrapped in a single * outer class with the given name. This applies to both Proto1 @@ -346,7 +329,17 @@ public function hasJavaPackage() */ public function getJavaOuterClassname() { - return $this->java_outer_classname; + return isset($this->java_outer_classname) ? $this->java_outer_classname : ''; + } + + public function hasJavaOuterClassname() + { + return isset($this->java_outer_classname); + } + + public function clearJavaOuterClassname() + { + unset($this->java_outer_classname); } /** @@ -364,16 +357,10 @@ public function setJavaOuterClassname($var) { GPBUtil::checkString($var, True); $this->java_outer_classname = $var; - $this->has_java_outer_classname = true; return $this; } - public function hasJavaOuterClassname() - { - return $this->has_java_outer_classname; - } - /** * If set true, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto @@ -387,7 +374,17 @@ public function hasJavaOuterClassname() */ public function getJavaMultipleFiles() { - return $this->java_multiple_files; + return isset($this->java_multiple_files) ? $this->java_multiple_files : false; + } + + public function hasJavaMultipleFiles() + { + return isset($this->java_multiple_files); + } + + public function clearJavaMultipleFiles() + { + unset($this->java_multiple_files); } /** @@ -406,16 +403,10 @@ public function setJavaMultipleFiles($var) { GPBUtil::checkBool($var); $this->java_multiple_files = $var; - $this->has_java_multiple_files = true; return $this; } - public function hasJavaMultipleFiles() - { - return $this->has_java_multiple_files; - } - /** * This option does nothing. * @@ -424,7 +415,17 @@ public function hasJavaMultipleFiles() */ public function getJavaGenerateEqualsAndHash() { - return $this->java_generate_equals_and_hash; + return isset($this->java_generate_equals_and_hash) ? $this->java_generate_equals_and_hash : false; + } + + public function hasJavaGenerateEqualsAndHash() + { + return isset($this->java_generate_equals_and_hash); + } + + public function clearJavaGenerateEqualsAndHash() + { + unset($this->java_generate_equals_and_hash); } /** @@ -438,16 +439,10 @@ public function setJavaGenerateEqualsAndHash($var) { GPBUtil::checkBool($var); $this->java_generate_equals_and_hash = $var; - $this->has_java_generate_equals_and_hash = true; return $this; } - public function hasJavaGenerateEqualsAndHash() - { - return $this->has_java_generate_equals_and_hash; - } - /** * If set true, then the Java2 code generator will generate code that * throws an exception whenever an attempt is made to assign a non-UTF-8 @@ -461,7 +456,17 @@ public function hasJavaGenerateEqualsAndHash() */ public function getJavaStringCheckUtf8() { - return $this->java_string_check_utf8; + return isset($this->java_string_check_utf8) ? $this->java_string_check_utf8 : false; + } + + public function hasJavaStringCheckUtf8() + { + return isset($this->java_string_check_utf8); + } + + public function clearJavaStringCheckUtf8() + { + unset($this->java_string_check_utf8); } /** @@ -480,23 +485,27 @@ public function setJavaStringCheckUtf8($var) { GPBUtil::checkBool($var); $this->java_string_check_utf8 = $var; - $this->has_java_string_check_utf8 = true; return $this; } - public function hasJavaStringCheckUtf8() - { - return $this->has_java_string_check_utf8; - } - /** * Generated from protobuf field optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; * @return int */ public function getOptimizeFor() { - return $this->optimize_for; + return isset($this->optimize_for) ? $this->optimize_for : 0; + } + + public function hasOptimizeFor() + { + return isset($this->optimize_for); + } + + public function clearOptimizeFor() + { + unset($this->optimize_for); } /** @@ -506,18 +515,12 @@ public function getOptimizeFor() */ public function setOptimizeFor($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FileOptions_OptimizeMode::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FileOptions\OptimizeMode::class); $this->optimize_for = $var; - $this->has_optimize_for = true; return $this; } - public function hasOptimizeFor() - { - return $this->has_optimize_for; - } - /** * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: @@ -530,7 +533,17 @@ public function hasOptimizeFor() */ public function getGoPackage() { - return $this->go_package; + return isset($this->go_package) ? $this->go_package : ''; + } + + public function hasGoPackage() + { + return isset($this->go_package); + } + + public function clearGoPackage() + { + unset($this->go_package); } /** @@ -548,16 +561,10 @@ public function setGoPackage($var) { GPBUtil::checkString($var, True); $this->go_package = $var; - $this->has_go_package = true; return $this; } - public function hasGoPackage() - { - return $this->has_go_package; - } - /** * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the @@ -574,7 +581,17 @@ public function hasGoPackage() */ public function getCcGenericServices() { - return $this->cc_generic_services; + return isset($this->cc_generic_services) ? $this->cc_generic_services : false; + } + + public function hasCcGenericServices() + { + return isset($this->cc_generic_services); + } + + public function clearCcGenericServices() + { + unset($this->cc_generic_services); } /** @@ -596,23 +613,27 @@ public function setCcGenericServices($var) { GPBUtil::checkBool($var); $this->cc_generic_services = $var; - $this->has_cc_generic_services = true; return $this; } - public function hasCcGenericServices() - { - return $this->has_cc_generic_services; - } - /** * Generated from protobuf field optional bool java_generic_services = 17 [default = false]; * @return bool */ public function getJavaGenericServices() { - return $this->java_generic_services; + return isset($this->java_generic_services) ? $this->java_generic_services : false; + } + + public function hasJavaGenericServices() + { + return isset($this->java_generic_services); + } + + public function clearJavaGenericServices() + { + unset($this->java_generic_services); } /** @@ -624,23 +645,27 @@ public function setJavaGenericServices($var) { GPBUtil::checkBool($var); $this->java_generic_services = $var; - $this->has_java_generic_services = true; return $this; } - public function hasJavaGenericServices() - { - return $this->has_java_generic_services; - } - /** * Generated from protobuf field optional bool py_generic_services = 18 [default = false]; * @return bool */ public function getPyGenericServices() { - return $this->py_generic_services; + return isset($this->py_generic_services) ? $this->py_generic_services : false; + } + + public function hasPyGenericServices() + { + return isset($this->py_generic_services); + } + + public function clearPyGenericServices() + { + unset($this->py_generic_services); } /** @@ -652,23 +677,27 @@ public function setPyGenericServices($var) { GPBUtil::checkBool($var); $this->py_generic_services = $var; - $this->has_py_generic_services = true; return $this; } - public function hasPyGenericServices() - { - return $this->has_py_generic_services; - } - /** * Generated from protobuf field optional bool php_generic_services = 42 [default = false]; * @return bool */ public function getPhpGenericServices() { - return $this->php_generic_services; + return isset($this->php_generic_services) ? $this->php_generic_services : false; + } + + public function hasPhpGenericServices() + { + return isset($this->php_generic_services); + } + + public function clearPhpGenericServices() + { + unset($this->php_generic_services); } /** @@ -680,16 +709,10 @@ public function setPhpGenericServices($var) { GPBUtil::checkBool($var); $this->php_generic_services = $var; - $this->has_php_generic_services = true; return $this; } - public function hasPhpGenericServices() - { - return $this->has_php_generic_services; - } - /** * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -701,7 +724,17 @@ public function hasPhpGenericServices() */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -718,33 +751,37 @@ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * - * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = false]; + * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = true]; * @return bool */ public function getCcEnableArenas() { - return $this->cc_enable_arenas; + return isset($this->cc_enable_arenas) ? $this->cc_enable_arenas : false; + } + + public function hasCcEnableArenas() + { + return isset($this->cc_enable_arenas); + } + + public function clearCcEnableArenas() + { + unset($this->cc_enable_arenas); } /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * - * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = false]; + * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = true]; * @param bool $var * @return $this */ @@ -752,16 +789,10 @@ public function setCcEnableArenas($var) { GPBUtil::checkBool($var); $this->cc_enable_arenas = $var; - $this->has_cc_enable_arenas = true; return $this; } - public function hasCcEnableArenas() - { - return $this->has_cc_enable_arenas; - } - /** * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. @@ -771,7 +802,17 @@ public function hasCcEnableArenas() */ public function getObjcClassPrefix() { - return $this->objc_class_prefix; + return isset($this->objc_class_prefix) ? $this->objc_class_prefix : ''; + } + + public function hasObjcClassPrefix() + { + return isset($this->objc_class_prefix); + } + + public function clearObjcClassPrefix() + { + unset($this->objc_class_prefix); } /** @@ -786,16 +827,10 @@ public function setObjcClassPrefix($var) { GPBUtil::checkString($var, True); $this->objc_class_prefix = $var; - $this->has_objc_class_prefix = true; return $this; } - public function hasObjcClassPrefix() - { - return $this->has_objc_class_prefix; - } - /** * Namespace for generated classes; defaults to the package. * @@ -804,7 +839,17 @@ public function hasObjcClassPrefix() */ public function getCsharpNamespace() { - return $this->csharp_namespace; + return isset($this->csharp_namespace) ? $this->csharp_namespace : ''; + } + + public function hasCsharpNamespace() + { + return isset($this->csharp_namespace); + } + + public function clearCsharpNamespace() + { + unset($this->csharp_namespace); } /** @@ -818,16 +863,10 @@ public function setCsharpNamespace($var) { GPBUtil::checkString($var, True); $this->csharp_namespace = $var; - $this->has_csharp_namespace = true; return $this; } - public function hasCsharpNamespace() - { - return $this->has_csharp_namespace; - } - /** * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols @@ -839,7 +878,17 @@ public function hasCsharpNamespace() */ public function getSwiftPrefix() { - return $this->swift_prefix; + return isset($this->swift_prefix) ? $this->swift_prefix : ''; + } + + public function hasSwiftPrefix() + { + return isset($this->swift_prefix); + } + + public function clearSwiftPrefix() + { + unset($this->swift_prefix); } /** @@ -856,16 +905,10 @@ public function setSwiftPrefix($var) { GPBUtil::checkString($var, True); $this->swift_prefix = $var; - $this->has_swift_prefix = true; return $this; } - public function hasSwiftPrefix() - { - return $this->has_swift_prefix; - } - /** * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. @@ -875,7 +918,17 @@ public function hasSwiftPrefix() */ public function getPhpClassPrefix() { - return $this->php_class_prefix; + return isset($this->php_class_prefix) ? $this->php_class_prefix : ''; + } + + public function hasPhpClassPrefix() + { + return isset($this->php_class_prefix); + } + + public function clearPhpClassPrefix() + { + unset($this->php_class_prefix); } /** @@ -890,16 +943,10 @@ public function setPhpClassPrefix($var) { GPBUtil::checkString($var, True); $this->php_class_prefix = $var; - $this->has_php_class_prefix = true; return $this; } - public function hasPhpClassPrefix() - { - return $this->has_php_class_prefix; - } - /** * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for @@ -910,7 +957,17 @@ public function hasPhpClassPrefix() */ public function getPhpNamespace() { - return $this->php_namespace; + return isset($this->php_namespace) ? $this->php_namespace : ''; + } + + public function hasPhpNamespace() + { + return isset($this->php_namespace); + } + + public function clearPhpNamespace() + { + unset($this->php_namespace); } /** @@ -926,16 +983,10 @@ public function setPhpNamespace($var) { GPBUtil::checkString($var, True); $this->php_namespace = $var; - $this->has_php_namespace = true; return $this; } - public function hasPhpNamespace() - { - return $this->has_php_namespace; - } - /** * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be @@ -946,7 +997,17 @@ public function hasPhpNamespace() */ public function getPhpMetadataNamespace() { - return $this->php_metadata_namespace; + return isset($this->php_metadata_namespace) ? $this->php_metadata_namespace : ''; + } + + public function hasPhpMetadataNamespace() + { + return isset($this->php_metadata_namespace); + } + + public function clearPhpMetadataNamespace() + { + unset($this->php_metadata_namespace); } /** @@ -962,16 +1023,10 @@ public function setPhpMetadataNamespace($var) { GPBUtil::checkString($var, True); $this->php_metadata_namespace = $var; - $this->has_php_metadata_namespace = true; return $this; } - public function hasPhpMetadataNamespace() - { - return $this->has_php_metadata_namespace; - } - /** * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for @@ -982,7 +1037,17 @@ public function hasPhpMetadataNamespace() */ public function getRubyPackage() { - return $this->ruby_package; + return isset($this->ruby_package) ? $this->ruby_package : ''; + } + + public function hasRubyPackage() + { + return isset($this->ruby_package); + } + + public function clearRubyPackage() + { + unset($this->ruby_package); } /** @@ -998,16 +1063,10 @@ public function setRubyPackage($var) { GPBUtil::checkString($var, True); $this->ruby_package = $var; - $this->has_ruby_package = true; return $this; } - public function hasRubyPackage() - { - return $this->has_ruby_package; - } - /** * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. @@ -1032,15 +1091,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php index c091fc6c8150..1900e71ccc52 100644 --- a/php/src/Google/Protobuf/Internal/GPBUtil.php +++ b/php/src/Google/Protobuf/Internal/GPBUtil.php @@ -338,9 +338,9 @@ public static function getFullClassName( $package = $file_proto->getPackage(); if ($package === "") { - $fullname = "." . $message_name_without_package; + $fullname = $message_name_without_package; } else { - $fullname = "." . $package . "." . $message_name_without_package; + $fullname = $package . "." . $message_name_without_package; } $class_name_without_package = diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php index f5a65bea4610..c261ed6ec944 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo.php @@ -26,7 +26,6 @@ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; */ private $annotation; - private $has_annotation = false; /** * Constructor. @@ -68,15 +67,9 @@ public function setAnnotation($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class); $this->annotation = $arr; - $this->has_annotation = true; return $this; } - public function hasAnnotation() - { - return $this->has_annotation; - } - } diff --git a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php index 369fea489293..0b043d0665be 100644 --- a/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php +++ b/php/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php @@ -22,22 +22,19 @@ class Annotation extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 path = 1 [packed = true]; */ private $path; - private $has_path = false; /** * Identifies the filesystem path to the original source .proto. * * Generated from protobuf field optional string source_file = 2; */ - protected $source_file = ''; - private $has_source_file = false; + protected $source_file = null; /** * Identifies the starting offset in bytes in the generated code * that relates to the identified object. * * Generated from protobuf field optional int32 begin = 3; */ - protected $begin = 0; - private $has_begin = false; + protected $begin = null; /** * Identifies the ending offset in bytes in the generated code that * relates to the identified offset. The end offset should be one past @@ -45,8 +42,7 @@ class Annotation extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional int32 end = 4; */ - protected $end = 0; - private $has_end = false; + protected $end = null; /** * Constructor. @@ -97,16 +93,10 @@ public function setPath($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->path = $arr; - $this->has_path = true; return $this; } - public function hasPath() - { - return $this->has_path; - } - /** * Identifies the filesystem path to the original source .proto. * @@ -115,7 +105,17 @@ public function hasPath() */ public function getSourceFile() { - return $this->source_file; + return isset($this->source_file) ? $this->source_file : ''; + } + + public function hasSourceFile() + { + return isset($this->source_file); + } + + public function clearSourceFile() + { + unset($this->source_file); } /** @@ -129,16 +129,10 @@ public function setSourceFile($var) { GPBUtil::checkString($var, True); $this->source_file = $var; - $this->has_source_file = true; return $this; } - public function hasSourceFile() - { - return $this->has_source_file; - } - /** * Identifies the starting offset in bytes in the generated code * that relates to the identified object. @@ -148,7 +142,17 @@ public function hasSourceFile() */ public function getBegin() { - return $this->begin; + return isset($this->begin) ? $this->begin : 0; + } + + public function hasBegin() + { + return isset($this->begin); + } + + public function clearBegin() + { + unset($this->begin); } /** @@ -163,16 +167,10 @@ public function setBegin($var) { GPBUtil::checkInt32($var); $this->begin = $var; - $this->has_begin = true; return $this; } - public function hasBegin() - { - return $this->has_begin; - } - /** * Identifies the ending offset in bytes in the generated code that * relates to the identified offset. The end offset should be one past @@ -183,7 +181,17 @@ public function hasBegin() */ public function getEnd() { - return $this->end; + return isset($this->end) ? $this->end : 0; + } + + public function hasEnd() + { + return isset($this->end); + } + + public function clearEnd() + { + unset($this->end); } /** @@ -199,16 +207,10 @@ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; - $this->has_end = true; return $this; } - public function hasEnd() - { - return $this->has_end; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 67c0b53f8545..c02d2b451729 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -94,6 +94,7 @@ private function initWithGeneratedPool() $this->desc = $pool->getDescriptorByClassName(get_class($this)); if (is_null($this->desc)) { user_error(get_class($this) . " is not found in descriptor pool."); + return; } foreach ($this->desc->getField() as $field) { $setter = $field->getSetter(); @@ -224,6 +225,15 @@ protected function readOneof($number) } } + protected function hasOneof($number) + { + $field = $this->desc->getFieldByNumber($number); + $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; + $oneof_name = $oneof->getName(); + $oneof_field = $this->$oneof_name; + return $number === $oneof_field->getNumber(); + } + protected function writeOneof($number, $value) { $field = $this->desc->getFieldByNumber($number); @@ -772,10 +782,10 @@ public function mergeFromString($data) * @return null. * @throws \Exception Invalid data. */ - public function mergeFromJsonString($data) + public function mergeFromJsonString($data, $ignore_unknown = false) { $input = new RawInputStream($data); - $this->parseFromJsonStream($input); + $this->parseFromJsonStream($input, $ignore_unknown); } /** @@ -800,6 +810,7 @@ public function parseFromStream($input) private function convertJsonValueToProtoValue( $value, $field, + $ignore_unknown, $is_map_key = false) { switch ($field->getType()) { @@ -848,7 +859,7 @@ private function convertJsonValueToProtoValue( } elseif (!is_object($value) && !is_array($value)) { throw new GPBDecodeException("Expect message."); } - $submsg->mergeFromJsonArray($value); + $submsg->mergeFromJsonArray($value, $ignore_unknown); } return $submsg; case GPBType::ENUM: @@ -861,9 +872,12 @@ private function convertJsonValueToProtoValue( $enum_value = $field->getEnumType()->getValueByName($value); if (!is_null($enum_value)) { return $enum_value->getNumber(); + } else if ($ignore_unknown) { + return $this->defaultValue($field); + } else { + throw new GPBDecodeException( + "Enum field only accepts integer or enum value name"); } - throw new GPBDecodeException( - "Enum field only accepts integer or enum value name"); case GPBType::STRING: if (is_null($value)) { return $this->defaultValue($field); @@ -1124,17 +1138,17 @@ private static function normalizeToMessageType(&$value, $class) } } - protected function mergeFromJsonArray($array) + protected function mergeFromJsonArray($array, $ignore_unknown) { if (is_a($this, "Google\Protobuf\Any")) { $this->clear(); $this->setTypeUrl($array["@type"]); $msg = $this->unpack(); if (GPBUtil::hasSpecialJsonMapping($msg)) { - $msg->mergeFromJsonArray($array["value"]); + $msg->mergeFromJsonArray($array["value"], $ignore_unknown); } else { unset($array["@type"]); - $msg->mergeFromJsonArray($array); + $msg->mergeFromJsonArray($array, $ignore_unknown); } $this->setValue($msg->serializeToString()); return; @@ -1170,7 +1184,7 @@ protected function mergeFromJsonArray($array) $fields = $this->getFields(); foreach($array as $key => $value) { $v = new Value(); - $v->mergeFromJsonArray($value); + $v->mergeFromJsonArray($value, $ignore_unknown); $fields[$key] = $v; } } @@ -1193,7 +1207,7 @@ protected function mergeFromJsonArray($array) } foreach ($array as $key => $v) { $value = new Value(); - $value->mergeFromJsonArray($v); + $value->mergeFromJsonArray($v, $ignore_unknown); $values = $struct_value->getFields(); $values[$key]= $value; } @@ -1206,7 +1220,7 @@ protected function mergeFromJsonArray($array) } foreach ($array as $v) { $value = new Value(); - $value->mergeFromJsonArray($v); + $value->mergeFromJsonArray($v, $ignore_unknown); $values = $list_value->getValues(); $values[]= $value; } @@ -1216,10 +1230,10 @@ protected function mergeFromJsonArray($array) } return; } - $this->mergeFromArrayJsonImpl($array); + $this->mergeFromArrayJsonImpl($array, $ignore_unknown); } - private function mergeFromArrayJsonImpl($array) + private function mergeFromArrayJsonImpl($array, $ignore_unknown) { foreach ($array as $key => $value) { $field = $this->desc->getFieldByJsonName($key); @@ -1243,10 +1257,12 @@ private function mergeFromArrayJsonImpl($array) $proto_key = $this->convertJsonValueToProtoValue( $tmp_key, $key_field, + $ignore_unknown, true); $proto_value = $this->convertJsonValueToProtoValue( $tmp_value, - $value_field); + $value_field, + $ignore_unknown); self::kvUpdateHelper($field, $proto_key, $proto_value); } } else if ($field->isRepeated()) { @@ -1260,14 +1276,16 @@ private function mergeFromArrayJsonImpl($array) } $proto_value = $this->convertJsonValueToProtoValue( $tmp, - $field); + $field, + $ignore_unknown); self::appendHelper($field, $proto_value); } } else { $setter = $field->getSetter(); $proto_value = $this->convertJsonValueToProtoValue( $value, - $field); + $field, + $ignore_unknown); if ($field->getType() === GPBType::MESSAGE) { if (is_null($proto_value)) { continue; @@ -1287,7 +1305,7 @@ private function mergeFromArrayJsonImpl($array) /** * @ignore */ - public function parseFromJsonStream($input) + public function parseFromJsonStream($input, $ignore_unknown) { $array = json_decode($input->getData(), true, 512, JSON_BIGINT_AS_STRING); if ($this instanceof \Google\Protobuf\ListValue) { @@ -1303,7 +1321,7 @@ public function parseFromJsonStream($input) } } try { - $this->mergeFromJsonArray($array); + $this->mergeFromJsonArray($array, $ignore_unknown); } catch (\Exception $e) { throw new GPBDecodeException($e->getMessage()); } @@ -1550,14 +1568,19 @@ public function serializeToJsonString() */ private function existField($field) { - $oneof_index = $field->getOneofIndex(); - if ($oneof_index !== -1) { - $oneof = $this->desc->getOneofDecl()[$oneof_index]; - $oneof_name = $oneof->getName(); - return $this->$oneof_name->getNumber() === $field->getNumber(); + $getter = $field->getGetter(); + $hazzer = "has" . substr($getter, 3); + + if (method_exists($this, $hazzer)) { + return $this->$hazzer(); + } else if ($field->getOneofIndex() !== -1) { + // For old generated code, which does not have hazzers for oneof + // fields. + $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; + $oneof_name = $oneof->getName(); + return $this->$oneof_name->getNumber() === $field->getNumber(); } - $getter = $field->getGetter(); $values = $this->$getter(); if ($field->isMap()) { return count($values) !== 0; diff --git a/php/src/Google/Protobuf/Internal/MessageOptions.php b/php/src/Google/Protobuf/Internal/MessageOptions.php index 95bb706a5a2a..2f4e3cb7f4fd 100644 --- a/php/src/Google/Protobuf/Internal/MessageOptions.php +++ b/php/src/Google/Protobuf/Internal/MessageOptions.php @@ -34,8 +34,7 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool message_set_wire_format = 1 [default = false]; */ - protected $message_set_wire_format = false; - private $has_message_set_wire_format = false; + protected $message_set_wire_format = null; /** * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration @@ -43,8 +42,7 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool no_standard_descriptor_accessor = 2 [default = false]; */ - protected $no_standard_descriptor_accessor = false; - private $has_no_standard_descriptor_accessor = false; + protected $no_standard_descriptor_accessor = null; /** * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -53,8 +51,7 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * Whether the message is an automatically generated map entry type for the * maps field. @@ -77,15 +74,13 @@ class MessageOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool map_entry = 7; */ - protected $map_entry = false; - private $has_map_entry = false; + protected $map_entry = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -168,7 +163,17 @@ public function __construct($data = NULL) { */ public function getMessageSetWireFormat() { - return $this->message_set_wire_format; + return isset($this->message_set_wire_format) ? $this->message_set_wire_format : false; + } + + public function hasMessageSetWireFormat() + { + return isset($this->message_set_wire_format); + } + + public function clearMessageSetWireFormat() + { + unset($this->message_set_wire_format); } /** @@ -196,16 +201,10 @@ public function setMessageSetWireFormat($var) { GPBUtil::checkBool($var); $this->message_set_wire_format = $var; - $this->has_message_set_wire_format = true; return $this; } - public function hasMessageSetWireFormat() - { - return $this->has_message_set_wire_format; - } - /** * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration @@ -216,7 +215,17 @@ public function hasMessageSetWireFormat() */ public function getNoStandardDescriptorAccessor() { - return $this->no_standard_descriptor_accessor; + return isset($this->no_standard_descriptor_accessor) ? $this->no_standard_descriptor_accessor : false; + } + + public function hasNoStandardDescriptorAccessor() + { + return isset($this->no_standard_descriptor_accessor); + } + + public function clearNoStandardDescriptorAccessor() + { + unset($this->no_standard_descriptor_accessor); } /** @@ -232,16 +241,10 @@ public function setNoStandardDescriptorAccessor($var) { GPBUtil::checkBool($var); $this->no_standard_descriptor_accessor = $var; - $this->has_no_standard_descriptor_accessor = true; return $this; } - public function hasNoStandardDescriptorAccessor() - { - return $this->has_no_standard_descriptor_accessor; - } - /** * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations @@ -253,7 +256,17 @@ public function hasNoStandardDescriptorAccessor() */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -270,16 +283,10 @@ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * Whether the message is an automatically generated map entry type for the * maps field. @@ -305,7 +312,17 @@ public function hasDeprecated() */ public function getMapEntry() { - return $this->map_entry; + return isset($this->map_entry) ? $this->map_entry : false; + } + + public function hasMapEntry() + { + return isset($this->map_entry); + } + + public function clearMapEntry() + { + unset($this->map_entry); } /** @@ -336,16 +353,10 @@ public function setMapEntry($var) { GPBUtil::checkBool($var); $this->map_entry = $var; - $this->has_map_entry = true; return $this; } - public function hasMapEntry() - { - return $this->has_map_entry; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -368,15 +379,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php index f40f20f0d73d..e2ea8ea6c522 100644 --- a/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/MethodDescriptorProto.php @@ -20,40 +20,34 @@ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. * * Generated from protobuf field optional string input_type = 2; */ - protected $input_type = ''; - private $has_input_type = false; + protected $input_type = null; /** * Generated from protobuf field optional string output_type = 3; */ - protected $output_type = ''; - private $has_output_type = false; + protected $output_type = null; /** * Generated from protobuf field optional .google.protobuf.MethodOptions options = 4; */ protected $options = null; - private $has_options = false; /** * Identifies if client streams multiple client messages * * Generated from protobuf field optional bool client_streaming = 5 [default = false]; */ - protected $client_streaming = false; - private $has_client_streaming = false; + protected $client_streaming = null; /** * Identifies if server streams multiple server messages * * Generated from protobuf field optional bool server_streaming = 6 [default = false]; */ - protected $server_streaming = false; - private $has_server_streaming = false; + protected $server_streaming = null; /** * Constructor. @@ -84,7 +78,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -96,16 +100,10 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. @@ -115,7 +113,17 @@ public function hasName() */ public function getInputType() { - return $this->input_type; + return isset($this->input_type) ? $this->input_type : ''; + } + + public function hasInputType() + { + return isset($this->input_type); + } + + public function clearInputType() + { + unset($this->input_type); } /** @@ -130,23 +138,27 @@ public function setInputType($var) { GPBUtil::checkString($var, True); $this->input_type = $var; - $this->has_input_type = true; return $this; } - public function hasInputType() - { - return $this->has_input_type; - } - /** * Generated from protobuf field optional string output_type = 3; * @return string */ public function getOutputType() { - return $this->output_type; + return isset($this->output_type) ? $this->output_type : ''; + } + + public function hasOutputType() + { + return isset($this->output_type); + } + + public function clearOutputType() + { + unset($this->output_type); } /** @@ -158,23 +170,27 @@ public function setOutputType($var) { GPBUtil::checkString($var, True); $this->output_type = $var; - $this->has_output_type = true; return $this; } - public function hasOutputType() - { - return $this->has_output_type; - } - /** * Generated from protobuf field optional .google.protobuf.MethodOptions options = 4; * @return \Google\Protobuf\Internal\MethodOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -186,16 +202,10 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MethodOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - /** * Identifies if client streams multiple client messages * @@ -204,7 +214,17 @@ public function hasOptions() */ public function getClientStreaming() { - return $this->client_streaming; + return isset($this->client_streaming) ? $this->client_streaming : false; + } + + public function hasClientStreaming() + { + return isset($this->client_streaming); + } + + public function clearClientStreaming() + { + unset($this->client_streaming); } /** @@ -218,16 +238,10 @@ public function setClientStreaming($var) { GPBUtil::checkBool($var); $this->client_streaming = $var; - $this->has_client_streaming = true; return $this; } - public function hasClientStreaming() - { - return $this->has_client_streaming; - } - /** * Identifies if server streams multiple server messages * @@ -236,7 +250,17 @@ public function hasClientStreaming() */ public function getServerStreaming() { - return $this->server_streaming; + return isset($this->server_streaming) ? $this->server_streaming : false; + } + + public function hasServerStreaming() + { + return isset($this->server_streaming); + } + + public function clearServerStreaming() + { + unset($this->server_streaming); } /** @@ -250,15 +274,9 @@ public function setServerStreaming($var) { GPBUtil::checkBool($var); $this->server_streaming = $var; - $this->has_server_streaming = true; return $this; } - public function hasServerStreaming() - { - return $this->has_server_streaming; - } - } diff --git a/php/src/Google/Protobuf/Internal/MethodOptions.php b/php/src/Google/Protobuf/Internal/MethodOptions.php index 6a4c92de5e53..a4595b744822 100644 --- a/php/src/Google/Protobuf/Internal/MethodOptions.php +++ b/php/src/Google/Protobuf/Internal/MethodOptions.php @@ -23,20 +23,17 @@ class MethodOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 33 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * Generated from protobuf field optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; */ - protected $idempotency_level = 0; - private $has_idempotency_level = false; + protected $idempotency_level = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -70,7 +67,17 @@ public function __construct($data = NULL) { */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -87,23 +94,27 @@ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * Generated from protobuf field optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; * @return int */ public function getIdempotencyLevel() { - return $this->idempotency_level; + return isset($this->idempotency_level) ? $this->idempotency_level : 0; + } + + public function hasIdempotencyLevel() + { + return isset($this->idempotency_level); + } + + public function clearIdempotencyLevel() + { + unset($this->idempotency_level); } /** @@ -113,18 +124,12 @@ public function getIdempotencyLevel() */ public function setIdempotencyLevel($var) { - GPBUtil::checkEnum($var, \Google\Protobuf\Internal\MethodOptions_IdempotencyLevel::class); + GPBUtil::checkEnum($var, \Google\Protobuf\Internal\MethodOptions\IdempotencyLevel::class); $this->idempotency_level = $var; - $this->has_idempotency_level = true; return $this; } - public function hasIdempotencyLevel() - { - return $this->has_idempotency_level; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -147,15 +152,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php index 413b8e55eb41..5ae36ce7d5a2 100644 --- a/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/OneofDescriptorProto.php @@ -20,13 +20,11 @@ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field optional .google.protobuf.OneofOptions options = 2; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -49,7 +47,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -61,23 +69,27 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field optional .google.protobuf.OneofOptions options = 2; * @return \Google\Protobuf\Internal\OneofOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -89,15 +101,9 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\OneofOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } diff --git a/php/src/Google/Protobuf/Internal/OneofOptions.php b/php/src/Google/Protobuf/Internal/OneofOptions.php index 46b516f3019f..8dde8f3b1715 100644 --- a/php/src/Google/Protobuf/Internal/OneofOptions.php +++ b/php/src/Google/Protobuf/Internal/OneofOptions.php @@ -21,7 +21,6 @@ class OneofOptions extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -60,15 +59,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php index aaeefbc9ea4f..9c2cc8fc9009 100644 --- a/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php +++ b/php/src/Google/Protobuf/Internal/ServiceDescriptorProto.php @@ -20,18 +20,15 @@ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field optional string name = 1; */ - protected $name = ''; - private $has_name = false; + protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.MethodDescriptorProto method = 2; */ private $method; - private $has_method = false; /** * Generated from protobuf field optional .google.protobuf.ServiceOptions options = 3; */ protected $options = null; - private $has_options = false; /** * Constructor. @@ -55,7 +52,17 @@ public function __construct($data = NULL) { */ public function getName() { - return $this->name; + return isset($this->name) ? $this->name : ''; + } + + public function hasName() + { + return isset($this->name); + } + + public function clearName() + { + unset($this->name); } /** @@ -67,16 +74,10 @@ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * Generated from protobuf field repeated .google.protobuf.MethodDescriptorProto method = 2; * @return \Google\Protobuf\Internal\RepeatedField @@ -95,23 +96,27 @@ public function setMethod($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\MethodDescriptorProto::class); $this->method = $arr; - $this->has_method = true; return $this; } - public function hasMethod() - { - return $this->has_method; - } - /** * Generated from protobuf field optional .google.protobuf.ServiceOptions options = 3; * @return \Google\Protobuf\Internal\ServiceOptions */ public function getOptions() { - return $this->options; + return isset($this->options) ? $this->options : null; + } + + public function hasOptions() + { + return isset($this->options); + } + + public function clearOptions() + { + unset($this->options); } /** @@ -123,15 +128,9 @@ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ServiceOptions::class); $this->options = $var; - $this->has_options = true; return $this; } - public function hasOptions() - { - return $this->has_options; - } - } diff --git a/php/src/Google/Protobuf/Internal/ServiceOptions.php b/php/src/Google/Protobuf/Internal/ServiceOptions.php index 0581efbafca3..d15a36ae0a5e 100644 --- a/php/src/Google/Protobuf/Internal/ServiceOptions.php +++ b/php/src/Google/Protobuf/Internal/ServiceOptions.php @@ -23,15 +23,13 @@ class ServiceOptions extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional bool deprecated = 33 [default = false]; */ - protected $deprecated = false; - private $has_deprecated = false; + protected $deprecated = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; - private $has_uninterpreted_option = false; /** * Constructor. @@ -64,7 +62,17 @@ public function __construct($data = NULL) { */ public function getDeprecated() { - return $this->deprecated; + return isset($this->deprecated) ? $this->deprecated : false; + } + + public function hasDeprecated() + { + return isset($this->deprecated); + } + + public function clearDeprecated() + { + unset($this->deprecated); } /** @@ -81,16 +89,10 @@ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; - $this->has_deprecated = true; return $this; } - public function hasDeprecated() - { - return $this->has_deprecated; - } - /** * The parser stores options it doesn't recognize here. See above. * @@ -113,15 +115,9 @@ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; - $this->has_uninterpreted_option = true; return $this; } - public function hasUninterpretedOption() - { - return $this->has_uninterpreted_option; - } - } diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php index dfeb69ff6978..1c572e75ebf1 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo.php @@ -64,7 +64,6 @@ class SourceCodeInfo extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.SourceCodeInfo.Location location = 1; */ private $location; - private $has_location = false; /** * Constructor. @@ -223,15 +222,9 @@ public function setLocation($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo\Location::class); $this->location = $arr; - $this->has_location = true; return $this; } - public function hasLocation() - { - return $this->has_location; - } - } diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php index 0aeea61cae0d..c4cc667e3a4b 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php @@ -41,7 +41,6 @@ class Location extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 path = 1 [packed = true]; */ private $path; - private $has_path = false; /** * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. @@ -52,7 +51,6 @@ class Location extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated int32 span = 2 [packed = true]; */ private $span; - private $has_span = false; /** * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be @@ -93,18 +91,15 @@ class Location extends \Google\Protobuf\Internal\Message * * Generated from protobuf field optional string leading_comments = 3; */ - protected $leading_comments = ''; - private $has_leading_comments = false; + protected $leading_comments = null; /** * Generated from protobuf field optional string trailing_comments = 4; */ - protected $trailing_comments = ''; - private $has_trailing_comments = false; + protected $trailing_comments = null; /** * Generated from protobuf field repeated string leading_detached_comments = 6; */ private $leading_detached_comments; - private $has_leading_detached_comments = false; /** * Constructor. @@ -248,16 +243,10 @@ public function setPath($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->path = $arr; - $this->has_path = true; return $this; } - public function hasPath() - { - return $this->has_path; - } - /** * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. @@ -288,16 +277,10 @@ public function setSpan($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->span = $arr; - $this->has_span = true; return $this; } - public function hasSpan() - { - return $this->has_span; - } - /** * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be @@ -341,7 +324,17 @@ public function hasSpan() */ public function getLeadingComments() { - return $this->leading_comments; + return isset($this->leading_comments) ? $this->leading_comments : ''; + } + + public function hasLeadingComments() + { + return isset($this->leading_comments); + } + + public function clearLeadingComments() + { + unset($this->leading_comments); } /** @@ -390,23 +383,27 @@ public function setLeadingComments($var) { GPBUtil::checkString($var, True); $this->leading_comments = $var; - $this->has_leading_comments = true; return $this; } - public function hasLeadingComments() - { - return $this->has_leading_comments; - } - /** * Generated from protobuf field optional string trailing_comments = 4; * @return string */ public function getTrailingComments() { - return $this->trailing_comments; + return isset($this->trailing_comments) ? $this->trailing_comments : ''; + } + + public function hasTrailingComments() + { + return isset($this->trailing_comments); + } + + public function clearTrailingComments() + { + unset($this->trailing_comments); } /** @@ -418,16 +415,10 @@ public function setTrailingComments($var) { GPBUtil::checkString($var, True); $this->trailing_comments = $var; - $this->has_trailing_comments = true; return $this; } - public function hasTrailingComments() - { - return $this->has_trailing_comments; - } - /** * Generated from protobuf field repeated string leading_detached_comments = 6; * @return \Google\Protobuf\Internal\RepeatedField @@ -446,16 +437,10 @@ public function setLeadingDetachedComments($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->leading_detached_comments = $arr; - $this->has_leading_detached_comments = true; return $this; } - public function hasLeadingDetachedComments() - { - return $this->has_leading_detached_comments; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Internal/TimestampBase.php b/php/src/Google/Protobuf/Internal/TimestampBase.php new file mode 100644 index 000000000000..653d1e99d71c --- /dev/null +++ b/php/src/Google/Protobuf/Internal/TimestampBase.php @@ -0,0 +1,32 @@ +seconds = $datetime->getTimestamp(); + $this->nanos = 1000 * $datetime->format('u'); + } + + /** + * Converts Timestamp to PHP DateTime. + * + * @return \DateTime $datetime + */ + public function toDateTime() + { + $time = sprintf('%s.%06d', $this->seconds, $this->nanos / 1000); + return \DateTime::createFromFormat('U.u', $time); + } +} diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption.php b/php/src/Google/Protobuf/Internal/UninterpretedOption.php index 6c871cc1aeb5..a2aae3e0a741 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption.php @@ -26,40 +26,33 @@ class UninterpretedOption extends \Google\Protobuf\Internal\Message * Generated from protobuf field repeated .google.protobuf.UninterpretedOption.NamePart name = 2; */ private $name; - private $has_name = false; /** * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. * * Generated from protobuf field optional string identifier_value = 3; */ - protected $identifier_value = ''; - private $has_identifier_value = false; + protected $identifier_value = null; /** * Generated from protobuf field optional uint64 positive_int_value = 4; */ - protected $positive_int_value = 0; - private $has_positive_int_value = false; + protected $positive_int_value = null; /** * Generated from protobuf field optional int64 negative_int_value = 5; */ - protected $negative_int_value = 0; - private $has_negative_int_value = false; + protected $negative_int_value = null; /** * Generated from protobuf field optional double double_value = 6; */ - protected $double_value = 0.0; - private $has_double_value = false; + protected $double_value = null; /** * Generated from protobuf field optional bytes string_value = 7; */ - protected $string_value = ''; - private $has_string_value = false; + protected $string_value = null; /** * Generated from protobuf field optional string aggregate_value = 8; */ - protected $aggregate_value = ''; - private $has_aggregate_value = false; + protected $aggregate_value = null; /** * Constructor. @@ -101,16 +94,10 @@ public function setName($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption\NamePart::class); $this->name = $arr; - $this->has_name = true; return $this; } - public function hasName() - { - return $this->has_name; - } - /** * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. @@ -120,7 +107,17 @@ public function hasName() */ public function getIdentifierValue() { - return $this->identifier_value; + return isset($this->identifier_value) ? $this->identifier_value : ''; + } + + public function hasIdentifierValue() + { + return isset($this->identifier_value); + } + + public function clearIdentifierValue() + { + unset($this->identifier_value); } /** @@ -135,23 +132,27 @@ public function setIdentifierValue($var) { GPBUtil::checkString($var, True); $this->identifier_value = $var; - $this->has_identifier_value = true; return $this; } - public function hasIdentifierValue() - { - return $this->has_identifier_value; - } - /** * Generated from protobuf field optional uint64 positive_int_value = 4; * @return int|string */ public function getPositiveIntValue() { - return $this->positive_int_value; + return isset($this->positive_int_value) ? $this->positive_int_value : 0; + } + + public function hasPositiveIntValue() + { + return isset($this->positive_int_value); + } + + public function clearPositiveIntValue() + { + unset($this->positive_int_value); } /** @@ -163,23 +164,27 @@ public function setPositiveIntValue($var) { GPBUtil::checkUint64($var); $this->positive_int_value = $var; - $this->has_positive_int_value = true; return $this; } - public function hasPositiveIntValue() - { - return $this->has_positive_int_value; - } - /** * Generated from protobuf field optional int64 negative_int_value = 5; * @return int|string */ public function getNegativeIntValue() { - return $this->negative_int_value; + return isset($this->negative_int_value) ? $this->negative_int_value : 0; + } + + public function hasNegativeIntValue() + { + return isset($this->negative_int_value); + } + + public function clearNegativeIntValue() + { + unset($this->negative_int_value); } /** @@ -191,23 +196,27 @@ public function setNegativeIntValue($var) { GPBUtil::checkInt64($var); $this->negative_int_value = $var; - $this->has_negative_int_value = true; return $this; } - public function hasNegativeIntValue() - { - return $this->has_negative_int_value; - } - /** * Generated from protobuf field optional double double_value = 6; * @return float */ public function getDoubleValue() { - return $this->double_value; + return isset($this->double_value) ? $this->double_value : 0.0; + } + + public function hasDoubleValue() + { + return isset($this->double_value); + } + + public function clearDoubleValue() + { + unset($this->double_value); } /** @@ -219,23 +228,27 @@ public function setDoubleValue($var) { GPBUtil::checkDouble($var); $this->double_value = $var; - $this->has_double_value = true; return $this; } - public function hasDoubleValue() - { - return $this->has_double_value; - } - /** * Generated from protobuf field optional bytes string_value = 7; * @return string */ public function getStringValue() { - return $this->string_value; + return isset($this->string_value) ? $this->string_value : ''; + } + + public function hasStringValue() + { + return isset($this->string_value); + } + + public function clearStringValue() + { + unset($this->string_value); } /** @@ -247,23 +260,27 @@ public function setStringValue($var) { GPBUtil::checkString($var, False); $this->string_value = $var; - $this->has_string_value = true; return $this; } - public function hasStringValue() - { - return $this->has_string_value; - } - /** * Generated from protobuf field optional string aggregate_value = 8; * @return string */ public function getAggregateValue() { - return $this->aggregate_value; + return isset($this->aggregate_value) ? $this->aggregate_value : ''; + } + + public function hasAggregateValue() + { + return isset($this->aggregate_value); + } + + public function clearAggregateValue() + { + unset($this->aggregate_value); } /** @@ -275,15 +292,9 @@ public function setAggregateValue($var) { GPBUtil::checkString($var, True); $this->aggregate_value = $var; - $this->has_aggregate_value = true; return $this; } - public function hasAggregateValue() - { - return $this->has_aggregate_value; - } - } diff --git a/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php index 1956ba7f085e..6212d1e4577e 100644 --- a/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php +++ b/php/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php @@ -24,13 +24,11 @@ class NamePart extends \Google\Protobuf\Internal\Message /** * Generated from protobuf field required string name_part = 1; */ - protected $name_part = ''; - private $has_name_part = false; + protected $name_part = null; /** * Generated from protobuf field required bool is_extension = 2; */ - protected $is_extension = false; - private $has_is_extension = false; + protected $is_extension = null; /** * Constructor. @@ -53,7 +51,17 @@ public function __construct($data = NULL) { */ public function getNamePart() { - return $this->name_part; + return isset($this->name_part) ? $this->name_part : ''; + } + + public function hasNamePart() + { + return isset($this->name_part); + } + + public function clearNamePart() + { + unset($this->name_part); } /** @@ -65,23 +73,27 @@ public function setNamePart($var) { GPBUtil::checkString($var, True); $this->name_part = $var; - $this->has_name_part = true; return $this; } - public function hasNamePart() - { - return $this->has_name_part; - } - /** * Generated from protobuf field required bool is_extension = 2; * @return bool */ public function getIsExtension() { - return $this->is_extension; + return isset($this->is_extension) ? $this->is_extension : false; + } + + public function hasIsExtension() + { + return isset($this->is_extension); + } + + public function clearIsExtension() + { + unset($this->is_extension); } /** @@ -93,16 +105,10 @@ public function setIsExtension($var) { GPBUtil::checkBool($var); $this->is_extension = $var; - $this->has_is_extension = true; return $this; } - public function hasIsExtension() - { - return $this->has_is_extension; - } - } // Adding a class alias for backwards compatibility with the previous class name. diff --git a/php/src/Google/Protobuf/Method.php b/php/src/Google/Protobuf/Method.php index 8e803506885c..2755baa0e8b0 100644 --- a/php/src/Google/Protobuf/Method.php +++ b/php/src/Google/Protobuf/Method.php @@ -20,31 +20,31 @@ class Method extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * A URL of the input message type. * * Generated from protobuf field string request_type_url = 2; */ - private $request_type_url = ''; + protected $request_type_url = ''; /** * If true, the request is streamed. * * Generated from protobuf field bool request_streaming = 3; */ - private $request_streaming = false; + protected $request_streaming = false; /** * The URL of the output message type. * * Generated from protobuf field string response_type_url = 4; */ - private $response_type_url = ''; + protected $response_type_url = ''; /** * If true, the response is streamed. * * Generated from protobuf field bool response_streaming = 5; */ - private $response_streaming = false; + protected $response_streaming = false; /** * Any metadata attached to the method. * @@ -56,7 +56,7 @@ class Method extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Syntax syntax = 7; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Mixin.php b/php/src/Google/Protobuf/Mixin.php index a2ea59c75784..4f7bf844ccfe 100644 --- a/php/src/Google/Protobuf/Mixin.php +++ b/php/src/Google/Protobuf/Mixin.php @@ -46,7 +46,7 @@ * The mixin construct implies that all methods in `AccessControl` are * also declared with same name and request/response types in * `Storage`. A documentation generator or annotation processor will - * see the effective `Storage.GetAcl` method after inherting + * see the effective `Storage.GetAcl` method after inheriting * documentation and annotations as follows: * service Storage { * // Get the underlying ACL object. @@ -81,14 +81,14 @@ class Mixin extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * If non-empty specifies a path under which inherited HTTP paths * are rooted. * * Generated from protobuf field string root = 2; */ - private $root = ''; + protected $root = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/NullValue.php b/php/src/Google/Protobuf/NullValue.php index a72cbb2edb62..61569f8a36f7 100644 --- a/php/src/Google/Protobuf/NullValue.php +++ b/php/src/Google/Protobuf/NullValue.php @@ -35,6 +35,7 @@ public static function name($value) return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/OneofDescriptor.php b/php/src/Google/Protobuf/OneofDescriptor.php index d9736634e352..92b4e279dac3 100644 --- a/php/src/Google/Protobuf/OneofDescriptor.php +++ b/php/src/Google/Protobuf/OneofDescriptor.php @@ -72,4 +72,9 @@ public function getFieldCount() { return count($this->internal_desc->getFields()); } + + public function isSynthetic() + { + return $this->internal_desc->isSynthetic(); + } } diff --git a/php/src/Google/Protobuf/Option.php b/php/src/Google/Protobuf/Option.php index 22ecfc5f5c6c..9b2cc6c22c32 100644 --- a/php/src/Google/Protobuf/Option.php +++ b/php/src/Google/Protobuf/Option.php @@ -24,7 +24,7 @@ class Option extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * The option's value packed in an Any message. If the value is a primitive, * the corresponding wrapper type defined in google/protobuf/wrappers.proto @@ -33,7 +33,7 @@ class Option extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.Any value = 2; */ - private $value = null; + protected $value = null; /** * Constructor. @@ -101,7 +101,17 @@ public function setName($var) */ public function getValue() { - return $this->value; + return isset($this->value) ? $this->value : null; + } + + public function hasValue() + { + return isset($this->value); + } + + public function clearValue() + { + unset($this->value); } /** diff --git a/php/src/Google/Protobuf/SourceContext.php b/php/src/Google/Protobuf/SourceContext.php index cbc50c684260..8b3ea11220cd 100644 --- a/php/src/Google/Protobuf/SourceContext.php +++ b/php/src/Google/Protobuf/SourceContext.php @@ -22,7 +22,7 @@ class SourceContext extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string file_name = 1; */ - private $file_name = ''; + protected $file_name = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/StringValue.php b/php/src/Google/Protobuf/StringValue.php index 8fb354f3881e..ad98316b2247 100644 --- a/php/src/Google/Protobuf/StringValue.php +++ b/php/src/Google/Protobuf/StringValue.php @@ -21,7 +21,7 @@ class StringValue extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string value = 1; */ - private $value = ''; + protected $value = ''; /** * Constructor. diff --git a/php/src/Google/Protobuf/Syntax.php b/php/src/Google/Protobuf/Syntax.php index 9812669dacac..10952bfd42ce 100644 --- a/php/src/Google/Protobuf/Syntax.php +++ b/php/src/Google/Protobuf/Syntax.php @@ -40,6 +40,7 @@ public static function name($value) return self::$valueToName[$value]; } + public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); diff --git a/php/src/Google/Protobuf/Timestamp.php b/php/src/Google/Protobuf/Timestamp.php index 6d26f6c5cfdf..a12f48520bf2 100644 --- a/php/src/Google/Protobuf/Timestamp.php +++ b/php/src/Google/Protobuf/Timestamp.php @@ -9,17 +9,17 @@ use Google\Protobuf\Internal\GPBUtil; /** - * A Timestamp represents a point in time independent of any time zone - * or calendar, represented as seconds and fractions of seconds at - * nanosecond resolution in UTC Epoch time. It is encoded using the - * Proleptic Gregorian Calendar which extends the Gregorian calendar - * backwards to year one. It is encoded assuming all minutes are 60 - * seconds long, i.e. leap seconds are "smeared" so that no leap second - * table is needed for interpretation. Range is from - * 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. - * By restricting to that range, we ensure that we can convert to - * and from RFC 3339 date strings. - * See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). + * A Timestamp represents a point in time independent of any time zone or local + * calendar, encoded as a count of seconds and fractions of seconds at + * nanosecond resolution. The count is relative to an epoch at UTC midnight on + * January 1, 1970, in the proleptic Gregorian calendar which extends the + * Gregorian calendar backwards to year one. + * All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap + * second table is needed for interpretation, using a [24-hour linear + * smear](https://developers.google.com/time/smear). + * The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By + * restricting to that range, we ensure that we can convert to and from [RFC + * 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. * # Examples * Example 1: Compute Timestamp from POSIX `time()`. * Timestamp timestamp; @@ -44,7 +44,12 @@ * long millis = System.currentTimeMillis(); * Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) * .setNanos((int) ((millis % 1000) * 1000000)).build(); - * Example 5: Compute Timestamp from current time in Python. + * Example 5: Compute Timestamp from Java `Instant.now()`. + * Instant now = Instant.now(); + * Timestamp timestamp = + * Timestamp.newBuilder().setSeconds(now.getEpochSecond()) + * .setNanos(now.getNano()).build(); + * Example 6: Compute Timestamp from current time in Python. * timestamp = Timestamp() * timestamp.GetCurrentTime() * # JSON Mapping @@ -61,17 +66,19 @@ * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past * 01:30 UTC on January 15, 2017. * In JavaScript, one can convert a Date object to this format using the - * standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] + * standard + * [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) * method. In Python, a standard `datetime.datetime` object can be converted - * to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) - * with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one - * can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( - * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- + * to this format using + * [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with + * the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use + * the Joda Time's [`ISODateTimeFormat.dateTime()`]( + * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D * ) to obtain a formatter capable of generating timestamps in this format. * * Generated from protobuf message google.protobuf.Timestamp */ -class Timestamp extends \Google\Protobuf\Internal\Message +class Timestamp extends \Google\Protobuf\Internal\TimestampBase { /** * Represents seconds of UTC time since Unix epoch @@ -80,7 +87,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int64 seconds = 1; */ - private $seconds = 0; + protected $seconds = 0; /** * Non-negative fractions of a second at nanosecond resolution. Negative * second values with fractions must still have non-negative nanos values @@ -89,7 +96,7 @@ class Timestamp extends \Google\Protobuf\Internal\Message * * Generated from protobuf field int32 nanos = 2; */ - private $nanos = 0; + protected $nanos = 0; /** * Constructor. @@ -175,26 +182,5 @@ public function setNanos($var) return $this; } - /* - * Converts PHP DateTime to Timestamp. - * - * @param \DateTime $datetime - */ - public function fromDateTime(\DateTime $datetime) - { - $this->seconds = $datetime->getTimestamp(); - $this->nanos = 1000 * $datetime->format('u'); - } - - /** - * Converts Timestamp to PHP DateTime. - * - * @return \DateTime $datetime - */ - public function toDateTime() - { - $time = sprintf('%s.%06d', $this->seconds, $this->nanos / 1000); - return \DateTime::createFromFormat('U.u', $time); - } } diff --git a/php/src/Google/Protobuf/Type.php b/php/src/Google/Protobuf/Type.php index 1b47811050a4..f60686665cd3 100644 --- a/php/src/Google/Protobuf/Type.php +++ b/php/src/Google/Protobuf/Type.php @@ -20,7 +20,7 @@ class Type extends \Google\Protobuf\Internal\Message * * Generated from protobuf field string name = 1; */ - private $name = ''; + protected $name = ''; /** * The list of fields. * @@ -44,13 +44,13 @@ class Type extends \Google\Protobuf\Internal\Message * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; */ - private $source_context = null; + protected $source_context = null; /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 6; */ - private $syntax = 0; + protected $syntax = 0; /** * Constructor. @@ -189,7 +189,17 @@ public function setOptions($var) */ public function getSourceContext() { - return $this->source_context; + return isset($this->source_context) ? $this->source_context : null; + } + + public function hasSourceContext() + { + return isset($this->source_context); + } + + public function clearSourceContext() + { + unset($this->source_context); } /** diff --git a/php/src/Google/Protobuf/UInt32Value.php b/php/src/Google/Protobuf/UInt32Value.php index f5a522d2e8ef..ae5fc5b42c8d 100644 --- a/php/src/Google/Protobuf/UInt32Value.php +++ b/php/src/Google/Protobuf/UInt32Value.php @@ -21,7 +21,7 @@ class UInt32Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field uint32 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/UInt64Value.php b/php/src/Google/Protobuf/UInt64Value.php index 89e69cd89206..aa9686726b93 100644 --- a/php/src/Google/Protobuf/UInt64Value.php +++ b/php/src/Google/Protobuf/UInt64Value.php @@ -21,7 +21,7 @@ class UInt64Value extends \Google\Protobuf\Internal\Message * * Generated from protobuf field uint64 value = 1; */ - private $value = 0; + protected $value = 0; /** * Constructor. diff --git a/php/src/Google/Protobuf/Value.php b/php/src/Google/Protobuf/Value.php index 5c1e864c3d29..20db3cc3e3b1 100644 --- a/php/src/Google/Protobuf/Value.php +++ b/php/src/Google/Protobuf/Value.php @@ -57,6 +57,11 @@ public function getNullValue() return $this->readOneof(1); } + public function hasNullValue() + { + return $this->hasOneof(1); + } + /** * Represents a null value. * @@ -83,6 +88,11 @@ public function getNumberValue() return $this->readOneof(2); } + public function hasNumberValue() + { + return $this->hasOneof(2); + } + /** * Represents a double value. * @@ -109,6 +119,11 @@ public function getStringValue() return $this->readOneof(3); } + public function hasStringValue() + { + return $this->hasOneof(3); + } + /** * Represents a string value. * @@ -135,6 +150,11 @@ public function getBoolValue() return $this->readOneof(4); } + public function hasBoolValue() + { + return $this->hasOneof(4); + } + /** * Represents a boolean value. * @@ -161,6 +181,11 @@ public function getStructValue() return $this->readOneof(5); } + public function hasStructValue() + { + return $this->hasOneof(5); + } + /** * Represents a structured value. * @@ -187,6 +212,11 @@ public function getListValue() return $this->readOneof(6); } + public function hasListValue() + { + return $this->hasOneof(6); + } + /** * Represents a repeated `Value`. * diff --git a/php/tests/array_test.php b/php/tests/ArrayTest.php similarity index 94% rename from php/tests/array_test.php rename to php/tests/ArrayTest.php index b25140408363..d167331364dd 100644 --- a/php/tests/array_test.php +++ b/php/tests/ArrayTest.php @@ -7,7 +7,7 @@ use Foo\TestMessage; use Foo\TestMessage\Sub; -class RepeatedFieldTest extends \PHPUnit\Framework\TestCase +class ArrayTest extends \PHPUnit\Framework\TestCase { ######################################################### @@ -590,4 +590,35 @@ public function testCycleLeak() $end = memory_get_usage(); $this->assertLessThan($start, $end); } + + ######################################################### + # Test equality + ######################################################### + + public function testEquality() + { + $arr = new RepeatedField(GPBType::INT32); + $arr2 = new RepeatedField(GPBType::INT32); + + $this->assertTrue($arr == $arr2); + + $arr[] = 0; + $arr[] = 1; + $arr[] = 2; + + $this->assertFalse($arr == $arr2); + + $arr2[] = 0; + $arr2[] = 1; + $arr2[] = 2; + + $this->assertTrue($arr == $arr2); + + // Arrays of different types always compare false. + $this->assertFalse(new RepeatedField(GPBType::INT32) == + new RepeatedField(GPBType::INT64)); + $this->assertFalse( + new RepeatedField(GPBType::MESSAGE, TestMessage::class) == + new RepeatedField(GPBType::MESSAGE, Sub::class)); + } } diff --git a/php/tests/descriptors_test.php b/php/tests/DescriptorsTest.php similarity index 94% rename from php/tests/descriptors_test.php rename to php/tests/DescriptorsTest.php index 93683b82fdfd..b2c5e0144d4b 100644 --- a/php/tests/descriptors_test.php +++ b/php/tests/DescriptorsTest.php @@ -11,6 +11,8 @@ use Descriptors\TestDescriptorsEnum; use Descriptors\TestDescriptorsMessage; use Descriptors\TestDescriptorsMessage\Sub; +use Foo\TestMessage; +use Bar\TestInclude; class DescriptorsTest extends TestBase { @@ -89,13 +91,24 @@ public function testDescriptor() $this->assertSame(1, $desc->getOneofDeclCount()); } + public function testDescriptorForIncludedMessage() + { + $pool = DescriptorPool::getGeneratedPool(); + $class = get_class(new TestMessage()); + $this->assertSame('Foo\TestMessage', $class); + $desc = $pool->getDescriptorByClassName($class); + $fielddesc = $desc->getField(17); + $subdesc = $fielddesc->getMessageType(); + $this->assertSame('Bar\TestInclude', $subdesc->getClass()); + } + ######################################################### # Test enum descriptor. ######################################################### public function testEnumDescriptor() { - // WARNINIG - we need to do this so that TestDescriptorsEnum is registered!!? + // WARNING - we need to do this so that TestDescriptorsEnum is registered!!? new TestDescriptorsMessage(); $pool = DescriptorPool::getGeneratedPool(); diff --git a/php/tests/encode_decode_test.php b/php/tests/EncodeDecodeTest.php similarity index 97% rename from php/tests/encode_decode_test.php rename to php/tests/EncodeDecodeTest.php index 319e3321d2a1..cea1e6a47faf 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/EncodeDecodeTest.php @@ -326,6 +326,42 @@ public function testEncodeDecodeOneof() } + public function testEncodeDecodeOptional() + { + $m = new TestMessage(); + $this->assertFalse($m->hasTrueOptionalInt32()); + $data = $m->serializeToString(); + $this->assertSame("", $data); + + $m->setTrueOptionalInt32(0); + $this->assertTrue($m->hasTrueOptionalInt32()); + $data = $m->serializeToString(); + $this->assertNotSame("", $data); + + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $this->assertTrue($m2->hasTrueOptionalInt32()); + $this->assertSame(0, $m2->getTrueOptionalInt32()); + } + + public function testJsonEncodeDecodeOptional() + { + $m = new TestMessage(); + $this->assertFalse($m->hasTrueOptionalInt32()); + $data = $m->serializeToJsonString(); + $this->assertSame("{}", $data); + + $m->setTrueOptionalInt32(0); + $this->assertTrue($m->hasTrueOptionalInt32()); + $data = $m->serializeToJsonString(); + $this->assertNotSame("{}", $data); + + $m2 = new TestMessage(); + $m2->mergeFromJsonString($data); + $this->assertTrue($m2->hasTrueOptionalInt32()); + $this->assertSame(0, $m2->getTrueOptionalInt32()); + } + public function testJsonEncodeDecodeOneof() { $m = new TestMessage(); @@ -884,6 +920,11 @@ public function testJsonUnknown() $m->mergeFromJsonString("{\"unknown\":{\"a\":1, \"b\":1}, \"optionalInt32\":1}", true); $this->assertSame(1, $m->getOptionalInt32()); + + // Test unknown enum value + $m = new TestMessage(); + $m->mergeFromJsonString("{\"optionalEnum\":\"UNKNOWN\"}", true); + $this->assertSame(0, $m->getOptionalEnum()); } public function testJsonEncode() diff --git a/php/tests/generated_class_test.php b/php/tests/GeneratedClassTest.php similarity index 88% rename from php/tests/generated_class_test.php rename to php/tests/GeneratedClassTest.php index 6af00effe29b..037bd1be9c5c 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/GeneratedClassTest.php @@ -71,6 +71,28 @@ public function testInt32Field() $this->assertSame(MIN_INT32, $m->getOptionalInt32()); } + ######################################################### + # Test optional int32 field. + ######################################################### + + public function testOptionalInt32Field() + { + $m = new TestMessage(); + + $this->assertFalse($m->hasTrueOptionalInt32()); + $this->assertSame(0, $m->getTrueOptionalInt32()); + + // Set integer. + $m->setTrueOptionalInt32(MAX_INT32); + $this->assertTrue($m->hasTrueOptionalInt32()); + $this->assertSame(MAX_INT32, $m->getTrueOptionalInt32()); + + // Clear integer. + $m->clearTrueOptionalInt32(); + $this->assertFalse($m->hasTrueOptionalInt32()); + $this->assertSame(0, $m->getTrueOptionalInt32()); + } + ######################################################### # Test uint32 field. ######################################################### @@ -1507,6 +1529,165 @@ public function testValueIsReference() $m->setOptionalString($values[0]); } + ######################################################### + # Test equality + ######################################################### + + public function testShallowEquality() + { + $m1 = new TestMessage([ + 'optional_int32' => -42, + 'optional_int64' => -43, + 'optional_uint32' => 42, + 'optional_uint64' => 43, + 'optional_sint32' => -44, + 'optional_sint64' => -45, + 'optional_fixed32' => 46, + 'optional_fixed64' => 47, + 'optional_sfixed32' => -46, + 'optional_sfixed64' => -47, + 'optional_float' => 1.5, + 'optional_double' => 1.6, + 'optional_bool' => true, + 'optional_string' => 'a', + 'optional_bytes' => 'bbbb', + 'optional_enum' => TestEnum::ONE, + ]); + $data = $m1->serializeToString(); + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $this->assertTrue($m1 == $m2); + + $m1->setOptionalInt32(1234); + $this->assertTrue($m1 != $m2); + } + + public function testDeepEquality() + { + $m1 = new TestMessage([ + 'optional_int32' => -42, + 'optional_int64' => -43, + 'optional_uint32' => 42, + 'optional_uint64' => 43, + 'optional_sint32' => -44, + 'optional_sint64' => -45, + 'optional_fixed32' => 46, + 'optional_fixed64' => 47, + 'optional_sfixed32' => -46, + 'optional_sfixed64' => -47, + 'optional_float' => 1.5, + 'optional_double' => 1.6, + 'optional_bool' => true, + 'optional_string' => 'a', + 'optional_bytes' => 'bbbb', + 'optional_enum' => TestEnum::ONE, + 'optional_message' => new Sub([ + 'a' => 33 + ]), + 'repeated_int32' => [-42, -52], + 'repeated_int64' => [-43, -53], + 'repeated_uint32' => [42, 52], + 'repeated_uint64' => [43, 53], + 'repeated_sint32' => [-44, -54], + 'repeated_sint64' => [-45, -55], + 'repeated_fixed32' => [46, 56], + 'repeated_fixed64' => [47, 57], + 'repeated_sfixed32' => [-46, -56], + 'repeated_sfixed64' => [-47, -57], + 'repeated_float' => [1.5, 2.5], + 'repeated_double' => [1.6, 2.6], + 'repeated_bool' => [true, false], + 'repeated_string' => ['a', 'c'], + 'repeated_bytes' => ['bbbb', 'dddd'], + 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], + 'repeated_message' => [new Sub(['a' => 34]), + new Sub(['a' => 35])], + 'map_int32_int32' => [-62 => -62], + 'map_int64_int64' => [-63 => -63], + 'map_uint32_uint32' => [62 => 62], + 'map_uint64_uint64' => [63 => 63], + 'map_sint32_sint32' => [-64 => -64], + 'map_sint64_sint64' => [-65 => -65], + 'map_fixed32_fixed32' => [66 => 66], + 'map_fixed64_fixed64' => [67 => 67], + 'map_sfixed32_sfixed32' => [-68 => -68], + 'map_sfixed64_sfixed64' => [-69 => -69], + 'map_int32_float' => [1 => 3.5], + 'map_int32_double' => [1 => 3.6], + 'map_bool_bool' => [true => true], + 'map_string_string' => ['e' => 'e'], + 'map_int32_bytes' => [1 => 'ffff'], + 'map_int32_enum' => [1 => TestEnum::ONE], + 'map_int32_message' => [1 => new Sub(['a' => 36])], + ]); + $data = $m1->serializeToString(); + + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $this->assertTrue($m1 == $m2); + + # Nested sub-message is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getOptionalMessage()->setA(1234); + $this->assertTrue($m1 != $m2); + + # Repeated field element is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getRepeatedInt32()[0] = 1234; + $this->assertTrue($m1 != $m2); + + # Repeated field length is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getRepeatedInt32()[] = 1234; + $this->assertTrue($m1 != $m2); + + # SubMessage inside repeated field is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getRepeatedMessage()[0]->setA(1234); + $this->assertTrue($m1 != $m2); + + # Map value is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getMapInt32Int32()[-62] = 1234; + $this->assertTrue($m1 != $m2); + + # Map size is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getMapInt32Int32()[1234] = 1234; + $this->assertTrue($m1 != $m2); + + # SubMessage inside map field is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getMapInt32Message()[1]->setA(1234); + $this->assertTrue($m1 != $m2); + + # TODO: what about unknown fields? + } + + ######################################################### + # Test hasOneof methods exists and working + ######################################################### + + public function testHasOneof() { + $m = new TestMessage(); + $this->assertFalse($m->hasOneofInt32()); + $m->setOneofInt32(42); + $this->assertTrue($m->hasOneofInt32()); + $m->setOneofString("bar"); + $this->assertFalse($m->hasOneofInt32()); + $this->assertTrue($m->hasOneofString()); + $m->clear(); + $this->assertFalse($m->hasOneofInt32()); + $this->assertFalse($m->hasOneofString()); + } + ######################################################### # Test no segfault when error happens ######################################################### @@ -1527,6 +1708,21 @@ public function testNoSegfaultWithError() public function testNoExceptionWithVarDump() { $m = new Sub(['a' => 1]); - var_dump($m); + /* + * This line currently segfaults on macOS with: + * + * frame #0: 0x00000001029936cc xdebug.so`xdebug_zend_hash_is_recursive + 4 + * frame #1: 0x00000001029a6736 xdebug.so`xdebug_var_export_text_ansi + 1006 + * frame #2: 0x00000001029a715d xdebug.so`xdebug_get_zval_value_text_ansi + 273 + * frame #3: 0x000000010298a441 xdebug.so`zif_xdebug_var_dump + 297 + * frame #4: 0x000000010298d558 xdebug.so`xdebug_execute_internal + 640 + * frame #5: 0x000000010046d47f php`ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER + 364 + * frame #6: 0x000000010043cabc php`execute_ex + 44 + * frame #7: 0x000000010298d151 xdebug.so`xdebug_execute_ex + 1662 + * frame #8: 0x000000010046d865 php`ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER + 426 + * + * The value we are passing to var_dump() appears to be corrupt somehow. + */ + /* var_dump($m); */ } } diff --git a/php/tests/generated_phpdoc_test.php b/php/tests/GeneratedPhpdocTest.php similarity index 100% rename from php/tests/generated_phpdoc_test.php rename to php/tests/GeneratedPhpdocTest.php diff --git a/php/tests/generated_service_test.php b/php/tests/GeneratedServiceTest.php similarity index 100% rename from php/tests/generated_service_test.php rename to php/tests/GeneratedServiceTest.php diff --git a/php/tests/map_field_test.php b/php/tests/MapFieldTest.php similarity index 94% rename from php/tests/map_field_test.php rename to php/tests/MapFieldTest.php index 577be681bf69..4ed4b09cffe0 100644 --- a/php/tests/map_field_test.php +++ b/php/tests/MapFieldTest.php @@ -479,6 +479,35 @@ public function testMapElementIsReference() $m->setMapInt32Message($values); } + ######################################################### + # Test equality + ######################################################### + + public function testEquality() + { + $map = new MapField(GPBType::INT32, GPBType::INT32); + $map2 = new MapField(GPBType::INT32, GPBType::INT32); + + $this->assertTrue($map == $map2); + + $map[1] = 2; + + $this->assertFalse($map == $map2); + + $map2[1] = 2; + + $this->assertTrue($map == $map2); + + // Arrays of different types always compare false. + $this->assertFalse(new MapField(GPBType::INT32, GPBType::INT32) == + new MapField(GPBType::INT32, GPBType::INT64)); + $this->assertFalse(new MapField(GPBType::INT32, GPBType::INT32) == + new MapField(GPBType::INT64, GPBType::INT32)); + $this->assertFalse( + new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class) == + new MapField(GPBType::INT32, GPBType::MESSAGE, Sub::class)); + } + ######################################################### # Test memory leak ######################################################### diff --git a/php/tests/php_implementation_test.php b/php/tests/PhpImplementationTest.php similarity index 99% rename from php/tests/php_implementation_test.php rename to php/tests/PhpImplementationTest.php index 307b749c4930..f9fc1fd5ea76 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/PhpImplementationTest.php @@ -515,7 +515,7 @@ public function testByteSize() { $m = new TestMessage(); TestUtil::setTestMessage($m); - $this->assertSame(518, $m->byteSize()); + $this->assertSame(504, $m->byteSize()); } public function testPackedByteSize() @@ -538,7 +538,7 @@ public function testArrayConstructorJsonCaseThrowsException() /** * @expectedException Exception - * @expectedExceptionMessage Expect Foo\TestMessage_Sub. + * @expectedExceptionMessage Expect Foo\TestMessage\Sub. */ public function testArraysForMessagesThrowsException() { diff --git a/php/tests/well_known_test.php b/php/tests/WellKnownTest.php similarity index 99% rename from php/tests/well_known_test.php rename to php/tests/WellKnownTest.php index a16e070a453b..a148fa4a5b40 100644 --- a/php/tests/well_known_test.php +++ b/php/tests/WellKnownTest.php @@ -4,6 +4,7 @@ require_once('test_util.php'); use Foo\TestMessage; +use Foo\TestImportDescriptorProto; use Google\Protobuf\Any; use Google\Protobuf\Api; use Google\Protobuf\BoolValue; diff --git a/php/tests/wrapper_type_setters_test.php b/php/tests/WrapperTypeSettersTest.php similarity index 100% rename from php/tests/wrapper_type_setters_test.php rename to php/tests/WrapperTypeSettersTest.php diff --git a/php/tests/autoload.php b/php/tests/autoload.php old mode 100755 new mode 100644 diff --git a/php/tests/compatibility_test.sh b/php/tests/compatibility_test.sh index 2b5c6ab5b701..7e44cce06b40 100755 --- a/php/tests/compatibility_test.sh +++ b/php/tests/compatibility_test.sh @@ -1,17 +1,5 @@ #!/bin/bash -function use_php() { - VERSION=$1 - - OLD_PATH=$PATH - OLD_CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH - OLD_C_INCLUDE_PATH=$C_INCLUDE_PATH - - export PATH=/usr/local/php-${VERSION}/bin:$OLD_PATH - export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_CPLUS_INCLUDE_PATH - export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$OLD_C_INCLUDE_PATH -} - function generate_proto() { PROTOC1=$1 PROTOC2=$2 @@ -92,7 +80,6 @@ git checkout v$OLD_VERSION popd # Build and copy the new runtime -use_php 7.1 pushd ../ext/google/protobuf make clean || true phpize && ./configure && make @@ -113,11 +100,18 @@ cd protobuf/php composer install # Remove implementation detail tests. -tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php ) +# TODO(teboring): Temporarily disable encode_decode_test.php. In 3.13.0-rc1, +# repeated primitive field encoding is changed to packed, which is a bug fix. +# However, this fails the compatibility test which hard coded old encoding. +# Will re-enable the test after making a release. After the version bump, the +# compatibility test will use the updated test code. +tests=( array_test.php generated_class_test.php map_field_test.php well_known_test.php ) sed -i.bak '/php_implementation_test.php/d' phpunit.xml sed -i.bak '/generated_phpdoc_test.php/d' phpunit.xml +sed -i.bak '/encode_decode_test.php/d' phpunit.xml sed -i.bak 's/generated_phpdoc_test.php//g' tests/test.sh sed -i.bak 's/generated_service_test.php//g' tests/test.sh +sed -i.bak 's/encode_decode_test.php//g' tests/test.sh sed -i.bak '/memory_leak_test.php/d' tests/test.sh sed -i.bak '/^ public function testTimestamp()$/,/^ }$/d' tests/well_known_test.php sed -i.bak 's/PHPUnit_Framework_TestCase/\\PHPUnit\\Framework\\TestCase/g' tests/array_test.php diff --git a/php/tests/compile_extension.sh b/php/tests/compile_extension.sh index 2ffc51f14b34..85c73c6eb5dd 100755 --- a/php/tests/compile_extension.sh +++ b/php/tests/compile_extension.sh @@ -1,14 +1,20 @@ #!/bin/bash -VERSION=$2 +set -ex -export PATH=/usr/local/php-$VERSION/bin:$PATH -export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH -export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH +cd $(dirname $0) +../prepare_c_extension.sh pushd ../ext/google/protobuf -make clean || true -set -e -# Add following in configure for debug: --enable-debug CFLAGS='-g -O0' -phpize && ./configure CFLAGS='-g -O0 -Wall' && make +phpize --clean +rm -f configure.in configure.ac +phpize +if [ "$1" = "--release" ]; then + ./configure --with-php-config=$(which php-config) +else + # To get debugging symbols in PHP itself, build PHP with: + # $ ./configure --enable-debug CFLAGS='-g -O0' + ./configure --with-php-config=$(which php-config) CFLAGS="-g -O0 -Wall" +fi +make popd diff --git a/php/tests/gdb_test.sh b/php/tests/gdb_test.sh index da5f3f3ac14b..76a0fc3b1989 100755 --- a/php/tests/gdb_test.sh +++ b/php/tests/gdb_test.sh @@ -1,11 +1,5 @@ #!/bin/bash -VERSION=$1 - -export PATH=/usr/local/php-$VERSION/bin:$PATH -export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH -export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH - php -i | grep "Configuration" # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which diff --git a/php/tests/generate_protos.sh b/php/tests/generate_protos.sh new file mode 100755 index 000000000000..e83c3c1c068d --- /dev/null +++ b/php/tests/generate_protos.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -ex + +cd `dirname $0` + +rm -rf generated +mkdir -p generated + +find proto -type f -name "*.proto"| xargs ../../src/protoc --experimental_allow_proto3_optional --php_out=generated -I../../src -I. + +if [ "$1" = "--aggregate_metadata" ]; then + # Overwrite some of the files to use aggregation. + AGGREGATED_FILES="proto/test.proto proto/test_include.proto proto/test_import_descriptor_proto.proto" + ../../src/protoc --experimental_allow_proto3_optional --php_out=aggregate_metadata=foo#bar:generated -I../../src -I. $AGGREGATED_FILES +fi diff --git a/php/tests/multirequest.sh b/php/tests/multirequest.sh index 97535ea0edea..ec4a1ae51e35 100755 --- a/php/tests/multirequest.sh +++ b/php/tests/multirequest.sh @@ -1,14 +1,12 @@ #!/bin/bash + +cd $(dirname $0) + set -e -# Compile c extension -VERSION=7.4 PORT=12345 -export PATH=/usr/local/php-$VERSION/bin:$PATH -export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH -export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH -/bin/bash ./compile_extension.sh $VERSION +./compile_extension.sh nohup php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so -S localhost:$PORT multirequest.php 2>&1 & diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index 95057090f976..368b19ec4d14 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -34,6 +34,27 @@ message TestMessage { bar.TestInclude optional_included_message = 18; TestMessage recursive = 19; + // True optional + optional int32 true_optional_int32 = 201; + optional int64 true_optional_int64 = 202; + optional uint32 true_optional_uint32 = 203; + optional uint64 true_optional_uint64 = 204; + optional sint32 true_optional_sint32 = 205; + optional sint64 true_optional_sint64 = 206; + optional fixed32 true_optional_fixed32 = 207; + optional fixed64 true_optional_fixed64 = 208; + optional sfixed32 true_optional_sfixed32 = 209; + optional sfixed64 true_optional_sfixed64 = 210; + optional float true_optional_float = 211; + optional double true_optional_double = 212; + optional bool true_optional_bool = 213; + optional string true_optional_string = 214; + optional bytes true_optional_bytes = 215; + + optional TestEnum true_optional_enum = 216; + optional Sub true_optional_message = 217; + optional bar.TestInclude true_optional_included_message = 218; + // Repeated repeated int32 repeated_int32 = 31; repeated int64 repeated_int64 = 32; diff --git a/php/tests/proto/test_import_descriptor_proto.proto b/php/tests/proto/test_import_descriptor_proto.proto index 2a19940dece0..b06160153fb7 100644 --- a/php/tests/proto/test_import_descriptor_proto.proto +++ b/php/tests/proto/test_import_descriptor_proto.proto @@ -1,5 +1,7 @@ syntax = "proto3"; +package foo; + import "google/protobuf/descriptor.proto"; message TestImportDescriptorProto { diff --git a/php/tests/test.sh b/php/tests/test.sh index 3c5e30d73833..91ea56ec8f5b 100755 --- a/php/tests/test.sh +++ b/php/tests/test.sh @@ -1,22 +1,42 @@ #!/bin/bash -VERSION=$1 +set -ex -export PATH=/usr/local/php-$VERSION/bin:$PATH -export C_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$C_INCLUDE_PATH -export CPLUS_INCLUDE_PATH=/usr/local/php-$VERSION/include/php/main:/usr/local/php-$VERSION/include/php:$CPLUS_INCLUDE_PATH +cd $(dirname $0) -# Compile c extension -/bin/bash ./compile_extension.sh $VERSION +./generate_protos.sh +./compile_extension.sh -tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php descriptors_test.php wrapper_type_setters_test.php) +PHP_VERSION=$(php -r "echo PHP_VERSION;") + +# Each version of PHPUnit supports a fairly narrow range of PHP versions. +case "$PHP_VERSION" in + 7.0.*|7.1.*|7.2.*) + # Oddly older than for 5.6. Not sure the reason. + PHPUNIT=phpunit-5.6.0.phar + ;; + 7.3.*|7.4.*) + PHPUNIT=phpunit-8.phar + ;; + 8.0.*) + PHPUNIT=phpunit-9.phar + ;; + *) + echo "ERROR: Unsupported PHP version $PHP_VERSION" + exit 1 + ;; +esac + +[ -f $PHPUNIT ] || wget https://phar.phpunit.de/$PHPUNIT + +tests=( ArrayTest.php EncodeDecodeTest.php GeneratedClassTest.php MapFieldTest.php WellKnownTest.php DescriptorsTest.php WrapperTypeSettersTest.php) for t in "${tests[@]}" do echo "****************************" echo "* $t" echo "****************************" - php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php $t + php -dextension=../ext/google/protobuf/modules/protobuf.so $PHPUNIT --bootstrap autoload.php $t echo "" done @@ -25,7 +45,7 @@ do echo "****************************" echo "* $t persistent" echo "****************************" - php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php $t + php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so $PHPUNIT --bootstrap autoload.php $t echo "" done @@ -34,17 +54,17 @@ done export ZEND_DONT_UNLOAD_MODULES=1 export USE_ZEND_ALLOC=0 -valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php -valgrind --leak-check=yes php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php +valgrind --suppressions=valgrind.supp --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php +valgrind --suppressions=valgrind.supp --leak-check=yes php -d protobuf.keep_descriptor_pool_after_request=1 -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php # TODO(teboring): Only for debug (phpunit has memory leak which blocks this beging used by -# regresssion test.) +# regression test.) # for t in "${tests[@]}" # do # echo "****************************" # echo "* $t (memory leak)" # echo "****************************" -# valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php $t +# valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so $PHPUNIT --bootstrap autoload.php $t # echo "" # done diff --git a/php/tests/test_util.php b/php/tests/test_util.php index 2c5b59541c47..c47bf586a90d 100644 --- a/php/tests/test_util.php +++ b/php/tests/test_util.php @@ -338,38 +338,24 @@ public static function getGoldenTestMessage() "800101" . "8A01020821" . - "F801D6FFFFFFFFFFFFFFFF01" . - "F801CCFFFFFFFFFFFFFFFF01" . - "8002D5FFFFFFFFFFFFFFFF01" . - "8002CBFFFFFFFFFFFFFFFF01" . - "88022A" . - "880234" . - "90022B" . - "900235" . - "980257" . - "98026B" . - "A00259" . - "A0026D" . - "AD022E000000" . - "AD0238000000" . - "B1022F00000000000000" . - "B1023900000000000000" . - "BD02D2FFFFFF" . - "BD02C8FFFFFF" . - "C102D1FFFFFFFFFFFFFF" . - "C102C7FFFFFFFFFFFFFF" . - "CD020000C03F" . - "CD0200002040" . - "D1029A9999999999F93F" . - "D102CDCCCCCCCCCC0440" . - "D80201" . - "D80200" . + "FA0114D6FFFFFFFFFFFFFFFF01CCFFFFFFFFFFFFFFFF01" . + "820214D5FFFFFFFFFFFFFFFF01CBFFFFFFFFFFFFFFFF01" . + "8A02022A34" . + "9202022B35" . + "9A0202576B" . + "A20202596D" . + "AA02082E00000038000000" . + "B202102F000000000000003900000000000000" . + "BA0208D2FFFFFFC8FFFFFF" . + "C20210D1FFFFFFFFFFFFFFC7FFFFFFFFFFFFFF" . + "CA02080000C03F00002040" . + "D202109A9999999999F93FCDCCCCCCCCCC0440" . + "DA02020100" . "E2020161" . "E2020163" . "EA020462626262" . "EA020464646464" . - "F00200" . - "F00201" . + "F202020001" . "FA02020822" . "FA02020823" . diff --git a/php/tests/valgrind.supp b/php/tests/valgrind.supp new file mode 100644 index 000000000000..e83b0a3dfa0e --- /dev/null +++ b/php/tests/valgrind.supp @@ -0,0 +1,12 @@ +{ + PHP_Equal_Val + Memcheck:Cond + fun:zend_string_equal_val +} + +{ + PHP_ScanDir_Tail + Memcheck:Cond + obj:/usr/bin/php7.3 + fun:__scandir64_tail +} diff --git a/protobuf.bzl b/protobuf.bzl index 5fa5543b18bc..12d3edb94756 100644 --- a/protobuf.bzl +++ b/protobuf.bzl @@ -1,5 +1,6 @@ load("@bazel_skylib//lib:versions.bzl", "versions") load("@rules_cc//cc:defs.bzl", "cc_library") +load("@rules_proto//proto:defs.bzl", "ProtoInfo") load("@rules_python//python:defs.bzl", "py_library", "py_test") def _GetPath(ctx, path): @@ -75,18 +76,23 @@ def _RelativeOutputPath(path, include, dest = ""): def _proto_gen_impl(ctx): """General implementation for generating protos""" srcs = ctx.files.srcs - deps = [] - deps += ctx.files.srcs + deps = depset(direct=ctx.files.srcs) source_dir = _SourceDir(ctx) gen_dir = _GenDir(ctx).rstrip("/") if source_dir: - import_flags = ["-I" + source_dir, "-I" + gen_dir] + import_flags = depset(direct=["-I" + source_dir, "-I" + gen_dir]) else: - import_flags = ["-I."] + import_flags = depset(direct=["-I."]) for dep in ctx.attr.deps: - import_flags += dep.proto.import_flags - deps += dep.proto.deps + if type(dep.proto.import_flags) == "list": + import_flags = depset(transitive=[import_flags], direct=dep.proto.import_flags) + else: + import_flags = depset(transitive=[import_flags, dep.proto.import_flags]) + if type(dep.proto.deps) == "list": + deps = depset(transitive=[deps], direct=dep.proto.deps) + else: + deps = depset(transitive=[deps, dep.proto.deps]) if not ctx.attr.gen_cc and not ctx.attr.gen_py and not ctx.executable.plugin: return struct( @@ -103,7 +109,7 @@ def _proto_gen_impl(ctx): in_gen_dir = src.root.path == gen_dir if in_gen_dir: import_flags_real = [] - for f in depset(import_flags).to_list(): + for f in import_flags.to_list(): path = f.replace("-I", "") import_flags_real.append("-I$(realpath -s %s)" % path) @@ -118,7 +124,7 @@ def _proto_gen_impl(ctx): outs.extend(_PyOuts([src.basename], use_grpc_plugin = use_grpc_plugin)) outs = [ctx.actions.declare_file(out, sibling = src) for out in outs] - inputs = [src] + deps + inputs = [src] + deps.to_list() tools = [ctx.executable.protoc] if ctx.executable.plugin: plugin = ctx.executable.plugin @@ -141,7 +147,7 @@ def _proto_gen_impl(ctx): inputs = inputs, tools = tools, outputs = outs, - arguments = args + import_flags + [src.path], + arguments = args + import_flags.to_list() + [src.path], executable = ctx.executable.protoc, mnemonic = "ProtoCompile", use_default_shell_env = True, @@ -224,6 +230,29 @@ Args: outs: a list of labels of the expected outputs from the protocol compiler. """ +def _adapt_proto_library_impl(ctx): + deps = [dep[ProtoInfo] for dep in ctx.attr.deps] + + srcs = [src for dep in deps for src in dep.direct_sources] + return struct( + proto = struct( + srcs = srcs, + import_flags = ["-I{}".format(path) for dep in deps for path in dep.transitive_proto_path.to_list()], + deps = srcs, + ), + ) + +adapt_proto_library = rule( + implementation = _adapt_proto_library_impl, + attrs = { + "deps": attr.label_list( + mandatory = True, + providers = [ProtoInfo], + ), + }, + doc = "Adapts `proto_library` from `@rules_proto` to be used with `{cc,py}_proto_library` from this file.", +) + def cc_proto_library( name, srcs = [], @@ -231,7 +260,6 @@ def cc_proto_library( cc_libs = [], include = None, protoc = "@com_google_protobuf//:protoc", - internal_bootstrap_hack = False, use_grpc_plugin = False, default_runtime = "@com_google_protobuf//:protobuf", **kargs): @@ -249,41 +277,17 @@ def cc_proto_library( cc_library. include: a string indicating the include path of the .proto files. protoc: the label of the protocol compiler to generate the sources. - internal_bootstrap_hack: a flag indicate the cc_proto_library is used only - for bootstrapping. When it is set to True, no files will be generated. - The rule will simply be a provider for .proto files, so that other - cc_proto_library can depend on it. use_grpc_plugin: a flag to indicate whether to call the grpc C++ plugin when processing the proto files. default_runtime: the implicitly default runtime which will be depended on by the generated cc_library target. **kargs: other keyword arguments that are passed to cc_library. - """ includes = [] if include != None: includes = [include] - if internal_bootstrap_hack: - # For pre-checked-in generated files, we add the internal_bootstrap_hack - # which will skip the codegen action. - proto_gen( - name = name + "_genproto", - srcs = srcs, - deps = [s + "_genproto" for s in deps], - includes = includes, - protoc = protoc, - visibility = ["//visibility:public"], - ) - - # An empty cc_library to make rule dependency consistent. - cc_library( - name = name, - **kargs - ) - return - grpc_cpp_plugin = None if use_grpc_plugin: grpc_cpp_plugin = "//external:grpc_cpp_plugin" @@ -318,29 +322,59 @@ def cc_proto_library( **kargs ) -def internal_gen_well_known_protos_java(srcs): - """Bazel rule to generate the gen_well_known_protos_java genrule +def _internal_gen_well_known_protos_java_impl(ctx): + args = ctx.actions.args() - Args: - srcs: the well known protos - """ - root = Label("%s//protobuf_java" % (native.repository_name())).workspace_root - pkg = native.package_name() + "/" if native.package_name() else "" - if root == "": - include = " -I%ssrc " % pkg - else: - include = " -I%s/%ssrc " % (root, pkg) - native.genrule( - name = "gen_well_known_protos_java", - srcs = srcs, - outs = [ - "wellknown.srcjar", - ], - cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" + - " %s $(SRCS) " % include + - " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar", - tools = [":protoc"], + deps = [d[ProtoInfo] for d in ctx.attr.deps] + + srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name)) + args.add("--java_out", srcjar) + + descriptors = depset( + transitive = [dep.transitive_descriptor_sets for dep in deps], ) + args.add_joined( + "--descriptor_set_in", + descriptors, + join_with = ctx.configuration.host_path_separator, + ) + + for dep in deps: + if "." == dep.proto_source_root: + args.add_all([src.path for src in dep.direct_sources]) + else: + source_root = dep.proto_source_root + offset = len(source_root) + 1 # + '/'. + args.add_all([src.path[offset:] for src in dep.direct_sources]) + + ctx.actions.run( + executable = ctx.executable._protoc, + inputs = descriptors, + outputs = [srcjar], + arguments = [args], + use_default_shell_env = True, + ) + + return [ + DefaultInfo( + files = depset([srcjar]), + ), + ] + +internal_gen_well_known_protos_java = rule( + implementation = _internal_gen_well_known_protos_java_impl, + attrs = { + "deps": attr.label_list( + mandatory = True, + providers = [ProtoInfo], + ), + "_protoc": attr.label( + executable = True, + cfg = "host", + default = "@com_google_protobuf//:protoc", + ), + }, +) def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs): """Macro to copy files to a different directory and then create a filegroup. @@ -404,7 +438,7 @@ def py_proto_library( protoc: the label of the protocol compiler to generate the sources. use_grpc_plugin: a flag to indicate whether to call the Python C++ plugin when processing the proto files. - **kargs: other keyword arguments that are passed to cc_library. + **kargs: other keyword arguments that are passed to py_library. """ outs = _PyOuts(srcs, use_grpc_plugin) diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index fb0c47786da0..a95008501b7f 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -35,9 +35,9 @@ def protobuf_deps(): if not native.existing_rule("rules_cc"): http_archive( name = "rules_cc", - sha256 = "29daf0159f0cf552fcff60b49d8bcd4f08f08506d2da6e41b07058ec50cfeaec", - strip_prefix = "rules_cc-b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e", - urls = ["https://github.com/bazelbuild/rules_cc/archive/b7fe9697c0c76ab2fd431a891dbb9a6a32ed7c3e.tar.gz"], + sha256 = "9d48151ea71b3e225adfb6867e6d2c7d0dce46cbdc8710d9a9a628574dfd40a0", + strip_prefix = "rules_cc-818289e5613731ae410efb54218a4077fb9dbb03", + urls = ["https://github.com/bazelbuild/rules_cc/archive/818289e5613731ae410efb54218a4077fb9dbb03.tar.gz"], ) if not native.existing_rule("rules_java"): @@ -51,9 +51,9 @@ def protobuf_deps(): if not native.existing_rule("rules_proto"): http_archive( name = "rules_proto", - sha256 = "602e7161d9195e50246177e7c55b2f39950a9cf7366f74ed5f22fd45750cd208", - strip_prefix = "rules_proto-97d8af4dc474595af3900dd85cb3a29ad28cc313", - urls = ["https://github.com/bazelbuild/rules_proto/archive/97d8af4dc474595af3900dd85cb3a29ad28cc313.tar.gz"], + sha256 = "aa1ee19226f707d44bee44c720915199c20c84a23318bb0597ed4e5c873ccbd5", + strip_prefix = "rules_proto-40298556293ae502c66579620a7ce867d5f57311", + urls = ["https://github.com/bazelbuild/rules_proto/archive/40298556293ae502c66579620a7ce867d5f57311.tar.gz"], ) if not native.existing_rule("rules_python"): diff --git a/protoc-artifacts/build-zip.sh b/protoc-artifacts/build-zip.sh index 9921c2d5c60b..2a25d3cd7e17 100755 --- a/protoc-artifacts/build-zip.sh +++ b/protoc-artifacts/build-zip.sh @@ -13,10 +13,9 @@ Example: This script will download pre-built protoc or protoc plugin binaries from maven repository and create .zip packages suitable to be included in the github release page. If the target is protoc, well-known type .proto files will also be -included. Each invocation will create 9 zip packages: +included. Each invocation will create 8 zip packages: dist/--win32.zip dist/--win64.zip - dist/--osx-x86_32.zip dist/--osx-x86_64.zip dist/--linux-x86_32.zip dist/--linux-x86_64.zip @@ -34,7 +33,6 @@ VERSION_NUMBER=$2 declare -a FILE_NAMES=( \ win32.zip windows-x86_32.exe \ win64.zip windows-x86_64.exe \ - osx-x86_32.zip osx-x86_32.exe \ osx-x86_64.zip osx-x86_64.exe \ linux-x86_32.zip linux-x86_32.exe \ linux-x86_64.zip linux-x86_64.exe \ @@ -100,7 +98,7 @@ for((i=0;i<${#FILE_NAMES[@]};i+=2));do BINARY="$TARGET" fi BINARY_NAME=${FILE_NAMES[$(($i+1))]} - BINARY_URL=http://repo1.maven.org/maven2/com/google/protobuf/$TARGET/${VERSION_NUMBER}/$TARGET-${VERSION_NUMBER}-${BINARY_NAME} + BINARY_URL=https://repo1.maven.org/maven2/com/google/protobuf/$TARGET/${VERSION_NUMBER}/$TARGET-${VERSION_NUMBER}-${BINARY_NAME} if ! wget ${BINARY_URL} -O ${DIR}/bin/$BINARY &> /dev/null; then echo "[ERROR] Failed to download ${BINARY_URL}" >&2 echo "[ERROR] Skipped $TARGET-${VERSION_NAME}-${ZIP_NAME}" >&2 diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml index 80d282d1ef44..97fd11e700b3 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -8,7 +8,7 @@ com.google.protobuf protoc - 3.11.2 + 3.14.0 pom Protobuf Compiler @@ -70,11 +70,6 @@ osx-x86_64 exe - - ${basedir}/target/osx/x86_32/protoc.exe - osx-x86_32 - exe - ${basedir}/target/linux/aarch_64/protoc.exe linux-aarch_64 diff --git a/python/.repo-metadata.json b/python/.repo-metadata.json new file mode 100644 index 000000000000..c8d71a84ec59 --- /dev/null +++ b/python/.repo-metadata.json @@ -0,0 +1,11 @@ +{ + "name": "protobuf", + "name_pretty": "Protocol Buffers", + "product_documentation": "https://developers.google.com/protocol-buffers ", + "client_documentation": "https://developers.google.com/protocol-buffers/docs/pythontutorial", + "issue_tracker": "https://github.com/protocolbuffers/protobuf/issues", + "release_level": "ga", + "language": "python", + "repo": "protocolbuffers/protobuf ", + "distribution_name": "protobuf" +} diff --git a/python/README.md b/python/README.md index 8f7e03131401..cb8b7e9892e6 100644 --- a/python/README.md +++ b/python/README.md @@ -22,10 +22,8 @@ package. Development Warning =================== -The Python implementation of Protocol Buffers is not as mature as the C++ -and Java implementations. It may be more buggy, and it is known to be -pretty slow at this time. If you would like to help fix these issues, -join the Protocol Buffers discussion list and let us know! +The pure python performance is slow. For better performance please +use python c++ implementation. Installation ============ diff --git a/python/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto b/python/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto index 031433e2a9e1..95c8d4d2e32b 100644 --- a/python/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto +++ b/python/compatibility_tests/v2.5.0/protos/src/proto/google/protobuf/descriptor.proto @@ -74,7 +74,7 @@ message FileDescriptorProto { optional FileOptions options = 8; // This field contains optional information about the original source code. - // You may safely remove this entire field whithout harming runtime + // You may safely remove this entire field without harming runtime // functionality of the descriptors -- the information is needed only by // development tools. optional SourceCodeInfo source_code_info = 9; diff --git a/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py b/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py old mode 100755 new mode 100644 diff --git a/python/docs/Makefile b/python/docs/Makefile new file mode 100644 index 000000000000..298ea9e213e8 --- /dev/null +++ b/python/docs/Makefile @@ -0,0 +1,19 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/python/docs/conf.py b/python/docs/conf.py new file mode 100644 index 000000000000..913f01283892 --- /dev/null +++ b/python/docs/conf.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- +# Protocol Buffers - Google's data interchange format +# Copyright 2019 Google LLC. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# 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 its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) +import google.protobuf + +# -- Project information ----------------------------------------------------- + +project = u"Protocol Buffers" +copyright = u"2008, Google LLC" +author = u"Google LLC" + +# The short X.Y version +version = u"" +# The full version, including alpha/beta/rc tags +release = google.protobuf.__version__ + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autosummary", + "sphinx.ext.ifconfig", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = ".rst" + +# The master toctree document. +master_doc = "index" + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [u"_build", "Thumbs.db", ".DS_Store"] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = None + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "alabaster" + +# Remove JavaScript. +html_js_files = [] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +html_show_sourcelink = True + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. + +# Remove searchbox.html to avoid embedded JavaScript. +html_sidebars = { + "**": [ + "globaltoc.html", "localtoc.html", "relations.html", "sourcelink.html", + ], +} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = "ProtocolBuffersdoc" + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + master_doc, + "ProtocolBuffers.tex", + "Protocol Buffers Documentation", + "Google LLC", + "manual", + ) +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + master_doc, # source start file + "protocolbuffers", # name + "Protocol Buffers Documentation", # description + [author], # authors + 1, # manual section + ) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ( + master_doc, + "ProtocolBuffers", + u"Protocol Buffers Documentation", + author, + "ProtocolBuffers", + "One line description of project.", + "Miscellaneous", + ) +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ["search.html"] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for autosummary extension --------------------------------------- +autosummary_generate = True + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {"https://docs.python.org/": None} + +# -- Config values ----------------------------------------------------------- +# The setup() function is needed to add configuration values to the Sphinx +# builder. We use this to show a banner when built on Read the Docs. +# https://www.sphinx-doc.org/en/master/usage/extensions/ifconfig.html + +def setup(app): + app.add_config_value( + "build_env", + # Read the Docs sets a READTHEDOCS environment during builds. + # https://docs.readthedocs.io/en/stable/builds.html#build-environment + "readthedocs" if os.getenv("READTHEDOCS") else "", + "env" + ) diff --git a/python/docs/environment.yml b/python/docs/environment.yml new file mode 100644 index 000000000000..0f6390e69861 --- /dev/null +++ b/python/docs/environment.yml @@ -0,0 +1,10 @@ +name: protobuf +channels: + - defaults +dependencies: + - libprotobuf=3.11.4 + - make=4.2.1 + - pip=19.3.1 + - python=3.7.6 + - sphinx=2.4.0 + - sphinx_rtd_theme=0.4.3 diff --git a/python/docs/generate_docs.py b/python/docs/generate_docs.py new file mode 100755 index 000000000000..e024aaa47909 --- /dev/null +++ b/python/docs/generate_docs.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# 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 its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Script to generate a list of all modules to use in autosummary. + +This script creates a ReStructured Text file for each public module in the +protobuf Python package. The script also updates the table of contents in +``docs/index.rst`` to point to these module references. + +To build the docs with Sphinx: + +1. Install the needed packages (``sphinx``, ``sphinxcontrib-napoleon`` for + Google-style docstring support). I've created a conda environment file to + make this easier: + +.. code:: bash + + conda env create -f python/docs/environment.yml + +2. (Optional) Generate reference docs files and regenerate index: + +.. code:: bash + + cd python/docs + python generate_docs.py + +3. Run Sphinx. + +.. code:: bash + + make html +""" + +import pathlib +import re + + +DOCS_DIR = pathlib.Path(__file__).parent.resolve() +PYTHON_DIR = DOCS_DIR.parent +SOURCE_DIR = PYTHON_DIR / "google" / "protobuf" +SOURCE_POSIX = SOURCE_DIR.as_posix() + +# Modules which are always included: +INCLUDED_MODULES = ( + "google.protobuf.internal.containers", +) + +# Packages to ignore, including all modules (unless in INCLUDED_MODULES): +IGNORED_PACKAGES = ( + "compiler", + "docs", + "internal", + "pyext", + "util", +) + +# Ignored module stems in all packages (unless in INCLUDED_MODULES): +IGNORED_MODULES = ( + "any_test_pb2", + "api_pb2", + "unittest", + "source_context_pb2", + "test_messages_proto3_pb2", + "test_messages_proto2", +) + +TOC_REGEX = re.compile( + r"\.\. START REFTOC.*\.\. END REFTOC\.\n", + flags=re.DOTALL, +) +TOC_TEMPLATE = """.. START REFTOC, generated by generate_docs.py. +.. toctree:: + + {toctree} + +.. END REFTOC. +""" + +AUTOMODULE_TEMPLATE = """.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +{module} +{underline} + +.. automodule:: {module} + :members: + :inherited-members: + :undoc-members: +""" + + +def find_modules(): + modules = [] + for module_path in SOURCE_DIR.glob("**/*.py"): + # Determine the (dotted) relative package and module names. + package_path = module_path.parent.relative_to(PYTHON_DIR) + if package_path == SOURCE_DIR: + package_name = "" + module_name = module_path.stem + else: + package_name = package_path.as_posix().replace("/", ".") + module_name = package_name + "." + module_path.stem + + # Filter: first, accept anything in the whitelist; then, reject anything + # at package level, then module name level. + if any(include == module_name for include in INCLUDED_MODULES): + pass + elif any(ignored in package_name for ignored in IGNORED_PACKAGES): + continue + elif any(ignored in module_path.stem for ignored in IGNORED_MODULES): + continue + + if module_path.name == "__init__.py": + modules.append(package_name) + else: + modules.append(module_name) + + return modules + + +def write_automodule(module): + contents = AUTOMODULE_TEMPLATE.format(module=module, underline="=" * len(module),) + automodule_path = DOCS_DIR.joinpath(*module.split(".")).with_suffix(".rst") + try: + automodule_path.parent.mkdir(parents=True) + except FileExistsError: + pass + with open(automodule_path, "w") as automodule_file: + automodule_file.write(contents) + + +def replace_toc(modules): + toctree = [module.replace(".", "/") for module in modules] + with open(DOCS_DIR / "index.rst", "r") as index_file: + index_contents = index_file.read() + toc = TOC_TEMPLATE.format( + toctree="\n ".join(toctree) + ) + index_contents = re.sub(TOC_REGEX, toc, index_contents) + with open(DOCS_DIR / "index.rst", "w") as index_file: + index_file.write(index_contents) + + +def main(): + modules = list(sorted(find_modules())) + for module in modules: + print("Generating reference for {}".format(module)) + write_automodule(module) + print("Generating index.rst") + replace_toc(modules) + +if __name__ == "__main__": + main() diff --git a/python/docs/google/protobuf.rst b/python/docs/google/protobuf.rst new file mode 100644 index 000000000000..b26102e11050 --- /dev/null +++ b/python/docs/google/protobuf.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf +=============== + +.. automodule:: google.protobuf + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/any_pb2.rst b/python/docs/google/protobuf/any_pb2.rst new file mode 100644 index 000000000000..b6f47ef3fd38 --- /dev/null +++ b/python/docs/google/protobuf/any_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.any_pb2 +======================= + +.. automodule:: google.protobuf.any_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/descriptor.rst b/python/docs/google/protobuf/descriptor.rst new file mode 100644 index 000000000000..29b07746f455 --- /dev/null +++ b/python/docs/google/protobuf/descriptor.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.descriptor +========================== + +.. automodule:: google.protobuf.descriptor + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/descriptor_database.rst b/python/docs/google/protobuf/descriptor_database.rst new file mode 100644 index 000000000000..1b8b3904d8c4 --- /dev/null +++ b/python/docs/google/protobuf/descriptor_database.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.descriptor_database +=================================== + +.. automodule:: google.protobuf.descriptor_database + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/descriptor_pb2.rst b/python/docs/google/protobuf/descriptor_pb2.rst new file mode 100644 index 000000000000..94eec35c347b --- /dev/null +++ b/python/docs/google/protobuf/descriptor_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.descriptor_pb2 +============================== + +.. automodule:: google.protobuf.descriptor_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/descriptor_pool.rst b/python/docs/google/protobuf/descriptor_pool.rst new file mode 100644 index 000000000000..c2ee33e7b355 --- /dev/null +++ b/python/docs/google/protobuf/descriptor_pool.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.descriptor_pool +=============================== + +.. automodule:: google.protobuf.descriptor_pool + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/duration_pb2.rst b/python/docs/google/protobuf/duration_pb2.rst new file mode 100644 index 000000000000..4233e3cb52b7 --- /dev/null +++ b/python/docs/google/protobuf/duration_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.duration_pb2 +============================ + +.. automodule:: google.protobuf.duration_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/empty_pb2.rst b/python/docs/google/protobuf/empty_pb2.rst new file mode 100644 index 000000000000..c386a4c5c906 --- /dev/null +++ b/python/docs/google/protobuf/empty_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.empty_pb2 +========================= + +.. automodule:: google.protobuf.empty_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/field_mask_pb2.rst b/python/docs/google/protobuf/field_mask_pb2.rst new file mode 100644 index 000000000000..d9d807069ee4 --- /dev/null +++ b/python/docs/google/protobuf/field_mask_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.field_mask_pb2 +============================== + +.. automodule:: google.protobuf.field_mask_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/internal/containers.rst b/python/docs/google/protobuf/internal/containers.rst new file mode 100644 index 000000000000..c3b8e594a77f --- /dev/null +++ b/python/docs/google/protobuf/internal/containers.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.internal.containers +=================================== + +.. automodule:: google.protobuf.internal.containers + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/json_format.rst b/python/docs/google/protobuf/json_format.rst new file mode 100644 index 000000000000..eb3b0c539967 --- /dev/null +++ b/python/docs/google/protobuf/json_format.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.json_format +=========================== + +.. automodule:: google.protobuf.json_format + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/message.rst b/python/docs/google/protobuf/message.rst new file mode 100644 index 000000000000..a20424807cd3 --- /dev/null +++ b/python/docs/google/protobuf/message.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.message +======================= + +.. automodule:: google.protobuf.message + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/message_factory.rst b/python/docs/google/protobuf/message_factory.rst new file mode 100644 index 000000000000..93183cc03d44 --- /dev/null +++ b/python/docs/google/protobuf/message_factory.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.message_factory +=============================== + +.. automodule:: google.protobuf.message_factory + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/proto_builder.rst b/python/docs/google/protobuf/proto_builder.rst new file mode 100644 index 000000000000..36243a2ffff5 --- /dev/null +++ b/python/docs/google/protobuf/proto_builder.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.proto_builder +============================= + +.. automodule:: google.protobuf.proto_builder + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/reflection.rst b/python/docs/google/protobuf/reflection.rst new file mode 100644 index 000000000000..d177fc02f65e --- /dev/null +++ b/python/docs/google/protobuf/reflection.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.reflection +========================== + +.. automodule:: google.protobuf.reflection + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/service.rst b/python/docs/google/protobuf/service.rst new file mode 100644 index 000000000000..6d71f810887c --- /dev/null +++ b/python/docs/google/protobuf/service.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.service +======================= + +.. automodule:: google.protobuf.service + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/service_reflection.rst b/python/docs/google/protobuf/service_reflection.rst new file mode 100644 index 000000000000..30f30dd29358 --- /dev/null +++ b/python/docs/google/protobuf/service_reflection.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.service_reflection +================================== + +.. automodule:: google.protobuf.service_reflection + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/struct_pb2.rst b/python/docs/google/protobuf/struct_pb2.rst new file mode 100644 index 000000000000..9179eede3cc5 --- /dev/null +++ b/python/docs/google/protobuf/struct_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.struct_pb2 +========================== + +.. automodule:: google.protobuf.struct_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/symbol_database.rst b/python/docs/google/protobuf/symbol_database.rst new file mode 100644 index 000000000000..6ea73522f532 --- /dev/null +++ b/python/docs/google/protobuf/symbol_database.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.symbol_database +=============================== + +.. automodule:: google.protobuf.symbol_database + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/text_encoding.rst b/python/docs/google/protobuf/text_encoding.rst new file mode 100644 index 000000000000..a2eb959dc0d0 --- /dev/null +++ b/python/docs/google/protobuf/text_encoding.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.text_encoding +============================= + +.. automodule:: google.protobuf.text_encoding + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/text_format.rst b/python/docs/google/protobuf/text_format.rst new file mode 100644 index 000000000000..686b8fc002b1 --- /dev/null +++ b/python/docs/google/protobuf/text_format.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.text_format +=========================== + +.. automodule:: google.protobuf.text_format + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/timestamp_pb2.rst b/python/docs/google/protobuf/timestamp_pb2.rst new file mode 100644 index 000000000000..540df8395d48 --- /dev/null +++ b/python/docs/google/protobuf/timestamp_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.timestamp_pb2 +============================= + +.. automodule:: google.protobuf.timestamp_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/type_pb2.rst b/python/docs/google/protobuf/type_pb2.rst new file mode 100644 index 000000000000..e9b19d7b8582 --- /dev/null +++ b/python/docs/google/protobuf/type_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.type_pb2 +======================== + +.. automodule:: google.protobuf.type_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/google/protobuf/wrappers_pb2.rst b/python/docs/google/protobuf/wrappers_pb2.rst new file mode 100644 index 000000000000..8f29aa7838b0 --- /dev/null +++ b/python/docs/google/protobuf/wrappers_pb2.rst @@ -0,0 +1,21 @@ +.. DO NOT EDIT, generated by generate_docs.py. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +google.protobuf.wrappers_pb2 +============================ + +.. automodule:: google.protobuf.wrappers_pb2 + :members: + :inherited-members: + :undoc-members: diff --git a/python/docs/index.rst b/python/docs/index.rst new file mode 100644 index 000000000000..5535b398a952 --- /dev/null +++ b/python/docs/index.rst @@ -0,0 +1,63 @@ +.. Protocol Buffers documentation master file, created by + sphinx-quickstart on Thu Aug 15 13:56:43 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +.. ifconfig:: build_env == 'readthedocs' + + .. warning:: + + You are reading the documentation for the `latest committed changes + `_ of + the `Protocol Buffers package for Python + `_. + Some features may not yet be released. Read the documentation for the + latest released package at `googleapis.dev + `_. + +Protocol Buffers Python API Reference +===================================== + +The complete documentation for Protocol Buffers is available via the web at: + + https://developers.google.com/protocol-buffers/ + + +Modules and Packages +-------------------- + +.. START REFTOC, generated by generate_docs.py. +.. toctree:: + + google/protobuf + google/protobuf/any_pb2 + google/protobuf/descriptor + google/protobuf/descriptor_database + google/protobuf/descriptor_pb2 + google/protobuf/descriptor_pool + google/protobuf/duration_pb2 + google/protobuf/empty_pb2 + google/protobuf/field_mask_pb2 + google/protobuf/internal/containers + google/protobuf/json_format + google/protobuf/message + google/protobuf/message_factory + google/protobuf/proto_builder + google/protobuf/reflection + google/protobuf/service + google/protobuf/service_reflection + google/protobuf/struct_pb2 + google/protobuf/symbol_database + google/protobuf/text_encoding + google/protobuf/text_format + google/protobuf/timestamp_pb2 + google/protobuf/type_pb2 + google/protobuf/wrappers_pb2 + +.. END REFTOC. + +Indices and tables +------------------ + +* :ref:`genindex` +* :ref:`modindex` diff --git a/python/docs/make.bat b/python/docs/make.bat new file mode 100644 index 000000000000..27f573b87af1 --- /dev/null +++ b/python/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/python/docs/requirements.txt b/python/docs/requirements.txt new file mode 100644 index 000000000000..2b3e98925ec7 --- /dev/null +++ b/python/docs/requirements.txt @@ -0,0 +1,3 @@ +sphinx==2.3.1 +sphinx_rtd_theme==0.4.3 +sphinxcontrib-napoleon==0.7 diff --git a/python/google/__init__.py b/python/google/__init__.py old mode 100755 new mode 100644 diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py old mode 100755 new mode 100644 index 25d2445ff9db..97ac28028b19 --- a/python/google/protobuf/__init__.py +++ b/python/google/protobuf/__init__.py @@ -30,10 +30,4 @@ # Copyright 2007 Google Inc. All Rights Reserved. -__version__ = '3.11.2' - -if __name__ != '__main__': - try: - __import__('pkg_resources').declare_namespace(__name__) - except ImportError: - __path__ = __import__('pkgutil').extend_path(__path__, __name__) +__version__ = '3.14.0' diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py old mode 100755 new mode 100644 index a0014092f95b..7583ea39f7a2 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -35,6 +35,7 @@ __author__ = 'robinson@google.com (Will Robinson)' import threading +import warnings import six from google.protobuf.internal import api_implementation @@ -91,6 +92,25 @@ def __exit__(self, exc_type, exc_value, exc_tb): _lock = threading.Lock() +def _Deprecated(name): + if _Deprecated.count > 0: + _Deprecated.count -= 1 + warnings.warn( + 'Call to deprecated create function %s(). Note: Create unlinked ' + 'descriptors is going to go away. Please use get/find descriptors from ' + 'generated code or query the descriptor_pool.' + % name, + category=DeprecationWarning, stacklevel=3) + + +# Deprecated warnings will print 100 times at most which should be enough for +# users to notice and do not cause timeout. +_Deprecated.count = 100 + + +_internal_create_key = object() + + class DescriptorBase(six.with_metaclass(DescriptorMetaclass)): """Descriptors base class. @@ -173,13 +193,12 @@ def __init__(self, options, options_class_name, name, full_name, Args: options: Protocol message options or None to use default message options. - options_class_name: (str) The class name of the above options. - - name: (str) Name of this protocol message type. - full_name: (str) Fully-qualified name of this protocol message type, + options_class_name (str): The class name of the above options. + name (str): Name of this protocol message type. + full_name (str): Fully-qualified name of this protocol message type, which will include protocol "package" name and the name of any enclosing types. - file: (FileDescriptor) Reference to file info. + file (FileDescriptor): Reference to file info. containing_type: if provided, this is a nested descriptor, with this descriptor as parent, otherwise None. serialized_start: The start index (inclusive) in block in the @@ -208,7 +227,8 @@ def CopyToProto(self, proto): proto: An empty proto instance from descriptor_pb2. Raises: - Error: If self couldnt be serialized, due to to few constructor arguments. + Error: If self couldn't be serialized, due to to few constructor + arguments. """ if (self.file is not None and self._serialized_start is not None and @@ -223,56 +243,45 @@ class Descriptor(_NestedDescriptorBase): """Descriptor for a protocol message type. - A Descriptor instance has the following attributes: - - name: (str) Name of this protocol message type. - full_name: (str) Fully-qualified name of this protocol message type, - which will include protocol "package" name and the name of any - enclosing types. - - containing_type: (Descriptor) Reference to the descriptor of the - type containing us, or None if this is top-level. - - fields: (list of FieldDescriptors) Field descriptors for all - fields in this type. - fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor - objects as in |fields|, but indexed by "number" attribute in each - FieldDescriptor. - fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor - objects as in |fields|, but indexed by "name" attribute in each - FieldDescriptor. - fields_by_camelcase_name: (dict str -> FieldDescriptor) Same - FieldDescriptor objects as in |fields|, but indexed by - "camelcase_name" attribute in each FieldDescriptor. - - nested_types: (list of Descriptors) Descriptor references - for all protocol message types nested within this one. - nested_types_by_name: (dict str -> Descriptor) Same Descriptor - objects as in |nested_types|, but indexed by "name" attribute - in each Descriptor. - - enum_types: (list of EnumDescriptors) EnumDescriptor references - for all enums contained within this type. - enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor - objects as in |enum_types|, but indexed by "name" attribute - in each EnumDescriptor. - enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping - from enum value name to EnumValueDescriptor for that value. - - extensions: (list of FieldDescriptor) All extensions defined directly - within this message type (NOT within a nested type). - extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor - objects as |extensions|, but indexed by "name" attribute of each - FieldDescriptor. - - is_extendable: Does this type define any extension ranges? - - oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields - in this message. - oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|, - but indexed by "name" attribute. - - file: (FileDescriptor) Reference to file descriptor. + Attributes: + name (str): Name of this protocol message type. + full_name (str): Fully-qualified name of this protocol message type, + which will include protocol "package" name and the name of any + enclosing types. + containing_type (Descriptor): Reference to the descriptor of the type + containing us, or None if this is top-level. + fields (list[FieldDescriptor]): Field descriptors for all fields in + this type. + fields_by_number (dict(int, FieldDescriptor)): Same + :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed + by "number" attribute in each FieldDescriptor. + fields_by_name (dict(str, FieldDescriptor)): Same + :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by + "name" attribute in each :class:`FieldDescriptor`. + nested_types (list[Descriptor]): Descriptor references + for all protocol message types nested within this one. + nested_types_by_name (dict(str, Descriptor)): Same Descriptor + objects as in :attr:`nested_types`, but indexed by "name" attribute + in each Descriptor. + enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references + for all enums contained within this type. + enum_types_by_name (dict(str, EnumDescriptor)): Same + :class:`EnumDescriptor` objects as in :attr:`enum_types`, but + indexed by "name" attribute in each EnumDescriptor. + enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping + from enum value name to :class:`EnumValueDescriptor` for that value. + extensions (list[FieldDescriptor]): All extensions defined directly + within this message type (NOT within a nested type). + extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor + objects as :attr:`extensions`, but indexed by "name" attribute of each + FieldDescriptor. + is_extendable (bool): Does this type define any extension ranges? + oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields + in this message. + oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in + :attr:`oneofs`, but indexed by "name" attribute. + file (FileDescriptor): Reference to file descriptor. + """ if _USE_C_DESCRIPTORS: @@ -283,7 +292,7 @@ def __new__(cls, name, full_name, filename, containing_type, fields, serialized_options=None, is_extendable=True, extension_ranges=None, oneofs=None, file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin - syntax=None): + syntax=None, create_key=None): _message.Message._CheckCalledFromGeneratedFile() return _message.default_pool.FindMessageTypeByName(full_name) @@ -295,13 +304,16 @@ def __init__(self, name, full_name, filename, containing_type, fields, serialized_options=None, is_extendable=True, extension_ranges=None, oneofs=None, file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin - syntax=None): + syntax=None, create_key=None): """Arguments to __init__() are as described in the description of Descriptor fields above. Note that filename is an obsolete argument, that is not used anymore. Please use file.name to access this as an attribute. """ + if create_key is not _internal_create_key: + _Deprecated('Descriptor') + super(Descriptor, self).__init__( options, 'MessageOptions', name, full_name, file, containing_type, serialized_start=serialized_start, @@ -345,6 +357,9 @@ def __init__(self, name, full_name, filename, containing_type, fields, @property def fields_by_camelcase_name(self): + """Same FieldDescriptor objects as in :attr:`fields`, but indexed by + :attr:`FieldDescriptor.camelcase_name`. + """ if self._fields_by_camelcase_name is None: self._fields_by_camelcase_name = dict( (f.camelcase_name, f) for f in self.fields) @@ -393,53 +408,51 @@ class FieldDescriptor(DescriptorBase): """Descriptor for a single field in a .proto file. - A FieldDescriptor instance has the following attributes: - - name: (str) Name of this field, exactly as it appears in .proto. - full_name: (str) Name of this field, including containing scope. This is + Attributes: + name (str): Name of this field, exactly as it appears in .proto. + full_name (str): Name of this field, including containing scope. This is particularly relevant for extensions. - camelcase_name: (str) Camelcase name of this field. - index: (int) Dense, 0-indexed index giving the order that this + index (int): Dense, 0-indexed index giving the order that this field textually appears within its message in the .proto file. - number: (int) Tag number declared for this field in the .proto file. + number (int): Tag number declared for this field in the .proto file. - type: (One of the TYPE_* constants below) Declared type. - cpp_type: (One of the CPPTYPE_* constants below) C++ type used to + type (int): (One of the TYPE_* constants below) Declared type. + cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to represent this field. - label: (One of the LABEL_* constants below) Tells whether this + label (int): (One of the LABEL_* constants below) Tells whether this field is optional, required, or repeated. - has_default_value: (bool) True if this field has a default value defined, + has_default_value (bool): True if this field has a default value defined, otherwise false. - default_value: (Varies) Default value of this field. Only + default_value (Varies): Default value of this field. Only meaningful for non-repeated scalar fields. Repeated fields should always set this to [], and non-repeated composite fields should always set this to None. - containing_type: (Descriptor) Descriptor of the protocol message + containing_type (Descriptor): Descriptor of the protocol message type that contains this field. Set by the Descriptor constructor if we're passed into one. Somewhat confusingly, for extension fields, this is the descriptor of the EXTENDED message, not the descriptor of the message containing this field. (See is_extension and extension_scope below). - message_type: (Descriptor) If a composite field, a descriptor + message_type (Descriptor): If a composite field, a descriptor of the message type contained in this field. Otherwise, this is None. - enum_type: (EnumDescriptor) If this field contains an enum, a + enum_type (EnumDescriptor): If this field contains an enum, a descriptor of that enum. Otherwise, this is None. is_extension: True iff this describes an extension field. - extension_scope: (Descriptor) Only meaningful if is_extension is True. + extension_scope (Descriptor): Only meaningful if is_extension is True. Gives the message that immediately contains this extension field. Will be None iff we're a top-level (file-level) extension field. - options: (descriptor_pb2.FieldOptions) Protocol message field options or + options (descriptor_pb2.FieldOptions): Protocol message field options or None to use default field options. - containing_oneof: (OneofDescriptor) If the field is a member of a oneof + containing_oneof (OneofDescriptor): If the field is a member of a oneof union, contains its descriptor. Otherwise, None. - file: (FileDescriptor) Reference to file descriptor. + file (FileDescriptor): Reference to file descriptor. """ # Must be consistent with C++ FieldDescriptor::Type enum in @@ -526,7 +539,7 @@ def __new__(cls, name, full_name, index, number, type, cpp_type, label, is_extension, extension_scope, options=None, serialized_options=None, has_default_value=True, containing_oneof=None, json_name=None, - file=None): # pylint: disable=redefined-builtin + file=None, create_key=None): # pylint: disable=redefined-builtin _message.Message._CheckCalledFromGeneratedFile() if is_extension: return _message.default_pool.FindExtensionByName(full_name) @@ -538,7 +551,7 @@ def __init__(self, name, full_name, index, number, type, cpp_type, label, is_extension, extension_scope, options=None, serialized_options=None, has_default_value=True, containing_oneof=None, json_name=None, - file=None): # pylint: disable=redefined-builtin + file=None, create_key=None): # pylint: disable=redefined-builtin """The arguments are as described in the description of FieldDescriptor attributes above. @@ -546,6 +559,9 @@ def __init__(self, name, full_name, index, number, type, cpp_type, label, (to deal with circular references between message types, for example). Likewise for extension_scope. """ + if create_key is not _internal_create_key: + _Deprecated('FieldDescriptor') + super(FieldDescriptor, self).__init__( options, serialized_options, 'FieldOptions') self.name = name @@ -579,6 +595,11 @@ def __init__(self, name, full_name, index, number, type, cpp_type, label, @property def camelcase_name(self): + """Camelcase name of this field. + + Returns: + str: the name in CamelCase. + """ if self._camelcase_name is None: self._camelcase_name = _ToCamelCase(self.name) return self._camelcase_name @@ -594,7 +615,7 @@ def ProtoTypeToCppProtoType(proto_type): Args: proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) Returns: - descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. + int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. Raises: TypeTransformationError: when the Python proto type isn't known. """ @@ -608,24 +629,23 @@ class EnumDescriptor(_NestedDescriptorBase): """Descriptor for an enum defined in a .proto file. - An EnumDescriptor instance has the following attributes: - - name: (str) Name of the enum type. - full_name: (str) Full name of the type, including package name + Attributes: + name (str): Name of the enum type. + full_name (str): Full name of the type, including package name and any enclosing type(s). - values: (list of EnumValueDescriptors) List of the values + values (list[EnumValueDescriptors]): List of the values in this enum. - values_by_name: (dict str -> EnumValueDescriptor) Same as |values|, + values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, but indexed by the "name" field of each EnumValueDescriptor. - values_by_number: (dict int -> EnumValueDescriptor) Same as |values|, + values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`, but indexed by the "number" field of each EnumValueDescriptor. - containing_type: (Descriptor) Descriptor of the immediate containing + containing_type (Descriptor): Descriptor of the immediate containing type of this enum, or None if this is an enum defined at the top level in a .proto file. Set by Descriptor's constructor if we're passed into one. - file: (FileDescriptor) Reference to file descriptor. - options: (descriptor_pb2.EnumOptions) Enum options message or + file (FileDescriptor): Reference to file descriptor. + options (descriptor_pb2.EnumOptions): Enum options message or None to use default enum options. """ @@ -635,19 +655,22 @@ class EnumDescriptor(_NestedDescriptorBase): def __new__(cls, name, full_name, filename, values, containing_type=None, options=None, serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None): + serialized_start=None, serialized_end=None, create_key=None): _message.Message._CheckCalledFromGeneratedFile() return _message.default_pool.FindEnumTypeByName(full_name) def __init__(self, name, full_name, filename, values, containing_type=None, options=None, serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None): + serialized_start=None, serialized_end=None, create_key=None): """Arguments are as described in the attribute description above. Note that filename is an obsolete argument, that is not used anymore. Please use file.name to access this as an attribute. """ + if create_key is not _internal_create_key: + _Deprecated('EnumDescriptor') + super(EnumDescriptor, self).__init__( options, 'EnumOptions', name, full_name, file, containing_type, serialized_start=serialized_start, @@ -664,7 +687,7 @@ def CopyToProto(self, proto): """Copies this to a descriptor_pb2.EnumDescriptorProto. Args: - proto: An empty descriptor_pb2.EnumDescriptorProto. + proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. """ # This function is overridden to give a better doc comment. super(EnumDescriptor, self).CopyToProto(proto) @@ -674,14 +697,15 @@ class EnumValueDescriptor(DescriptorBase): """Descriptor for a single value within an enum. - name: (str) Name of this value. - index: (int) Dense, 0-indexed index giving the order that this + Attributes: + name (str): Name of this value. + index (int): Dense, 0-indexed index giving the order that this value appears textually within its enum in the .proto file. - number: (int) Actual number assigned to this enum value. - type: (EnumDescriptor) EnumDescriptor to which this value - belongs. Set by EnumDescriptor's constructor if we're + number (int): Actual number assigned to this enum value. + type (EnumDescriptor): :class:`EnumDescriptor` to which this value + belongs. Set by :class:`EnumDescriptor`'s constructor if we're passed into one. - options: (descriptor_pb2.EnumValueOptions) Enum value options message or + options (descriptor_pb2.EnumValueOptions): Enum value options message or None to use default enum value options options. """ @@ -690,7 +714,7 @@ class EnumValueDescriptor(DescriptorBase): def __new__(cls, name, index, number, type=None, # pylint: disable=redefined-builtin - options=None, serialized_options=None): + options=None, serialized_options=None, create_key=None): _message.Message._CheckCalledFromGeneratedFile() # There is no way we can build a complete EnumValueDescriptor with the # given parameters (the name of the Enum is not known, for example). @@ -700,8 +724,11 @@ def __new__(cls, name, index, number, def __init__(self, name, index, number, type=None, # pylint: disable=redefined-builtin - options=None, serialized_options=None): + options=None, serialized_options=None, create_key=None): """Arguments are as described in the attribute description above.""" + if create_key is not _internal_create_key: + _Deprecated('EnumValueDescriptor') + super(EnumValueDescriptor, self).__init__( options, serialized_options, 'EnumValueOptions') self.name = name @@ -713,14 +740,15 @@ def __init__(self, name, index, number, class OneofDescriptor(DescriptorBase): """Descriptor for a oneof field. - name: (str) Name of the oneof field. - full_name: (str) Full name of the oneof field, including package name. - index: (int) 0-based index giving the order of the oneof field inside + Attributes: + name (str): Name of the oneof field. + full_name (str): Full name of the oneof field, including package name. + index (int): 0-based index giving the order of the oneof field inside its containing type. - containing_type: (Descriptor) Descriptor of the protocol message - type that contains this field. Set by the Descriptor constructor + containing_type (Descriptor): :class:`Descriptor` of the protocol message + type that contains this field. Set by the :class:`Descriptor` constructor if we're passed into one. - fields: (list of FieldDescriptor) The list of field descriptors this + fields (list[FieldDescriptor]): The list of field descriptors this oneof can contain. """ @@ -729,14 +757,17 @@ class OneofDescriptor(DescriptorBase): def __new__( cls, name, full_name, index, containing_type, fields, options=None, - serialized_options=None): + serialized_options=None, create_key=None): _message.Message._CheckCalledFromGeneratedFile() return _message.default_pool.FindOneofByName(full_name) def __init__( self, name, full_name, index, containing_type, fields, options=None, - serialized_options=None): + serialized_options=None, create_key=None): """Arguments are as described in the attribute description above.""" + if create_key is not _internal_create_key: + _Deprecated('OneofDescriptor') + super(OneofDescriptor, self).__init__( options, serialized_options, 'OneofOptions') self.name = name @@ -750,18 +781,19 @@ class ServiceDescriptor(_NestedDescriptorBase): """Descriptor for a service. - name: (str) Name of the service. - full_name: (str) Full name of the service, including package name. - index: (int) 0-indexed index giving the order that this services + Attributes: + name (str): Name of the service. + full_name (str): Full name of the service, including package name. + index (int): 0-indexed index giving the order that this services definition appears within the .proto file. - methods: (list of MethodDescriptor) List of methods provided by this + methods (list[MethodDescriptor]): List of methods provided by this service. - methods_by_name: (dict str -> MethodDescriptor) Same MethodDescriptor - objects as in |methods_by_name|, but indexed by "name" attribute in each - MethodDescriptor. - options: (descriptor_pb2.ServiceOptions) Service options message or + methods_by_name (dict(str, MethodDescriptor)): Same + :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but + indexed by "name" attribute in each :class:`MethodDescriptor`. + options (descriptor_pb2.ServiceOptions): Service options message or None to use default service options. - file: (FileDescriptor) Reference to file info. + file (FileDescriptor): Reference to file info. """ if _USE_C_DESCRIPTORS: @@ -769,13 +801,16 @@ class ServiceDescriptor(_NestedDescriptorBase): def __new__(cls, name, full_name, index, methods, options=None, serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None): + serialized_start=None, serialized_end=None, create_key=None): _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access return _message.default_pool.FindServiceByName(full_name) def __init__(self, name, full_name, index, methods, options=None, serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None): + serialized_start=None, serialized_end=None, create_key=None): + if create_key is not _internal_create_key: + _Deprecated('ServiceDescriptor') + super(ServiceDescriptor, self).__init__( options, 'ServiceOptions', name, full_name, file, None, serialized_start=serialized_start, @@ -788,14 +823,21 @@ def __init__(self, name, full_name, index, methods, options=None, method.containing_service = self def FindMethodByName(self, name): - """Searches for the specified method, and returns its descriptor.""" + """Searches for the specified method, and returns its descriptor. + + Args: + name (str): Name of the method. + Returns: + MethodDescriptor or None: the descriptor for the requested method, if + found. + """ return self.methods_by_name.get(name, None) def CopyToProto(self, proto): """Copies this to a descriptor_pb2.ServiceDescriptorProto. Args: - proto: An empty descriptor_pb2.ServiceDescriptorProto. + proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. """ # This function is overridden to give a better doc comment. super(ServiceDescriptor, self).CopyToProto(proto) @@ -805,32 +847,40 @@ class MethodDescriptor(DescriptorBase): """Descriptor for a method in a service. - name: (str) Name of the method within the service. - full_name: (str) Full name of method. - index: (int) 0-indexed index of the method inside the service. - containing_service: (ServiceDescriptor) The service that contains this - method. - input_type: The descriptor of the message that this method accepts. - output_type: The descriptor of the message that this method returns. - options: (descriptor_pb2.MethodOptions) Method options message or - None to use default method options. + Attributes: + name (str): Name of the method within the service. + full_name (str): Full name of method. + index (int): 0-indexed index of the method inside the service. + containing_service (ServiceDescriptor): The service that contains this + method. + input_type (Descriptor): The descriptor of the message that this method + accepts. + output_type (Descriptor): The descriptor of the message that this method + returns. + options (descriptor_pb2.MethodOptions or None): Method options message, or + None to use default method options. """ if _USE_C_DESCRIPTORS: _C_DESCRIPTOR_CLASS = _message.MethodDescriptor def __new__(cls, name, full_name, index, containing_service, - input_type, output_type, options=None, serialized_options=None): + input_type, output_type, options=None, serialized_options=None, + create_key=None): _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access return _message.default_pool.FindMethodByName(full_name) def __init__(self, name, full_name, index, containing_service, - input_type, output_type, options=None, serialized_options=None): + input_type, output_type, options=None, serialized_options=None, + create_key=None): """The arguments are as described in the description of MethodDescriptor attributes above. Note that containing_service may be None, and may be set later if necessary. """ + if create_key is not _internal_create_key: + _Deprecated('MethodDescriptor') + super(MethodDescriptor, self).__init__( options, serialized_options, 'MethodOptions') self.name = name @@ -844,24 +894,32 @@ def __init__(self, name, full_name, index, containing_service, class FileDescriptor(DescriptorBase): """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. - Note that enum_types_by_name, extensions_by_name, and dependencies - fields are only set by the message_factory module, and not by the - generated proto code. - - name: name of file, relative to root of source tree. - package: name of the package - syntax: string indicating syntax of the file (can be "proto2" or "proto3") - serialized_pb: (str) Byte string of serialized - descriptor_pb2.FileDescriptorProto. - dependencies: List of other FileDescriptors this FileDescriptor depends on. - public_dependencies: A list of FileDescriptors, subset of the dependencies - above, which were declared as "public". - message_types_by_name: Dict of message names and their descriptors. - enum_types_by_name: Dict of enum names and their descriptors. - extensions_by_name: Dict of extension names and their descriptors. - services_by_name: Dict of services names and their descriptors. - pool: the DescriptorPool this descriptor belongs to. When not passed to the - constructor, the global default pool is used. + Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and + :attr:`dependencies` fields are only set by the + :py:mod:`google.protobuf.message_factory` module, and not by the generated + proto code. + + Attributes: + name (str): Name of file, relative to root of source tree. + package (str): Name of the package + syntax (str): string indicating syntax of the file (can be "proto2" or + "proto3") + serialized_pb (bytes): Byte string of serialized + :class:`descriptor_pb2.FileDescriptorProto`. + dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` + objects this :class:`FileDescriptor` depends on. + public_dependencies (list[FileDescriptor]): A subset of + :attr:`dependencies`, which were declared as "public". + message_types_by_name (dict(str, Descriptor)): Mapping from message names + to their :class:`Desctiptor`. + enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to + their :class:`EnumDescriptor`. + extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension + names declared at file scope to their :class:`FieldDescriptor`. + services_by_name (dict(str, ServiceDescriptor)): Mapping from services' + names to their :class:`ServiceDescriptor`. + pool (DescriptorPool): The pool this descriptor belongs to. When not + passed to the constructor, the global default pool is used. """ if _USE_C_DESCRIPTORS: @@ -870,11 +928,11 @@ class FileDescriptor(DescriptorBase): def __new__(cls, name, package, options=None, serialized_options=None, serialized_pb=None, dependencies=None, public_dependencies=None, - syntax=None, pool=None): + syntax=None, pool=None, create_key=None): # FileDescriptor() is called from various places, not only from generated # files, to register dynamic proto files and messages. # pylint: disable=g-explicit-bool-comparison - if serialized_pb == '': + if serialized_pb == b'': # Cpp generated code must be linked in if serialized_pb is '' try: return _message.default_pool.FindFileByName(name) @@ -888,8 +946,11 @@ def __new__(cls, name, package, options=None, def __init__(self, name, package, options=None, serialized_options=None, serialized_pb=None, dependencies=None, public_dependencies=None, - syntax=None, pool=None): + syntax=None, pool=None, create_key=None): """Constructor.""" + if create_key is not _internal_create_key: + _Deprecated('FileDescriptor') + super(FileDescriptor, self).__init__( options, serialized_options, 'FileOptions') @@ -1028,9 +1089,11 @@ def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, for enum_proto in desc_proto.enum_type: full_name = '.'.join(full_message_name + [enum_proto.name]) enum_desc = EnumDescriptor( - enum_proto.name, full_name, None, [ - EnumValueDescriptor(enum_val.name, ii, enum_val.number) - for ii, enum_val in enumerate(enum_proto.value)]) + enum_proto.name, full_name, None, [ + EnumValueDescriptor(enum_val.name, ii, enum_val.number, + create_key=_internal_create_key) + for ii, enum_val in enumerate(enum_proto.value)], + create_key=_internal_create_key) enum_types[full_name] = enum_desc # Create Descriptors for nested types @@ -1069,10 +1132,11 @@ def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), field_proto.label, None, nested_desc, enum_desc, None, False, None, options=_OptionsOrNone(field_proto), has_default_value=False, - json_name=json_name) + json_name=json_name, create_key=_internal_create_key) fields.append(field) desc_name = '.'.join(full_message_name) return Descriptor(desc_proto.name, desc_name, None, None, fields, list(nested_types.values()), list(enum_types.values()), [], - options=_OptionsOrNone(desc_proto)) + options=_OptionsOrNone(desc_proto), + create_key=_internal_create_key) diff --git a/python/google/protobuf/descriptor_database.py b/python/google/protobuf/descriptor_database.py index 5453f50c80b4..073eddc71157 100644 --- a/python/google/protobuf/descriptor_database.py +++ b/python/google/protobuf/descriptor_database.py @@ -58,7 +58,7 @@ def Add(self, file_desc_proto): Raises: DescriptorDatabaseConflictingDefinitionError: if an attempt is made to add a proto with the same name but different definition than an - exisiting proto in the database. + existing proto in the database. """ proto_name = file_desc_proto.name if proto_name not in self._file_desc_protos_by_file: diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index 9a4f1cc27196..de9100b09ca5 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -38,7 +38,7 @@ the protocol buffer compiler tool. This should only be used when the type of protocol buffers used in an application or library cannot be predetermined. -Below is a straightforward example on how to use this class: +Below is a straightforward example on how to use this class:: pool = DescriptorPool() file_descriptor_protos = [ ... ] @@ -91,10 +91,10 @@ def _NormalizeFullyQualifiedName(name): generated with a leading period. This function removes that prefix. Args: - name: A str, the fully-qualified symbol name. + name (str): The fully-qualified symbol name. Returns: - A str, the normalized fully-qualified symbol name. + str: The normalized fully-qualified symbol name. """ return name.lstrip('.') @@ -159,8 +159,8 @@ def _CheckConflictRegister(self, desc, desc_name, file_name): Args: desc: Descriptor of a message, enum, service, extension or enum value. - desc_name: the full name of desc. - file_name: The file name of descriptor. + desc_name (str): the full name of desc. + file_name (str): The file name of descriptor. """ for register, descriptor_type in [ (self._descriptors, descriptor.Descriptor), @@ -196,7 +196,7 @@ def Add(self, file_desc_proto): """Adds the FileDescriptorProto and its types to this pool. Args: - file_desc_proto: The FileDescriptorProto to add. + file_desc_proto (FileDescriptorProto): The file descriptor to add. """ self._internal_db.Add(file_desc_proto) @@ -205,8 +205,8 @@ def AddSerializedFile(self, serialized_file_desc_proto): """Adds the FileDescriptorProto and its types to this pool. Args: - serialized_file_desc_proto: A bytes string, serialization of the - FileDescriptorProto to add. + serialized_file_desc_proto (bytes): A bytes string, serialization of the + :class:`FileDescriptorProto` to add. """ # pylint: disable=g-import-not-at-top @@ -392,10 +392,10 @@ def FindFileByName(self, file_name): """Gets a FileDescriptor by file name. Args: - file_name: The path to the file to get a descriptor for. + file_name (str): The path to the file to get a descriptor for. Returns: - A FileDescriptor for the named file. + FileDescriptor: The descriptor for the named file. Raises: KeyError: if the file cannot be found in the pool. @@ -421,10 +421,11 @@ def FindFileContainingSymbol(self, symbol): """Gets the FileDescriptor for the file containing the specified symbol. Args: - symbol: The name of the symbol to search for. + symbol (str): The name of the symbol to search for. Returns: - A FileDescriptor that contains the specified symbol. + FileDescriptor: Descriptor for the file that contains the specified + symbol. Raises: KeyError: if the file cannot be found in the pool. @@ -447,10 +448,11 @@ def _InternalFindFileContainingSymbol(self, symbol): """Gets the already built FileDescriptor containing the specified symbol. Args: - symbol: The name of the symbol to search for. + symbol (str): The name of the symbol to search for. Returns: - A FileDescriptor that contains the specified symbol. + FileDescriptor: Descriptor for the file that contains the specified + symbol. Raises: KeyError: if the file cannot be found in the pool. @@ -495,10 +497,10 @@ def FindMessageTypeByName(self, full_name): """Loads the named descriptor from the pool. Args: - full_name: The full name of the descriptor to load. + full_name (str): The full name of the descriptor to load. Returns: - The descriptor for the named type. + Descriptor: The descriptor for the named type. Raises: KeyError: if the message cannot be found in the pool. @@ -513,10 +515,10 @@ def FindEnumTypeByName(self, full_name): """Loads the named enum descriptor from the pool. Args: - full_name: The full name of the enum descriptor to load. + full_name (str): The full name of the enum descriptor to load. Returns: - The enum descriptor for the named type. + EnumDescriptor: The enum descriptor for the named type. Raises: KeyError: if the enum cannot be found in the pool. @@ -531,10 +533,10 @@ def FindFieldByName(self, full_name): """Loads the named field descriptor from the pool. Args: - full_name: The full name of the field descriptor to load. + full_name (str): The full name of the field descriptor to load. Returns: - The field descriptor for the named field. + FieldDescriptor: The field descriptor for the named field. Raises: KeyError: if the field cannot be found in the pool. @@ -548,10 +550,10 @@ def FindOneofByName(self, full_name): """Loads the named oneof descriptor from the pool. Args: - full_name: The full name of the oneof descriptor to load. + full_name (str): The full name of the oneof descriptor to load. Returns: - The oneof descriptor for the named oneof. + OneofDescriptor: The oneof descriptor for the named oneof. Raises: KeyError: if the oneof cannot be found in the pool. @@ -565,10 +567,10 @@ def FindExtensionByName(self, full_name): """Loads the named extension descriptor from the pool. Args: - full_name: The full name of the extension descriptor to load. + full_name (str): The full name of the extension descriptor to load. Returns: - A FieldDescriptor, describing the named extension. + FieldDescriptor: The field descriptor for the named extension. Raises: KeyError: if the extension cannot be found in the pool. @@ -594,15 +596,15 @@ def FindExtensionByName(self, full_name): def FindExtensionByNumber(self, message_descriptor, number): """Gets the extension of the specified message with the specified number. - Extensions have to be registered to this pool by calling - AddExtensionDescriptor. + Extensions have to be registered to this pool by calling :func:`Add` or + :func:`AddExtensionDescriptor`. Args: - message_descriptor: descriptor of the extended message. - number: integer, number of the extension field. + message_descriptor (Descriptor): descriptor of the extended message. + number (int): Number of the extension field. Returns: - A FieldDescriptor describing the extension. + FieldDescriptor: The descriptor for the extension. Raises: KeyError: when no extension with the given number is known for the @@ -615,16 +617,16 @@ def FindExtensionByNumber(self, message_descriptor, number): return self._extensions_by_number[message_descriptor][number] def FindAllExtensions(self, message_descriptor): - """Gets all the known extension of a given message. + """Gets all the known extensions of a given message. - Extensions have to be registered to this pool by calling - AddExtensionDescriptor. + Extensions have to be registered to this pool by build related + :func:`Add` or :func:`AddExtensionDescriptor`. Args: - message_descriptor: descriptor of the extended message. + message_descriptor (Descriptor): Descriptor of the extended message. Returns: - A list of FieldDescriptor describing the extensions. + list[FieldDescriptor]: Field descriptors describing the extensions. """ # Fallback to descriptor db if FindAllExtensionNumbers is provided. if self._descriptor_db and hasattr( @@ -660,18 +662,7 @@ def _TryLoadExtensionFromDB(self, message_descriptor, number): return try: - file_desc = self._ConvertFileProtoToFileDescriptor(file_proto) - for extension in file_desc.extensions_by_name.values(): - self._extensions_by_number[extension.containing_type][ - extension.number] = extension - self._extensions_by_name[extension.containing_type][ - extension.full_name] = extension - for message_type in file_desc.message_types_by_name.values(): - for extension in message_type.extensions: - self._extensions_by_number[extension.containing_type][ - extension.number] = extension - self._extensions_by_name[extension.containing_type][ - extension.full_name] = extension + self._ConvertFileProtoToFileDescriptor(file_proto) except: warn_msg = ('Unable to load proto file %s for extension number %d.' % (file_proto.name, number)) @@ -681,10 +672,10 @@ def FindServiceByName(self, full_name): """Loads the named service descriptor from the pool. Args: - full_name: The full name of the service descriptor to load. + full_name (str): The full name of the service descriptor to load. Returns: - The service descriptor for the named service. + ServiceDescriptor: The service descriptor for the named service. Raises: KeyError: if the service cannot be found in the pool. @@ -698,10 +689,10 @@ def FindMethodByName(self, full_name): """Loads the named service method descriptor from the pool. Args: - full_name: The full name of the method descriptor to load. + full_name (str): The full name of the method descriptor to load. Returns: - The method descriptor for the service method. + MethodDescriptor: The method descriptor for the service method. Raises: KeyError: if the method cannot be found in the pool. @@ -715,10 +706,10 @@ def _FindFileContainingSymbolInDb(self, symbol): """Finds the file in descriptor DB containing the specified symbol. Args: - symbol: The name of the symbol to search for. + symbol (str): The name of the symbol to search for. Returns: - A FileDescriptor that contains the specified symbol. + FileDescriptor: The file that contains the specified symbol. Raises: KeyError: if the file cannot be found in the descriptor database. @@ -759,7 +750,9 @@ def _ConvertFileProtoToFileDescriptor(self, file_proto): options=_OptionsOrNone(file_proto), serialized_pb=file_proto.SerializeToString(), dependencies=direct_deps, - public_dependencies=public_deps) + public_dependencies=public_deps, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) scope = {} # This loop extracts all the message and enum types from all the @@ -818,7 +811,15 @@ def _ConvertFileProtoToFileDescriptor(self, file_proto): self.Add(file_proto) self._file_descriptors[file_proto.name] = file_descriptor - return self._file_descriptors[file_proto.name] + # Add extensions to the pool + file_desc = self._file_descriptors[file_proto.name] + for extension in file_desc.extensions_by_name.values(): + self._AddExtensionDescriptor(extension) + for message_type in file_desc.message_types_by_name.values(): + for extension in message_type.extensions: + self._AddExtensionDescriptor(extension) + + return file_desc def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, scope=None, syntax=None): @@ -863,8 +864,11 @@ def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, is_extension=True) for index, extension in enumerate(desc_proto.extension)] oneofs = [ + # pylint: disable=g-complex-comprehension descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)), - index, None, [], desc.options) + index, None, [], desc.options, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) for index, desc in enumerate(desc_proto.oneof_decl)] extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] if extension_ranges: @@ -887,7 +891,9 @@ def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, file=file_desc, serialized_start=None, serialized_end=None, - syntax=syntax) + syntax=syntax, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) for nested in desc.nested_types: nested.containing_type = desc for enum in desc.enum_types: @@ -938,7 +944,9 @@ def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None, file=file_desc, values=values, containing_type=containing_type, - options=_OptionsOrNone(enum_proto)) + options=_OptionsOrNone(enum_proto), + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) scope['.%s' % enum_name] = desc self._CheckConflictRegister(desc, desc.full_name, desc.file.name) self._enum_descriptors[enum_name] = desc @@ -995,7 +1003,9 @@ def _MakeFieldDescriptor(self, field_proto, message_name, index, is_extension=is_extension, extension_scope=None, options=_OptionsOrNone(field_proto), - file=file_desc) + file=file_desc, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) def _SetAllFieldTypes(self, package, desc_proto, scope): """Sets all the descriptor's fields's types. @@ -1119,7 +1129,9 @@ def _MakeEnumValueDescriptor(self, value_proto, index): index=index, number=value_proto.number, options=_OptionsOrNone(value_proto), - type=None) + type=None, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) def _MakeServiceDescriptor(self, service_proto, service_index, scope, package, file_desc): @@ -1144,12 +1156,15 @@ def _MakeServiceDescriptor(self, service_proto, service_index, scope, methods = [self._MakeMethodDescriptor(method_proto, service_name, package, scope, index) for index, method_proto in enumerate(service_proto.method)] - desc = descriptor.ServiceDescriptor(name=service_proto.name, - full_name=service_name, - index=service_index, - methods=methods, - options=_OptionsOrNone(service_proto), - file=file_desc) + desc = descriptor.ServiceDescriptor( + name=service_proto.name, + full_name=service_name, + index=service_index, + methods=methods, + options=_OptionsOrNone(service_proto), + file=file_desc, + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) self._CheckConflictRegister(desc, desc.full_name, desc.file.name) self._service_descriptors[service_name] = desc return desc @@ -1173,13 +1188,16 @@ def _MakeMethodDescriptor(self, method_proto, service_name, package, scope, package, method_proto.input_type, scope) output_type = self._GetTypeFromScope( package, method_proto.output_type, scope) - return descriptor.MethodDescriptor(name=method_proto.name, - full_name=full_name, - index=index, - containing_service=None, - input_type=input_type, - output_type=output_type, - options=_OptionsOrNone(method_proto)) + return descriptor.MethodDescriptor( + name=method_proto.name, + full_name=full_name, + index=index, + containing_service=None, + input_type=input_type, + output_type=output_type, + options=_OptionsOrNone(method_proto), + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) def _ExtractSymbols(self, descriptors): """Pulls out all the symbols from descriptor protos. diff --git a/python/google/protobuf/internal/__init__.py b/python/google/protobuf/internal/__init__.py old mode 100755 new mode 100644 diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py old mode 100755 new mode 100644 index e8448e88a62b..7592be4eed3d --- a/python/google/protobuf/internal/api_implementation.py +++ b/python/google/protobuf/internal/api_implementation.py @@ -60,11 +60,16 @@ raise ImportError('_use_fast_cpp_protos import succeeded but was None') del _use_fast_cpp_protos _api_version = 2 + # Can not import both use_fast_cpp_protos and use_pure_python. + from google.protobuf import use_pure_python + raise RuntimeError( + 'Conflict depend on both use_fast_cpp_protos and use_pure_python') except ImportError: try: # pylint: disable=g-import-not-at-top - from google.protobuf.internal import use_pure_python + from google.protobuf import use_pure_python del use_pure_python # Avoids a pylint error and namespace pollution. + _api_version = 0 except ImportError: # TODO(b/74017912): It's unsafe to enable :use_fast_cpp_protos by default; # it can cause data loss if you have any Python-only extensions to any diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py old mode 100755 new mode 100644 index 173666f8b8e0..92793490bbc3 --- a/python/google/protobuf/internal/containers.py +++ b/python/google/protobuf/internal/containers.py @@ -33,9 +33,10 @@ This file defines container classes which represent categories of protocol buffer field types which need extra maintenance. Currently these categories are: - - Repeated scalar fields - These are all repeated fields which aren't + +- Repeated scalar fields - These are all repeated fields which aren't composite (e.g. they are of simple types like int32, string, etc). - - Repeated composite fields - Repeated fields which are composite. This +- Repeated composite fields - Repeated fields which are composite. This includes groups and nested messages. """ @@ -230,6 +231,9 @@ def sort(self, *args, **kwargs): kwargs['cmp'] = kwargs.pop('sort_function') self._values.sort(*args, **kwargs) + def reverse(self): + self._values.reverse() + collections_abc.MutableSequence.register(BaseContainer) @@ -285,7 +289,6 @@ def extend(self, elem_seq): def MergeFrom(self, other): """Appends the contents of another repeated field of the same type to this - one. We do not check the types of the individual fields. """ self._values.extend(other._values) @@ -416,7 +419,6 @@ def extend(self, elem_seq): def MergeFrom(self, other): """Appends the contents of another repeated field of the same type to this - one, copying each individual message. """ self.extend(other._values) @@ -630,7 +632,8 @@ def __repr__(self): return repr(self._values) def MergeFrom(self, other): - for key in other: + # pylint: disable=protected-access + for key in other._values: # According to documentation: "When parsing from the wire or when merging, # if there are duplicate map keys the last key seen is used". if key in self: diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py old mode 100755 new mode 100644 index c04df8e294a1..6804986b6ebe --- a/python/google/protobuf/internal/decoder.py +++ b/python/google/protobuf/internal/decoder.py @@ -209,7 +209,8 @@ def _SimpleDecoder(wire_type, decode_value): _DecodeVarint() """ - def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default): + def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default, + clear_if_default=False): if is_packed: local_DecodeVarint = _DecodeVarint def DecodePackedField(buffer, pos, end, message, field_dict): @@ -249,10 +250,13 @@ def DecodeRepeatedField(buffer, pos, end, message, field_dict): return DecodeRepeatedField else: def DecodeField(buffer, pos, end, message, field_dict): - (field_dict[key], pos) = decode_value(buffer, pos) + (new_value, pos) = decode_value(buffer, pos) if pos > end: - del field_dict[key] # Discard corrupt value. raise _DecodeError('Truncated message.') + if clear_if_default and not new_value: + field_dict.pop(key, None) + else: + field_dict[key] = new_value return pos return DecodeField @@ -383,7 +387,9 @@ def InnerDecode(buffer, pos): return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode) -def EnumDecoder(field_number, is_repeated, is_packed, key, new_default): +def EnumDecoder(field_number, is_repeated, is_packed, key, new_default, + clear_if_default=False): + """Returns a decoder for enum field.""" enum_type = key.enum_type if is_packed: local_DecodeVarint = _DecodeVarint @@ -498,6 +504,9 @@ def DecodeField(buffer, pos, end, message, field_dict): (enum_value, pos) = _DecodeSignedVarint32(buffer, pos) if pos > end: raise _DecodeError('Truncated message.') + if clear_if_default and not enum_value: + field_dict.pop(key, None) + return pos # pylint: disable=protected-access if enum_value in enum_type.values_by_number: field_dict[key] = enum_value @@ -550,7 +559,7 @@ def DecodeField(buffer, pos, end, message, field_dict): def StringDecoder(field_number, is_repeated, is_packed, key, new_default, - is_strict_utf8=False): + is_strict_utf8=False, clear_if_default=False): """Returns a decoder for a string field.""" local_DecodeVarint = _DecodeVarint @@ -604,12 +613,16 @@ def DecodeField(buffer, pos, end, message, field_dict): new_pos = pos + size if new_pos > end: raise _DecodeError('Truncated string.') - field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) + if clear_if_default and not size: + field_dict.pop(key, None) + else: + field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) return new_pos return DecodeField -def BytesDecoder(field_number, is_repeated, is_packed, key, new_default): +def BytesDecoder(field_number, is_repeated, is_packed, key, new_default, + clear_if_default=False): """Returns a decoder for a bytes field.""" local_DecodeVarint = _DecodeVarint @@ -641,7 +654,10 @@ def DecodeField(buffer, pos, end, message, field_dict): new_pos = pos + size if new_pos > end: raise _DecodeError('Truncated string.') - field_dict[key] = buffer[pos:new_pos].tobytes() + if clear_if_default and not size: + field_dict.pop(key, None) + else: + field_dict[key] = buffer[pos:new_pos].tobytes() return new_pos return DecodeField @@ -816,8 +832,12 @@ def DecodeItem(buffer, pos, end, message, field_dict): if extension is not None: value = field_dict.get(extension) if value is None: + message_type = extension.message_type + if not hasattr(message_type, '_concrete_class'): + # pylint: disable=protected-access + message._FACTORY.GetPrototype(message_type) value = field_dict.setdefault( - extension, extension.message_type._concrete_class()) + extension, message_type._concrete_class()) if value._InternalParse(buffer, message_start,message_end) != message_end: # The only reason _InternalParse would return early is if it encountered # an end-group tag. diff --git a/python/google/protobuf/internal/descriptor_database_test.py b/python/google/protobuf/internal/descriptor_database_test.py old mode 100644 new mode 100755 diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py old mode 100644 new mode 100755 index ad1eb653fd78..fed82bfc7ab7 --- a/python/google/protobuf/internal/descriptor_pool_test.py +++ b/python/google/protobuf/internal/descriptor_pool_test.py @@ -36,6 +36,7 @@ import copy import os +import warnings try: import unittest2 as unittest #PY26 @@ -63,6 +64,9 @@ +warnings.simplefilter('error', DeprecationWarning) + + class DescriptorPoolTestBase(object): def testFindFileByName(self): @@ -336,12 +340,10 @@ def testFindAllExtensions(self): 'google.protobuf.python.internal.Factory2Message') # An extension defined in a message. one_more_field = factory2_message.extensions_by_name['one_more_field'] - self.pool.AddExtensionDescriptor(one_more_field) # An extension defined at file scope. factory_test2 = self.pool.FindFileByName( 'google/protobuf/internal/factory_test2.proto') another_field = factory_test2.extensions_by_name['another_field'] - self.pool.AddExtensionDescriptor(another_field) extensions = self.pool.FindAllExtensions(factory1_message) expected_extension_numbers = set([one_more_field, another_field]) @@ -356,16 +358,9 @@ def testFindAllExtensions(self): def testFindExtensionByNumber(self): factory1_message = self.pool.FindMessageTypeByName( 'google.protobuf.python.internal.Factory1Message') - factory2_message = self.pool.FindMessageTypeByName( - 'google.protobuf.python.internal.Factory2Message') - # An extension defined in a message. - one_more_field = factory2_message.extensions_by_name['one_more_field'] - self.pool.AddExtensionDescriptor(one_more_field) - # An extension defined at file scope. - factory_test2 = self.pool.FindFileByName( + # Build factory_test2.proto which will put extensions to the pool + self.pool.FindFileByName( 'google/protobuf/internal/factory_test2.proto') - another_field = factory_test2.extensions_by_name['another_field'] - self.pool.AddExtensionDescriptor(another_field) # An extension defined in a message. extension = self.pool.FindExtensionByNumber(factory1_message, 1001) @@ -533,13 +528,13 @@ def testConflictRegister(self): else: pool = copy.deepcopy(self.pool) file_descriptor = unittest_pb2.DESCRIPTOR - pool.AddDescriptor( + pool._AddDescriptor( file_descriptor.message_types_by_name['TestAllTypes']) - pool.AddEnumDescriptor( + pool._AddEnumDescriptor( file_descriptor.enum_types_by_name['ForeignEnum']) - pool.AddServiceDescriptor( + pool._AddServiceDescriptor( file_descriptor.services_by_name['TestService']) - pool.AddExtensionDescriptor( + pool._AddExtensionDescriptor( file_descriptor.extensions_by_name['optional_int32_extension']) pool.Add(unittest_fd) pool.Add(conflict_fd) @@ -873,7 +868,7 @@ class AddDescriptorTest(unittest.TestCase): def _TestMessage(self, prefix): pool = descriptor_pool.DescriptorPool() - pool.AddDescriptor(unittest_pb2.TestAllTypes.DESCRIPTOR) + pool._AddDescriptor(unittest_pb2.TestAllTypes.DESCRIPTOR) self.assertEqual( 'protobuf_unittest.TestAllTypes', pool.FindMessageTypeByName( @@ -884,7 +879,7 @@ def _TestMessage(self, prefix): pool.FindMessageTypeByName( prefix + 'protobuf_unittest.TestAllTypes.NestedMessage') - pool.AddDescriptor(unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR) + pool._AddDescriptor(unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR) self.assertEqual( 'protobuf_unittest.TestAllTypes.NestedMessage', pool.FindMessageTypeByName( @@ -909,7 +904,10 @@ def testMessage(self): def _TestEnum(self, prefix): pool = descriptor_pool.DescriptorPool() - pool.AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR) + if api_implementation.Type() == 'cpp': + pool.AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR) + else: + pool._AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR) self.assertEqual( 'protobuf_unittest.ForeignEnum', pool.FindEnumTypeByName( @@ -920,7 +918,10 @@ def _TestEnum(self, prefix): pool.FindEnumTypeByName( prefix + 'protobuf_unittest.ForeignEnum.NestedEnum') - pool.AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR) + if api_implementation.Type() == 'cpp': + pool.AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR) + else: + pool._AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR) self.assertEqual( 'protobuf_unittest.TestAllTypes.NestedEnum', pool.FindEnumTypeByName( @@ -949,7 +950,7 @@ def testService(self): pool = descriptor_pool.DescriptorPool() with self.assertRaises(KeyError): pool.FindServiceByName('protobuf_unittest.TestService') - pool.AddServiceDescriptor(unittest_pb2._TESTSERVICE) + pool._AddServiceDescriptor(unittest_pb2._TESTSERVICE) self.assertEqual( 'protobuf_unittest.TestService', pool.FindServiceByName('protobuf_unittest.TestService').full_name) @@ -958,7 +959,7 @@ def testService(self): 'With the cpp implementation, Add() must be called first') def testFile(self): pool = descriptor_pool.DescriptorPool() - pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR) + pool._AddFileDescriptor(unittest_pb2.DESCRIPTOR) self.assertEqual( 'google/protobuf/unittest.proto', pool.FindFileByName( @@ -1032,16 +1033,28 @@ def testFileDescriptorOptionsWithCustomDescriptorPool(self): def testAddTypeError(self): pool = descriptor_pool.DescriptorPool() - with self.assertRaises(TypeError): - pool.AddDescriptor(0) - with self.assertRaises(TypeError): - pool.AddEnumDescriptor(0) - with self.assertRaises(TypeError): - pool.AddServiceDescriptor(0) - with self.assertRaises(TypeError): - pool.AddExtensionDescriptor(0) - with self.assertRaises(TypeError): - pool.AddFileDescriptor(0) + if api_implementation.Type() == 'cpp': + with self.assertRaises(TypeError): + pool.AddDescriptor(0) + with self.assertRaises(TypeError): + pool.AddEnumDescriptor(0) + with self.assertRaises(TypeError): + pool.AddServiceDescriptor(0) + with self.assertRaises(TypeError): + pool.AddExtensionDescriptor(0) + with self.assertRaises(TypeError): + pool.AddFileDescriptor(0) + else: + with self.assertRaises(TypeError): + pool._AddDescriptor(0) + with self.assertRaises(TypeError): + pool._AddEnumDescriptor(0) + with self.assertRaises(TypeError): + pool._AddServiceDescriptor(0) + with self.assertRaises(TypeError): + pool._AddExtensionDescriptor(0) + with self.assertRaises(TypeError): + pool._AddFileDescriptor(0) TEST1_FILE = ProtoFile( diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index bff2d5f54881..5e3b0a9b4c9a 100755 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -35,6 +35,7 @@ __author__ = 'robinson@google.com (Will Robinson)' import sys +import warnings try: import unittest2 as unittest #PY26 @@ -58,6 +59,9 @@ """ +warnings.simplefilter('error', DeprecationWarning) + + class DescriptorTest(unittest.TestCase): def setUp(self): diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py old mode 100755 new mode 100644 index 0d1f49dd9c68..0c016f3cfafd --- a/python/google/protobuf/internal/encoder.py +++ b/python/google/protobuf/internal/encoder.py @@ -372,14 +372,15 @@ def FieldSize(map_value): def _VarintEncoder(): """Return an encoder for a basic varint value (does not include tag).""" + local_int2byte = six.int2byte def EncodeVarint(write, value, unused_deterministic=None): bits = value & 0x7f value >>= 7 while value: - write(six.int2byte(0x80|bits)) + write(local_int2byte(0x80|bits)) bits = value & 0x7f value >>= 7 - return write(six.int2byte(bits)) + return write(local_int2byte(bits)) return EncodeVarint @@ -388,16 +389,17 @@ def _SignedVarintEncoder(): """Return an encoder for a basic signed varint value (does not include tag).""" + local_int2byte = six.int2byte def EncodeSignedVarint(write, value, unused_deterministic=None): if value < 0: value += (1 << 64) bits = value & 0x7f value >>= 7 while value: - write(six.int2byte(0x80|bits)) + write(local_int2byte(0x80|bits)) bits = value & 0x7f value >>= 7 - return write(six.int2byte(bits)) + return write(local_int2byte(bits)) return EncodeSignedVarint diff --git a/python/google/protobuf/internal/enum_type_wrapper.py b/python/google/protobuf/internal/enum_type_wrapper.py index eeb2dae90f48..9ae006658499 100644 --- a/python/google/protobuf/internal/enum_type_wrapper.py +++ b/python/google/protobuf/internal/enum_type_wrapper.py @@ -48,32 +48,38 @@ class EnumTypeWrapper(object): def __init__(self, enum_type): """Inits EnumTypeWrapper with an EnumDescriptor.""" self._enum_type = enum_type - self.DESCRIPTOR = enum_type + self.DESCRIPTOR = enum_type # pylint: disable=invalid-name - def Name(self, number): + def Name(self, number): # pylint: disable=invalid-name """Returns a string containing the name of an enum value.""" - if number in self._enum_type.values_by_number: + try: return self._enum_type.values_by_number[number].name + except KeyError: + pass # fall out to break exception chaining if not isinstance(number, six.integer_types): - raise TypeError('Enum value for %s must be an int, but got %r.' % ( - self._enum_type.name, number)) + raise TypeError( + 'Enum value for {} must be an int, but got {} {!r}.'.format( + self._enum_type.name, type(number), number)) else: - # %r here to handle the odd case when you pass in a boolean. - raise ValueError('Enum %s has no name defined for value %r' % ( + # repr here to handle the odd case when you pass in a boolean. + raise ValueError('Enum {} has no name defined for value {!r}'.format( self._enum_type.name, number)) - def Value(self, name): + def Value(self, name): # pylint: disable=invalid-name """Returns the value corresponding to the given enum name.""" - if name in self._enum_type.values_by_name: + try: return self._enum_type.values_by_name[name].number - raise ValueError('Enum %s has no value defined for name %s' % ( + except KeyError: + pass # fall out to break exception chaining + raise ValueError('Enum {} has no value defined for name {!r}'.format( self._enum_type.name, name)) def keys(self): """Return a list of the string names in the enum. - These are returned in the order they were defined in the .proto file. + Returns: + A list of strs, in the order they were defined in the .proto file. """ return [value_descriptor.name @@ -82,7 +88,8 @@ def keys(self): def values(self): """Return a list of the integer values in the enum. - These are returned in the order they were defined in the .proto file. + Returns: + A list of ints, in the order they were defined in the .proto file. """ return [value_descriptor.number @@ -91,13 +98,20 @@ def values(self): def items(self): """Return a list of the (name, value) pairs of the enum. - These are returned in the order they were defined in the .proto file. + Returns: + A list of (str, int) pairs, in the order they were defined + in the .proto file. """ return [(value_descriptor.name, value_descriptor.number) for value_descriptor in self._enum_type.values] def __getattr__(self, name): """Returns the value corresponding to the given enum name.""" - if name in self._enum_type.values_by_name: - return self._enum_type.values_by_name[name].number - raise AttributeError + try: + return super( + EnumTypeWrapper, + self).__getattribute__('_enum_type').values_by_name[name].number + except KeyError: + pass # fall out to break exception chaining + raise AttributeError('Enum {} has no value defined for name {!r}'.format( + self._enum_type.name, name)) diff --git a/python/google/protobuf/internal/extension_dict.py b/python/google/protobuf/internal/extension_dict.py index d08df4a8f97d..b346cf283e2c 100644 --- a/python/google/protobuf/internal/extension_dict.py +++ b/python/google/protobuf/internal/extension_dict.py @@ -87,6 +87,10 @@ def __getitem__(self, extension_handle): if extension_handle.label == FieldDescriptor.LABEL_REPEATED: result = extension_handle._default_constructor(self._extended_message) elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: + message_type = extension_handle.message_type + if not hasattr(message_type, '_concrete_class'): + # pylint: disable=protected-access + self._extended_message._FACTORY.GetPrototype(message_type) assert getattr(extension_handle.message_type, '_concrete_class', None), ( 'Uninitialized concrete class found for field %r (message type %r)' % (extension_handle.full_name, diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py old mode 100644 new mode 100755 index e3992f99ba26..4310115a4025 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -36,6 +36,7 @@ import json import math +import struct import sys try: @@ -52,6 +53,7 @@ from google.protobuf import any_test_pb2 from google.protobuf import unittest_mset_pb2 from google.protobuf import unittest_pb2 +from google.protobuf.internal import test_proto3_optional_pb2 from google.protobuf import descriptor_pool from google.protobuf import json_format from google.protobuf.util import json_format_pb2 @@ -237,16 +239,19 @@ def testExtensionSerializationDictMatchesProto3Spec(self): golden_dict = { 'messageSet': { '[protobuf_unittest.' - 'TestMessageSetExtension1.messageSetExtension]': { + 'TestMessageSetExtension1.message_set_extension]': { 'i': 23, }, '[protobuf_unittest.' - 'TestMessageSetExtension2.messageSetExtension]': { + 'TestMessageSetExtension2.message_set_extension]': { 'str': u'foo', }, }, } self.assertEqual(golden_dict, message_dict) + parsed_msg = unittest_mset_pb2.TestMessageSetContainer() + json_format.ParseDict(golden_dict, parsed_msg) + self.assertEqual(message, parsed_msg) def testExtensionSerializationDictMatchesProto3SpecMore(self): """See go/proto3-json-spec for spec. @@ -264,7 +269,6 @@ def testExtensionSerializationDictMatchesProto3SpecMore(self): } self.assertEqual(expected_dict, message_dict) - def testExtensionSerializationJsonMatchesProto3Spec(self): """See go/proto3-json-spec for spec. """ @@ -277,9 +281,9 @@ def testExtensionSerializationJsonMatchesProto3Spec(self): message ) ext1_text = ('protobuf_unittest.TestMessageSetExtension1.' - 'messageSetExtension') + 'message_set_extension') ext2_text = ('protobuf_unittest.TestMessageSetExtension2.' - 'messageSetExtension') + 'message_set_extension') golden_text = ('{"messageSet": {' ' "[%s]": {' ' "i": 23' @@ -290,7 +294,6 @@ def testExtensionSerializationJsonMatchesProto3Spec(self): '}}') % (ext1_text, ext2_text) self.assertEqual(json.loads(golden_text), json.loads(message_text)) - def testJsonEscapeString(self): message = json_format_proto3_pb2.TestMessage() if sys.version_info[0] < 3: @@ -338,6 +341,20 @@ def testAlwaysSeriliaze(self): parsed_message = json_format_proto3_pb2.TestMessage() self.CheckParseBack(message, parsed_message) + def testProto3Optional(self): + message = test_proto3_optional_pb2.TestProto3Optional() + self.assertEqual( + json.loads( + json_format.MessageToJson( + message, including_default_value_fields=True)), + json.loads('{}')) + message.optional_int32 = 0 + self.assertEqual( + json.loads( + json_format.MessageToJson( + message, including_default_value_fields=True)), + json.loads('{"optionalInt32": 0}')) + def testIntegersRepresentedAsFloat(self): message = json_format_proto3_pb2.TestMessage() json_format.Parse('{"int32Value": -2.147483648e9}', message) @@ -619,6 +636,20 @@ def testListValueMessage(self): parsed_message = json_format_proto3_pb2.TestListValue() self.CheckParseBack(message, parsed_message) + def testNullValue(self): + message = json_format_proto3_pb2.TestOneof() + message.oneof_null_value = 0 + self.assertEqual(json_format.MessageToJson(message), + '{\n "oneofNullValue": null\n}') + parsed_message = json_format_proto3_pb2.TestOneof() + self.CheckParseBack(message, parsed_message) + # Check old format is also accepted + new_message = json_format_proto3_pb2.TestOneof() + json_format.Parse('{\n "oneofNullValue": "NULL_VALUE"\n}', + new_message) + self.assertEqual(json_format.MessageToJson(new_message), + '{\n "oneofNullValue": null\n}') + def testAnyMessage(self): message = json_format_proto3_pb2.TestAny() value1 = json_format_proto3_pb2.MessageType() @@ -813,19 +844,53 @@ def testNanFloat(self): def testParseDoubleToFloat(self): message = json_format_proto3_pb2.TestMessage() - text = ('{"repeatedFloatValue": [3.4028235e+39, 1.4028235e-39]\n}') + text = ('{"repeatedDoubleValue": [3.4028235e+39, 1.4028235e-39]\n}') json_format.Parse(text, message) - self.assertEqual(message.repeated_float_value[0], float('inf')) - self.assertAlmostEqual(message.repeated_float_value[1], 1.4028235e-39) + self.assertEqual(message.repeated_double_value[0], 3.4028235e+39) + self.assertEqual(message.repeated_double_value[1], 1.4028235e-39) + text = ('{"repeatedFloatValue": [3.4028235e+39, 1.4028235e-39]\n}') + self.CheckError(text, + 'Failed to parse repeatedFloatValue field: ' + 'Float value too large.') def testFloatPrecision(self): message = json_format_proto3_pb2.TestMessage() message.float_value = 1.123456789 + # Set to 8 valid digits. + text = '{\n "floatValue": 1.1234568\n}' + self.assertEqual( + json_format.MessageToJson(message, float_precision=8), text) # Set to 7 valid digits. text = '{\n "floatValue": 1.123457\n}' self.assertEqual( json_format.MessageToJson(message, float_precision=7), text) + # Default float_precision will automatic print shortest float. + message.float_value = 1.1000000011 + text = '{\n "floatValue": 1.1\n}' + self.assertEqual( + json_format.MessageToJson(message), text) + message.float_value = 1.00000075e-36 + text = '{\n "floatValue": 1.00000075e-36\n}' + self.assertEqual( + json_format.MessageToJson(message), text) + message.float_value = 12345678912345e+11 + text = '{\n "floatValue": 1.234568e+24\n}' + self.assertEqual( + json_format.MessageToJson(message), text) + + # Test a bunch of data and check json encode/decode do not + # lose precision + value_list = [0x00, 0xD8, 0x6E, 0x00] + msg2 = json_format_proto3_pb2.TestMessage() + for a in range(0, 256): + value_list[3] = a + for b in range(0, 256): + value_list[0] = b + byte_array = bytearray(value_list) + message.float_value = struct.unpack('.", + json_format.ParseDict, + {'value': UnknownClass()}, + message) + def testMessageToDict(self): message = json_format_proto3_pb2.TestMessage() message.int32_value = 12345 diff --git a/python/google/protobuf/internal/message_factory_test.py b/python/google/protobuf/internal/message_factory_test.py old mode 100644 new mode 100755 diff --git a/python/google/protobuf/internal/message_listener.py b/python/google/protobuf/internal/message_listener.py old mode 100755 new mode 100644 diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index f12b531f8b2e..feff228fb62c 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -83,6 +83,7 @@ from google.protobuf.internal import more_extensions_pb2 from google.protobuf.internal import packed_field_test_pb2 from google.protobuf.internal import test_util +from google.protobuf.internal import test_proto3_optional_pb2 from google.protobuf.internal import testing_refleaks from google.protobuf import message from google.protobuf.internal import _parameterized @@ -106,6 +107,9 @@ def IsNegInf(val): return isinf(val) and (val < 0) +warnings.simplefilter('error', DeprecationWarning) + + @_parameterized.named_parameters( ('_proto2', unittest_pb2), ('_proto3', unittest_proto3_arena_pb2)) @@ -438,12 +442,19 @@ def testFloatPrinting(self, message_module): self.assertEqual(str(message), 'optional_float: 2.0\n') def testHighPrecisionFloatPrinting(self, message_module): - message = message_module.TestAllTypes() - message.optional_double = 0.12345678912345678 + msg = message_module.TestAllTypes() + msg.optional_float = 0.12345678912345678 + old_float = msg.optional_float + msg.ParseFromString(msg.SerializeToString()) + self.assertEqual(old_float, msg.optional_float) + + def testHighPrecisionDoublePrinting(self, message_module): + msg = message_module.TestAllTypes() + msg.optional_double = 0.12345678912345678 if sys.version_info >= (3,): - self.assertEqual(str(message), 'optional_double: 0.12345678912345678\n') + self.assertEqual(str(msg), 'optional_double: 0.12345678912345678\n') else: - self.assertEqual(str(message), 'optional_double: 0.123456789123\n') + self.assertEqual(str(msg), 'optional_double: 0.123456789123\n') def testUnknownFieldPrinting(self, message_module): populated = message_module.TestAllTypes() @@ -885,11 +896,13 @@ def testOneofGetCaseNonexistingField(self, message_module): def testOneofDefaultValues(self, message_module): m = message_module.TestAllTypes() self.assertIs(None, m.WhichOneof('oneof_field')) + self.assertFalse(m.HasField('oneof_field')) self.assertFalse(m.HasField('oneof_uint32')) # Oneof is set even when setting it to a default value. m.oneof_uint32 = 0 self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field')) + self.assertTrue(m.HasField('oneof_field')) self.assertTrue(m.HasField('oneof_uint32')) self.assertFalse(m.HasField('oneof_string')) @@ -1046,7 +1059,7 @@ def testAssignByteStringToUnicodeField(self, message_module): self.assertIsInstance(m.optional_string, six.text_type) def testLongValuedSlice(self, message_module): - """It should be possible to use long-valued indicies in slices + """It should be possible to use long-valued indices in slices. This didn't used to work in the v2 C++ implementation. """ @@ -1662,6 +1675,70 @@ def testFieldPresence(self): self.assertEqual(False, message.optional_bool) self.assertEqual(0, message.optional_nested_message.bb) + def testProto3ParserDropDefaultScalar(self): + message_proto2 = unittest_pb2.TestAllTypes() + message_proto2.optional_int32 = 0 + message_proto2.optional_string = '' + message_proto2.optional_bytes = b'' + self.assertEqual(len(message_proto2.ListFields()), 3) + + message_proto3 = unittest_proto3_arena_pb2.TestAllTypes() + message_proto3.ParseFromString(message_proto2.SerializeToString()) + self.assertEqual(len(message_proto3.ListFields()), 0) + + def testProto3Optional(self): + msg = test_proto3_optional_pb2.TestProto3Optional() + self.assertFalse(msg.HasField('optional_int32')) + self.assertFalse(msg.HasField('optional_float')) + self.assertFalse(msg.HasField('optional_string')) + self.assertFalse(msg.HasField('optional_nested_message')) + self.assertFalse(msg.optional_nested_message.HasField('bb')) + + # Set fields. + msg.optional_int32 = 1 + msg.optional_float = 1.0 + msg.optional_string = '123' + msg.optional_nested_message.bb = 1 + self.assertTrue(msg.HasField('optional_int32')) + self.assertTrue(msg.HasField('optional_float')) + self.assertTrue(msg.HasField('optional_string')) + self.assertTrue(msg.HasField('optional_nested_message')) + self.assertTrue(msg.optional_nested_message.HasField('bb')) + # Set to default value does not clear the fields + msg.optional_int32 = 0 + msg.optional_float = 0.0 + msg.optional_string = '' + msg.optional_nested_message.bb = 0 + self.assertTrue(msg.HasField('optional_int32')) + self.assertTrue(msg.HasField('optional_float')) + self.assertTrue(msg.HasField('optional_string')) + self.assertTrue(msg.HasField('optional_nested_message')) + self.assertTrue(msg.optional_nested_message.HasField('bb')) + + # Test serialize + msg2 = test_proto3_optional_pb2.TestProto3Optional() + msg2.ParseFromString(msg.SerializeToString()) + self.assertTrue(msg2.HasField('optional_int32')) + self.assertTrue(msg2.HasField('optional_float')) + self.assertTrue(msg2.HasField('optional_string')) + self.assertTrue(msg2.HasField('optional_nested_message')) + self.assertTrue(msg2.optional_nested_message.HasField('bb')) + + self.assertEqual(msg.WhichOneof('_optional_int32'), 'optional_int32') + + # Clear these fields. + msg.ClearField('optional_int32') + msg.ClearField('optional_float') + msg.ClearField('optional_string') + msg.ClearField('optional_nested_message') + self.assertFalse(msg.HasField('optional_int32')) + self.assertFalse(msg.HasField('optional_float')) + self.assertFalse(msg.HasField('optional_string')) + self.assertFalse(msg.HasField('optional_nested_message')) + self.assertFalse(msg.optional_nested_message.HasField('bb')) + + self.assertEqual(msg.WhichOneof('_optional_int32'), None) + def testAssignUnknownEnum(self): """Assigning an unknown enum value is allowed and preserves the value.""" m = unittest_proto3_arena_pb2.TestAllTypes() @@ -2030,6 +2107,11 @@ def testMapMergeFrom(self): self.assertEqual(msg.map_int32_foreign_message[222].d, 20) self.assertNotEqual(msg.map_int32_foreign_message[222].c, 123) + # Merge a dict to map field is not accepted + with self.assertRaises(AttributeError): + m1.map_int32_all_types.MergeFrom( + {1: unittest_proto3_arena_pb2.TestAllTypes()}) + def testMergeFromBadType(self): msg = map_unittest_pb2.TestMap() with self.assertRaisesRegexp( diff --git a/python/google/protobuf/internal/proto_builder_test.py b/python/google/protobuf/internal/proto_builder_test.py old mode 100644 new mode 100755 diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py old mode 100755 new mode 100644 index 8fb19460272c..d1f4dcde8e5e --- a/python/google/protobuf/internal/python_message.py +++ b/python/google/protobuf/internal/python_message.py @@ -124,9 +124,16 @@ def __new__(cls, name, bases, dictionary): Returns: Newly-allocated class. + + Raises: + RuntimeError: Generated code only work with python cpp extension. """ descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] + if isinstance(descriptor, str): + raise RuntimeError('The generated code only work with python cpp ' + 'extension, but it is using pure python runtime.') + # If a concrete class already exists for this descriptor, don't try to # create another. Doing so will break any messages that already exist with # the existing class. @@ -288,6 +295,7 @@ def _AttachFieldHelpers(cls, field_descriptor): is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) is_packable = (is_repeated and wire_format.IsTypePackable(field_descriptor.type)) + is_proto3 = field_descriptor.containing_type.syntax == 'proto3' if not is_packable: is_packed = False elif field_descriptor.containing_type.syntax == 'proto2': @@ -326,8 +334,12 @@ def AddDecoder(wiretype, is_packed): decode_type = _FieldDescriptor.TYPE_INT32 oneof_descriptor = None + clear_if_default = False if field_descriptor.containing_oneof is not None: oneof_descriptor = field_descriptor + elif (is_proto3 and not is_repeated and + field_descriptor.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE): + clear_if_default = True if is_map_entry: is_message_map = _IsMessageMapField(field_descriptor) @@ -340,11 +352,17 @@ def AddDecoder(wiretype, is_packed): field_decoder = decoder.StringDecoder( field_descriptor.number, is_repeated, is_packed, field_descriptor, field_descriptor._default_constructor, - is_strict_utf8_check) - else: + is_strict_utf8_check, clear_if_default) + elif field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( field_descriptor.number, is_repeated, is_packed, field_descriptor, field_descriptor._default_constructor) + else: + field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( + field_descriptor.number, is_repeated, is_packed, + # pylint: disable=protected-access + field_descriptor, field_descriptor._default_constructor, + clear_if_default) cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor) @@ -819,7 +837,8 @@ def ListFields(self): cls.ListFields = ListFields _PROTO3_ERROR_TEMPLATE = \ - 'Protocol message %s has no non-repeated submessage field "%s"' + ('Protocol message %s has no non-repeated submessage field "%s" ' + 'nor marked as optional') _PROTO2_ERROR_TEMPLATE = 'Protocol message %s has no non-repeated field "%s"' def _AddHasFieldMethod(message_descriptor, cls): @@ -838,10 +857,9 @@ def _AddHasFieldMethod(message_descriptor, cls): continue hassable_fields[field.name] = field - if not is_proto3: - # Fields inside oneofs are never repeated (enforced by the compiler). - for oneof in message_descriptor.oneofs: - hassable_fields[oneof.name] = oneof + # Has methods are supported for oneof descriptors. + for oneof in message_descriptor.oneofs: + hassable_fields[oneof.name] = oneof def HasField(self, field_name): try: diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index dace15447cdd..2b9ed1cb5a44 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -40,6 +40,7 @@ import operator import six import struct +import warnings try: import unittest2 as unittest #PY26 @@ -70,6 +71,9 @@ long = int # pylint: disable=redefined-builtin,invalid-name +warnings.simplefilter('error', DeprecationWarning) + + class _MiniDecoder(object): """Decodes a stream of values from a string. @@ -1307,6 +1311,38 @@ def testRepeatedScalarsRemove(self): # Remove a non-existent element. self.assertRaises(ValueError, proto.repeated_int32.remove, 123) + def testRepeatedScalarsReverse_Empty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_int32) + self.assertEqual(0, len(proto.repeated_int32)) + + self.assertIsNone(proto.repeated_int32.reverse()) + + self.assertFalse(proto.repeated_int32) + self.assertEqual(0, len(proto.repeated_int32)) + + def testRepeatedScalarsReverse_NonEmpty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_int32) + self.assertEqual(0, len(proto.repeated_int32)) + + proto.repeated_int32.append(1) + proto.repeated_int32.append(2) + proto.repeated_int32.append(3) + proto.repeated_int32.append(4) + + self.assertEqual(4, len(proto.repeated_int32)) + + self.assertIsNone(proto.repeated_int32.reverse()) + + self.assertEqual(4, len(proto.repeated_int32)) + self.assertEqual(4, proto.repeated_int32[0]) + self.assertEqual(3, proto.repeated_int32[1]) + self.assertEqual(2, proto.repeated_int32[2]) + self.assertEqual(1, proto.repeated_int32[3]) + def testRepeatedComposites(self): proto = unittest_pb2.TestAllTypes() self.assertFalse(proto.repeated_nested_message) @@ -1419,6 +1455,35 @@ def testRepeatedCompositeRemove(self): self.assertEqual(1, len(proto.repeated_nested_message)) self.assertEqual(m1, proto.repeated_nested_message[0]) + def testRepeatedCompositeReverse_Empty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_nested_message) + self.assertEqual(0, len(proto.repeated_nested_message)) + + self.assertIsNone(proto.repeated_nested_message.reverse()) + + self.assertFalse(proto.repeated_nested_message) + self.assertEqual(0, len(proto.repeated_nested_message)) + + def testRepeatedCompositeReverse_NonEmpty(self): + proto = unittest_pb2.TestAllTypes() + + self.assertFalse(proto.repeated_nested_message) + self.assertEqual(0, len(proto.repeated_nested_message)) + + m0 = proto.repeated_nested_message.add() + m0.bb = len(proto.repeated_nested_message) + m1 = proto.repeated_nested_message.add() + m1.bb = len(proto.repeated_nested_message) + m2 = proto.repeated_nested_message.add() + m2.bb = len(proto.repeated_nested_message) + self.assertListsEqual([m0, m1, m2], proto.repeated_nested_message) + + self.assertIsNone(proto.repeated_nested_message.reverse()) + + self.assertListsEqual([m2, m1, m0], proto.repeated_nested_message) + def testHandWrittenReflection(self): # Hand written extensions are only supported by the pure-Python # implementation of the API. @@ -1433,12 +1498,16 @@ def testHandWrittenReflection(self): label=FieldDescriptor.LABEL_OPTIONAL, default_value=0, containing_type=None, message_type=None, enum_type=None, is_extension=False, extension_scope=None, - options=descriptor_pb2.FieldOptions()) + options=descriptor_pb2.FieldOptions(), + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) mydescriptor = descriptor.Descriptor( name='MyProto', full_name='MyProto', filename='ignored', containing_type=None, nested_types=[], enum_types=[], fields=[foo_field_descriptor], extensions=[], - options=descriptor_pb2.MessageOptions()) + options=descriptor_pb2.MessageOptions(), + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) class MyProtoClass(six.with_metaclass(reflection.GeneratedProtocolMessageType, message.Message)): DESCRIPTOR = mydescriptor myproto_instance = MyProtoClass() @@ -2805,7 +2874,7 @@ def testUnknownFields(self): proto2.MergeFromString(serialized)) def _CheckRaises(self, exc_class, callable_obj, exception): - """This method checks if the excpetion type and message are as expected.""" + """This method checks if the exception type and message are as expected.""" try: callable_obj() except exc_class as ex: @@ -3053,10 +3122,10 @@ def testFieldDataDescriptor(self): unittest_pb2.ForeignMessage.c.__get__(msg) except TypeError: pass # The cpp implementation cannot mix fields from other messages. - # This test exercises a specific check that avoids a crash. + # This test exercises a specific check that avoids a crash. else: pass # The python implementation allows fields from other messages. - # This is useless, but works. + # This is useless, but works. def testInitKwargs(self): proto = unittest_pb2.TestAllTypes( @@ -3168,22 +3237,34 @@ class ClassAPITest(unittest.TestCase): 'C++ implementation requires a call to MakeDescriptor()') @testing_refleaks.SkipReferenceLeakChecker('MakeClass is not repeatable') def testMakeClassWithNestedDescriptor(self): - leaf_desc = descriptor.Descriptor('leaf', 'package.parent.child.leaf', '', - containing_type=None, fields=[], - nested_types=[], enum_types=[], - extensions=[]) - child_desc = descriptor.Descriptor('child', 'package.parent.child', '', - containing_type=None, fields=[], - nested_types=[leaf_desc], enum_types=[], - extensions=[]) - sibling_desc = descriptor.Descriptor('sibling', 'package.parent.sibling', - '', containing_type=None, fields=[], - nested_types=[], enum_types=[], - extensions=[]) - parent_desc = descriptor.Descriptor('parent', 'package.parent', '', - containing_type=None, fields=[], - nested_types=[child_desc, sibling_desc], - enum_types=[], extensions=[]) + leaf_desc = descriptor.Descriptor( + 'leaf', 'package.parent.child.leaf', '', + containing_type=None, fields=[], + nested_types=[], enum_types=[], + extensions=[], + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) + child_desc = descriptor.Descriptor( + 'child', 'package.parent.child', '', + containing_type=None, fields=[], + nested_types=[leaf_desc], enum_types=[], + extensions=[], + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) + sibling_desc = descriptor.Descriptor( + 'sibling', 'package.parent.sibling', + '', containing_type=None, fields=[], + nested_types=[], enum_types=[], + extensions=[], + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) + parent_desc = descriptor.Descriptor( + 'parent', 'package.parent', '', + containing_type=None, fields=[], + nested_types=[child_desc, sibling_desc], + enum_types=[], extensions=[], + # pylint: disable=protected-access + create_key=descriptor._internal_create_key) reflection.MakeClass(parent_desc) def _GetSerializedFileDescriptor(self, name): @@ -3247,7 +3328,7 @@ def _GetSerializedFileDescriptor(self, name): # conflicting message descriptors. def testParsingFlatClassWithExplicitClassDeclaration(self): """Test that the generated class can parse a flat message.""" - # TODO(xiaofeng): This test fails with cpp implemetnation in the call + # TODO(xiaofeng): This test fails with cpp implementation in the call # of six.with_metaclass(). The other two callsites of with_metaclass # in this file are both excluded from cpp test, so it might be expected # to fail. Need someone more familiar with the python code to take a @@ -3305,4 +3386,3 @@ def testParsingNestedClass(self): if __name__ == '__main__': unittest.main() - diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py old mode 100644 new mode 100755 diff --git a/python/google/protobuf/internal/test_proto3_optional.proto b/python/google/protobuf/internal/test_proto3_optional.proto new file mode 100644 index 000000000000..f3e0a2e761cd --- /dev/null +++ b/python/google/protobuf/internal/test_proto3_optional.proto @@ -0,0 +1,70 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +syntax = "proto3"; + +package google.protobuf.python.internal; + +message TestProto3Optional { + message NestedMessage { + // The field name "b" fails to compile in proto1 because it conflicts with + // a local variable named "b" in one of the generated methods. Doh. + // This file needs to compile in proto1 to test backwards-compatibility. + optional int32 bb = 1; + } + + enum NestedEnum { + UNSPECIFIED = 0; + FOO = 1; + BAR = 2; + BAZ = 3; + NEG = -1; // Intentionally negative. + } + + // Singular + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + + optional NestedMessage optional_nested_message = 18; + optional NestedEnum optional_nested_enum = 21; +} diff --git a/python/google/protobuf/internal/test_util.py b/python/google/protobuf/internal/test_util.py old mode 100755 new mode 100644 diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 89520887ae83..987116a1061e 100755 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -57,6 +57,7 @@ from google.protobuf import descriptor_pb2 from google.protobuf.internal import any_test_pb2 as test_extend_any from google.protobuf.internal import message_set_extensions_pb2 +from google.protobuf.internal import test_proto3_optional_pb2 from google.protobuf.internal import test_util from google.protobuf import descriptor_pool from google.protobuf import text_format @@ -125,6 +126,114 @@ def testPrintExotic(self, message_module): ' "\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n' 'repeated_string: "\\303\\274\\352\\234\\237"\n') + def testPrintFloatPrecision(self, message_module): + message = message_module.TestAllTypes() + + message.repeated_float.append(0.0) + message.repeated_float.append(0.8) + message.repeated_float.append(1.0) + message.repeated_float.append(1.2) + message.repeated_float.append(1.23) + message.repeated_float.append(1.234) + message.repeated_float.append(1.2345) + message.repeated_float.append(1.23456) + message.repeated_float.append(1.2e10) + message.repeated_float.append(1.23e10) + message.repeated_float.append(1.234e10) + message.repeated_float.append(1.2345e10) + message.repeated_float.append(1.23456e10) + message.repeated_float.append(float('NaN')) + message.repeated_float.append(float('inf')) + message.repeated_double.append(0.0) + message.repeated_double.append(0.8) + message.repeated_double.append(1.0) + message.repeated_double.append(1.2) + message.repeated_double.append(1.23) + message.repeated_double.append(1.234) + message.repeated_double.append(1.2345) + message.repeated_double.append(1.23456) + message.repeated_double.append(1.234567) + message.repeated_double.append(1.2345678) + message.repeated_double.append(1.23456789) + message.repeated_double.append(1.234567898) + message.repeated_double.append(1.2345678987) + message.repeated_double.append(1.23456789876) + message.repeated_double.append(1.234567898765) + message.repeated_double.append(1.2345678987654) + message.repeated_double.append(1.23456789876543) + message.repeated_double.append(1.2e100) + message.repeated_double.append(1.23e100) + message.repeated_double.append(1.234e100) + message.repeated_double.append(1.2345e100) + message.repeated_double.append(1.23456e100) + message.repeated_double.append(1.234567e100) + message.repeated_double.append(1.2345678e100) + message.repeated_double.append(1.23456789e100) + message.repeated_double.append(1.234567898e100) + message.repeated_double.append(1.2345678987e100) + message.repeated_double.append(1.23456789876e100) + message.repeated_double.append(1.234567898765e100) + message.repeated_double.append(1.2345678987654e100) + message.repeated_double.append(1.23456789876543e100) + # pylint: disable=g-long-ternary + self.CompareToGoldenText( + self.RemoveRedundantZeros(text_format.MessageToString(message)), + 'repeated_float: 0\n' + 'repeated_float: 0.8\n' + 'repeated_float: 1\n' + 'repeated_float: 1.2\n' + 'repeated_float: 1.23\n' + 'repeated_float: 1.234\n' + 'repeated_float: 1.2345\n' + 'repeated_float: 1.23456\n' + # Note that these don't use scientific notation. + 'repeated_float: 12000000000\n' + 'repeated_float: 12300000000\n' + 'repeated_float: 12340000000\n' + 'repeated_float: 12345000000\n' + 'repeated_float: 12345600000\n' + 'repeated_float: nan\n' + 'repeated_float: inf\n' + 'repeated_double: 0\n' + 'repeated_double: 0.8\n' + 'repeated_double: 1\n' + 'repeated_double: 1.2\n' + 'repeated_double: 1.23\n' + 'repeated_double: 1.234\n' + 'repeated_double: 1.2345\n' + 'repeated_double: 1.23456\n' + 'repeated_double: 1.234567\n' + 'repeated_double: 1.2345678\n' + 'repeated_double: 1.23456789\n' + 'repeated_double: 1.234567898\n' + 'repeated_double: 1.2345678987\n' + 'repeated_double: 1.23456789876\n' + + ('repeated_double: 1.23456789876\n' + 'repeated_double: 1.23456789877\n' + 'repeated_double: 1.23456789877\n' + if six.PY2 else + 'repeated_double: 1.234567898765\n' + 'repeated_double: 1.2345678987654\n' + 'repeated_double: 1.23456789876543\n') + + 'repeated_double: 1.2e+100\n' + 'repeated_double: 1.23e+100\n' + 'repeated_double: 1.234e+100\n' + 'repeated_double: 1.2345e+100\n' + 'repeated_double: 1.23456e+100\n' + 'repeated_double: 1.234567e+100\n' + 'repeated_double: 1.2345678e+100\n' + 'repeated_double: 1.23456789e+100\n' + 'repeated_double: 1.234567898e+100\n' + 'repeated_double: 1.2345678987e+100\n' + 'repeated_double: 1.23456789876e+100\n' + + ('repeated_double: 1.23456789877e+100\n' + 'repeated_double: 1.23456789877e+100\n' + 'repeated_double: 1.23456789877e+100\n' + if six.PY2 else + 'repeated_double: 1.234567898765e+100\n' + 'repeated_double: 1.2345678987654e+100\n' + 'repeated_double: 1.23456789876543e+100\n')) + def testPrintExoticUnicodeSubclass(self, message_module): class UnicodeSub(six.text_type): @@ -294,8 +403,7 @@ def testPrintFloatFormat(self, message_module): # 32-bit 1.2 is noisy when extended to 64-bit: # >>> struct.unpack('f', struct.pack('f', 1.2))[0] # 1.2000000476837158 - # TODO(jieluo): change to 1.2 with cl/241634942. - message.payload.optional_float = 1.2000000476837158 + message.payload.optional_float = 1.2 formatted_fields = ['optional_float: 1.2', 'optional_double: -3.45678901234568e-6', 'repeated_float: -5642', 'repeated_double: 7.89e-5'] @@ -316,7 +424,7 @@ def testPrintFloatFormat(self, message_module): 'payload {{\n {0}\n {1}\n {2}\n {3}\n}}\n'.format( *formatted_fields)) - # Test default float_format has 8 valid digits. + # Test default float_format will automatic print shortest float. message.payload.optional_float = 1.2345678912 message.payload.optional_double = 1.2345678912 formatted_fields = ['optional_float: 1.2345679', @@ -328,6 +436,17 @@ def testPrintFloatFormat(self, message_module): 'payload {{\n {0}\n {1}\n {2}\n {3}\n}}\n'.format( *formatted_fields)) + message.Clear() + message.payload.optional_float = 1.1000000000011 + self.assertEqual(text_format.MessageToString(message), + 'payload {\n optional_float: 1.1\n}\n') + message.payload.optional_float = 1.00000075e-36 + self.assertEqual(text_format.MessageToString(message), + 'payload {\n optional_float: 1.00000075e-36\n}\n') + message.payload.optional_float = 12345678912345e+11 + self.assertEqual(text_format.MessageToString(message), + 'payload {\n optional_float: 1.234568e+24\n}\n') + def testMessageToString(self, message_module): message = message_module.ForeignMessage() message.c = 123 @@ -1744,6 +1863,24 @@ def testMergeMissingAnyEndToken(self): text_format.Merge(text, message) self.assertEqual(str(e.exception), '3:11 : Expected "}".') + def testProto3Optional(self): + msg = test_proto3_optional_pb2.TestProto3Optional() + self.assertEqual(text_format.MessageToString(msg), '') + msg.optional_int32 = 0 + msg.optional_float = 0.0 + msg.optional_string = '' + msg.optional_nested_message.bb = 0 + text = ('optional_int32: 0\n' + 'optional_float: 0.0\n' + 'optional_string: ""\n' + 'optional_nested_message {\n' + ' bb: 0\n' + '}\n') + self.assertEqual(text_format.MessageToString(msg), text) + msg2 = test_proto3_optional_pb2.TestProto3Optional() + text_format.Parse(text, msg2) + self.assertEqual(text_format.MessageToString(msg2), text) + class TokenizerTest(unittest.TestCase): @@ -2194,5 +2331,23 @@ def testPrintFieldValue(self): }""")) +class OptionalColonMessageToStringTest(unittest.TestCase): + + def testForcePrintOptionalColon(self): + packed_message = unittest_pb2.OneString() + packed_message.data = 'string' + message = any_test_pb2.TestAny() + message.any_value.Pack(packed_message) + output = text_format.MessageToString( + message, + force_colon=True) + expected = ('any_value: {\n' + ' [type.googleapis.com/protobuf_unittest.OneString]: {\n' + ' data: "string"\n' + ' }\n' + '}\n') + self.assertEqual(expected, output) + + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/type_checkers.py b/python/google/protobuf/internal/type_checkers.py old mode 100755 new mode 100644 index 8deba47507c6..eb66f9f6fbae --- a/python/google/protobuf/internal/type_checkers.py +++ b/python/google/protobuf/internal/type_checkers.py @@ -45,6 +45,11 @@ __author__ = 'robinson@google.com (Will Robinson)' +try: + import ctypes +except Exception: # pylint: disable=broad-except + ctypes = None + import struct import numbers import six @@ -59,6 +64,29 @@ _FieldDescriptor = descriptor.FieldDescriptor + +def TruncateToFourByteFloat(original): + if ctypes: + return ctypes.c_float(original).value + else: + return struct.unpack(' 0: + raise ParseError('Couldn\'t parse Infinity or value too large, ' + 'use quoted "Infinity" instead.') + else: + raise ParseError('Couldn\'t parse -Infinity or value too small, ' + 'use quoted "-Infinity" instead.') + if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: + # pylint: disable=protected-access + if value > type_checkers._FLOAT_MAX: + raise ParseError('Float value too large') + # pylint: disable=protected-access + if value < type_checkers._FLOAT_MIN: + raise ParseError('Float value too small') if value == 'nan': raise ParseError('Couldn\'t parse float "nan", use "NaN" instead.') try: diff --git a/python/google/protobuf/message.py b/python/google/protobuf/message.py old mode 100755 new mode 100644 index 2f132194c384..224d2fc49178 --- a/python/google/protobuf/message.py +++ b/python/google/protobuf/message.py @@ -36,9 +36,19 @@ __author__ = 'robinson@google.com (Will Robinson)' -class Error(Exception): pass -class DecodeError(Error): pass -class EncodeError(Error): pass +class Error(Exception): + """Base error type for this module.""" + pass + + +class DecodeError(Error): + """Exception raised when deserializing messages.""" + pass + + +class EncodeError(Error): + """Exception raised when serializing messages.""" + pass class Message(object): @@ -48,22 +58,23 @@ class Message(object): Protocol message classes are almost always generated by the protocol compiler. These generated types subclass Message and implement the methods shown below. + """ - TODO(robinson): Link to an HTML document here. + # TODO(robinson): Link to an HTML document here. - TODO(robinson): Document that instances of this class will also - have an Extensions attribute with __getitem__ and __setitem__. - Again, not sure how to best convey this. + # TODO(robinson): Document that instances of this class will also + # have an Extensions attribute with __getitem__ and __setitem__. + # Again, not sure how to best convey this. - TODO(robinson): Document that the class must also have a static - RegisterExtension(extension_field) method. - Not sure how to best express at this point. - """ + # TODO(robinson): Document that the class must also have a static + # RegisterExtension(extension_field) method. + # Not sure how to best express at this point. # TODO(robinson): Document these fields and methods. __slots__ = [] + #: The :class:`google.protobuf.descriptor.Descriptor` for this message type. DESCRIPTOR = None def __deepcopy__(self, memo=None): @@ -99,7 +110,7 @@ def MergeFrom(self, other_msg): appended. Singular sub-messages and groups are recursively merged. Args: - other_msg: Message to merge into the current message. + other_msg (Message): A message to merge into the current message. """ raise NotImplementedError @@ -110,7 +121,7 @@ def CopyFrom(self, other_msg): message using MergeFrom. Args: - other_msg: Message to copy into the current one. + other_msg (Message): A message to copy into the current one. """ if self is other_msg: return @@ -127,15 +138,16 @@ def SetInParent(self): This normally happens automatically when you assign a field of a sub-message, but sometimes you want to make the sub-message present while keeping it empty. If you find yourself using this, - you may want to reconsider your design.""" + you may want to reconsider your design. + """ raise NotImplementedError def IsInitialized(self): """Checks if the message is initialized. Returns: - The method returns True if the message is initialized (i.e. all of its - required fields are set). + bool: The method returns True if the message is initialized (i.e. all of + its required fields are set). """ raise NotImplementedError @@ -148,40 +160,40 @@ def IsInitialized(self): def MergeFromString(self, serialized): """Merges serialized protocol buffer data into this message. - When we find a field in |serialized| that is already present + When we find a field in `serialized` that is already present in this message: - - If it's a "repeated" field, we append to the end of our list. - - Else, if it's a scalar, we overwrite our field. - - Else, (it's a nonrepeated composite), we recursively merge - into the existing composite. - TODO(robinson): Document handling of unknown fields. + - If it's a "repeated" field, we append to the end of our list. + - Else, if it's a scalar, we overwrite our field. + - Else, (it's a nonrepeated composite), we recursively merge + into the existing composite. Args: - serialized: Any object that allows us to call buffer(serialized) - to access a string of bytes using the buffer interface. - - TODO(robinson): When we switch to a helper, this will return None. + serialized (bytes): Any object that allows us to call + ``memoryview(serialized)`` to access a string of bytes using the + buffer interface. Returns: - The number of bytes read from |serialized|. - For non-group messages, this will always be len(serialized), + int: The number of bytes read from `serialized`. + For non-group messages, this will always be `len(serialized)`, but for messages which are actually groups, this will - generally be less than len(serialized), since we must - stop when we reach an END_GROUP tag. Note that if - we *do* stop because of an END_GROUP tag, the number + generally be less than `len(serialized)`, since we must + stop when we reach an ``END_GROUP`` tag. Note that if + we *do* stop because of an ``END_GROUP`` tag, the number of bytes returned does not include the bytes - for the END_GROUP tag information. + for the ``END_GROUP`` tag information. Raises: - message.DecodeError if the input cannot be parsed. + DecodeError: if the input cannot be parsed. """ + # TODO(robinson): Document handling of unknown fields. + # TODO(robinson): When we switch to a helper, this will return None. raise NotImplementedError def ParseFromString(self, serialized): """Parse serialized protocol buffer data into this message. - Like MergeFromString(), except we clear the object first. + Like :func:`MergeFromString()`, except we clear the object first. """ self.Clear() return self.MergeFromString(serialized) @@ -189,18 +201,16 @@ def ParseFromString(self, serialized): def SerializeToString(self, **kwargs): """Serializes the protocol message to a binary string. - Arguments: - **kwargs: Keyword arguments to the serialize method, accepts - the following keyword args: - deterministic: If true, requests deterministic serialization of the - protobuf, with predictable ordering of map keys. + Keyword Args: + deterministic (bool): If true, requests deterministic serialization + of the protobuf, with predictable ordering of map keys. Returns: A binary string representation of the message if all of the required fields in the message are set (i.e. the message is initialized). Raises: - message.EncodeError if the message isn't initialized. + EncodeError: if the message isn't initialized (see :func:`IsInitialized`). """ raise NotImplementedError @@ -210,14 +220,12 @@ def SerializePartialToString(self, **kwargs): This method is similar to SerializeToString but doesn't check if the message is initialized. - Arguments: - **kwargs: Keyword arguments to the serialize method, accepts - the following keyword args: - deterministic: If true, requests deterministic serialization of the - protobuf, with predictable ordering of map keys. + Keyword Args: + deterministic (bool): If true, requests deterministic serialization + of the protobuf, with predictable ordering of map keys. Returns: - A string representation of the partial message. + bytes: A serialized representation of the partial message. """ raise NotImplementedError @@ -238,48 +246,116 @@ def SerializePartialToString(self, **kwargs): # keywords. So they would become lambda_ or yield_. # """ def ListFields(self): - """Returns a list of (FieldDescriptor, value) tuples for all - fields in the message which are not empty. A message field is - non-empty if HasField() would return true. A singular primitive field - is non-empty if HasField() would return true in proto2 or it is non zero - in proto3. A repeated field is non-empty if it contains at least one - element. The fields are ordered by field number""" + """Returns a list of (FieldDescriptor, value) tuples for present fields. + + A message field is non-empty if HasField() would return true. A singular + primitive field is non-empty if HasField() would return true in proto2 or it + is non zero in proto3. A repeated field is non-empty if it contains at least + one element. The fields are ordered by field number. + + Returns: + list[tuple(FieldDescriptor, value)]: field descriptors and values + for all fields in the message which are not empty. The values vary by + field type. + """ raise NotImplementedError def HasField(self, field_name): - """Checks if a certain field is set for the message, or if any field inside - a oneof group is set. Note that if the field_name is not defined in the - message descriptor, ValueError will be raised.""" + """Checks if a certain field is set for the message. + + For a oneof group, checks if any field inside is set. Note that if the + field_name is not defined in the message descriptor, :exc:`ValueError` will + be raised. + + Args: + field_name (str): The name of the field to check for presence. + + Returns: + bool: Whether a value has been set for the named field. + + Raises: + ValueError: if the `field_name` is not a member of this message. + """ raise NotImplementedError def ClearField(self, field_name): - """Clears the contents of a given field, or the field set inside a oneof - group. If the name neither refers to a defined field or oneof group, - ValueError is raised.""" + """Clears the contents of a given field. + + Inside a oneof group, clears the field set. If the name neither refers to a + defined field or oneof group, :exc:`ValueError` is raised. + + Args: + field_name (str): The name of the field to check for presence. + + Raises: + ValueError: if the `field_name` is not a member of this message. + """ raise NotImplementedError def WhichOneof(self, oneof_group): - """Returns the name of the field that is set inside a oneof group, or - None if no field is set. If no group with the given name exists, ValueError - will be raised.""" + """Returns the name of the field that is set inside a oneof group. + + If no field is set, returns None. + + Args: + oneof_group (str): the name of the oneof group to check. + + Returns: + str or None: The name of the group that is set, or None. + + Raises: + ValueError: no group with the given name exists + """ raise NotImplementedError def HasExtension(self, extension_handle): + """Checks if a certain extension is present for this message. + + Extensions are retrieved using the :attr:`Extensions` mapping (if present). + + Args: + extension_handle: The handle for the extension to check. + + Returns: + bool: Whether the extension is present for this message. + + Raises: + KeyError: if the extension is repeated. Similar to repeated fields, + there is no separate notion of presence: a "not present" repeated + extension is an empty list. + """ raise NotImplementedError def ClearExtension(self, extension_handle): + """Clears the contents of a given extension. + + Args: + extension_handle: The handle for the extension to clear. + """ raise NotImplementedError def UnknownFields(self): - """Returns the UnknownFieldSet.""" + """Returns the UnknownFieldSet. + + Returns: + UnknownFieldSet: The unknown fields stored in this message. + """ raise NotImplementedError def DiscardUnknownFields(self): + """Clears all fields in the :class:`UnknownFieldSet`. + + This operation is recursive for nested message. + """ raise NotImplementedError def ByteSize(self): """Returns the serialized size of this message. + Recursively calls ByteSize() on all contained messages. + + Returns: + int: The number of bytes required to serialize this message. """ raise NotImplementedError diff --git a/python/google/protobuf/message_factory.py b/python/google/protobuf/message_factory.py index f3ab0a5571f6..24a524af4fa3 100644 --- a/python/google/protobuf/message_factory.py +++ b/python/google/protobuf/message_factory.py @@ -83,6 +83,8 @@ def GetPrototype(self, descriptor): descriptor_name, (message.Message,), {'DESCRIPTOR': descriptor, '__module__': None}) + # pylint: disable=protected-access + result_class._FACTORY = self # If module not set, it wrongly points to message_factory module. self._classes[descriptor] = result_class for field in descriptor.fields: diff --git a/python/google/protobuf/pyext/__init__.py b/python/google/protobuf/pyext/__init__.py index 558561412299..e69de29bb2d1 100644 --- a/python/google/protobuf/pyext/__init__.py +++ b/python/google/protobuf/pyext/__init__.py @@ -1,4 +0,0 @@ -try: - __import__('pkg_resources').declare_namespace(__name__) -except ImportError: - __path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 24b2b46c6620..75f1760ccf45 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -1690,7 +1690,7 @@ static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) { } const MethodDescriptor* method_descriptor = - _GetDescriptor(self)->FindMethodByName(std::string(name, name_size)); + _GetDescriptor(self)->FindMethodByName(StringParam(name, name_size)); if (method_descriptor == NULL) { PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name); return NULL; diff --git a/python/google/protobuf/pyext/descriptor.h b/python/google/protobuf/pyext/descriptor.h index 327ba4b3ce8c..b99209dd1996 100644 --- a/python/google/protobuf/pyext/descriptor.h +++ b/python/google/protobuf/pyext/descriptor.h @@ -41,6 +41,9 @@ namespace google { namespace protobuf { namespace python { +// Should match the type of ConstStringParam. +using StringParam = std::string; + extern PyTypeObject PyMessageDescriptor_Type; extern PyTypeObject PyFieldDescriptor_Type; extern PyTypeObject PyEnumDescriptor_Type; diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc index 865f0c0a6a75..c6ec2583a09a 100644 --- a/python/google/protobuf/pyext/descriptor_containers.cc +++ b/python/google/protobuf/pyext/descriptor_containers.cc @@ -81,9 +81,9 @@ struct PyContainer; typedef int (*CountMethod)(PyContainer* self); typedef const void* (*GetByIndexMethod)(PyContainer* self, int index); typedef const void* (*GetByNameMethod)(PyContainer* self, - const std::string& name); + ConstStringParam name); typedef const void* (*GetByCamelcaseNameMethod)(PyContainer* self, - const std::string& name); + ConstStringParam name); typedef const void* (*GetByNumberMethod)(PyContainer* self, int index); typedef PyObject* (*NewObjectFromItemMethod)(const void* descriptor); typedef const std::string& (*GetItemNameMethod)(const void* descriptor); @@ -183,7 +183,7 @@ static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) { return false; } *item = self->container_def->get_by_name_fn( - self, std::string(name, name_size)); + self, StringParam(name, name_size)); return true; } case PyContainer::KIND_BYCAMELCASENAME: @@ -200,7 +200,7 @@ static bool _GetItemByKey(PyContainer* self, PyObject* key, const void** item) { return false; } *item = self->container_def->get_by_camelcase_name_fn( - self, std::string(camelcase_name, name_size)); + self, StringParam(camelcase_name, name_size)); return true; } case PyContainer::KIND_BYNUMBER: @@ -962,12 +962,12 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->field_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindFieldByName(name); } static const void* GetByCamelcaseName(PyContainer* self, - const std::string& name) { + ConstStringParam name) { return GetDescriptor(self)->FindFieldByCamelcaseName(name); } @@ -1040,7 +1040,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->nested_type_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindNestedTypeByName(name); } @@ -1092,7 +1092,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->enum_type_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindEnumTypeByName(name); } @@ -1155,7 +1155,7 @@ static int Count(PyContainer* self) { return count; } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindEnumValueByName(name); } @@ -1215,7 +1215,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->extension_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindExtensionByName(name); } @@ -1267,7 +1267,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->oneof_decl_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindOneofByName(name); } @@ -1333,7 +1333,7 @@ static const void* GetByIndex(PyContainer* self, int index) { return GetDescriptor(self)->value(index); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindValueByName(name); } @@ -1454,7 +1454,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->method_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindMethodByName(name); } @@ -1516,7 +1516,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->message_type_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindMessageTypeByName(name); } @@ -1564,7 +1564,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->enum_type_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindEnumTypeByName(name); } @@ -1612,7 +1612,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->extension_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindExtensionByName(name); } @@ -1660,7 +1660,7 @@ static int Count(PyContainer* self) { return GetDescriptor(self)->service_count(); } -static const void* GetByName(PyContainer* self, const std::string& name) { +static const void* GetByName(PyContainer* self, ConstStringParam name) { return GetDescriptor(self)->FindServiceByName(name); } diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index 2cffea305e5d..6f1464e3212d 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -240,7 +240,7 @@ static PyObject* FindMessageByName(PyObject* self, PyObject* arg) { const Descriptor* message_descriptor = reinterpret_cast(self)->pool->FindMessageTypeByName( - std::string(name, name_size)); + StringParam(name, name_size)); if (message_descriptor == NULL) { return SetErrorFromCollector( @@ -264,7 +264,7 @@ static PyObject* FindFileByName(PyObject* self, PyObject* arg) { PyDescriptorPool* py_pool = reinterpret_cast(self); const FileDescriptor* file_descriptor = - py_pool->pool->FindFileByName(std::string(name, name_size)); + py_pool->pool->FindFileByName(StringParam(name, name_size)); if (file_descriptor == NULL) { return SetErrorFromCollector(py_pool->error_collector, name, "file"); @@ -280,7 +280,7 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) { } const FieldDescriptor* field_descriptor = - self->pool->FindFieldByName(std::string(name, name_size)); + self->pool->FindFieldByName(StringParam(name, name_size)); if (field_descriptor == NULL) { return SetErrorFromCollector(self->error_collector, name, "field"); } @@ -301,7 +301,7 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) { } const FieldDescriptor* field_descriptor = - self->pool->FindExtensionByName(std::string(name, name_size)); + self->pool->FindExtensionByName(StringParam(name, name_size)); if (field_descriptor == NULL) { return SetErrorFromCollector(self->error_collector, name, "extension field"); @@ -323,7 +323,7 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) { } const EnumDescriptor* enum_descriptor = - self->pool->FindEnumTypeByName(std::string(name, name_size)); + self->pool->FindEnumTypeByName(StringParam(name, name_size)); if (enum_descriptor == NULL) { return SetErrorFromCollector(self->error_collector, name, "enum"); } @@ -344,7 +344,7 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) { } const OneofDescriptor* oneof_descriptor = - self->pool->FindOneofByName(std::string(name, name_size)); + self->pool->FindOneofByName(StringParam(name, name_size)); if (oneof_descriptor == NULL) { return SetErrorFromCollector(self->error_collector, name, "oneof"); } @@ -366,7 +366,7 @@ static PyObject* FindServiceByName(PyObject* self, PyObject* arg) { const ServiceDescriptor* service_descriptor = reinterpret_cast(self)->pool->FindServiceByName( - std::string(name, name_size)); + StringParam(name, name_size)); if (service_descriptor == NULL) { return SetErrorFromCollector( reinterpret_cast(self)->error_collector, name, @@ -386,7 +386,7 @@ static PyObject* FindMethodByName(PyObject* self, PyObject* arg) { const MethodDescriptor* method_descriptor = reinterpret_cast(self)->pool->FindMethodByName( - std::string(name, name_size)); + StringParam(name, name_size)); if (method_descriptor == NULL) { return SetErrorFromCollector( reinterpret_cast(self)->error_collector, name, @@ -406,7 +406,7 @@ static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) { const FileDescriptor* file_descriptor = reinterpret_cast(self)->pool->FindFileContainingSymbol( - std::string(name, name_size)); + StringParam(name, name_size)); if (file_descriptor == NULL) { return SetErrorFromCollector( reinterpret_cast(self)->error_collector, name, diff --git a/python/google/protobuf/pyext/extension_dict.cc b/python/google/protobuf/pyext/extension_dict.cc index d7226d0c3809..e9ac71409e28 100644 --- a/python/google/protobuf/pyext/extension_dict.cc +++ b/python/google/protobuf/pyext/extension_dict.cc @@ -240,11 +240,11 @@ PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* arg) { PyDescriptorPool* pool = cmessage::GetFactoryForMessage(self->parent)->pool; const FieldDescriptor* message_extension = - pool->pool->FindExtensionByName(std::string(name, name_size)); + pool->pool->FindExtensionByName(StringParam(name, name_size)); if (message_extension == NULL) { // Is is the name of a message set extension? const Descriptor* message_descriptor = - pool->pool->FindMessageTypeByName(std::string(name, name_size)); + pool->pool->FindMessageTypeByName(StringParam(name, name_size)); if (message_descriptor && message_descriptor->extension_count() > 0) { const FieldDescriptor* extension = message_descriptor->extension(0); if (extension->is_extension() && diff --git a/python/google/protobuf/pyext/field.cc b/python/google/protobuf/pyext/field.cc old mode 100755 new mode 100644 diff --git a/python/google/protobuf/pyext/field.h b/python/google/protobuf/pyext/field.h old mode 100755 new mode 100644 diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc index ed0d31c8b6f4..a0ee16fe8634 100644 --- a/python/google/protobuf/pyext/map_container.cc +++ b/python/google/protobuf/pyext/map_container.cc @@ -125,9 +125,9 @@ static bool PyStringToSTL(PyObject* py_string, std::string* stl_string) { } } -static bool PythonToMapKey(PyObject* obj, - const FieldDescriptor* field_descriptor, - MapKey* key) { +static bool PythonToMapKey(MapContainer* self, PyObject* obj, MapKey* key) { + const FieldDescriptor* field_descriptor = + self->parent_field_descriptor->message_type()->map_key(); switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { GOOGLE_CHECK_GET_INT32(obj, value, false); @@ -171,8 +171,9 @@ static bool PythonToMapKey(PyObject* obj, return true; } -static PyObject* MapKeyToPython(const FieldDescriptor* field_descriptor, - const MapKey& key) { +static PyObject* MapKeyToPython(MapContainer* self, const MapKey& key) { + const FieldDescriptor* field_descriptor = + self->parent_field_descriptor->message_type()->map_key(); switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: return PyInt_FromLong(key.GetInt32Value()); @@ -196,8 +197,9 @@ static PyObject* MapKeyToPython(const FieldDescriptor* field_descriptor, // This is only used for ScalarMap, so we don't need to handle the // CPPTYPE_MESSAGE case. -PyObject* MapValueRefToPython(const FieldDescriptor* field_descriptor, - const MapValueRef& value) { +PyObject* MapValueRefToPython(MapContainer* self, const MapValueRef& value) { + const FieldDescriptor* field_descriptor = + self->parent_field_descriptor->message_type()->map_value(); switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: return PyInt_FromLong(value.GetInt32Value()); @@ -227,10 +229,11 @@ PyObject* MapValueRefToPython(const FieldDescriptor* field_descriptor, // This is only used for ScalarMap, so we don't need to handle the // CPPTYPE_MESSAGE case. -static bool PythonToMapValueRef(PyObject* obj, - const FieldDescriptor* field_descriptor, +static bool PythonToMapValueRef(MapContainer* self, PyObject* obj, bool allow_unknown_enum_values, MapValueRef* value_ref) { + const FieldDescriptor* field_descriptor = + self->parent_field_descriptor->message_type()->map_value(); switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { GOOGLE_CHECK_GET_INT32(obj, value, false); @@ -336,6 +339,11 @@ PyObject* GetEntryClass(PyObject* _self) { PyObject* MapReflectionFriend::MergeFrom(PyObject* _self, PyObject* arg) { MapContainer* self = GetMap(_self); + if (!PyObject_TypeCheck(arg, ScalarMapContainer_Type) && + !PyObject_TypeCheck(arg, MessageMapContainer_Type)) { + PyErr_SetString(PyExc_AttributeError, "Not a map field"); + return nullptr; + } MapContainer* other_map = GetMap(arg); Message* message = self->GetMutableMessage(); const Message* other_message = other_map->parent->message; @@ -357,7 +365,7 @@ PyObject* MapReflectionFriend::Contains(PyObject* _self, PyObject* key) { const Reflection* reflection = message->GetReflection(); MapKey map_key; - if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { + if (!PythonToMapKey(self, key, &map_key)) { return NULL; } @@ -391,18 +399,6 @@ MapContainer* NewScalarMapContainer( self->parent_field_descriptor = parent_field_descriptor; self->version = 0; - self->key_field_descriptor = - parent_field_descriptor->message_type()->FindFieldByName("key"); - self->value_field_descriptor = - parent_field_descriptor->message_type()->FindFieldByName("value"); - - if (self->key_field_descriptor == NULL || - self->value_field_descriptor == NULL) { - PyErr_Format(PyExc_KeyError, - "Map entry descriptor did not have key/value fields"); - return NULL; - } - return self; } @@ -415,7 +411,7 @@ PyObject* MapReflectionFriend::ScalarMapGetItem(PyObject* _self, MapKey map_key; MapValueRef value; - if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { + if (!PythonToMapKey(self, key, &map_key)) { return NULL; } @@ -424,7 +420,7 @@ PyObject* MapReflectionFriend::ScalarMapGetItem(PyObject* _self, self->version++; } - return MapValueRefToPython(self->value_field_descriptor, value); + return MapValueRefToPython(self, value); } int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key, @@ -436,7 +432,7 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key, MapKey map_key; MapValueRef value; - if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { + if (!PythonToMapKey(self, key, &map_key)) { return -1; } @@ -447,10 +443,11 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key, reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor, map_key, &value); - return PythonToMapValueRef(v, self->value_field_descriptor, - reflection->SupportsUnknownEnumValues(), &value) - ? 0 - : -1; + if (!PythonToMapValueRef(self, v, reflection->SupportsUnknownEnumValues(), + &value)) { + return -1; + } + return 0; } else { // Delete key from map. if (reflection->DeleteMapValue(message, self->parent_field_descriptor, @@ -505,13 +502,11 @@ PyObject* MapReflectionFriend::ScalarMapToStr(PyObject* _self) { message, self->parent_field_descriptor); it != reflection->MapEnd(message, self->parent_field_descriptor); ++it) { - key.reset(MapKeyToPython(self->key_field_descriptor, - it.GetKey())); + key.reset(MapKeyToPython(self, it.GetKey())); if (key == NULL) { return NULL; } - value.reset(MapValueRefToPython(self->value_field_descriptor, - it.GetValueRef())); + value.reset(MapValueRefToPython(self, it.GetValueRef())); if (value == NULL) { return NULL; } @@ -655,22 +650,9 @@ MessageMapContainer* NewMessageMapContainer( self->parent_field_descriptor = parent_field_descriptor; self->version = 0; - self->key_field_descriptor = - parent_field_descriptor->message_type()->FindFieldByName("key"); - self->value_field_descriptor = - parent_field_descriptor->message_type()->FindFieldByName("value"); - Py_INCREF(message_class); self->message_class = message_class; - if (self->key_field_descriptor == NULL || - self->value_field_descriptor == NULL) { - Py_DECREF(self); - PyErr_SetString(PyExc_KeyError, - "Map entry descriptor did not have key/value fields"); - return NULL; - } - return self; } @@ -692,7 +674,7 @@ int MapReflectionFriend::MessageMapSetItem(PyObject* _self, PyObject* key, self->version++; - if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { + if (!PythonToMapKey(self, key, &map_key)) { return -1; } @@ -732,7 +714,7 @@ PyObject* MapReflectionFriend::MessageMapGetItem(PyObject* _self, MapKey map_key; MapValueRef value; - if (!PythonToMapKey(key, self->key_field_descriptor, &map_key)) { + if (!PythonToMapKey(self, key, &map_key)) { return NULL; } @@ -759,8 +741,7 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) { message, self->parent_field_descriptor); it != reflection->MapEnd(message, self->parent_field_descriptor); ++it) { - key.reset(MapKeyToPython(self->key_field_descriptor, - it.GetKey())); + key.reset(MapKeyToPython(self, it.GetKey())); if (key == NULL) { return NULL; } @@ -961,8 +942,7 @@ PyObject* MapReflectionFriend::IterNext(PyObject* _self) { return NULL; } - PyObject* ret = MapKeyToPython(self->container->key_field_descriptor, - self->iter->GetKey()); + PyObject* ret = MapKeyToPython(self->container, self->iter->GetKey()); ++(*self->iter); diff --git a/python/google/protobuf/pyext/map_container.h b/python/google/protobuf/pyext/map_container.h index 2c9b323efaef..a28945da07b2 100644 --- a/python/google/protobuf/pyext/map_container.h +++ b/python/google/protobuf/pyext/map_container.h @@ -54,9 +54,6 @@ struct MapContainer : public ContainerBase { // Use to get a mutable message when necessary. Message* GetMutableMessage(); - // Cache some descriptors, used to convert keys and values. - const FieldDescriptor* key_field_descriptor; - const FieldDescriptor* value_field_descriptor; // We bump this whenever we perform a mutation, to invalidate existing // iterators. uint64 version; diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 419f8f516ec7..0301e9634daf 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -33,11 +33,14 @@ #include +#include // A Python header file. + #include #include #include #include -#include // A Python header file. + +#include #ifndef PyVarObject_HEAD_INIT #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, @@ -240,7 +243,7 @@ static PyObject* New(PyTypeObject* type, } message_descriptor = GetDefaultDescriptorPool()->pool->FindMessageTypeByName( - std::string(full_name, name_size)); + StringParam(full_name, name_size)); if (message_descriptor == nullptr) { PyErr_Format(PyExc_KeyError, "Can not find message descriptor %s " @@ -456,7 +459,7 @@ static PyObject* GetClassAttribute(CMessageClass *self, PyObject* name) { Py_ssize_t attr_size; static const char kSuffix[] = "_FIELD_NUMBER"; if (PyString_AsStringAndSize(name, &attr, &attr_size) >= 0 && - strings::EndsWith(StringPiece(attr, attr_size), kSuffix)) { + HasSuffixString(StringPiece(attr, attr_size), kSuffix)) { std::string field_name(attr, attr_size - sizeof(kSuffix) + 1); LowerString(&field_name); @@ -806,7 +809,7 @@ bool CheckAndSetString( return false; } - string value_string(value, value_len); + std::string value_string(value, value_len); if (append) { reflection->AddString(message, descriptor, std::move(value_string)); } else if (index < 0) { @@ -981,7 +984,7 @@ static PyObject* GetIntegerEnumValue(const FieldDescriptor& descriptor, return NULL; } const EnumValueDescriptor* enum_value_descriptor = - enum_descriptor->FindValueByName(std::string(enum_label, size)); + enum_descriptor->FindValueByName(StringParam(enum_label, size)); if (enum_value_descriptor == NULL) { PyErr_Format(PyExc_ValueError, "unknown enum label \"%s\"", enum_label); return NULL; @@ -1396,7 +1399,7 @@ int HasFieldByDescriptor(CMessage* self, } const FieldDescriptor* FindFieldWithOneofs(const Message* message, - const std::string& field_name, + ConstStringParam field_name, bool* in_oneof) { *in_oneof = false; const Descriptor* descriptor = message->GetDescriptor(); @@ -1424,28 +1427,12 @@ bool CheckHasPresence(const FieldDescriptor* field_descriptor, bool in_oneof) { return false; } - if (field_descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { - // HasField() for a oneof *itself* isn't supported. - if (in_oneof) { - PyErr_Format(PyExc_ValueError, - "Can't test oneof field \"%s.%s\" for presence in proto3, " - "use WhichOneof instead.", message_name.c_str(), - field_descriptor->containing_oneof()->name().c_str()); - return false; - } - - // ...but HasField() for fields *in* a oneof is supported. - if (field_descriptor->containing_oneof() != NULL) { - return true; - } - - if (field_descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - PyErr_Format( - PyExc_ValueError, - "Can't test non-submessage field \"%s.%s\" for presence in proto3.", - message_name.c_str(), field_descriptor->name().c_str()); - return false; - } + if (!field_descriptor->has_presence()) { + PyErr_Format(PyExc_ValueError, + "Can't test non-optional, non-submessage field \"%s.%s\" for " + "presence in proto3.", + message_name.c_str(), field_descriptor->name().c_str()); + return false; } return true; @@ -1468,7 +1455,7 @@ PyObject* HasField(CMessage* self, PyObject* arg) { Message* message = self->message; bool is_in_oneof; const FieldDescriptor* field_descriptor = - FindFieldWithOneofs(message, std::string(field_name, size), &is_in_oneof); + FindFieldWithOneofs(message, StringParam(field_name, size), &is_in_oneof); if (field_descriptor == NULL) { if (!is_in_oneof) { PyErr_Format(PyExc_ValueError, "Protocol message %s has no field %s.", @@ -1645,7 +1632,7 @@ PyObject* ClearField(CMessage* self, PyObject* arg) { AssureWritable(self); bool is_in_oneof; const FieldDescriptor* field_descriptor = FindFieldWithOneofs( - self->message, std::string(field_name, field_size), &is_in_oneof); + self->message, StringParam(field_name, field_size), &is_in_oneof); if (field_descriptor == NULL) { if (is_in_oneof) { // We gave the name of a oneof, and none of its fields are set. @@ -2046,13 +2033,12 @@ static PyObject* WhichOneof(CMessage* self, PyObject* arg) { char *name_data; if (PyString_AsStringAndSize(arg, &name_data, &name_size) < 0) return NULL; - std::string oneof_name = std::string(name_data, name_size); const OneofDescriptor* oneof_desc = - self->message->GetDescriptor()->FindOneofByName(oneof_name); + self->message->GetDescriptor()->FindOneofByName( + StringParam(name_data, name_size)); if (oneof_desc == NULL) { PyErr_Format(PyExc_ValueError, - "Protocol message has no oneof \"%s\" field.", - oneof_name.c_str()); + "Protocol message has no oneof \"%s\" field.", name_data); return NULL; } const FieldDescriptor* field_in_oneof = @@ -2183,19 +2169,21 @@ static PyObject* RichCompare(CMessage* self, PyObject* other, int opid) { // If other is not a message, it cannot be equal. if (!PyObject_TypeCheck(other, CMessage_Type)) { equals = false; - } - const google::protobuf::Message* other_message = - reinterpret_cast(other)->message; - // If messages don't have the same descriptors, they are not equal. - if (equals && - self->message->GetDescriptor() != other_message->GetDescriptor()) { - equals = false; - } - // Check the message contents. - if (equals && !google::protobuf::util::MessageDifferencer::Equals( - *self->message, - *reinterpret_cast(other)->message)) { - equals = false; + } else { + // Otherwise, we have a CMessage whose message we can inspect. + const google::protobuf::Message* other_message = + reinterpret_cast(other)->message; + // If messages don't have the same descriptors, they are not equal. + if (equals && + self->message->GetDescriptor() != other_message->GetDescriptor()) { + equals = false; + } + // Check the message contents. + if (equals && + !google::protobuf::util::MessageDifferencer::Equals( + *self->message, *reinterpret_cast(other)->message)) { + equals = false; + } } if (equals ^ (opid == Py_EQ)) { diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc index 4bb35b31936b..63d60b70e7b3 100644 --- a/python/google/protobuf/pyext/message_module.cc +++ b/python/google/protobuf/pyext/message_module.cc @@ -107,9 +107,12 @@ PyMODINIT_FUNC INITFUNC() { } // Adds the C++ API - if (PyObject* api = - PyCapsule_New(new ApiImplementation(), - google::protobuf::python::PyProtoAPICapsuleName(), NULL)) { + if (PyObject* api = PyCapsule_New( + new ApiImplementation(), google::protobuf::python::PyProtoAPICapsuleName(), + [](PyObject* o) { + delete (ApiImplementation*)PyCapsule_GetPointer( + o, google::protobuf::python::PyProtoAPICapsuleName()); + })) { PyModule_AddObject(m, "proto_API", api); } else { return INITFUNC_ERRORVAL; diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc index 4188b5f4a1b8..1b739ae23936 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.cc +++ b/python/google/protobuf/pyext/repeated_composite_container.cc @@ -77,8 +77,7 @@ static Py_ssize_t Length(PyObject* pself) { PyObject* Add(RepeatedCompositeContainer* self, PyObject* args, PyObject* kwargs) { - if (cmessage::AssureWritable(self->parent) == -1) - return NULL; + if (cmessage::AssureWritable(self->parent) == -1) return nullptr; Message* message = self->parent->message; Message* sub_message = @@ -93,7 +92,7 @@ PyObject* Add(RepeatedCompositeContainer* self, PyObject* args, message->GetReflection()->RemoveLast( message, self->parent_field_descriptor); Py_DECREF(cmsg); - return NULL; + return nullptr; } return cmsg->AsPyObject(); @@ -172,28 +171,28 @@ static PyObject* Insert(PyObject* pself, PyObject* args) { PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) { cmessage::AssureWritable(self->parent); ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); - return NULL; + return nullptr; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { if (!PyObject_TypeCheck(next.get(), CMessage_Type)) { PyErr_SetString(PyExc_TypeError, "Not a cmessage"); - return NULL; + return nullptr; } - ScopedPyObjectPtr new_message(Add(self, NULL, NULL)); - if (new_message == NULL) { - return NULL; + ScopedPyObjectPtr new_message(Add(self, nullptr, nullptr)); + if (new_message == nullptr) { + return nullptr; } CMessage* new_cmessage = reinterpret_cast(new_message.get()); if (ScopedPyObjectPtr(cmessage::MergeFrom(new_cmessage, next.get())) == - NULL) { - return NULL; + nullptr) { + return nullptr; } } if (PyErr_Occurred()) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -220,7 +219,7 @@ static PyObject* GetItem(RepeatedCompositeContainer* self, Py_ssize_t index, } if (index < 0 || index >= length) { PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); - return NULL; + return nullptr; } Message* message = self->parent->message; Message* sub_message = message->GetReflection()->MutableRepeatedMessage( @@ -240,7 +239,7 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* item) { if (PyIndex_Check(item)) { Py_ssize_t index; index = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (index == -1 && PyErr_Occurred()) return NULL; + if (index == -1 && PyErr_Occurred()) return nullptr; if (index < 0) index += length; return GetItem(self, index, length); } else if (PySlice_Check(item)) { @@ -254,14 +253,14 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* item) { if (PySlice_GetIndicesEx(reinterpret_cast(item), length, &from, &to, &step, &slicelength) == -1) { #endif - return NULL; + return nullptr; } if (slicelength <= 0) { return PyList_New(0); } else { result = PyList_New(slicelength); - if (!result) return NULL; + if (!result) return nullptr; for (cur = from, i = 0; i < slicelength; cur += step, i++) { PyList_SET_ITEM(result, i, GetItem(self, cur, length)); @@ -272,7 +271,7 @@ PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* item) { } else { PyErr_Format(PyExc_TypeError, "indices must be integers, not %.200s", item->ob_type->tp_name); - return NULL; + return nullptr; } } @@ -283,7 +282,7 @@ static PyObject* SubscriptMethod(PyObject* self, PyObject* slice) { int AssignSubscript(RepeatedCompositeContainer* self, PyObject* slice, PyObject* value) { - if (value != NULL) { + if (value != nullptr) { PyErr_SetString(PyExc_TypeError, "does not support assignment"); return -1; } @@ -305,23 +304,23 @@ static PyObject* Remove(PyObject* pself, PyObject* value) { for (Py_ssize_t i = 0; i < len; i++) { ScopedPyObjectPtr item(GetItem(self, i, len)); - if (item == NULL) { - return NULL; + if (item == nullptr) { + return nullptr; } int result = PyObject_RichCompareBool(item.get(), value, Py_EQ); if (result < 0) { - return NULL; + return nullptr; } if (result) { ScopedPyObjectPtr py_index(PyLong_FromSsize_t(i)); - if (AssignSubscript(self, py_index.get(), NULL) < 0) { - return NULL; + if (AssignSubscript(self, py_index.get(), nullptr) < 0) { + return nullptr; } Py_RETURN_NONE; } } PyErr_SetString(PyExc_ValueError, "Item to delete not in list"); - return NULL; + return nullptr; } static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { @@ -332,23 +331,23 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { PyErr_SetString(PyExc_TypeError, "Can only compare repeated composite fields " "against other repeated composite fields."); - return NULL; + return nullptr; } if (opid == Py_EQ || opid == Py_NE) { // TODO(anuraag): Don't make new lists just for this... - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript(self, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } ScopedPyObjectPtr other_list( Subscript(reinterpret_cast(other), full_slice.get())); - if (other_list == NULL) { - return NULL; + if (other_list == nullptr) { + return nullptr; } return PyObject_RichCompare(list.get(), other_list.get(), opid); } else { @@ -358,14 +357,14 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { } static PyObject* ToStr(PyObject* pself) { - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript( reinterpret_cast(pself), full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } return PyObject_Repr(list.get()); } @@ -400,13 +399,12 @@ static int SortPythonMessages(RepeatedCompositeContainer* self, PyObject* kwds) { ScopedPyObjectPtr child_list( PySequence_List(reinterpret_cast(self))); - if (child_list == NULL) { + if (child_list == nullptr) { return -1; } ScopedPyObjectPtr m(PyObject_GetAttrString(child_list.get(), "sort")); - if (m == NULL) - return -1; - if (ScopedPyObjectPtr(PyObject_Call(m.get(), args, kwds)) == NULL) + if (m == nullptr) return -1; + if (ScopedPyObjectPtr(PyObject_Call(m.get(), args, kwds)) == nullptr) return -1; ReorderAttached(self, child_list.get()); return 0; @@ -418,9 +416,9 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { // Support the old sort_function argument for backwards // compatibility. - if (kwds != NULL) { + if (kwds != nullptr) { PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function"); - if (sort_func != NULL) { + if (sort_func != nullptr) { // Must set before deleting as sort_func is a borrowed reference // and kwds might be the only thing keeping it alive. PyDict_SetItemString(kwds, "cmp", sort_func); @@ -429,7 +427,35 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { } if (SortPythonMessages(self, args, kwds) < 0) { - return NULL; + return nullptr; + } + Py_RETURN_NONE; +} + +// --------------------------------------------------------------------- +// reverse() + +// Returns 0 if successful; returns -1 and sets an exception if +// unsuccessful. +static int ReversePythonMessages(RepeatedCompositeContainer* self) { + ScopedPyObjectPtr child_list( + PySequence_List(reinterpret_cast(self))); + if (child_list == nullptr) { + return -1; + } + if (ScopedPyObjectPtr( + PyObject_CallMethod(child_list.get(), "reverse", nullptr)) == nullptr) + return -1; + ReorderAttached(self, child_list.get()); + return 0; +} + +static PyObject* Reverse(PyObject* pself) { + RepeatedCompositeContainer* self = + reinterpret_cast(pself); + + if (ReversePythonMessages(self) < 0) { + return nullptr; } Py_RETURN_NONE; } @@ -448,17 +474,17 @@ static PyObject* Pop(PyObject* pself, PyObject* args) { Py_ssize_t index = -1; if (!PyArg_ParseTuple(args, "|n", &index)) { - return NULL; + return nullptr; } Py_ssize_t length = Length(pself); if (index < 0) index += length; PyObject* item = GetItem(self, index, length); - if (item == NULL) { - return NULL; + if (item == nullptr) { + return nullptr; } ScopedPyObjectPtr py_index(PyLong_FromSsize_t(index)); - if (AssignSubscript(self, py_index.get(), NULL) < 0) { - return NULL; + if (AssignSubscript(self, py_index.get(), nullptr) < 0) { + return nullptr; } return item; } @@ -473,14 +499,14 @@ RepeatedCompositeContainer *NewContainer( const FieldDescriptor* parent_field_descriptor, CMessageClass* child_message_class) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } RepeatedCompositeContainer* self = reinterpret_cast( PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -500,10 +526,10 @@ static void Dealloc(PyObject* pself) { } static PySequenceMethods SqMethods = { - Length, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - Item /* sq_item */ + Length, /* sq_length */ + nullptr, /* sq_concat */ + nullptr, /* sq_repeat */ + Item /* sq_item */ }; static PyMappingMethods MpMethods = { @@ -513,66 +539,65 @@ static PyMappingMethods MpMethods = { }; static PyMethodDef Methods[] = { - { "__deepcopy__", DeepCopy, METH_VARARGS, - "Makes a deep copy of the class." }, - { "add", (PyCFunction)AddMethod, METH_VARARGS | METH_KEYWORDS, - "Adds an object to the repeated container." }, - { "append", AppendMethod, METH_O, - "Appends a message to the end of the repeated container."}, - { "insert", Insert, METH_VARARGS, - "Inserts a message before the specified index." }, - { "extend", ExtendMethod, METH_O, - "Adds objects to the repeated container." }, - { "pop", Pop, METH_VARARGS, - "Removes an object from the repeated container and returns it." }, - { "remove", Remove, METH_O, - "Removes an object from the repeated container." }, - { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS, - "Sorts the repeated container." }, - { "MergeFrom", MergeFromMethod, METH_O, - "Adds objects to the repeated container." }, - { NULL, NULL } -}; + {"__deepcopy__", DeepCopy, METH_VARARGS, "Makes a deep copy of the class."}, + {"add", reinterpret_cast(AddMethod), + METH_VARARGS | METH_KEYWORDS, "Adds an object to the repeated container."}, + {"append", AppendMethod, METH_O, + "Appends a message to the end of the repeated container."}, + {"insert", Insert, METH_VARARGS, + "Inserts a message before the specified index."}, + {"extend", ExtendMethod, METH_O, "Adds objects to the repeated container."}, + {"pop", Pop, METH_VARARGS, + "Removes an object from the repeated container and returns it."}, + {"remove", Remove, METH_O, + "Removes an object from the repeated container."}, + {"sort", reinterpret_cast(Sort), METH_VARARGS | METH_KEYWORDS, + "Sorts the repeated container."}, + {"reverse", reinterpret_cast(Reverse), METH_NOARGS, + "Reverses elements order of the repeated container."}, + {"MergeFrom", MergeFromMethod, METH_O, + "Adds objects to the repeated container."}, + {nullptr, nullptr}}; } // namespace repeated_composite_container PyTypeObject RepeatedCompositeContainer_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".RepeatedCompositeContainer", // tp_name - sizeof(RepeatedCompositeContainer), // tp_basicsize - 0, // tp_itemsize - repeated_composite_container::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - repeated_composite_container::ToStr, // tp_repr - 0, // tp_as_number - &repeated_composite_container::SqMethods, // tp_as_sequence - &repeated_composite_container::MpMethods, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Repeated scalar container", // tp_doc - 0, // tp_traverse - 0, // tp_clear - repeated_composite_container::RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - repeated_composite_container::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".RepeatedCompositeContainer", // tp_name + sizeof(RepeatedCompositeContainer), // tp_basicsize + 0, // tp_itemsize + repeated_composite_container::Dealloc, // tp_dealloc + 0, // tp_print, in Python >=3.8: Py_ssize_t tp_vectorcall_offset + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + repeated_composite_container::ToStr, // tp_repr + nullptr, // tp_as_number + &repeated_composite_container::SqMethods, // tp_as_sequence + &repeated_composite_container::MpMethods, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Repeated scalar container", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + repeated_composite_container::RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + repeated_composite_container::Methods, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; } // namespace python diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc index 712182b3747e..6b15258fd81c 100644 --- a/python/google/protobuf/pyext/repeated_scalar_container.cc +++ b/python/google/protobuf/pyext/repeated_scalar_container.cc @@ -46,13 +46,13 @@ #include #if PY_MAJOR_VERSION >= 3 - #define PyInt_FromLong PyLong_FromLong - #if PY_VERSION_HEX < 0x03030000 - #error "Python 3.0 - 3.2 are not supported." - #else - #define PyString_AsString(ob) \ - (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AsString(ob)) - #endif +#define PyInt_FromLong PyLong_FromLong +#if PY_VERSION_HEX < 0x03030000 +#error "Python 3.0 - 3.2 are not supported." +#else +#define PyString_AsString(ob) \ + (PyUnicode_Check(ob) ? PyUnicode_AsUTF8(ob) : PyBytes_AsString(ob)) +#endif #endif namespace google { @@ -61,13 +61,13 @@ namespace python { namespace repeated_scalar_container { -static int InternalAssignRepeatedField( - RepeatedScalarContainer* self, PyObject* list) { +static int InternalAssignRepeatedField(RepeatedScalarContainer* self, + PyObject* list) { Message* message = self->parent->message; message->GetReflection()->ClearField(message, self->parent_field_descriptor); for (Py_ssize_t i = 0; i < PyList_GET_SIZE(list); ++i) { PyObject* value = PyList_GET_ITEM(list, i); - if (ScopedPyObjectPtr(Append(self, value)) == NULL) { + if (ScopedPyObjectPtr(Append(self, value)) == nullptr) { return -1; } } @@ -96,13 +96,12 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { index = field_size + index; } if (index < 0 || index >= field_size) { - PyErr_Format(PyExc_IndexError, - "list assignment index (%d) out of range", + PyErr_Format(PyExc_IndexError, "list assignment index (%d) out of range", static_cast(index)); return -1; } - if (arg == NULL) { + if (arg == nullptr) { ScopedPyObjectPtr py_index(PyLong_FromLong(index)); return cmessage::DeleteRepeatedField(self->parent, field_descriptor, py_index.get()); @@ -150,8 +149,8 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { break; } case FieldDescriptor::CPPTYPE_STRING: { - if (!CheckAndSetString( - arg, message, field_descriptor, reflection, false, index)) { + if (!CheckAndSetString(arg, message, field_descriptor, reflection, false, + index)) { return -1; } break; @@ -165,12 +164,12 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { const EnumDescriptor* enum_descriptor = field_descriptor->enum_type(); const EnumValueDescriptor* enum_value = enum_descriptor->FindValueByNumber(value); - if (enum_value != NULL) { + if (enum_value != nullptr) { reflection->SetRepeatedEnum(message, field_descriptor, index, enum_value); } else { ScopedPyObjectPtr s(PyObject_Str(arg)); - if (s != NULL) { + if (s != nullptr) { PyErr_Format(PyExc_ValueError, "Unknown enum value: %s", PyString_AsString(s.get())); } @@ -180,9 +179,9 @@ static int AssignItem(PyObject* pself, Py_ssize_t index, PyObject* arg) { break; } default: - PyErr_Format( - PyExc_SystemError, "Adding value to a field of unknown type %d", - field_descriptor->cpp_type()); + PyErr_Format(PyExc_SystemError, + "Adding value to a field of unknown type %d", + field_descriptor->cpp_type()); return -1; } return 0; @@ -201,60 +200,58 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { index = field_size + index; } if (index < 0 || index >= field_size) { - PyErr_Format(PyExc_IndexError, - "list index (%zd) out of range", - index); - return NULL; + PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); + return nullptr; } - PyObject* result = NULL; + PyObject* result = nullptr; switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { - int32 value = reflection->GetRepeatedInt32( - *message, field_descriptor, index); + int32 value = + reflection->GetRepeatedInt32(*message, field_descriptor, index); result = PyInt_FromLong(value); break; } case FieldDescriptor::CPPTYPE_INT64: { - int64 value = reflection->GetRepeatedInt64( - *message, field_descriptor, index); + int64 value = + reflection->GetRepeatedInt64(*message, field_descriptor, index); result = PyLong_FromLongLong(value); break; } case FieldDescriptor::CPPTYPE_UINT32: { - uint32 value = reflection->GetRepeatedUInt32( - *message, field_descriptor, index); + uint32 value = + reflection->GetRepeatedUInt32(*message, field_descriptor, index); result = PyLong_FromLongLong(value); break; } case FieldDescriptor::CPPTYPE_UINT64: { - uint64 value = reflection->GetRepeatedUInt64( - *message, field_descriptor, index); + uint64 value = + reflection->GetRepeatedUInt64(*message, field_descriptor, index); result = PyLong_FromUnsignedLongLong(value); break; } case FieldDescriptor::CPPTYPE_FLOAT: { - float value = reflection->GetRepeatedFloat( - *message, field_descriptor, index); + float value = + reflection->GetRepeatedFloat(*message, field_descriptor, index); result = PyFloat_FromDouble(value); break; } case FieldDescriptor::CPPTYPE_DOUBLE: { - double value = reflection->GetRepeatedDouble( - *message, field_descriptor, index); + double value = + reflection->GetRepeatedDouble(*message, field_descriptor, index); result = PyFloat_FromDouble(value); break; } case FieldDescriptor::CPPTYPE_BOOL: { - bool value = reflection->GetRepeatedBool( - *message, field_descriptor, index); + bool value = + reflection->GetRepeatedBool(*message, field_descriptor, index); result = PyBool_FromLong(value ? 1 : 0); break; } case FieldDescriptor::CPPTYPE_ENUM: { const EnumValueDescriptor* enum_value = - message->GetReflection()->GetRepeatedEnum( - *message, field_descriptor, index); + message->GetReflection()->GetRepeatedEnum(*message, field_descriptor, + index); result = PyInt_FromLong(enum_value->number()); break; } @@ -266,10 +263,9 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { break; } default: - PyErr_Format( - PyExc_SystemError, - "Getting value from a repeated field of unknown type %d", - field_descriptor->cpp_type()); + PyErr_Format(PyExc_SystemError, + "Getting value from a repeated field of unknown type %d", + field_descriptor->cpp_type()); } return result; @@ -287,23 +283,23 @@ static PyObject* Subscript(PyObject* pself, PyObject* slice) { from = to = PyInt_AsLong(slice); } else // NOLINT #endif - if (PyLong_Check(slice)) { + if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); } else if (PySlice_Check(slice)) { length = Len(pself); #if PY_MAJOR_VERSION >= 3 - if (PySlice_GetIndicesEx(slice, - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) == + -1) { #else - if (PySlice_GetIndicesEx(reinterpret_cast(slice), - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(reinterpret_cast(slice), length, + &from, &to, &step, &slicelength) == -1) { #endif - return NULL; + return nullptr; } return_list = true; } else { PyErr_SetString(PyExc_TypeError, "list indices must be integers"); - return NULL; + return nullptr; } if (!return_list) { @@ -311,8 +307,8 @@ static PyObject* Subscript(PyObject* pself, PyObject* slice) { } PyObject* list = PyList_New(0); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } if (from <= to) { if (step < 0) { @@ -348,73 +344,73 @@ PyObject* Append(RepeatedScalarContainer* self, PyObject* item) { const Reflection* reflection = message->GetReflection(); switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { - GOOGLE_CHECK_GET_INT32(item, value, NULL); + GOOGLE_CHECK_GET_INT32(item, value, nullptr); reflection->AddInt32(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_INT64: { - GOOGLE_CHECK_GET_INT64(item, value, NULL); + GOOGLE_CHECK_GET_INT64(item, value, nullptr); reflection->AddInt64(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_UINT32: { - GOOGLE_CHECK_GET_UINT32(item, value, NULL); + GOOGLE_CHECK_GET_UINT32(item, value, nullptr); reflection->AddUInt32(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_UINT64: { - GOOGLE_CHECK_GET_UINT64(item, value, NULL); + GOOGLE_CHECK_GET_UINT64(item, value, nullptr); reflection->AddUInt64(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_FLOAT: { - GOOGLE_CHECK_GET_FLOAT(item, value, NULL); + GOOGLE_CHECK_GET_FLOAT(item, value, nullptr); reflection->AddFloat(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_DOUBLE: { - GOOGLE_CHECK_GET_DOUBLE(item, value, NULL); + GOOGLE_CHECK_GET_DOUBLE(item, value, nullptr); reflection->AddDouble(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_BOOL: { - GOOGLE_CHECK_GET_BOOL(item, value, NULL); + GOOGLE_CHECK_GET_BOOL(item, value, nullptr); reflection->AddBool(message, field_descriptor, value); break; } case FieldDescriptor::CPPTYPE_STRING: { - if (!CheckAndSetString( - item, message, field_descriptor, reflection, true, -1)) { - return NULL; + if (!CheckAndSetString(item, message, field_descriptor, reflection, true, + -1)) { + return nullptr; } break; } case FieldDescriptor::CPPTYPE_ENUM: { - GOOGLE_CHECK_GET_INT32(item, value, NULL); + GOOGLE_CHECK_GET_INT32(item, value, nullptr); if (reflection->SupportsUnknownEnumValues()) { reflection->AddEnumValue(message, field_descriptor, value); } else { const EnumDescriptor* enum_descriptor = field_descriptor->enum_type(); const EnumValueDescriptor* enum_value = enum_descriptor->FindValueByNumber(value); - if (enum_value != NULL) { + if (enum_value != nullptr) { reflection->AddEnum(message, field_descriptor, enum_value); } else { ScopedPyObjectPtr s(PyObject_Str(item)); - if (s != NULL) { + if (s != nullptr) { PyErr_Format(PyExc_ValueError, "Unknown enum value: %s", PyString_AsString(s.get())); } - return NULL; + return nullptr; } } break; } default: - PyErr_Format( - PyExc_SystemError, "Adding value to a field of unknown type %d", - field_descriptor->cpp_type()); - return NULL; + PyErr_Format(PyExc_SystemError, + "Adding value to a field of unknown type %d", + field_descriptor->cpp_type()); + return nullptr; } Py_RETURN_NONE; @@ -437,25 +433,24 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) { cmessage::AssureWritable(self->parent); Message* message = self->parent->message; - const FieldDescriptor* field_descriptor = - self->parent_field_descriptor; + const FieldDescriptor* field_descriptor = self->parent_field_descriptor; #if PY_MAJOR_VERSION < 3 if (PyInt_Check(slice)) { from = to = PyInt_AsLong(slice); } else // NOLINT #endif - if (PyLong_Check(slice)) { + if (PyLong_Check(slice)) { from = to = PyLong_AsLong(slice); } else if (PySlice_Check(slice)) { const Reflection* reflection = message->GetReflection(); length = reflection->FieldSize(*message, field_descriptor); #if PY_MAJOR_VERSION >= 3 - if (PySlice_GetIndicesEx(slice, - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(slice, length, &from, &to, &step, &slicelength) == + -1) { #else - if (PySlice_GetIndicesEx(reinterpret_cast(slice), - length, &from, &to, &step, &slicelength) == -1) { + if (PySlice_GetIndicesEx(reinterpret_cast(slice), length, + &from, &to, &step, &slicelength) == -1) { #endif return -1; } @@ -465,7 +460,7 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) { return -1; } - if (value == NULL) { + if (value == nullptr) { return cmessage::DeleteRepeatedField(self->parent, field_descriptor, slice); } @@ -473,12 +468,12 @@ static int AssSubscript(PyObject* pself, PyObject* slice, PyObject* value) { return AssignItem(pself, from, value); } - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { return -1; } ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get())); - if (new_list == NULL) { + if (new_list == nullptr) { return -1; } if (PySequence_SetSlice(new_list.get(), from, to, value) < 0) { @@ -495,23 +490,23 @@ PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) { if (value == Py_None) { Py_RETURN_NONE; } - if ((Py_TYPE(value)->tp_as_sequence == NULL) && PyObject_Not(value)) { + if ((Py_TYPE(value)->tp_as_sequence == nullptr) && PyObject_Not(value)) { Py_RETURN_NONE; } ScopedPyObjectPtr iter(PyObject_GetIter(value)); - if (iter == NULL) { + if (iter == nullptr) { PyErr_SetString(PyExc_TypeError, "Value must be iterable"); - return NULL; + return nullptr; } ScopedPyObjectPtr next; - while ((next.reset(PyIter_Next(iter.get()))) != NULL) { - if (ScopedPyObjectPtr(Append(self, next.get())) == NULL) { - return NULL; + while ((next.reset(PyIter_Next(iter.get()))) != nullptr) { + if (ScopedPyObjectPtr(Append(self, next.get())) == nullptr) { + return nullptr; } } if (PyErr_Occurred()) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -523,16 +518,16 @@ static PyObject* Insert(PyObject* pself, PyObject* args) { Py_ssize_t index; PyObject* value; if (!PyArg_ParseTuple(args, "lO", &index, &value)) { - return NULL; + return nullptr; } - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); ScopedPyObjectPtr new_list(Subscript(pself, full_slice.get())); if (PyList_Insert(new_list.get(), index, value) < 0) { - return NULL; + return nullptr; } int ret = InternalAssignRepeatedField(self, new_list.get()); if (ret < 0) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -548,10 +543,10 @@ static PyObject* Remove(PyObject* pself, PyObject* value) { } if (match_index == -1) { PyErr_SetString(PyExc_ValueError, "remove(x): x not in container"); - return NULL; + return nullptr; } - if (AssignItem(pself, match_index, NULL) < 0) { - return NULL; + if (AssignItem(pself, match_index, nullptr) < 0) { + return nullptr; } Py_RETURN_NONE; } @@ -570,9 +565,9 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { // also a repeated scalar container, into Python lists so we can delegate // to the list's compare method. - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr other_list_deleter; @@ -582,54 +577,72 @@ static PyObject* RichCompare(PyObject* pself, PyObject* other, int opid) { } ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } return PyObject_RichCompare(list.get(), other, opid); } PyObject* Reduce(PyObject* unused_self, PyObject* unused_other) { - PyErr_Format( - PickleError_class, - "can't pickle repeated message fields, convert to list first"); - return NULL; + PyErr_Format(PickleError_class, + "can't pickle repeated message fields, convert to list first"); + return nullptr; } static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { // Support the old sort_function argument for backwards // compatibility. - if (kwds != NULL) { + if (kwds != nullptr) { PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function"); - if (sort_func != NULL) { + if (sort_func != nullptr) { // Must set before deleting as sort_func is a borrowed reference // and kwds might be the only thing keeping it alive. - if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1) - return NULL; - if (PyDict_DelItemString(kwds, "sort_function") == -1) - return NULL; + if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1) return nullptr; + if (PyDict_DelItemString(kwds, "sort_function") == -1) return nullptr; } } - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } ScopedPyObjectPtr m(PyObject_GetAttrString(list.get(), "sort")); - if (m == NULL) { - return NULL; + if (m == nullptr) { + return nullptr; } ScopedPyObjectPtr res(PyObject_Call(m.get(), args, kwds)); - if (res == NULL) { - return NULL; + if (res == nullptr) { + return nullptr; + } + int ret = InternalAssignRepeatedField( + reinterpret_cast(pself), list.get()); + if (ret < 0) { + return nullptr; + } + Py_RETURN_NONE; +} + +static PyObject* Reverse(PyObject* pself) { + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; + } + ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); + if (list == nullptr) { + return nullptr; + } + ScopedPyObjectPtr res(PyObject_CallMethod(list.get(), "reverse", nullptr)); + if (res == nullptr) { + return nullptr; } int ret = InternalAssignRepeatedField( reinterpret_cast(pself), list.get()); if (ret < 0) { - return NULL; + return nullptr; } Py_RETURN_NONE; } @@ -637,27 +650,27 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { static PyObject* Pop(PyObject* pself, PyObject* args) { Py_ssize_t index = -1; if (!PyArg_ParseTuple(args, "|n", &index)) { - return NULL; + return nullptr; } PyObject* item = Item(pself, index); - if (item == NULL) { + if (item == nullptr) { PyErr_Format(PyExc_IndexError, "list index (%zd) out of range", index); - return NULL; + return nullptr; } - if (AssignItem(pself, index, NULL) < 0) { - return NULL; + if (AssignItem(pself, index, nullptr) < 0) { + return nullptr; } return item; } static PyObject* ToStr(PyObject* pself) { - ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL)); - if (full_slice == NULL) { - return NULL; + ScopedPyObjectPtr full_slice(PySlice_New(nullptr, nullptr, nullptr)); + if (full_slice == nullptr) { + return nullptr; } ScopedPyObjectPtr list(Subscript(pself, full_slice.get())); - if (list == NULL) { - return NULL; + if (list == nullptr) { + return nullptr; } return PyObject_Repr(list.get()); } @@ -670,13 +683,13 @@ static PyObject* MergeFrom(PyObject* pself, PyObject* arg) { RepeatedScalarContainer* NewContainer( CMessage* parent, const FieldDescriptor* parent_field_descriptor) { if (!CheckFieldBelongsToMessage(parent_field_descriptor, parent->message)) { - return NULL; + return nullptr; } RepeatedScalarContainer* self = reinterpret_cast( PyType_GenericAlloc(&RepeatedScalarContainer_Type, 0)); - if (self == NULL) { - return NULL; + if (self == nullptr) { + return nullptr; } Py_INCREF(parent); @@ -696,81 +709,81 @@ static void Dealloc(PyObject* pself) { } static PySequenceMethods SqMethods = { - Len, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - Item, /* sq_item */ - 0, /* sq_slice */ - AssignItem /* sq_ass_item */ + Len, /* sq_length */ + nullptr, /* sq_concat */ + nullptr, /* sq_repeat */ + Item, /* sq_item */ + nullptr, /* sq_slice */ + AssignItem /* sq_ass_item */ }; static PyMappingMethods MpMethods = { - Len, /* mp_length */ - Subscript, /* mp_subscript */ - AssSubscript, /* mp_ass_subscript */ + Len, /* mp_length */ + Subscript, /* mp_subscript */ + AssSubscript, /* mp_ass_subscript */ }; static PyMethodDef Methods[] = { - { "__deepcopy__", DeepCopy, METH_VARARGS, - "Makes a deep copy of the class." }, - { "__reduce__", Reduce, METH_NOARGS, - "Outputs picklable representation of the repeated field." }, - { "append", AppendMethod, METH_O, - "Appends an object to the repeated container." }, - { "extend", ExtendMethod, METH_O, - "Appends objects to the repeated container." }, - { "insert", Insert, METH_VARARGS, - "Inserts an object at the specified position in the container." }, - { "pop", Pop, METH_VARARGS, - "Removes an object from the repeated container and returns it." }, - { "remove", Remove, METH_O, - "Removes an object from the repeated container." }, - { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS, - "Sorts the repeated container."}, - { "MergeFrom", (PyCFunction)MergeFrom, METH_O, - "Merges a repeated container into the current container." }, - { NULL, NULL } -}; + {"__deepcopy__", DeepCopy, METH_VARARGS, "Makes a deep copy of the class."}, + {"__reduce__", Reduce, METH_NOARGS, + "Outputs picklable representation of the repeated field."}, + {"append", AppendMethod, METH_O, + "Appends an object to the repeated container."}, + {"extend", ExtendMethod, METH_O, + "Appends objects to the repeated container."}, + {"insert", Insert, METH_VARARGS, + "Inserts an object at the specified position in the container."}, + {"pop", Pop, METH_VARARGS, + "Removes an object from the repeated container and returns it."}, + {"remove", Remove, METH_O, + "Removes an object from the repeated container."}, + {"sort", reinterpret_cast(Sort), METH_VARARGS | METH_KEYWORDS, + "Sorts the repeated container."}, + {"reverse", reinterpret_cast(Reverse), METH_NOARGS, + "Reverses elements order of the repeated container."}, + {"MergeFrom", static_cast(MergeFrom), METH_O, + "Merges a repeated container into the current container."}, + {nullptr, nullptr}}; } // namespace repeated_scalar_container PyTypeObject RepeatedScalarContainer_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - FULL_MODULE_NAME ".RepeatedScalarContainer", // tp_name - sizeof(RepeatedScalarContainer), // tp_basicsize - 0, // tp_itemsize - repeated_scalar_container::Dealloc, // tp_dealloc - 0, // tp_print - 0, // tp_getattr - 0, // tp_setattr - 0, // tp_compare - repeated_scalar_container::ToStr, // tp_repr - 0, // tp_as_number - &repeated_scalar_container::SqMethods, // tp_as_sequence - &repeated_scalar_container::MpMethods, // tp_as_mapping - PyObject_HashNotImplemented, // tp_hash - 0, // tp_call - 0, // tp_str - 0, // tp_getattro - 0, // tp_setattro - 0, // tp_as_buffer - Py_TPFLAGS_DEFAULT, // tp_flags - "A Repeated scalar container", // tp_doc - 0, // tp_traverse - 0, // tp_clear - repeated_scalar_container::RichCompare, // tp_richcompare - 0, // tp_weaklistoffset - 0, // tp_iter - 0, // tp_iternext - repeated_scalar_container::Methods, // tp_methods - 0, // tp_members - 0, // tp_getset - 0, // tp_base - 0, // tp_dict - 0, // tp_descr_get - 0, // tp_descr_set - 0, // tp_dictoffset - 0, // tp_init + PyVarObject_HEAD_INIT(&PyType_Type, 0) FULL_MODULE_NAME + ".RepeatedScalarContainer", // tp_name + sizeof(RepeatedScalarContainer), // tp_basicsize + 0, // tp_itemsize + repeated_scalar_container::Dealloc, // tp_dealloc + 0, // tp_print, in Python >=3.8: Py_ssize_t tp_vectorcall_offset + nullptr, // tp_getattr + nullptr, // tp_setattr + nullptr, // tp_compare + repeated_scalar_container::ToStr, // tp_repr + nullptr, // tp_as_number + &repeated_scalar_container::SqMethods, // tp_as_sequence + &repeated_scalar_container::MpMethods, // tp_as_mapping + PyObject_HashNotImplemented, // tp_hash + nullptr, // tp_call + nullptr, // tp_str + nullptr, // tp_getattro + nullptr, // tp_setattro + nullptr, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + "A Repeated scalar container", // tp_doc + nullptr, // tp_traverse + nullptr, // tp_clear + repeated_scalar_container::RichCompare, // tp_richcompare + 0, // tp_weaklistoffset + nullptr, // tp_iter + nullptr, // tp_iternext + repeated_scalar_container::Methods, // tp_methods + nullptr, // tp_members + nullptr, // tp_getset + nullptr, // tp_base + nullptr, // tp_dict + nullptr, // tp_descr_get + nullptr, // tp_descr_set + 0, // tp_dictoffset + nullptr, // tp_init }; } // namespace python diff --git a/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/python/google/protobuf/pyext/scoped_pyobject_ptr.h index 9faaa4f93bab..6f7fc29813f9 100644 --- a/python/google/protobuf/pyext/scoped_pyobject_ptr.h +++ b/python/google/protobuf/pyext/scoped_pyobject_ptr.h @@ -77,7 +77,7 @@ class ScopedPythonPtr { PyObject* as_pyobject() const { return reinterpret_cast(ptr_); } - // Increments the reference count fo the current object. + // Increments the reference count of the current object. // Should not be called when no object is held. void inc() const { Py_INCREF(ptr_); } diff --git a/python/google/protobuf/pyext/unknown_fields.cc b/python/google/protobuf/pyext/unknown_fields.cc old mode 100755 new mode 100644 index 8509213b18dc..deb86e691682 --- a/python/google/protobuf/pyext/unknown_fields.cc +++ b/python/google/protobuf/pyext/unknown_fields.cc @@ -142,6 +142,7 @@ static void Dealloc(PyObject* pself) { } Py_CLEAR(self->parent); self->~PyUnknownFields(); + Py_TYPE(pself)->tp_free(pself); } static PySequenceMethods SqMethods = { diff --git a/python/google/protobuf/pyext/unknown_fields.h b/python/google/protobuf/pyext/unknown_fields.h old mode 100755 new mode 100644 diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py old mode 100755 new mode 100644 diff --git a/python/google/protobuf/service.py b/python/google/protobuf/service.py old mode 100755 new mode 100644 index 9e00de704257..5625246324ca --- a/python/google/protobuf/service.py +++ b/python/google/protobuf/service.py @@ -73,6 +73,7 @@ def CallMethod(self, method_descriptor, rpc_controller, In the blocking case, RpcException will be raised on error. Preconditions: + * method_descriptor.service == GetDescriptor * request is of the exact same classes as returned by GetRequestClass(method). @@ -82,6 +83,7 @@ def CallMethod(self, method_descriptor, rpc_controller, RpcChannel which the stub is using. Postconditions: + * "done" will be called when the method is complete. This may be before CallMethod() returns or it may be at some point in the future. * If the RPC failed, the response value passed to "done" will be None. diff --git a/python/google/protobuf/service_reflection.py b/python/google/protobuf/service_reflection.py old mode 100755 new mode 100644 index 147131f25d60..8590e46b17ee --- a/python/google/protobuf/service_reflection.py +++ b/python/google/protobuf/service_reflection.py @@ -55,14 +55,14 @@ class GeneratedServiceType(type): The protocol compiler currently uses this metaclass to create protocol service classes at runtime. Clients can also manually create their own classes at - runtime, as in this example: - - mydescriptor = ServiceDescriptor(.....) - class MyProtoService(service.Service): - __metaclass__ = GeneratedServiceType - DESCRIPTOR = mydescriptor - myservice_instance = MyProtoService() - ... + runtime, as in this example:: + + mydescriptor = ServiceDescriptor(.....) + class MyProtoService(service.Service): + __metaclass__ = GeneratedServiceType + DESCRIPTOR = mydescriptor + myservice_instance = MyProtoService() + # ... """ _DESCRIPTOR_KEY = 'DESCRIPTOR' diff --git a/python/google/protobuf/symbol_database.py b/python/google/protobuf/symbol_database.py index 4020b156cde6..fdcf8cf06ced 100644 --- a/python/google/protobuf/symbol_database.py +++ b/python/google/protobuf/symbol_database.py @@ -34,7 +34,7 @@ and makes it easy to create new instances of a registered type, given only the type's protocol buffer symbol name. -Example usage: +Example usage:: db = symbol_database.SymbolDatabase() @@ -72,7 +72,8 @@ def RegisterMessage(self, message): Calls to GetSymbol() and GetMessages() will return messages registered here. Args: - message: a message.Message, to be registered. + message: A :class:`google.protobuf.message.Message` subclass (or + instance); its descriptor will be registered. Returns: The provided message. @@ -87,7 +88,7 @@ def RegisterMessageDescriptor(self, message_descriptor): """Registers the given message descriptor in the local database. Args: - message_descriptor: a descriptor.MessageDescriptor. + message_descriptor (Descriptor): the message descriptor to add. """ if api_implementation.Type() == 'python': # pylint: disable=protected-access @@ -97,10 +98,10 @@ def RegisterEnumDescriptor(self, enum_descriptor): """Registers the given enum descriptor in the local database. Args: - enum_descriptor: a descriptor.EnumDescriptor. + enum_descriptor (EnumDescriptor): The enum descriptor to register. Returns: - The provided descriptor. + EnumDescriptor: The provided descriptor. """ if api_implementation.Type() == 'python': # pylint: disable=protected-access @@ -111,10 +112,8 @@ def RegisterServiceDescriptor(self, service_descriptor): """Registers the given service descriptor in the local database. Args: - service_descriptor: a descriptor.ServiceDescriptor. - - Returns: - The provided descriptor. + service_descriptor (ServiceDescriptor): the service descriptor to + register. """ if api_implementation.Type() == 'python': # pylint: disable=protected-access @@ -124,10 +123,7 @@ def RegisterFileDescriptor(self, file_descriptor): """Registers the given file descriptor in the local database. Args: - file_descriptor: a descriptor.FileDescriptor. - - Returns: - The provided descriptor. + file_descriptor (FileDescriptor): The file descriptor to register. """ if api_implementation.Type() == 'python': # pylint: disable=protected-access @@ -140,7 +136,7 @@ def GetSymbol(self, symbol): may be extended in future to support other symbol types. Args: - symbol: A str, a protocol buffer symbol. + symbol (str): a protocol buffer symbol. Returns: A Python class corresponding to the symbol. @@ -161,7 +157,7 @@ def GetMessages(self, files): messages, but does not register any message extensions. Args: - files: The file names to extract messages from. + files (list[str]): The file names to extract messages from. Returns: A dictionary mapping proto names to the message classes. diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py old mode 100755 new mode 100644 index a85184e321d3..9ebe8b46b17e --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -30,7 +30,7 @@ """Contains routines for printing protocol messages in text format. -Simple usage example: +Simple usage example:: # Create a proto object and serialize it to a text proto string. message = my_proto_pb2.MyMessage(foo='bar') @@ -46,19 +46,19 @@ import encodings.raw_unicode_escape # pylint: disable=unused-import import encodings.unicode_escape # pylint: disable=unused-import import io +import math import re - import six -if six.PY3: - long = int # pylint: disable=redefined-builtin,invalid-name - -# pylint: disable=g-import-not-at-top from google.protobuf.internal import decoder from google.protobuf.internal import type_checkers from google.protobuf import descriptor from google.protobuf import text_encoding +if six.PY3: + long = int # pylint: disable=redefined-builtin,invalid-name + +# pylint: disable=g-import-not-at-top __all__ = ['MessageToString', 'Parse', 'PrintMessage', 'PrintField', 'PrintFieldValue', 'Merge', 'MessageToBytes'] @@ -120,19 +120,21 @@ def getvalue(self): return self._writer.getvalue() -def MessageToString(message, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - indent=0, - message_formatter=None, - print_unknown_fields=False): +def MessageToString( + message, + as_utf8=False, + as_one_line=False, + use_short_repeated_primitives=False, + pointy_brackets=False, + use_index_order=False, + float_format=None, + double_format=None, + use_field_number=False, + descriptor_pool=None, + indent=0, + message_formatter=None, + print_unknown_fields=False, + force_colon=False): # type: (...) -> str """Convert protobuf message to text format. @@ -155,31 +157,43 @@ def MessageToString(message, will be printed at the end of the message and their relative order is determined by the extension number. By default, use the field number order. - float_format: If set, use this to specify float field formatting - (per the "Format Specification Mini-Language"); otherwise, 8 valid digits - is used (default '.8g'). Also affect double field if double_format is - not set but float_format is set. - double_format: If set, use this to specify double field formatting + float_format (str): If set, use this to specify float field formatting + (per the "Format Specification Mini-Language"); otherwise, shortest float + that has same value in wire will be printed. Also affect double field + if double_format is not set but float_format is set. + double_format (str): If set, use this to specify double field formatting (per the "Format Specification Mini-Language"); if it is not set but - float_format is set, use float_format. Otherwise, use str() + float_format is set, use float_format. Otherwise, use ``str()`` use_field_number: If True, print field numbers instead of names. - descriptor_pool: A DescriptorPool used to resolve Any types. - indent: The initial indent level, in terms of spaces, for pretty print. - message_formatter: A function(message, indent, as_one_line): unicode|None - to custom format selected sub-messages (usually based on message type). - Use to pretty print parts of the protobuf for easier diffing. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. + indent (int): The initial indent level, in terms of spaces, for pretty + print. + message_formatter (function(message, indent, as_one_line) -> unicode|None): + Custom formatter for selected sub-messages (usually based on message + type). Use to pretty print parts of the protobuf for easier diffing. print_unknown_fields: If True, unknown fields will be printed. + force_colon: If set, a colon will be added after the field name even if the + field is a proto message. Returns: - A string of the text formatted protocol buffer message. + str: A string of the text formatted protocol buffer message. """ out = TextWriter(as_utf8) - printer = _Printer(out, indent, as_utf8, as_one_line, - use_short_repeated_primitives, pointy_brackets, - use_index_order, float_format, double_format, - use_field_number, - descriptor_pool, message_formatter, - print_unknown_fields=print_unknown_fields) + printer = _Printer( + out, + indent, + as_utf8, + as_one_line, + use_short_repeated_primitives, + pointy_brackets, + use_index_order, + float_format, + double_format, + use_field_number, + descriptor_pool, + message_formatter, + print_unknown_fields=print_unknown_fields, + force_colon=force_colon) printer.PrintMessage(message) result = out.getvalue() out.close() @@ -217,7 +231,8 @@ def PrintMessage(message, use_field_number=False, descriptor_pool=None, message_formatter=None, - print_unknown_fields=False): + print_unknown_fields=False, + force_colon=False): printer = _Printer( out=out, indent=indent, as_utf8=as_utf8, as_one_line=as_one_line, @@ -229,7 +244,8 @@ def PrintMessage(message, use_field_number=use_field_number, descriptor_pool=descriptor_pool, message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields) + print_unknown_fields=print_unknown_fields, + force_colon=force_colon) printer.PrintMessage(message) @@ -245,13 +261,15 @@ def PrintField(field, float_format=None, double_format=None, message_formatter=None, - print_unknown_fields=False): + print_unknown_fields=False, + force_colon=False): """Print a single field name/value pair.""" printer = _Printer(out, indent, as_utf8, as_one_line, use_short_repeated_primitives, pointy_brackets, use_index_order, float_format, double_format, message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields) + print_unknown_fields=print_unknown_fields, + force_colon=force_colon) printer.PrintField(field, value) @@ -267,13 +285,15 @@ def PrintFieldValue(field, float_format=None, double_format=None, message_formatter=None, - print_unknown_fields=False): + print_unknown_fields=False, + force_colon=False): """Print a single field value (not including name).""" printer = _Printer(out, indent, as_utf8, as_one_line, use_short_repeated_primitives, pointy_brackets, use_index_order, float_format, double_format, message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields) + print_unknown_fields=print_unknown_fields, + force_colon=force_colon) printer.PrintFieldValue(field, value) @@ -310,20 +330,22 @@ def _BuildMessageFromTypeName(type_name, descriptor_pool): class _Printer(object): """Text format printer for protocol message.""" - def __init__(self, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - message_formatter=None, - print_unknown_fields=False): + def __init__( + self, + out, + indent=0, + as_utf8=False, + as_one_line=False, + use_short_repeated_primitives=False, + pointy_brackets=False, + use_index_order=False, + float_format=None, + double_format=None, + use_field_number=False, + descriptor_pool=None, + message_formatter=None, + print_unknown_fields=False, + force_colon=False): """Initialize the Printer. Double values can be formatted compactly with 15 digits of precision @@ -345,9 +367,9 @@ def __init__(self, defined in source code instead of the field number. By default, use the field number order. float_format: If set, use this to specify float field formatting - (per the "Format Specification Mini-Language"); otherwise, 8 valid - digits is used (default '.8g'). Also affect double field if - double_format is not set but float_format is set. + (per the "Format Specification Mini-Language"); otherwise, shortest + float that has same value in wire will be printed. Also affect double + field if double_format is not set but float_format is set. double_format: If set, use this to specify double field formatting (per the "Format Specification Mini-Language"); if it is not set but float_format is set, use float_format. Otherwise, str() is used. @@ -357,6 +379,8 @@ def __init__(self, to custom format selected sub-messages (usually based on message type). Use to pretty print parts of the protobuf for easier diffing. print_unknown_fields: If True, unknown fields will be printed. + force_colon: If set, a colon will be added after the field name even if + the field is a proto message. """ self.out = out self.indent = indent @@ -374,6 +398,7 @@ def __init__(self, self.descriptor_pool = descriptor_pool self.message_formatter = message_formatter self.print_unknown_fields = print_unknown_fields + self.force_colon = force_colon def _TryPrintAsAnyMessage(self, message): """Serializes if message is a google.protobuf.Any field.""" @@ -383,7 +408,8 @@ def _TryPrintAsAnyMessage(self, message): self.descriptor_pool) if packed_message: packed_message.MergeFromString(message.value) - self.out.write('%s[%s] ' % (self.indent * ' ', message.type_url)) + colon = ':' if self.force_colon else '' + self.out.write('%s[%s]%s ' % (self.indent * ' ', message.type_url, colon)) self._PrintMessageFieldValue(packed_message) self.out.write(' ' if self.as_one_line else '\n') return True @@ -517,9 +543,11 @@ def _PrintFieldName(self, field): else: out.write(field.name) - if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE: + if (self.force_colon or + field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE): # The colon is optional in this case, but our cross-language golden files - # don't include it. + # don't include it. Here, the colon is only included if force_colon is + # set to True out.write(':') def PrintField(self, field, value): @@ -530,6 +558,7 @@ def PrintField(self, field, value): self.out.write(' ' if self.as_one_line else '\n') def _PrintShortRepeatedPrimitivesValue(self, field, value): + """"Prints short repeated primitives value.""" # Note: this is called only when value has at least one element. self._PrintFieldName(field) self.out.write(' [') @@ -538,6 +567,8 @@ def _PrintShortRepeatedPrimitivesValue(self, field, value): self.out.write(', ') self.PrintFieldValue(field, value[-1]) self.out.write(']') + if self.force_colon: + self.out.write(':') self.out.write(' ' if self.as_one_line else '\n') def _PrintMessageFieldValue(self, value): @@ -599,7 +630,10 @@ def PrintFieldValue(self, field, value): if self.float_format is not None: out.write('{1:{0}}'.format(self.float_format, value)) else: - out.write(str(float(format(value, '.8g')))) + if math.isnan(value): + out.write(str(value)) + else: + out.write(str(type_checkers.ToShortestFloat(value))) elif (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_DOUBLE and self.double_format is not None): out.write('{1:{0}}'.format(self.double_format, value)) @@ -620,7 +654,8 @@ def Parse(text, If text contains a field already set in message, the value is appended if the field is repeated. Otherwise, an error is raised. - Example + Example:: + a = MyProto() a.repeated_field.append('test') b = MyProto() @@ -640,18 +675,18 @@ def Parse(text, Caller is responsible for clearing the message as needed. Args: - text: Message text representation. - message: A protocol buffer message to merge into. + text (str): Message text representation. + message (Message): A protocol buffer message to merge into. allow_unknown_extension: if True, skip over missing extensions and keep parsing allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. allow_unknown_field: if True, skip over unknown field and keep parsing. Avoid to use this option if possible. It may hide some errors (e.g. spelling error on field name) Returns: - The same message passed as argument. + Message: The same message passed as argument. Raises: ParseError: On text parsing problems. @@ -677,18 +712,18 @@ def Merge(text, replace those in the message. Args: - text: Message text representation. - message: A protocol buffer message to merge into. + text (str): Message text representation. + message (Message): A protocol buffer message to merge into. allow_unknown_extension: if True, skip over missing extensions and keep parsing allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. + descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. allow_unknown_field: if True, skip over unknown field and keep parsing. Avoid to use this option if possible. It may hide some errors (e.g. spelling error on field name) Returns: - The same message passed as argument. + Message: The same message passed as argument. Raises: ParseError: On text parsing problems. @@ -847,8 +882,11 @@ def _MergeField(self, tokenizer, message): raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (expanded_any_end_token,)) self._MergeField(tokenizer, expanded_any_sub_message) + deterministic = False + message.Pack(expanded_any_sub_message, - type_url_prefix=type_url_prefix) + type_url_prefix=type_url_prefix, + deterministic=deterministic) return if tokenizer.TryConsume('['): diff --git a/python/protobuf_distutils/README.md b/python/protobuf_distutils/README.md new file mode 100644 index 000000000000..63d12b5200b5 --- /dev/null +++ b/python/protobuf_distutils/README.md @@ -0,0 +1,121 @@ +# Python setuptools extension + +This is an extension for Python setuptools which uses an installed protobuf +compiler (`protoc`) to generate Python sources. + +## Installing + +To use this extension, it needs to be installed so it can be imported by other +projects' setup.py. + +```shell +$ python setup.py build +$ python -m pip install . +``` + +(If you want to test changes to the extension, you can use `python setup.py +develop`.) + +## Usage + +### Example setup.py configuration + +```python +from setuptools import setup +setup( + # ... + name='example_project', + + # Require this package, but only for setup (not installation): + setup_requires=['protobuf_distutils'], + + options={ + # See below for details. + 'generate_py_protobufs': { + 'source_dir': 'path/to/protos', + 'extra_proto_paths': ['path/to/other/project/protos'], + 'output_dir': 'path/to/project/sources', # default '.' + 'proto_files': ['relative/path/to/just_this_file.proto'], + 'protoc': 'path/to/protoc.exe', + }, + }, +) +``` + +### Example build invocation + +These steps will generate protobuf sources so they are included when building +and installing `example_project` (see above): + +```shell +$ python setup.py generate_py_protobufs +$ python setup.py build +$ python -m pip install . +``` + +## Options + +- `source_dir`: + + This is the directory holding .proto files to be processed. + + The default behavior is to generate sources for all .proto files found under + `source_dir`, recursively. This behavior can be controlled with options below. + +- `proto_root_path`: + + This is the root path for resolving imports in source .proto files. + + The default is the shortest prefix of `source_dir` among `[source_dir] + + self.extra_proto_paths`. + +- `extra_proto_paths`: + + Specifies additional paths that should be used to find imports, in + addition to `source_dir`. + + This option can be used to specify the path to other protobuf sources, + which are imported by files under `source_dir`. No Python code will + be generated for .proto files under `extra_proto_paths`. + +- `output_dir`: + + Specifies where generated code should be placed. + + Typically, this should be the root package that generated Python modules + should be below. + + The generated files will be placed under `output_dir` according to the + relative source paths under `proto_root_path`. For example, the source file + `${proto_root_path}/subdir/message.proto` will be generated as the Python + module `${output_dir}/subdir/message_pb2.py`. + +- `proto_files`: + + A list of strings, specific .proto file paths for generating code, instead of + searching for all .proto files under `source_path`. + + These paths are relative to `source_dir`. For example, to generate code + for just `${source_dir}/subdir/message.proto`, specify + `['subdir/message.proto']`. + +- `protoc`: + + By default, the protoc binary (the Protobuf compiler) is found by + searching the environment path. To use a specific protoc binary, its + path can be specified. Resolution of the `protoc` value is as follows: + 1. If the `--protoc=VALUE` flag is passed to `generate_py_protobufs`, + then `VALUE` will be used. + For example: + ```shell + $ python setup.py generate_py_protobufs --protoc=/path/to/protoc + ``` + 2. Otherwise, if a value was set in the `options`, it will be used. + (See "Example setup.py configuration," above.) + 3. Otherwise, if the `PROTOC` environment variable is set, it will be + used. For example: + For example: + ```shell + $ PROTOC=/path/to/protoc python setup.py generate_py_protobufs + ``` + 4. Otherwise, `$PATH` will be searched. diff --git a/python/protobuf_distutils/protobuf_distutils/__init__.py b/python/protobuf_distutils/protobuf_distutils/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py b/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py new file mode 100644 index 000000000000..515ded2334e3 --- /dev/null +++ b/python/protobuf_distutils/protobuf_distutils/generate_py_protobufs.py @@ -0,0 +1,147 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# 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 its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Implements the generate_py_protobufs command.""" + +__author__ = 'dlj@google.com (David L. Jones)' + +import glob +import sys +import os +import distutils.spawn as spawn +from distutils.cmd import Command +from distutils.errors import DistutilsOptionError, DistutilsExecError + +class generate_py_protobufs(Command): + """Generates Python sources for .proto files.""" + + description = 'Generate Python sources for .proto files' + user_options = [ + ('extra-proto-paths=', None, + 'Additional paths to resolve imports in .proto files.'), + + ('protoc=', None, + 'Path to a specific `protoc` command to use.'), + ] + boolean_options = ['recurse'] + + def initialize_options(self): + """Sets the defaults for the command options.""" + self.source_dir = None + self.proto_root_path = None + self.extra_proto_paths = [] + self.output_dir = '.' + self.proto_files = None + self.recurse = True + self.protoc = None + + def finalize_options(self): + """Sets the final values for the command options. + + Defaults were set in `initialize_options`, but could have been changed + by command-line options or by other commands. + """ + self.ensure_dirname('source_dir') + self.ensure_string_list('extra_proto_paths') + + if self.output_dir is None: + self.output_dir = '.' + self.ensure_dirname('output_dir') + + # SUBTLE: if 'source_dir' is a subdirectory of any entry in + # 'extra_proto_paths', then in general, the shortest --proto_path prefix + # (and the longest relative .proto filenames) must be used for + # correctness. For example, consider: + # + # source_dir = 'a/b/c' + # extra_proto_paths = ['a/b', 'x/y'] + # + # In this case, we must ensure that a/b/c/d/foo.proto resolves + # canonically as c/d/foo.proto, not just d/foo.proto. Otherwise, this + # import: + # + # import "c/d/foo.proto"; + # + # would result in different FileDescriptor.name keys from "d/foo.proto". + # That will cause all the definitions in the file to be flagged as + # duplicates, with an error similar to: + # + # c/d/foo.proto: "packagename.MessageName" is already defined in file "d/foo.proto" + # + # For paths in self.proto_files, we transform them to be relative to + # self.proto_root_path, which may be different from self.source_dir. + # + # Although the order of --proto_paths is significant, shadowed filenames + # are errors: if 'a/b/c.proto' resolves to different files under two + # different --proto_path arguments, then the path is rejected as an + # error. (Implementation note: this is enforced in protoc's + # DiskSourceTree class.) + + if self.proto_root_path is None: + self.proto_root_path = os.path.normpath(self.source_dir) + for root_candidate in self.extra_proto_paths: + root_candidate = os.path.normpath(root_candidate) + if self.proto_root_path.startswith(root_candidate): + self.proto_root_path = root_candidate + if self.proto_root_path != self.source_dir: + self.announce('using computed proto_root_path: ' + self.proto_root_path, level=2) + + if not self.source_dir.startswith(self.proto_root_path): + raise DistutilsOptionError('source_dir ' + self.source_dir + + ' is not under proto_root_path ' + self.proto_root_path) + + if self.proto_files is None: + files = glob.glob(os.path.join(self.source_dir, '*.proto')) + if self.recurse: + files.extend(glob.glob(os.path.join(self.source_dir, '**', '*.proto'))) + self.proto_files = [f.partition(self.proto_root_path + os.path.sep)[-1] for f in files] + if not self.proto_files: + raise DistutilsOptionError('no .proto files were found under ' + self.source_dir) + + self.ensure_string_list('proto_files') + + if self.protoc is None: + self.protoc = os.getenv('PROTOC') + if self.protoc is None: + self.protoc = spawn.find_executable('protoc') + + def run(self): + # All proto file paths were adjusted in finalize_options to be relative + # to self.proto_root_path. + proto_paths = ['--proto_path=' + self.proto_root_path] + proto_paths.extend(['--proto_path=' + x for x in self.extra_proto_paths]) + + # Run protoc. It was already resolved, so don't try to resolve + # through PATH. + spawn.spawn( + [self.protoc, + '--python_out=' + self.output_dir, + ] + proto_paths + self.proto_files, + search_path=0) diff --git a/python/protobuf_distutils/setup.py b/python/protobuf_distutils/setup.py new file mode 100644 index 000000000000..96259a91e0cc --- /dev/null +++ b/python/protobuf_distutils/setup.py @@ -0,0 +1,77 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2008 Google Inc. All rights reserved. +# https://developers.google.com/protocol-buffers/ +# +# 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 its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +"""Setuptools/distutils extension for generating Python protobuf code.""" + +__author__ = 'dlj@google.com (David L. Jones)' + +from os import path +from setuptools import setup, find_packages + +# Use README.md as the source for long_description. +this_directory = path.abspath(path.dirname(__file__)) +with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f: + _readme = f.read() + +setup( + name='protobuf_distutils', + version='1.0', + packages=find_packages(), + maintainer='protobuf@googlegroups.com', + maintainer_email='protobuf@googlegroups.com', + license='3-Clause BSD License', + classifiers=[ + "Framework :: Setuptools Plugin", + "Operating System :: OS Independent", + # These Python versions should match the protobuf package: + "Programming Language :: Python", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Topic :: Software Development :: Code Generators", + ], + description=('This is a distutils extension to generate Python code for ' + '.proto files using an installed protoc binary.'), + long_description=_readme, + long_description_content_type='text/markdown', + url='https://github.com/protocolbuffers/protobuf/', + entry_points={ + 'distutils.commands': [ + ('generate_py_protobufs = ' + 'protobuf_distutils.generate_py_protobufs:generate_py_protobufs'), + ], + }, +) diff --git a/python/release.sh b/python/release.sh index 8d35640e9229..fc88b08e3eee 100755 --- a/python/release.sh +++ b/python/release.sh @@ -11,7 +11,10 @@ function run_install_test() { local PYTHON=$2 local PYPI=$3 - virtualenv --no-site-packages -p `which $PYTHON` test-venv + # Setuptools 45.0 removed support for Python 2, so to test with Python 2 we + # pass --no-setuptools here and then install an older setuptools version + # below. + virtualenv -p `which $PYTHON` --no-setuptools test-venv # Intentionally put a broken protoc in the path to make sure installation # doesn't require protoc installed. @@ -19,6 +22,7 @@ function run_install_test() { chmod +x test-venv/bin/protoc source test-venv/bin/activate + pip install "setuptools<45" pip install -i ${PYPI} protobuf==${VERSION} --no-cache-dir deactivate rm -fr test-venv @@ -76,18 +80,20 @@ fi cd python # Run tests locally. -python setup.py build -python setup.py test +python3 setup.py build +python3 setup.py test # Deploy source package to testing PyPI -python setup.py sdist upload -r https://test.pypi.org/legacy/ +python3 setup.py sdist +twine upload --skip-existing -r testpypi -u protobuf-wheel-test dist/* # Test locally with different python versions. run_install_test ${TESTING_VERSION} python2.7 https://test.pypi.org/simple run_install_test ${TESTING_VERSION} python3 https://test.pypi.org/simple # Deploy egg/wheel packages to testing PyPI and test again. -python setup.py bdist_egg bdist_wheel upload -r https://test.pypi.org/legacy/ +python3 setup.py clean build bdist_wheel +twine upload --skip-existing -r testpypi -u protobuf-wheel-test dist/* run_install_test ${TESTING_VERSION} python2.7 https://test.pypi.org/simple run_install_test ${TESTING_VERSION} python3 https://test.pypi.org/simple @@ -103,13 +109,15 @@ if [ $TESTING_ONLY -eq 0 ]; then echo "Publishing to PyPI..." # Be sure to run build before sdist, because otherwise sdist will not include # well-known types. - python setup.py clean build sdist upload + python3 setup.py clean build sdist + twine upload --skip-existing -u protobuf-packages dist/* # Be sure to run clean before bdist_xxx, because otherwise bdist_xxx will # include files you may not want in the package. E.g., if you have built # and tested with --cpp_implemenation, bdist_xxx will include the _message.so # file even when you no longer pass the --cpp_implemenation flag. See: # https://github.com/protocolbuffers/protobuf/issues/3042 - python setup.py clean build bdist_egg bdist_wheel upload + python3 setup.py clean build bdist_wheel + twine upload --skip-existing -u protobuf-packages dist/* else # Set the version number back (i.e., remove dev suffix). sed -i -r "s/__version__ = '.*'/__version__ = '${VERSION}'/" google/protobuf/__init__.py diff --git a/python/setup.py b/python/setup.py index 9aabbf7aaa1b..d003c969ab99 100755 --- a/python/setup.py +++ b/python/setup.py @@ -2,6 +2,7 @@ # # See README for usage instructions. from distutils import util +import fnmatch import glob import os import pkg_resources @@ -82,8 +83,6 @@ def GenerateUnittestProtos(): generate_proto("../src/google/protobuf/test_messages_proto3.proto", False) generate_proto("../src/google/protobuf/test_messages_proto2.proto", False) generate_proto("../src/google/protobuf/unittest_arena.proto", False) - generate_proto("../src/google/protobuf/unittest_no_arena.proto", False) - generate_proto("../src/google/protobuf/unittest_no_arena_import.proto", False) generate_proto("../src/google/protobuf/unittest.proto", False) generate_proto("../src/google/protobuf/unittest_custom_options.proto", False) generate_proto("../src/google/protobuf/unittest_import.proto", False) @@ -110,6 +109,7 @@ def GenerateUnittestProtos(): generate_proto("google/protobuf/internal/no_package.proto", False) generate_proto("google/protobuf/internal/packed_field_test.proto", False) generate_proto("google/protobuf/internal/test_bad_identifiers.proto", False) + generate_proto("google/protobuf/internal/test_proto3_optional.proto", False) generate_proto("google/protobuf/pyext/python.proto", False) @@ -145,6 +145,18 @@ def run(self): # _build_py is an old-style class, so super() doesn't work. _build_py.run(self) + def find_package_modules(self, package, package_dir): + exclude = ( + "*test*", + "google/protobuf/internal/*_pb2.py", + "google/protobuf/internal/_parameterized.py", + "google/protobuf/pyext/python_pb2.py", + ) + modules = _build_py.find_package_modules(self, package, package_dir) + return [(pkg, mod, fil) for (pkg, mod, fil) in modules + if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)] + + class test_conformance(_build_py): target = 'test_python' def run(self): @@ -242,7 +254,7 @@ def get_option_from_sys_argv(option_str): os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp' # Keep this list of dependencies in sync with tox.ini. - install_requires = ['six>=1.9', 'setuptools'] + install_requires = ['six>=1.9'] if sys.version_info <= (2,7): install_requires.append('ordereddict') install_requires.append('unittest2') @@ -272,6 +284,7 @@ def get_option_from_sys_argv(option_str): packages=find_packages( exclude=[ 'import_test_package', + 'protobuf_distutils', ], ), test_suite='google.protobuf.internal', diff --git a/python/tox.ini b/python/tox.ini index 999f8ceeb8fa..56be1258ae99 100644 --- a/python/tox.ini +++ b/python/tox.ini @@ -14,7 +14,10 @@ setenv = commands = python setup.py -q build_py python: python setup.py -q build - cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + # --warnings_as_errors disabled until we update the Python C extension. See: + # https://github.com/protocolbuffers/protobuf/issues/7930 + # cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension + cpp: python setup.py -q build --cpp_implementation --compile_static_extension python: python setup.py -q test -q cpp: python setup.py -q test -q --cpp_implementation python: python setup.py -q test_conformance diff --git a/ruby/Rakefile b/ruby/Rakefile index ad70e3107ccb..2aa7743e20d1 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -70,13 +70,18 @@ else task 'gem:windows' do require 'rake_compiler_dock' - RakeCompilerDock.sh "bundle && IN_DOCKER=true rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.0:2.4.0:2.3.0" + ['x86-mingw32', 'x64-mingw32', 'x86_64-linux', 'x86-linux'].each do |plat| + RakeCompilerDock.sh <<-"EOT", platform: plat + bundle && \ + IN_DOCKER=true rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem RUBY_CC_VERSION=2.7.0:2.6.0:2.5.0:2.4.0:2.3.0 + EOT + end end if RUBY_PLATFORM =~ /darwin/ task 'gem:native' do system "rake genproto" - system "rake cross native gem RUBY_CC_VERSION=2.6.0:2.5.1:2.4.0:2.3.0" + system "rake cross native gem RUBY_CC_VERSION=2.7.0:2.6.0:2.5.1:2.4.0:2.3.0" end else task 'gem:native' => [:genproto, 'gem:windows'] @@ -119,7 +124,7 @@ file "tests/test_ruby_package_proto2.rb" => "tests/test_ruby_package_proto2.prot end file "tests/basic_test.rb" => "tests/basic_test.proto" do |file_task| - sh "../src/protoc -I../src -I. --ruby_out=. tests/basic_test.proto" + sh "../src/protoc --experimental_allow_proto3_optional -I../src -I. --ruby_out=. tests/basic_test.proto" end file "tests/basic_test_proto2.rb" => "tests/basic_test_proto2.proto" do |file_task| diff --git a/ruby/compatibility_tests/v3.0.0/tests/basic.rb b/ruby/compatibility_tests/v3.0.0/tests/basic.rb old mode 100644 new mode 100755 diff --git a/ruby/compatibility_tests/v3.0.0/tests/generated_code_test.rb b/ruby/compatibility_tests/v3.0.0/tests/generated_code_test.rb old mode 100644 new mode 100755 diff --git a/ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb b/ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb old mode 100644 new mode 100755 index 4ebb731a83f6..b4a158f37ccd --- a/ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb +++ b/ruby/compatibility_tests/v3.0.0/tests/repeated_field_test.rb @@ -20,6 +20,7 @@ def test_acts_like_an_array :iter_for_each_with_index, :dimensions, :copy_data, :copy_data_simple, :nitems, :iter_for_reverse_each, :indexes, :append, :prepend] arr_methods -= [:union, :difference, :filter!] + arr_methods -= [:intersection, :deconstruct] # ruby 2.7 methods we can ignore arr_methods.each do |method_name| assert m.repeated_string.respond_to?(method_name) == true, "does not respond to #{method_name}" end diff --git a/ruby/compatibility_tests/v3.0.0/tests/stress.rb b/ruby/compatibility_tests/v3.0.0/tests/stress.rb old mode 100644 new mode 100755 diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c index babdfa97115f..1a09cc5ffb77 100644 --- a/ruby/ext/google/protobuf_c/defs.c +++ b/ruby/ext/google/protobuf_c/defs.c @@ -1100,7 +1100,7 @@ VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) { * FieldDescriptor.has?(message) => boolean * * Returns whether the value is set on the given message. Raises an - * exception when calling with proto syntax 3. + * exception when calling for fields that do not have presence. */ VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) { DEFINE_SELF(FieldDescriptor, self, _self); @@ -1434,6 +1434,7 @@ void MessageBuilderContext_register(VALUE module) { rb_define_method(klass, "initialize", MessageBuilderContext_initialize, 2); rb_define_method(klass, "optional", MessageBuilderContext_optional, -1); + rb_define_method(klass, "proto3_optional", MessageBuilderContext_proto3_optional, -1); rb_define_method(klass, "required", MessageBuilderContext_required, -1); rb_define_method(klass, "repeated", MessageBuilderContext_repeated, -1); rb_define_method(klass, "map", MessageBuilderContext_map, -1); @@ -1469,7 +1470,8 @@ VALUE MessageBuilderContext_initialize(VALUE _self, static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name, VALUE type, VALUE number, VALUE type_class, - VALUE options, int oneof_index) { + VALUE options, int oneof_index, + bool proto3_optional) { DEFINE_SELF(MessageBuilderContext, self, msgbuilder_rb); FileBuilderContext* file_context = ruby_to_FileBuilderContext(self->file_builder); @@ -1489,6 +1491,10 @@ static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name, google_protobuf_FieldDescriptorProto_set_type( field_proto, (int)ruby_to_descriptortype(type)); + if (proto3_optional) { + google_protobuf_FieldDescriptorProto_set_proto3_optional(field_proto, true); + } + if (type_class != Qnil) { Check_Type(type_class, T_STRING); @@ -1574,7 +1580,38 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) { } msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class, - options, -1); + options, -1, false); + + return Qnil; +} + +/* + * call-seq: + * MessageBuilderContext.proto3_optional(name, type, number, + * type_class = nil, options = nil) + * + * Defines a true proto3 optional field (that tracks presence) on this message + * type with the given type, tag number, and type class (for message and enum + * fields). The type must be a Ruby symbol (as accepted by + * FieldDescriptor#type=) and the type_class must be a string, if present (as + * accepted by FieldDescriptor#submsg_name=). + */ +VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv, + VALUE _self) { + VALUE name, type, number; + VALUE type_class, options = Qnil; + + rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options); + + // Allow passing (name, type, number, options) or + // (name, type, number, type_class, options) + if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) { + options = type_class; + type_class = Qnil; + } + + msgdef_add_field(_self, UPB_LABEL_OPTIONAL, name, type, number, type_class, + options, -1, true); return Qnil; } @@ -1607,7 +1644,7 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) { } msgdef_add_field(_self, UPB_LABEL_REQUIRED, name, type, number, type_class, - options, -1); + options, -1, false); return Qnil; } @@ -1633,7 +1670,7 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) { type_class = (argc > 3) ? argv[3] : Qnil; msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class, - Qnil, -1); + Qnil, -1, false); return Qnil; } @@ -1758,6 +1795,56 @@ VALUE MessageBuilderContext_oneof(VALUE _self, VALUE name) { return Qnil; } +void MessageBuilderContext_add_synthetic_oneofs(VALUE _self) { + DEFINE_SELF(MessageBuilderContext, self, _self); + FileBuilderContext* file_context = + ruby_to_FileBuilderContext(self->file_builder); + size_t field_count, oneof_count; + google_protobuf_FieldDescriptorProto** fields = + google_protobuf_DescriptorProto_mutable_field(self->msg_proto, &field_count); + const google_protobuf_OneofDescriptorProto*const* oneofs = + google_protobuf_DescriptorProto_oneof_decl(self->msg_proto, &oneof_count); + VALUE names = rb_hash_new(); + VALUE underscore = rb_str_new2("_"); + size_t i; + + // We have to build a set of all names, to ensure that synthetic oneofs are + // not creating conflicts. + for (i = 0; i < field_count; i++) { + upb_strview name = google_protobuf_FieldDescriptorProto_name(fields[i]); + rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue); + } + for (i = 0; i < oneof_count; i++) { + upb_strview name = google_protobuf_OneofDescriptorProto_name(oneofs[i]); + rb_hash_aset(names, rb_str_new(name.data, name.size), Qtrue); + } + + for (i = 0; i < field_count; i++) { + google_protobuf_OneofDescriptorProto* oneof_proto; + VALUE oneof_name; + upb_strview field_name; + + if (!google_protobuf_FieldDescriptorProto_proto3_optional(fields[i])) { + continue; + } + + // Prepend '_' until we are no longer conflicting. + field_name = google_protobuf_FieldDescriptorProto_name(fields[i]); + oneof_name = rb_str_new(field_name.data, field_name.size); + while (rb_hash_lookup(names, oneof_name) != Qnil) { + oneof_name = rb_str_plus(underscore, oneof_name); + } + + rb_hash_aset(names, oneof_name, Qtrue); + google_protobuf_FieldDescriptorProto_set_oneof_index(fields[i], + oneof_count++); + oneof_proto = google_protobuf_DescriptorProto_add_oneof_decl( + self->msg_proto, file_context->arena); + google_protobuf_OneofDescriptorProto_set_name( + oneof_proto, FileBuilderContext_strdup(self->file_builder, oneof_name)); + } +} + // ----------------------------------------------------------------------------- // OneofBuilderContext. // ----------------------------------------------------------------------------- @@ -1829,7 +1916,7 @@ VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) { rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options); msgdef_add_field(self->message_builder, UPB_LABEL_OPTIONAL, name, type, - number, type_class, options, self->oneof_index); + number, type_class, options, self->oneof_index, false); return Qnil; } @@ -2033,6 +2120,7 @@ VALUE FileBuilderContext_add_message(VALUE _self, VALUE name) { VALUE ctx = rb_class_new_instance(2, args, cMessageBuilderContext); VALUE block = rb_block_proc(); rb_funcall_with_block(ctx, rb_intern("instance_eval"), 0, NULL, block); + MessageBuilderContext_add_synthetic_oneofs(ctx); return Qnil; } diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c index 713da435229f..a58a5d2f849d 100644 --- a/ruby/ext/google/protobuf_c/encode_decode.c +++ b/ruby/ext/google/protobuf_c/encode_decode.c @@ -30,6 +30,10 @@ #include "protobuf.h" +VALUE initialize_rb_class_with_no_args(VALUE klass) { + return rb_funcall(klass, rb_intern("new"), 0); +} + // This function is equivalent to rb_str_cat(), but unlike the real // rb_str_cat(), it doesn't leak memory in some versions of Ruby. // For more information, see: @@ -44,6 +48,23 @@ VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) { return rb_str; } +bool is_wrapper(const upb_msgdef* m) { + switch (upb_msgdef_wellknowntype(m)) { + case UPB_WELLKNOWN_DOUBLEVALUE: + case UPB_WELLKNOWN_FLOATVALUE: + case UPB_WELLKNOWN_INT64VALUE: + case UPB_WELLKNOWN_UINT64VALUE: + case UPB_WELLKNOWN_INT32VALUE: + case UPB_WELLKNOWN_UINT32VALUE: + case UPB_WELLKNOWN_STRINGVALUE: + case UPB_WELLKNOWN_BYTESVALUE: + case UPB_WELLKNOWN_BOOLVALUE: + return true; + default: + return false; + } +} + // The code below also comes from upb's prototype Ruby binding, developed by // haberman@. @@ -117,19 +138,26 @@ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs, int32_t hasbit) typedef struct { size_t ofs; int32_t hasbit; + upb_fieldtype_t wrapped_type; // Only for wrappers. VALUE subklass; } submsg_handlerdata_t; // Creates a handlerdata that contains offset and submessage type information. static const void *newsubmsghandlerdata(upb_handlers* h, + const upb_fielddef *f, uint32_t ofs, int32_t hasbit, VALUE subklass) { submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t); + const upb_msgdef *subm = upb_fielddef_msgsubdef(f); hd->ofs = ofs; hd->hasbit = hasbit; hd->subklass = subklass; upb_handlers_addcleanup(h, hd, xfree); + if (is_wrapper(subm)) { + const upb_fielddef *value_f = upb_msgdef_itof(subm, 1); + hd->wrapped_type = upb_fielddef_type(value_f); + } return hd; } @@ -271,7 +299,7 @@ static void *appendsubmsg_handler(void *closure, const void *hd) { const submsg_handlerdata_t *submsgdata = hd; MessageHeader* submsg; - VALUE submsg_rb = rb_class_new_instance(0, NULL, submsgdata->subklass); + VALUE submsg_rb = initialize_rb_class_with_no_args(submsgdata->subklass); RepeatedField_push(ary, submsg_rb); TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg); @@ -298,7 +326,7 @@ static void *submsg_handler(void *closure, const void *hd) { if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) { DEREF(msg, submsgdata->ofs, VALUE) = - rb_class_new_instance(0, NULL, submsgdata->subklass); + initialize_rb_class_with_no_args(submsgdata->subklass); } set_hasbit(closure, submsgdata->hasbit); @@ -310,12 +338,39 @@ static void *submsg_handler(void *closure, const void *hd) { } static void* startwrapper(void* closure, const void* hd) { - char* msg = closure; const submsg_handlerdata_t* submsgdata = hd; + char* msg = closure; + VALUE* field = (VALUE*)(msg + submsgdata->ofs); set_hasbit(closure, submsgdata->hasbit); - return msg + submsgdata->ofs; + switch (submsgdata->wrapped_type) { + case UPB_TYPE_FLOAT: + case UPB_TYPE_DOUBLE: + *field = DBL2NUM(0); + break; + case UPB_TYPE_BOOL: + *field = Qfalse; + break; + case UPB_TYPE_STRING: + *field = get_frozen_string(NULL, 0, false); + break; + case UPB_TYPE_BYTES: + *field = get_frozen_string(NULL, 0, true); + break; + case UPB_TYPE_ENUM: + case UPB_TYPE_INT32: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT32: + case UPB_TYPE_UINT64: + *field = INT2NUM(0); + break; + case UPB_TYPE_MESSAGE: + rb_raise(rb_eRuntimeError, + "Internal logic error with well-known types."); + } + + return field; } // Handler data for startmap/endmap handlers. @@ -379,10 +434,8 @@ static void *startmap_handler(void *closure, const void *hd) { } static bool endmap_handler(void *closure, const void *hd) { - MessageHeader* msg = closure; - const map_handlerdata_t* mapdata = hd; - VALUE map_rb = DEREF(msg, mapdata->ofs, VALUE); - Map_set_frame(map_rb, Qnil); + map_parse_frame_t* frame = closure; + Map_set_frame(frame->map, Qnil); return true; } @@ -498,7 +551,7 @@ static void *oneofsubmsg_handler(void *closure, if (oldcase != oneofdata->oneof_case_num || DEREF(msg, oneofdata->ofs, VALUE) == Qnil) { DEREF(msg, oneofdata->ofs, VALUE) = - rb_class_new_instance(0, NULL, oneofdata->subklass); + initialize_rb_class_with_no_args(oneofdata->subklass); } // Set the oneof case *after* allocating the new class instance -- otherwise, // if the Ruby GC is invoked as part of a call into the VM, it might invoke @@ -522,23 +575,6 @@ static void* oneof_startwrapper(void* closure, const void* hd) { return msg + oneofdata->ofs; } -bool is_wrapper(const upb_msgdef* m) { - switch (upb_msgdef_wellknowntype(m)) { - case UPB_WELLKNOWN_DOUBLEVALUE: - case UPB_WELLKNOWN_FLOATVALUE: - case UPB_WELLKNOWN_INT64VALUE: - case UPB_WELLKNOWN_UINT64VALUE: - case UPB_WELLKNOWN_INT32VALUE: - case UPB_WELLKNOWN_UINT32VALUE: - case UPB_WELLKNOWN_STRINGVALUE: - case UPB_WELLKNOWN_BYTESVALUE: - case UPB_WELLKNOWN_BOOLVALUE: - return true; - default: - return false; - } -} - // Set up handlers for a repeated field. static void add_handlers_for_repeated_field(upb_handlers *h, const Descriptor* desc, @@ -579,7 +615,7 @@ static void add_handlers_for_repeated_field(upb_handlers *h, case UPB_TYPE_MESSAGE: { VALUE subklass = field_type_class(desc->layout, f); upb_handlerattr attr = UPB_HANDLERATTR_INIT; - attr.handler_data = newsubmsghandlerdata(h, 0, -1, subklass); + attr.handler_data = newsubmsghandlerdata(h, f, 0, -1, subklass); if (is_wrapper(upb_fielddef_msgsubdef(f))) { upb_handlers_setstartsubmsg(h, f, appendwrapper_handler, &attr); } else { @@ -708,7 +744,7 @@ static void add_handlers_for_singular_field(const Descriptor* desc, case UPB_TYPE_MESSAGE: { upb_handlerattr attr = UPB_HANDLERATTR_INIT; attr.handler_data = newsubmsghandlerdata( - h, offset, hasbit, field_type_class(desc->layout, f)); + h, f, offset, hasbit, field_type_class(desc->layout, f)); if (is_wrapper(upb_fielddef_msgsubdef(f))) { upb_handlers_setstartsubmsg(h, f, startwrapper, &attr); } else { @@ -897,7 +933,7 @@ void add_handlers_for_message(const void *closure, upb_handlers *h) { !upb_msg_field_done(&i); upb_msg_field_next(&i)) { const upb_fielddef *f = upb_msg_iter_field(&i); - const upb_oneofdef *oneof = upb_fielddef_containingoneof(f); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f); size_t offset = get_field_offset(desc->layout, f); if (oneof) { @@ -1004,7 +1040,7 @@ VALUE Message_decode(VALUE klass, VALUE data) { rb_raise(rb_eArgError, "Expected string for binary protobuf data."); } - msg_rb = rb_class_new_instance(0, NULL, msgklass); + msg_rb = initialize_rb_class_with_no_args(msgklass); TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); { @@ -1080,7 +1116,7 @@ VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { // convert, because string handlers pass data directly to message string // fields. - msg_rb = rb_class_new_instance(0, NULL, msgklass); + msg_rb = initialize_rb_class_with_no_args(msgklass); TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg); { @@ -1162,7 +1198,7 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink sink, upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink); putmsg(submsg, subdesc, subsink, depth + 1, emit_defaults, is_json, true); - upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG)); + upb_sink_endsubmsg(sink, subsink, getsel(f, UPB_HANDLER_ENDSUBMSG)); } static void putary(VALUE ary, const upb_fielddef* f, upb_sink sink, int depth, @@ -1307,7 +1343,7 @@ static void putmap(VALUE map, const upb_fielddef* f, upb_sink sink, int depth, entry_sink, emit_defaults, is_json); upb_sink_endmsg(entry_sink, &status); - upb_sink_endsubmsg(subsink, getsel(f, UPB_HANDLER_ENDSUBMSG)); + upb_sink_endsubmsg(subsink, entry_sink, getsel(f, UPB_HANDLER_ENDSUBMSG)); } upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ)); @@ -1432,6 +1468,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, MessageHeader* msg; upb_msg_field_iter i; upb_status status; + bool json_wrapper = is_wrapper(desc->msgdef) && is_json; if (is_json && upb_msgdef_wellknowntype(desc->msgdef) == UPB_WELLKNOWN_ANY) { @@ -1469,7 +1506,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, !upb_msg_field_done(&i); upb_msg_field_next(&i)) { upb_fielddef *f = upb_msg_iter_field(&i); - const upb_oneofdef *oneof = upb_fielddef_containingoneof(f); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f); bool is_matching_oneof = false; uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset + @@ -1508,7 +1545,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, is_default = RSTRING_LEN(str) == 0; } - if (is_matching_oneof || emit_defaults || !is_default) { + if (is_matching_oneof || emit_defaults || !is_default || json_wrapper) { putstr(str, f, sink); } } else if (upb_fielddef_issubmsg(f)) { @@ -1528,7 +1565,7 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc, } else if (upb_msgdef_syntax(desc->msgdef) == UPB_SYNTAX_PROTO3) { \ is_default = default_value == value; \ } \ - if (is_matching_oneof || emit_defaults || !is_default) { \ + if (is_matching_oneof || emit_defaults || !is_default || json_wrapper) { \ upb_sink_put##upbtype(sink, sel, value); \ } \ } break; @@ -1677,7 +1714,7 @@ static void discard_unknown(VALUE msg_rb, const Descriptor* desc) { !upb_msg_field_done(&it); upb_msg_field_next(&it)) { upb_fielddef *f = upb_msg_iter_field(&it); - const upb_oneofdef *oneof = upb_fielddef_containingoneof(f); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(f); uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset + sizeof(MessageHeader); diff --git a/ruby/ext/google/protobuf_c/extconf.rb b/ruby/ext/google/protobuf_c/extconf.rb old mode 100644 new mode 100755 diff --git a/ruby/ext/google/protobuf_c/map.c b/ruby/ext/google/protobuf_c/map.c index 719706b9dd79..00d23a76fa30 100644 --- a/ruby/ext/google/protobuf_c/map.c +++ b/ruby/ext/google/protobuf_c/map.c @@ -100,11 +100,11 @@ static VALUE table_key(Map* self, VALUE key, return key; } -static VALUE table_key_to_ruby(Map* self, const char* buf, size_t length) { +static VALUE table_key_to_ruby(Map* self, upb_strview key) { switch (self->key_type) { case UPB_TYPE_BYTES: case UPB_TYPE_STRING: { - VALUE ret = rb_str_new(buf, length); + VALUE ret = rb_str_new(key.data, key.size); rb_enc_associate(ret, (self->key_type == UPB_TYPE_BYTES) ? kRubyString8bitEncoding : kRubyStringUtf8Encoding); @@ -116,7 +116,7 @@ static VALUE table_key_to_ruby(Map* self, const char* buf, size_t length) { case UPB_TYPE_INT64: case UPB_TYPE_UINT32: case UPB_TYPE_UINT64: - return native_slot_get(self->key_type, Qnil, buf); + return native_slot_get(self->key_type, Qnil, key.data); default: assert(false); @@ -289,9 +289,7 @@ VALUE Map_each(VALUE _self) { for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - - VALUE key = table_key_to_ruby( - self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it)); + VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it)); upb_value v = upb_strtable_iter_value(&it); void* mem = value_memory(&v); @@ -319,9 +317,7 @@ VALUE Map_keys(VALUE _self) { for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - - VALUE key = table_key_to_ruby( - self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it)); + VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it)); rb_ary_push(ret, key); } @@ -526,17 +522,14 @@ VALUE Map_dup(VALUE _self) { for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - + upb_strview k = upb_strtable_iter_key(&it); upb_value v = upb_strtable_iter_value(&it); void* mem = value_memory(&v); upb_value dup; void* dup_mem = value_memory(&dup); native_slot_dup(self->value_type, dup_mem, mem); - if (!upb_strtable_insert2(&new_self->table, - upb_strtable_iter_key(&it), - upb_strtable_iter_keylength(&it), - dup)) { + if (!upb_strtable_insert2(&new_self->table, k.data, k.size, dup)) { rb_raise(rb_eRuntimeError, "Error inserting value into new table"); } } @@ -554,7 +547,7 @@ VALUE Map_deep_copy(VALUE _self) { for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - + upb_strview k = upb_strtable_iter_key(&it); upb_value v = upb_strtable_iter_value(&it); void* mem = value_memory(&v); upb_value dup; @@ -562,10 +555,7 @@ VALUE Map_deep_copy(VALUE _self) { native_slot_deep_copy(self->value_type, self->value_type_class, dup_mem, mem); - if (!upb_strtable_insert2(&new_self->table, - upb_strtable_iter_key(&it), - upb_strtable_iter_keylength(&it), - dup)) { + if (!upb_strtable_insert2(&new_self->table, k.data, k.size, dup)) { rb_raise(rb_eRuntimeError, "Error inserting value into new table"); } } @@ -618,16 +608,13 @@ VALUE Map_eq(VALUE _self, VALUE _other) { for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - + upb_strview k = upb_strtable_iter_key(&it); upb_value v = upb_strtable_iter_value(&it); void* mem = value_memory(&v); upb_value other_v; void* other_mem = value_memory(&other_v); - if (!upb_strtable_lookup2(&other->table, - upb_strtable_iter_key(&it), - upb_strtable_iter_keylength(&it), - &other_v)) { + if (!upb_strtable_lookup2(&other->table, k.data, k.size, &other_v)) { // Not present in other map. return Qfalse; } @@ -655,11 +642,9 @@ VALUE Map_hash(VALUE _self) { VALUE hash_sym = rb_intern("hash"); upb_strtable_iter it; - for (upb_strtable_begin(&it, &self->table); - !upb_strtable_done(&it); + for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - VALUE key = table_key_to_ruby( - self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it)); + VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it)); upb_value v = upb_strtable_iter_value(&it); void* mem = value_memory(&v); @@ -687,8 +672,7 @@ VALUE Map_to_h(VALUE _self) { for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - VALUE key = table_key_to_ruby( - self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it)); + VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it)); upb_value v = upb_strtable_iter_value(&it); void* mem = value_memory(&v); VALUE value = native_slot_get(self->value_type, @@ -720,11 +704,9 @@ VALUE Map_inspect(VALUE _self) { VALUE inspect_sym = rb_intern("inspect"); upb_strtable_iter it; - for (upb_strtable_begin(&it, &self->table); - !upb_strtable_done(&it); + for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { - VALUE key = table_key_to_ruby( - self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it)); + VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it)); upb_value v = upb_strtable_iter_value(&it); void* mem = value_memory(&v); @@ -785,20 +767,15 @@ VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) { for (upb_strtable_begin(&it, &other->table); !upb_strtable_done(&it); upb_strtable_next(&it)) { + upb_strview k = upb_strtable_iter_key(&it); // Replace any existing value by issuing a 'remove' operation first. upb_value v; upb_value oldv; - upb_strtable_remove2(&self->table, - upb_strtable_iter_key(&it), - upb_strtable_iter_keylength(&it), - &oldv); + upb_strtable_remove2(&self->table, k.data, k.size, &oldv); v = upb_strtable_iter_value(&it); - upb_strtable_insert2(&self->table, - upb_strtable_iter_key(&it), - upb_strtable_iter_keylength(&it), - v); + upb_strtable_insert2(&self->table, k.data, k.size, v); } } else { rb_raise(rb_eArgError, "Unknown type merging into Map"); @@ -822,10 +799,7 @@ bool Map_done(Map_iter* iter) { } VALUE Map_iter_key(Map_iter* iter) { - return table_key_to_ruby( - iter->self, - upb_strtable_iter_key(&iter->it), - upb_strtable_iter_keylength(&iter->it)); + return table_key_to_ruby(iter->self, upb_strtable_iter_key(&iter->it)); } VALUE Map_iter_value(Map_iter* iter) { diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index f57501cc65c8..0050506d3bca 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -242,9 +242,14 @@ static int extract_method_call(VALUE method_name, MessageHeader* self, // Method calls like 'has_foo?' are not allowed if field "foo" does not have // a hasbit (e.g. repeated fields or non-message type fields for proto3 // syntax). - if (accessor_type == METHOD_PRESENCE && test_f != NULL && - !upb_fielddef_haspresence(test_f)) { - return METHOD_UNKNOWN; + if (accessor_type == METHOD_PRESENCE && test_f != NULL) { + if (!upb_fielddef_haspresence(test_f)) return METHOD_UNKNOWN; + + // TODO(haberman): remove this case, allow for proto3 oneofs. + if (upb_fielddef_realcontainingoneof(test_f) && + upb_filedef_syntax(upb_fielddef_file(test_f)) == UPB_SYNTAX_PROTO3) { + return METHOD_UNKNOWN; + } } *o = test_o; @@ -605,11 +610,17 @@ VALUE Message_inspect(VALUE _self) { */ VALUE Message_to_h(VALUE _self) { MessageHeader* self; - VALUE hash; + VALUE hash = rb_hash_new(); upb_msg_field_iter it; + bool is_proto2; TypedData_Get_Struct(_self, MessageHeader, &Message_type, self); - hash = rb_hash_new(); + // We currently have a few behaviors that are specific to proto2. + // This is unfortunate, we should key behaviors off field attributes (like + // whether a field has presence), not proto2 vs. proto3. We should see if we + // can change this without breaking users. + is_proto2 = + upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2; for (upb_msg_field_begin(&it, self->descriptor->msgdef); !upb_msg_field_done(&it); @@ -618,10 +629,9 @@ VALUE Message_to_h(VALUE _self) { VALUE msg_value; VALUE msg_key; - // For proto2, do not include fields which are not set. - if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 && - field_contains_hasbit(self->descriptor->layout, field) && - !layout_has(self->descriptor->layout, Message_data(self), field)) { + // Do not include fields that are not present (oneof or optional fields). + if (is_proto2 && upb_fielddef_haspresence(field) && + !layout_has(self->descriptor->layout, Message_data(self), field)) { continue; } @@ -631,8 +641,7 @@ VALUE Message_to_h(VALUE _self) { msg_value = Map_to_h(msg_value); } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { msg_value = RepeatedField_to_ary(msg_value); - if (upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2 && - RARRAY_LEN(msg_value) == 0) { + if (is_proto2 && RARRAY_LEN(msg_value) == 0) { continue; } diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index ae9895c537c5..0ec78fc4fbd6 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -285,6 +285,7 @@ VALUE MessageBuilderContext_initialize(VALUE _self, VALUE _file_builder, VALUE name); VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self); +VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv, VALUE _self); VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self); VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self); VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self); diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c index 739c0a77650f..a3805c96a34f 100644 --- a/ruby/ext/google/protobuf_c/storage.c +++ b/ruby/ext/google/protobuf_c/storage.c @@ -496,11 +496,14 @@ void create_layout(Descriptor* desc) { const upb_msgdef *msgdef = desc->msgdef; MessageLayout* layout = ALLOC(MessageLayout); int nfields = upb_msgdef_numfields(msgdef); - int noneofs = upb_msgdef_numoneofs(msgdef); + int noneofs = upb_msgdef_numrealoneofs(msgdef); upb_msg_field_iter it; upb_msg_oneof_iter oit; size_t off = 0; size_t hasbit = 0; + int i; + + (void)i; layout->empty_template = NULL; layout->desc = desc; @@ -513,11 +516,22 @@ void create_layout(Descriptor* desc) { layout->oneofs = ALLOC_N(MessageOneof, noneofs); } +#ifndef NDEBUG + for (i = 0; i < nfields; i++) { + layout->fields[i].offset = -1; + } + + for (i = 0; i < noneofs; i++) { + layout->oneofs[i].offset = -1; + } +#endif + for (upb_msg_field_begin(&it, msgdef); !upb_msg_field_done(&it); upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); - if (upb_fielddef_haspresence(field)) { + if (upb_fielddef_haspresence(field) && + !upb_fielddef_realcontainingoneof(field)) { layout->fields[upb_fielddef_index(field)].hasbit = hasbit++; } else { layout->fields[upb_fielddef_index(field)].hasbit = @@ -540,7 +554,7 @@ void create_layout(Descriptor* desc) { !upb_msg_field_done(&it); upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); - if (upb_fielddef_containingoneof(field) || !upb_fielddef_isseq(field) || + if (upb_fielddef_realcontainingoneof(field) || !upb_fielddef_isseq(field) || upb_fielddef_ismap(field)) { continue; } @@ -555,7 +569,7 @@ void create_layout(Descriptor* desc) { !upb_msg_field_done(&it); upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); - if (upb_fielddef_containingoneof(field) || !upb_fielddef_isseq(field) || + if (upb_fielddef_realcontainingoneof(field) || !upb_fielddef_isseq(field) || !upb_fielddef_ismap(field)) { continue; } @@ -572,7 +586,7 @@ void create_layout(Descriptor* desc) { !upb_msg_field_done(&it); upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); - if (upb_fielddef_containingoneof(field) || !is_value_field(field) || + if (upb_fielddef_realcontainingoneof(field) || !is_value_field(field) || upb_fielddef_isseq(field)) { continue; } @@ -589,7 +603,7 @@ void create_layout(Descriptor* desc) { const upb_fielddef* field = upb_msg_iter_field(&it); size_t field_size; - if (upb_fielddef_containingoneof(field) || is_value_field(field)) { + if (upb_fielddef_realcontainingoneof(field) || is_value_field(field)) { continue; } @@ -624,6 +638,10 @@ void create_layout(Descriptor* desc) { // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between // all fields. size_t field_size = NATIVE_SLOT_MAX_SIZE; + + if (upb_oneofdef_issynthetic(oneof)) continue; + assert(upb_oneofdef_index(oneof) < noneofs); + // Align the offset. off = align_up_to(off, field_size); // Assign all fields in the oneof this same offset. @@ -643,6 +661,8 @@ void create_layout(Descriptor* desc) { upb_msg_oneof_next(&oit)) { const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit); size_t field_size = sizeof(uint32_t); + if (upb_oneofdef_issynthetic(oneof)) continue; + assert(upb_oneofdef_index(oneof) < noneofs); // Align the offset. off = (off + field_size - 1) & ~(field_size - 1); layout->oneofs[upb_oneofdef_index(oneof)].case_offset = off; @@ -652,6 +672,16 @@ void create_layout(Descriptor* desc) { layout->size = off; layout->msgdef = msgdef; +#ifndef NDEBUG + for (i = 0; i < nfields; i++) { + assert(layout->fields[i].offset != -1); + } + + for (i = 0; i < noneofs; i++) { + assert(layout->oneofs[i].offset != -1); + } +#endif + // Create the empty message template. layout->empty_template = ALLOC_N(char, layout->size); memset(layout->empty_template, 0, layout->size); @@ -725,10 +755,7 @@ static bool slot_is_hasbit_set(MessageLayout* layout, const void* storage, const upb_fielddef* field) { size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit; - if (hasbit == MESSAGE_FIELD_NO_HASBIT) { - return false; - } - + assert(field_contains_hasbit(layout, field)); return DEREF_OFFSET( (uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8)); } @@ -736,15 +763,21 @@ static bool slot_is_hasbit_set(MessageLayout* layout, VALUE layout_has(MessageLayout* layout, const void* storage, const upb_fielddef* field) { - assert(field_contains_hasbit(layout, field)); - return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse; + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field); + assert(upb_fielddef_haspresence(field)); + if (oneof) { + uint32_t oneof_case = slot_read_oneof_case(layout, storage, oneof); + return oneof_case == upb_fielddef_number(field) ? Qtrue : Qfalse; + } else { + return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse; + } } void layout_clear(MessageLayout* layout, const void* storage, const upb_fielddef* field) { void* memory = slot_memory(layout, storage, field); - const upb_oneofdef* oneof = upb_fielddef_containingoneof(field); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field); if (field_contains_hasbit(layout, field)) { slot_clear_hasbit(layout, storage, field); @@ -837,7 +870,7 @@ VALUE layout_get(MessageLayout* layout, const void* storage, const upb_fielddef* field) { void* memory = slot_memory(layout, storage, field); - const upb_oneofdef* oneof = upb_fielddef_containingoneof(field); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field); bool field_set; if (field_contains_hasbit(layout, field)) { field_set = slot_is_hasbit_set(layout, storage, field); @@ -910,7 +943,7 @@ void layout_set(MessageLayout* layout, const upb_fielddef* field, VALUE val) { void* memory = slot_memory(layout, storage, field); - const upb_oneofdef* oneof = upb_fielddef_containingoneof(field); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field); if (oneof) { uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof); @@ -953,7 +986,16 @@ void layout_set(MessageLayout* layout, if (layout->fields[upb_fielddef_index(field)].hasbit != MESSAGE_FIELD_NO_HASBIT) { - slot_set_hasbit(layout, storage, field); + if (val == Qnil) { + // No other field type has a hasbit and allows nil assignment. + if (upb_fielddef_type(field) != UPB_TYPE_MESSAGE) { + fprintf(stderr, "field: %s\n", upb_fielddef_fullname(field)); + } + assert(upb_fielddef_type(field) == UPB_TYPE_MESSAGE); + slot_clear_hasbit(layout, storage, field); + } else { + slot_set_hasbit(layout, storage, field); + } } } @@ -972,7 +1014,7 @@ void layout_init(MessageLayout* layout, void* storage) { void layout_mark(MessageLayout* layout, void* storage) { VALUE* values = (VALUE*)CHARPTR_AT(storage, layout->value_offset); - int noneofs = upb_msgdef_numoneofs(layout->msgdef); + int noneofs = upb_msgdef_numrealoneofs(layout->msgdef); int i; for (i = 0; i < layout->value_count; i++) { @@ -994,7 +1036,7 @@ void layout_dup(MessageLayout* layout, void* to, void* from) { !upb_msg_field_done(&it); upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); - const upb_oneofdef* oneof = upb_fielddef_containingoneof(field); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field); void* to_memory = slot_memory(layout, to, field); void* from_memory = slot_memory(layout, from, field); @@ -1028,7 +1070,7 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) { !upb_msg_field_done(&it); upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); - const upb_oneofdef* oneof = upb_fielddef_containingoneof(field); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field); void* to_memory = slot_memory(layout, to, field); void* from_memory = slot_memory(layout, from, field); @@ -1068,7 +1110,7 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) { !upb_msg_field_done(&it); upb_msg_field_next(&it)) { const upb_fielddef* field = upb_msg_iter_field(&it); - const upb_oneofdef* oneof = upb_fielddef_containingoneof(field); + const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field); void* msg1_memory = slot_memory(layout, msg1, field); void* msg2_memory = slot_memory(layout, msg2, field); @@ -1095,9 +1137,16 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) { return Qfalse; } } else { - if (slot_is_hasbit_set(layout, msg1, field) != - slot_is_hasbit_set(layout, msg2, field) || - !native_slot_eq(upb_fielddef_type(field), + if (field_contains_hasbit(layout, field) && + slot_is_hasbit_set(layout, msg1, field) != + slot_is_hasbit_set(layout, msg2, field)) { + // TODO(haberman): I don't think we should actually care about hasbits + // here: an unset default should be able to equal a set default. But we + // can address this later (will also have to make sure defaults are + // being properly set when hasbit is clear). + return Qfalse; + } + if (!native_slot_eq(upb_fielddef_type(field), field_type_class(layout, field), msg1_memory, msg2_memory)) { return Qfalse; diff --git a/ruby/ext/google/protobuf_c/upb.c b/ruby/ext/google/protobuf_c/upb.c index b7d7c162cf79..61e86fcf104a 100644 --- a/ruby/ext/google/protobuf_c/upb.c +++ b/ruby/ext/google/protobuf_c/upb.c @@ -22,9 +22,7 @@ * * This file is private and must not be included by users! */ -#ifndef UINTPTR_MAX -#error must include stdint.h first -#endif +#include #if UINTPTR_MAX == 0xffffffff #define UPB_SIZE(size32, size64) size32 @@ -32,17 +30,21 @@ #define UPB_SIZE(size32, size64) size64 #endif -#define UPB_FIELD_AT(msg, fieldtype, offset) \ - *(fieldtype*)((const char*)(msg) + offset) +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ - UPB_FIELD_AT(msg, int, case_offset) == case_val \ - ? UPB_FIELD_AT(msg, fieldtype, offset) \ + *UPB_PTR_AT(msg, case_offset, int) == case_val \ + ? *UPB_PTR_AT(msg, offset, fieldtype) \ : default #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ - UPB_FIELD_AT(msg, int, case_offset) = case_val; \ - UPB_FIELD_AT(msg, fieldtype, offset) = value; + *UPB_PTR_AT(msg, case_offset, int) = case_val; \ + *UPB_PTR_AT(msg, offset, fieldtype) = value; + +#define UPB_MAPTYPE_STRING 0 /* UPB_INLINE: inline if possible, emit standalone code if required. */ #ifdef __cplusplus @@ -116,7 +118,7 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #ifdef __cplusplus #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ (defined(_MSC_VER) && _MSC_VER >= 1900) -// C++11 is present +/* C++11 is present */ #else #error upb requires C++11 for C++ support #endif @@ -127,6 +129,18 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_UNUSED(var) (void)var +/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. + */ +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable() +#else +#define UPB_ASSUME(expr) do {} if (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + /* UPB_ASSERT(): in release mode, we use the expression without letting it be * evaluated. This prevents "unused variable" warnings. */ #ifdef NDEBUG @@ -153,606 +167,572 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_INFINITY (1.0 / 0.0) #endif +#include #include + /* Maps descriptor type -> upb field type. */ -const uint8_t upb_desctype_to_fieldtype[] = { - UPB_WIRE_TYPE_END_GROUP, /* ENDGROUP */ - UPB_TYPE_DOUBLE, /* DOUBLE */ - UPB_TYPE_FLOAT, /* FLOAT */ - UPB_TYPE_INT64, /* INT64 */ - UPB_TYPE_UINT64, /* UINT64 */ - UPB_TYPE_INT32, /* INT32 */ - UPB_TYPE_UINT64, /* FIXED64 */ - UPB_TYPE_UINT32, /* FIXED32 */ - UPB_TYPE_BOOL, /* BOOL */ - UPB_TYPE_STRING, /* STRING */ - UPB_TYPE_MESSAGE, /* GROUP */ - UPB_TYPE_MESSAGE, /* MESSAGE */ - UPB_TYPE_BYTES, /* BYTES */ - UPB_TYPE_UINT32, /* UINT32 */ - UPB_TYPE_ENUM, /* ENUM */ - UPB_TYPE_INT32, /* SFIXED32 */ - UPB_TYPE_INT64, /* SFIXED64 */ - UPB_TYPE_INT32, /* SINT32 */ - UPB_TYPE_INT64, /* SINT64 */ +static const uint8_t desctype_to_fieldtype[] = { + -1, /* invalid descriptor type */ + UPB_TYPE_DOUBLE, /* DOUBLE */ + UPB_TYPE_FLOAT, /* FLOAT */ + UPB_TYPE_INT64, /* INT64 */ + UPB_TYPE_UINT64, /* UINT64 */ + UPB_TYPE_INT32, /* INT32 */ + UPB_TYPE_UINT64, /* FIXED64 */ + UPB_TYPE_UINT32, /* FIXED32 */ + UPB_TYPE_BOOL, /* BOOL */ + UPB_TYPE_STRING, /* STRING */ + UPB_TYPE_MESSAGE, /* GROUP */ + UPB_TYPE_MESSAGE, /* MESSAGE */ + UPB_TYPE_BYTES, /* BYTES */ + UPB_TYPE_UINT32, /* UINT32 */ + UPB_TYPE_ENUM, /* ENUM */ + UPB_TYPE_INT32, /* SFIXED32 */ + UPB_TYPE_INT64, /* SFIXED64 */ + UPB_TYPE_INT32, /* SINT32 */ + UPB_TYPE_INT64, /* SINT64 */ +}; + +/* Maps descriptor type -> upb map size. */ +static const uint8_t desctype_to_mapsize[] = { + -1, /* invalid descriptor type */ + 8, /* DOUBLE */ + 4, /* FLOAT */ + 8, /* INT64 */ + 8, /* UINT64 */ + 4, /* INT32 */ + 8, /* FIXED64 */ + 4, /* FIXED32 */ + 1, /* BOOL */ + UPB_MAPTYPE_STRING, /* STRING */ + sizeof(void *), /* GROUP */ + sizeof(void *), /* MESSAGE */ + UPB_MAPTYPE_STRING, /* BYTES */ + 4, /* UINT32 */ + 4, /* ENUM */ + 4, /* SFIXED32 */ + 8, /* SFIXED64 */ + 4, /* SINT32 */ + 8, /* SINT64 */ +}; + +static const unsigned fixed32_ok = (1 << UPB_DTYPE_FLOAT) | + (1 << UPB_DTYPE_FIXED32) | + (1 << UPB_DTYPE_SFIXED32); + +static const unsigned fixed64_ok = (1 << UPB_DTYPE_DOUBLE) | + (1 << UPB_DTYPE_FIXED64) | + (1 << UPB_DTYPE_SFIXED64); + +/* Op: an action to be performed for a wire-type/field-type combination. */ +#define OP_SCALAR_LG2(n) (n) +#define OP_FIXPCK_LG2(n) (n + 4) +#define OP_VARPCK_LG2(n) (n + 8) +#define OP_STRING 4 +#define OP_SUBMSG 5 + +static const int8_t varint_ops[19] = { + -1, /* field not found */ + -1, /* DOUBLE */ + -1, /* FLOAT */ + OP_SCALAR_LG2(3), /* INT64 */ + OP_SCALAR_LG2(3), /* UINT64 */ + OP_SCALAR_LG2(2), /* INT32 */ + -1, /* FIXED64 */ + -1, /* FIXED32 */ + OP_SCALAR_LG2(0), /* BOOL */ + -1, /* STRING */ + -1, /* GROUP */ + -1, /* MESSAGE */ + -1, /* BYTES */ + OP_SCALAR_LG2(2), /* UINT32 */ + OP_SCALAR_LG2(2), /* ENUM */ + -1, /* SFIXED32 */ + -1, /* SFIXED64 */ + OP_SCALAR_LG2(2), /* SINT32 */ + OP_SCALAR_LG2(3), /* SINT64 */ +}; + +static const int8_t delim_ops[37] = { + /* For non-repeated field type. */ + -1, /* field not found */ + -1, /* DOUBLE */ + -1, /* FLOAT */ + -1, /* INT64 */ + -1, /* UINT64 */ + -1, /* INT32 */ + -1, /* FIXED64 */ + -1, /* FIXED32 */ + -1, /* BOOL */ + OP_STRING, /* STRING */ + -1, /* GROUP */ + OP_SUBMSG, /* MESSAGE */ + OP_STRING, /* BYTES */ + -1, /* UINT32 */ + -1, /* ENUM */ + -1, /* SFIXED32 */ + -1, /* SFIXED64 */ + -1, /* SINT32 */ + -1, /* SINT64 */ + /* For repeated field type. */ + OP_FIXPCK_LG2(3), /* REPEATED DOUBLE */ + OP_FIXPCK_LG2(2), /* REPEATED FLOAT */ + OP_VARPCK_LG2(3), /* REPEATED INT64 */ + OP_VARPCK_LG2(3), /* REPEATED UINT64 */ + OP_VARPCK_LG2(2), /* REPEATED INT32 */ + OP_FIXPCK_LG2(3), /* REPEATED FIXED64 */ + OP_FIXPCK_LG2(2), /* REPEATED FIXED32 */ + OP_VARPCK_LG2(0), /* REPEATED BOOL */ + OP_STRING, /* REPEATED STRING */ + OP_SUBMSG, /* REPEATED GROUP */ + OP_SUBMSG, /* REPEATED MESSAGE */ + OP_STRING, /* REPEATED BYTES */ + OP_VARPCK_LG2(2), /* REPEATED UINT32 */ + OP_VARPCK_LG2(2), /* REPEATED ENUM */ + OP_FIXPCK_LG2(2), /* REPEATED SFIXED32 */ + OP_FIXPCK_LG2(3), /* REPEATED SFIXED64 */ + OP_VARPCK_LG2(2), /* REPEATED SINT32 */ + OP_VARPCK_LG2(3), /* REPEATED SINT64 */ }; /* Data pertaining to the parse. */ typedef struct { - const char *ptr; /* Current parsing position. */ - const char *field_start; /* Start of this field. */ - const char *limit; /* End of delimited region or end of buffer. */ + const char *limit; /* End of delimited region or end of buffer. */ upb_arena *arena; int depth; - uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ + uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ + jmp_buf err; } upb_decstate; -/* Data passed by value to each parsing function. */ -typedef struct { - char *msg; - const upb_msglayout *layout; - upb_decstate *state; -} upb_decframe; +typedef union { + bool bool_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + upb_strview str_val; +} wireval; -#define CHK(x) if (!(x)) { return 0; } +static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout); -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number); -static bool upb_decode_message(upb_decstate *d, char *msg, - const upb_msglayout *l); +UPB_NORETURN static void decode_err(upb_decstate *d) { longjmp(d->err, 1); } -static bool upb_decode_varint(const char **ptr, const char *limit, - uint64_t *val) { +static bool decode_reserve(upb_decstate *d, upb_array *arr, int elem) { + bool need_realloc = arr->size - arr->len < elem; + if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, d->arena)) { + decode_err(d); + } + return need_realloc; +} + +UPB_NOINLINE +static const char *decode_longvarint64(upb_decstate *d, const char *ptr, + const char *limit, uint64_t *val) { uint8_t byte; int bitpos = 0; - const char *p = *ptr; - *val = 0; + uint64_t out = 0; do { - CHK(bitpos < 70 && p < limit); - byte = *p; - *val |= (uint64_t)(byte & 0x7F) << bitpos; - p++; + if (bitpos >= 70 || ptr == limit) decode_err(d); + byte = *ptr; + out |= (uint64_t)(byte & 0x7F) << bitpos; + ptr++; bitpos += 7; } while (byte & 0x80); - *ptr = p; - return true; -} - -static bool upb_decode_varint32(const char **ptr, const char *limit, - uint32_t *val) { - uint64_t u64; - CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX); - *val = (uint32_t)u64; - return true; -} - -static bool upb_decode_64bit(const char **ptr, const char *limit, - uint64_t *val) { - CHK(limit - *ptr >= 8); - memcpy(val, *ptr, 8); - *ptr += 8; - return true; + *val = out; + return ptr; } -static bool upb_decode_32bit(const char **ptr, const char *limit, - uint32_t *val) { - CHK(limit - *ptr >= 4); - memcpy(val, *ptr, 4); - *ptr += 4; - return true; -} - -static int32_t upb_zzdecode_32(uint32_t n) { - return (n >> 1) ^ -(int32_t)(n & 1); -} - -static int64_t upb_zzdecode_64(uint64_t n) { - return (n >> 1) ^ -(int64_t)(n & 1); -} - -static bool upb_decode_string(const char **ptr, const char *limit, - int *outlen) { - uint32_t len; - - CHK(upb_decode_varint32(ptr, limit, &len) && - len < INT32_MAX && - limit - *ptr >= (int32_t)len); - - *outlen = len; - return true; -} - -static void upb_set32(void *msg, size_t ofs, uint32_t val) { - memcpy((char*)msg + ofs, &val, sizeof(val)); +UPB_FORCEINLINE +static const char *decode_varint64(upb_decstate *d, const char *ptr, + const char *limit, uint64_t *val) { + if (UPB_LIKELY(ptr < limit && (*ptr & 0x80) == 0)) { + *val = (uint8_t)*ptr; + return ptr + 1; + } else { + return decode_longvarint64(d, ptr, limit, val); + } } -static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame) { - upb_msg_addunknown(frame->msg, d->field_start, d->ptr - d->field_start, - d->arena); - return true; +static const char *decode_varint32(upb_decstate *d, const char *ptr, + const char *limit, uint32_t *val) { + uint64_t u64; + ptr = decode_varint64(d, ptr, limit, &u64); + if (u64 > UINT32_MAX) decode_err(d); + *val = (uint32_t)u64; + return ptr; } - -static bool upb_skip_unknownfielddata(upb_decstate *d, uint32_t tag, - uint32_t group_fieldnum) { - switch (tag & 7) { - case UPB_WIRE_TYPE_VARINT: { - uint64_t val; - return upb_decode_varint(&d->ptr, d->limit, &val); - } - case UPB_WIRE_TYPE_32BIT: { - uint32_t val; - return upb_decode_32bit(&d->ptr, d->limit, &val); - } - case UPB_WIRE_TYPE_64BIT: { - uint64_t val; - return upb_decode_64bit(&d->ptr, d->limit, &val); +static void decode_munge(int type, wireval *val) { + switch (type) { + case UPB_DESCRIPTOR_TYPE_BOOL: + val->bool_val = val->uint64_val != 0; + break; + case UPB_DESCRIPTOR_TYPE_SINT32: { + uint32_t n = val->uint32_val; + val->int32_val = (n >> 1) ^ -(int32_t)(n & 1); + break; } - case UPB_WIRE_TYPE_DELIMITED: { - int len; - CHK(upb_decode_string(&d->ptr, d->limit, &len)); - d->ptr += len; - return true; + case UPB_DESCRIPTOR_TYPE_SINT64: { + uint64_t n = val->uint64_val; + val->int64_val = (n >> 1) ^ -(int64_t)(n & 1); + break; } - case UPB_WIRE_TYPE_START_GROUP: - return upb_skip_unknowngroup(d, tag >> 3); - case UPB_WIRE_TYPE_END_GROUP: - return (tag >> 3) == group_fieldnum; - } - return false; -} - -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number) { - while (d->ptr < d->limit && d->end_group == 0) { - uint32_t tag = 0; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); - CHK(upb_skip_unknownfielddata(d, tag, field_number)); } - - CHK(d->end_group == field_number); - d->end_group = 0; - return true; } -static bool upb_array_grow(upb_array *arr, size_t elements, size_t elem_size, - upb_arena *arena) { - size_t needed = arr->len + elements; - size_t new_size = UPB_MAX(arr->size, 8); - size_t new_bytes; - size_t old_bytes; - void *new_data; - upb_alloc *alloc = upb_arena_alloc(arena); +static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, + uint32_t field_number) { + static upb_msglayout_field none = {0}; - while (new_size < needed) { - new_size *= 2; + /* Lots of optimization opportunities here. */ + int i; + if (l == NULL) return &none; + for (i = 0; i < l->field_count; i++) { + if (l->fields[i].number == field_number) { + return &l->fields[i]; + } } - old_bytes = arr->len * elem_size; - new_bytes = new_size * elem_size; - new_data = upb_realloc(alloc, arr->data, old_bytes, new_bytes); - CHK(new_data); - - arr->data = new_data; - arr->size = new_size; - return true; + return &none; /* Unknown field. */ } -static void *upb_array_reserve(upb_array *arr, size_t elements, - size_t elem_size, upb_arena *arena) { - if (arr->size - arr->len < elements) { - CHK(upb_array_grow(arr, elements, elem_size, arena)); - } - return (char*)arr->data + (arr->len * elem_size); +static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout, + const upb_msglayout_field *field) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + return _upb_msg_new(subl, d->arena); } -bool upb_array_add(upb_array *arr, size_t elements, size_t elem_size, - const void *data, upb_arena *arena) { - void *dest = upb_array_reserve(arr, elements, elem_size, arena); - - CHK(dest); - arr->len += elements; - memcpy(dest, data, elements * elem_size); +static void decode_tosubmsg(upb_decstate *d, upb_msg *submsg, + const upb_msglayout *layout, + const upb_msglayout_field *field, upb_strview val) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + const char *saved_limit = d->limit; + if (--d->depth < 0) decode_err(d); + d->limit = val.data + val.size; + decode_msg(d, val.data, submsg, subl); + d->limit = saved_limit; + if (d->end_group != 0) decode_err(d); + d->depth++; +} - return true; +static const char *decode_group(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *subl, + uint32_t number) { + if (--d->depth < 0) decode_err(d); + ptr = decode_msg(d, ptr, submsg, subl); + if (d->end_group != number) decode_err(d); + d->end_group = 0; + d->depth++; + return ptr; } -static upb_array *upb_getarr(upb_decframe *frame, - const upb_msglayout_field *field) { - UPB_ASSERT(field->label == UPB_LABEL_REPEATED); - return *(upb_array**)&frame->msg[field->offset]; +static const char *decode_togroup(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *layout, + const upb_msglayout_field *field) { + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + return decode_group(d, ptr, submsg, subl, field->number); } -static upb_array *upb_getorcreatearr(upb_decframe *frame, - const upb_msglayout_field *field) { - upb_array *arr = upb_getarr(frame, field); +static const char *decode_toarray(upb_decstate *d, const char *ptr, + upb_msg *msg, const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val, + int op) { + upb_array **arrp = UPB_PTR_AT(msg, field->offset, void); + upb_array *arr = *arrp; + void *mem; if (!arr) { - arr = upb_array_new(frame->state->arena); - CHK(arr); - *(upb_array**)&frame->msg[field->offset] = arr; + upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype]; + arr = _upb_array_new(d->arena, type); + if (!arr) decode_err(d); + *arrp = arr; } - return arr; -} - -static upb_msg *upb_getorcreatemsg(upb_decframe *frame, - const upb_msglayout_field *field, - const upb_msglayout **subm) { - upb_msg **submsg = (void*)(frame->msg + field->offset); - *subm = frame->layout->submsgs[field->submsg_index]; - - UPB_ASSERT(field->label != UPB_LABEL_REPEATED); + decode_reserve(d, arr, 1); - if (!*submsg) { - *submsg = upb_msg_new(*subm, frame->state->arena); - CHK(*submsg); + switch (op) { + case OP_SCALAR_LG2(0): + case OP_SCALAR_LG2(2): + case OP_SCALAR_LG2(3): + /* Append scalar value. */ + mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void); + arr->len++; + memcpy(mem, &val, 1 << op); + return ptr; + case OP_STRING: + /* Append string. */ + mem = + UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(upb_strview), void); + arr->len++; + memcpy(mem, &val, sizeof(upb_strview)); + return ptr; + case OP_SUBMSG: { + /* Append submessage / group. */ + upb_msg *submsg = decode_newsubmsg(d, layout, field); + *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) = + submsg; + arr->len++; + if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) { + ptr = decode_togroup(d, ptr, submsg, layout, field); + } else { + decode_tosubmsg(d, submsg, layout, field, val.str_val); + } + return ptr; + } + case OP_FIXPCK_LG2(2): + case OP_FIXPCK_LG2(3): { + /* Fixed packed. */ + int lg2 = op - OP_FIXPCK_LG2(0); + int mask = (1 << lg2) - 1; + int count = val.str_val.size >> lg2; + if ((val.str_val.size & mask) != 0) { + decode_err(d); /* Length isn't a round multiple of elem size. */ + } + decode_reserve(d, arr, count); + mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + arr->len += count; + memcpy(mem, val.str_val.data, count << op); + return ptr; + } + case OP_VARPCK_LG2(0): + case OP_VARPCK_LG2(2): + case OP_VARPCK_LG2(3): { + /* Varint packed. */ + int lg2 = op - OP_VARPCK_LG2(0); + int scale = 1 << lg2; + const char *ptr = val.str_val.data; + const char *end = ptr + val.str_val.size; + char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + while (ptr < end) { + wireval elem; + ptr = decode_varint64(d, ptr, end, &elem.uint64_val); + decode_munge(field->descriptortype, &elem); + if (decode_reserve(d, arr, 1)) { + out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); + } + arr->len++; + memcpy(out, &elem, scale); + out += scale; + } + if (ptr != end) decode_err(d); + return ptr; + } + default: + UPB_UNREACHABLE(); } - - return *submsg; } -static upb_msg *upb_addmsg(upb_decframe *frame, - const upb_msglayout_field *field, - const upb_msglayout **subm) { - upb_msg *submsg; - upb_array *arr = upb_getorcreatearr(frame, field); - - *subm = frame->layout->submsgs[field->submsg_index]; - submsg = upb_msg_new(*subm, frame->state->arena); - CHK(submsg); - upb_array_add(arr, 1, sizeof(submsg), &submsg, frame->state->arena); - - return submsg; -} +static void decode_tomap(upb_decstate *d, upb_msg *msg, + const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val) { + upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *); + upb_map *map = *map_p; + upb_map_entry ent; + const upb_msglayout *entry = layout->submsgs[field->submsg_index]; -static void upb_sethasbit(upb_decframe *frame, - const upb_msglayout_field *field) { - int32_t hasbit = field->presence; - UPB_ASSERT(field->presence > 0); - frame->msg[hasbit / 8] |= (1 << (hasbit % 8)); -} - -static void upb_setoneofcase(upb_decframe *frame, - const upb_msglayout_field *field) { - UPB_ASSERT(field->presence < 0); - upb_set32(frame->msg, ~field->presence, field->number); -} - -static bool upb_decode_addval(upb_decframe *frame, - const upb_msglayout_field *field, void *val, - size_t size) { - char *field_mem = frame->msg + field->offset; - upb_array *arr; - - if (field->label == UPB_LABEL_REPEATED) { - arr = upb_getorcreatearr(frame, field); - CHK(arr); - field_mem = upb_array_reserve(arr, 1, size, frame->state->arena); - CHK(field_mem); + if (!map) { + /* Lazily create map. */ + const upb_msglayout *entry = layout->submsgs[field->submsg_index]; + const upb_msglayout_field *key_field = &entry->fields[0]; + const upb_msglayout_field *val_field = &entry->fields[1]; + char key_size = desctype_to_mapsize[key_field->descriptortype]; + char val_size = desctype_to_mapsize[val_field->descriptortype]; + UPB_ASSERT(key_field->offset == 0); + UPB_ASSERT(val_field->offset == sizeof(upb_strview)); + map = _upb_map_new(d->arena, key_size, val_size); + *map_p = map; } - memcpy(field_mem, val, size); - return true; -} + /* Parse map entry. */ + memset(&ent, 0, sizeof(ent)); -static void upb_decode_setpresent(upb_decframe *frame, - const upb_msglayout_field *field) { - if (field->label == UPB_LABEL_REPEATED) { - upb_array *arr = upb_getarr(frame, field); - UPB_ASSERT(arr->len < arr->size); - arr->len++; - } else if (field->presence < 0) { - upb_setoneofcase(frame, field); - } else if (field->presence > 0) { - upb_sethasbit(frame, field); + if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || + entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) { + /* Create proactively to handle the case where it doesn't appear. */ + ent.v.val.val = (uint64_t)_upb_msg_new(entry->submsgs[0], d->arena); } -} -static bool upb_decode_msgfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, int limit) { - const char* saved_limit = d->limit; - d->limit = d->ptr + limit; - CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); - d->depth++; - d->limit = saved_limit; - CHK(d->end_group == 0); - return true; -} + decode_tosubmsg(d, &ent.k, layout, field, val.str_val); -static bool upb_decode_groupfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, - int field_number) { - CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); - d->depth++; - CHK(d->end_group == field_number); - d->end_group = 0; - return true; + /* Insert into map. */ + _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena); } -static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint64_t val; - CHK(upb_decode_varint(&d->ptr, d->limit, &val)); +static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout, + const upb_msglayout_field *field, wireval val, + int op) { + void *mem = UPB_PTR_AT(msg, field->offset, void); + int type = field->descriptortype; - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); - break; - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_ENUM: { - uint32_t val32 = (uint32_t)val; - CHK(upb_decode_addval(frame, field, &val32, sizeof(val32))); - break; - } - case UPB_DESCRIPTOR_TYPE_BOOL: { - bool valbool = val != 0; - CHK(upb_decode_addval(frame, field, &valbool, sizeof(valbool))); + /* Set presence if necessary. */ + if (field->presence < 0) { + /* Oneof case */ + *UPB_PTR_AT(msg, -field->presence, int32_t) = field->number; + } else if (field->presence > 0) { + /* Hasbit */ + uint32_t hasbit = field->presence; + *UPB_PTR_AT(msg, hasbit / 8, uint8_t) |= (1 << (hasbit % 8)); + } + + /* Store into message. */ + switch (op) { + case OP_SUBMSG: { + upb_msg **submsgp = mem; + upb_msg *submsg = *submsgp; + if (!submsg) { + submsg = decode_newsubmsg(d, layout, field); + *submsgp = submsg; + } + if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) { + ptr = decode_togroup(d, ptr, submsg, layout, field); + } else { + decode_tosubmsg(d, submsg, layout, field, val.str_val); + } break; } - case UPB_DESCRIPTOR_TYPE_SINT32: { - int32_t decoded = upb_zzdecode_32((uint32_t)val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); + case OP_STRING: + memcpy(mem, &val, sizeof(upb_strview)); break; - } - case UPB_DESCRIPTOR_TYPE_SINT64: { - int64_t decoded = upb_zzdecode_64(val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); + case OP_SCALAR_LG2(3): + memcpy(mem, &val, 8); break; - } - default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint64_t val; - CHK(upb_decode_64bit(&d->ptr, d->limit, &val)); - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - case UPB_DESCRIPTOR_TYPE_FIXED64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); + case OP_SCALAR_LG2(2): + memcpy(mem, &val, 4); break; - default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - uint32_t val; - CHK(upb_decode_32bit(&d->ptr, d->limit, &val)); - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_FLOAT: - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); + case OP_SCALAR_LG2(0): + memcpy(mem, &val, 1); break; default: - return upb_append_unknown(d, frame); - } - - upb_decode_setpresent(frame, field); - return true; -} - -static bool upb_decode_fixedpacked(upb_decstate *d, upb_array *arr, - uint32_t len, int elem_size) { - size_t elements = len / elem_size; - - CHK((size_t)(elements * elem_size) == len); - CHK(upb_array_add(arr, elements, elem_size, d->ptr, d->arena)); - d->ptr += len; - - return true; -} - -static upb_strview upb_decode_strfield(upb_decstate *d, uint32_t len) { - upb_strview ret; - ret.data = d->ptr; - ret.size = len; - d->ptr += len; - return ret; -} - -static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field, int len) { - upb_array *arr = upb_getorcreatearr(frame, field); - CHK(arr); - -#define VARINT_CASE(ctype, decode) \ - VARINT_CASE_EX(ctype, decode, decode) - -#define VARINT_CASE_EX(ctype, decode, dtype) \ - { \ - const char *ptr = d->ptr; \ - const char *limit = ptr + len; \ - while (ptr < limit) { \ - uint64_t val; \ - ctype decoded; \ - CHK(upb_decode_varint(&ptr, limit, &val)); \ - decoded = (decode)((dtype)val); \ - CHK(upb_array_add(arr, 1, sizeof(decoded), &decoded, d->arena)); \ - } \ - d->ptr = ptr; \ - return true; \ - } - - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - return upb_array_add(arr, 1, sizeof(str), &str, d->arena); - } - case UPB_DESCRIPTOR_TYPE_FLOAT: - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - return upb_decode_fixedpacked(d, arr, len, sizeof(int32_t)); - case UPB_DESCRIPTOR_TYPE_DOUBLE: - case UPB_DESCRIPTOR_TYPE_FIXED64: - case UPB_DESCRIPTOR_TYPE_SFIXED64: - return upb_decode_fixedpacked(d, arr, len, sizeof(int64_t)); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_UINT32: - case UPB_DESCRIPTOR_TYPE_ENUM: - VARINT_CASE(uint32_t, uint32_t); - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - VARINT_CASE(uint64_t, uint64_t); - case UPB_DESCRIPTOR_TYPE_BOOL: - VARINT_CASE(bool, bool); - case UPB_DESCRIPTOR_TYPE_SINT32: - VARINT_CASE_EX(int32_t, upb_zzdecode_32, uint32_t); - case UPB_DESCRIPTOR_TYPE_SINT64: - VARINT_CASE_EX(int64_t, upb_zzdecode_64, uint64_t); - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_addmsg(frame, field, &subm); - CHK(submsg); - return upb_decode_msgfield(d, submsg, subm, len); - } - case UPB_DESCRIPTOR_TYPE_GROUP: - return upb_append_unknown(d, frame); + UPB_UNREACHABLE(); } -#undef VARINT_CASE - UPB_UNREACHABLE(); -} - -static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { - int len; - - CHK(upb_decode_string(&d->ptr, d->limit, &len)); - if (field->label == UPB_LABEL_REPEATED) { - return upb_decode_toarray(d, frame, field, len); - } else { - switch (field->descriptortype) { - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - CHK(upb_decode_addval(frame, field, &str, sizeof(str))); - break; - } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_getorcreatemsg(frame, field, &subm); - CHK(submsg); - CHK(upb_decode_msgfield(d, submsg, subm, len)); - break; - } - default: - /* TODO(haberman): should we accept the last element of a packed? */ - d->ptr += len; - return upb_append_unknown(d, frame); - } - upb_decode_setpresent(frame, field); - return true; - } + return ptr; } -static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, - uint32_t field_number) { - /* Lots of optimization opportunities here. */ - int i; - for (i = 0; i < l->field_count; i++) { - if (l->fields[i].number == field_number) { - return &l->fields[i]; - } - } - - return NULL; /* Unknown field. */ -} +static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, + const upb_msglayout *layout) { + while (ptr < d->limit) { + uint32_t tag; + const upb_msglayout_field *field; + int field_number; + int wire_type; + const char *field_start = ptr; + wireval val; + int op; -static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) { - uint32_t tag; - const upb_msglayout_field *field; - int field_number; + ptr = decode_varint32(d, ptr, d->limit, &tag); + field_number = tag >> 3; + wire_type = tag & 7; - d->field_start = d->ptr; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); - field_number = tag >> 3; - field = upb_find_field(frame->layout, field_number); + field = upb_find_field(layout, field_number); - if (field) { - switch (tag & 7) { + switch (wire_type) { case UPB_WIRE_TYPE_VARINT: - return upb_decode_varintfield(d, frame, field); + ptr = decode_varint64(d, ptr, d->limit, &val.uint64_val); + op = varint_ops[field->descriptortype]; + decode_munge(field->descriptortype, &val); + break; case UPB_WIRE_TYPE_32BIT: - return upb_decode_32bitfield(d, frame, field); + if (d->limit - ptr < 4) decode_err(d); + memcpy(&val, ptr, 4); + ptr += 4; + op = OP_SCALAR_LG2(2); + if (((1 << field->descriptortype) & fixed32_ok) == 0) goto unknown; + break; case UPB_WIRE_TYPE_64BIT: - return upb_decode_64bitfield(d, frame, field); - case UPB_WIRE_TYPE_DELIMITED: - return upb_decode_delimitedfield(d, frame, field); - case UPB_WIRE_TYPE_START_GROUP: { - const upb_msglayout *layout; - upb_msg *group; - - if (field->label == UPB_LABEL_REPEATED) { - group = upb_addmsg(frame, field, &layout); - } else { - group = upb_getorcreatemsg(frame, field, &layout); + if (d->limit - ptr < 8) decode_err(d); + memcpy(&val, ptr, 8); + ptr += 8; + op = OP_SCALAR_LG2(3); + if (((1 << field->descriptortype) & fixed64_ok) == 0) goto unknown; + break; + case UPB_WIRE_TYPE_DELIMITED: { + uint32_t size; + int ndx = field->descriptortype; + if (_upb_isrepeated(field)) ndx += 18; + ptr = decode_varint32(d, ptr, d->limit, &size); + if (size >= INT32_MAX || (size_t)(d->limit - ptr) < size) { + decode_err(d); /* Length overflow. */ } - - return upb_decode_groupfield(d, group, layout, field_number); + val.str_val.data = ptr; + val.str_val.size = size; + ptr += size; + op = delim_ops[ndx]; + break; } + case UPB_WIRE_TYPE_START_GROUP: + val.int32_val = field_number; + op = OP_SUBMSG; + if (field->descriptortype != UPB_DTYPE_GROUP) goto unknown; + break; case UPB_WIRE_TYPE_END_GROUP: d->end_group = field_number; - return true; + return ptr; default: - CHK(false); + decode_err(d); + } + + if (op >= 0) { + /* Parse, using op for dispatch. */ + switch (field->label) { + case UPB_LABEL_REPEATED: + case _UPB_LABEL_PACKED: + ptr = decode_toarray(d, ptr, msg, layout, field, val, op); + break; + case _UPB_LABEL_MAP: + decode_tomap(d, msg, layout, field, val); + break; + default: + ptr = decode_tomsg(d, ptr, msg, layout, field, val, op); + break; + } + } else { + unknown: + /* Skip unknown field. */ + if (field_number == 0) decode_err(d); + if (wire_type == UPB_WIRE_TYPE_START_GROUP) { + ptr = decode_group(d, ptr, NULL, NULL, field_number); + } + if (msg) { + if (!_upb_msg_addunknown(msg, field_start, ptr - field_start, + d->arena)) { + decode_err(d); + } + } } - } else { - CHK(field_number != 0); - CHK(upb_skip_unknownfielddata(d, tag, -1)); - CHK(upb_append_unknown(d, frame)); - return true; - } -} - -static bool upb_decode_message(upb_decstate *d, char *msg, const upb_msglayout *l) { - upb_decframe frame; - frame.msg = msg; - frame.layout = l; - frame.state = d; - - while (d->ptr < d->limit) { - CHK(upb_decode_field(d, &frame)); } - return true; + if (ptr != d->limit) decode_err(d); + return ptr; } bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, upb_arena *arena) { upb_decstate state; - state.ptr = buf; state.limit = buf + size; state.arena = arena; state.depth = 64; state.end_group = 0; - CHK(upb_decode_message(&state, msg, l)); + if (setjmp(state.err)) return false; + + if (size == 0) return true; + decode_msg(&state, buf, msg, l); + return state.end_group == 0; } -#undef CHK +#undef OP_SCALAR_LG2 +#undef OP_FIXPCK_LG2 +#undef OP_VARPCK_LG2 +#undef OP_STRING +#undef OP_SUBMSG /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */ @@ -821,6 +801,7 @@ static bool upb_encode_reserve(upb_encstate *e, size_t bytes) { /* Writes the given bytes to the buffer, handling reserve/advance. */ static bool upb_put_bytes(upb_encstate *e, const void *data, size_t len) { + if (len == 0) return true; CHK(upb_encode_reserve(e, len)); memcpy(e->ptr, data, len); return true; @@ -863,15 +844,14 @@ static bool upb_put_float(upb_encstate *e, float d) { static uint32_t upb_readcase(const char *msg, const upb_msglayout_field *f) { uint32_t ret; - uint32_t offset = ~f->presence; - memcpy(&ret, msg + offset, sizeof(ret)); + memcpy(&ret, msg - f->presence, sizeof(ret)); return ret; } static bool upb_readhasbit(const char *msg, const upb_msglayout_field *f) { uint32_t hasbit = f->presence; UPB_ASSERT(f->presence > 0); - return msg[hasbit / 8] & (1 << (hasbit % 8)); + return (*UPB_PTR_AT(msg, hasbit / 8, uint8_t)) & (1 << (hasbit % 8)); } static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) { @@ -879,50 +859,145 @@ static bool upb_put_tag(upb_encstate *e, int field_number, int wire_type) { } static bool upb_put_fixedarray(upb_encstate *e, const upb_array *arr, - size_t size) { - size_t bytes = arr->len * size; - return upb_put_bytes(e, arr->data, bytes) && upb_put_varint(e, bytes); + size_t elem_size, uint32_t tag) { + size_t bytes = arr->len * elem_size; + const char* data = _upb_array_constptr(arr); + const char* ptr = data + bytes - elem_size; + if (tag) { + while (true) { + CHK(upb_put_bytes(e, ptr, elem_size) && upb_put_varint(e, tag)); + if (ptr == data) break; + ptr -= elem_size; + } + return true; + } else { + return upb_put_bytes(e, data, bytes) && upb_put_varint(e, bytes); + } } bool upb_encode_message(upb_encstate *e, const char *msg, const upb_msglayout *m, size_t *size); +static bool upb_encode_scalarfield(upb_encstate *e, const void *_field_mem, + const upb_msglayout *m, + const upb_msglayout_field *f, + bool skip_zero_value) { + const char *field_mem = _field_mem; +#define CASE(ctype, type, wire_type, encodeval) do { \ + ctype val = *(ctype*)field_mem; \ + if (skip_zero_value && val == 0) { \ + return true; \ + } \ + return upb_put_ ## type(e, encodeval) && \ + upb_put_tag(e, f->number, wire_type); \ +} while(0) + + switch (f->descriptortype) { + case UPB_DESCRIPTOR_TYPE_DOUBLE: + CASE(double, double, UPB_WIRE_TYPE_64BIT, val); + case UPB_DESCRIPTOR_TYPE_FLOAT: + CASE(float, float, UPB_WIRE_TYPE_32BIT, val); + case UPB_DESCRIPTOR_TYPE_INT64: + case UPB_DESCRIPTOR_TYPE_UINT64: + CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val); + case UPB_DESCRIPTOR_TYPE_UINT32: + CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val); + case UPB_DESCRIPTOR_TYPE_INT32: + case UPB_DESCRIPTOR_TYPE_ENUM: + CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val); + case UPB_DESCRIPTOR_TYPE_SFIXED64: + case UPB_DESCRIPTOR_TYPE_FIXED64: + CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val); + case UPB_DESCRIPTOR_TYPE_FIXED32: + case UPB_DESCRIPTOR_TYPE_SFIXED32: + CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val); + case UPB_DESCRIPTOR_TYPE_BOOL: + CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val); + case UPB_DESCRIPTOR_TYPE_SINT32: + CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val)); + case UPB_DESCRIPTOR_TYPE_SINT64: + CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val)); + case UPB_DESCRIPTOR_TYPE_STRING: + case UPB_DESCRIPTOR_TYPE_BYTES: { + upb_strview view = *(upb_strview*)field_mem; + if (skip_zero_value && view.size == 0) { + return true; + } + return upb_put_bytes(e, view.data, view.size) && + upb_put_varint(e, view.size) && + upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + } + case UPB_DESCRIPTOR_TYPE_GROUP: { + size_t size; + void *submsg = *(void **)field_mem; + const upb_msglayout *subm = m->submsgs[f->submsg_index]; + if (submsg == NULL) { + return true; + } + return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) && + upb_encode_message(e, submsg, subm, &size) && + upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); + } + case UPB_DESCRIPTOR_TYPE_MESSAGE: { + size_t size; + void *submsg = *(void **)field_mem; + const upb_msglayout *subm = m->submsgs[f->submsg_index]; + if (submsg == NULL) { + return true; + } + return upb_encode_message(e, submsg, subm, &size) && + upb_put_varint(e, size) && + upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); + } + } +#undef CASE + UPB_UNREACHABLE(); +} + static bool upb_encode_array(upb_encstate *e, const char *field_mem, const upb_msglayout *m, const upb_msglayout_field *f) { const upb_array *arr = *(const upb_array**)field_mem; + bool packed = f->label == _UPB_LABEL_PACKED; if (arr == NULL || arr->len == 0) { return true; } -#define VARINT_CASE(ctype, encode) { \ - ctype *start = arr->data; \ - ctype *ptr = start + arr->len; \ - size_t pre_len = e->limit - e->ptr; \ - do { \ - ptr--; \ - CHK(upb_put_varint(e, encode)); \ - } while (ptr != start); \ - CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \ -} \ -break; \ -do { ; } while(0) +#define VARINT_CASE(ctype, encode) \ + { \ + const ctype *start = _upb_array_constptr(arr); \ + const ctype *ptr = start + arr->len; \ + size_t pre_len = e->limit - e->ptr; \ + uint32_t tag = packed ? 0 : (f->number << 3) | UPB_WIRE_TYPE_VARINT; \ + do { \ + ptr--; \ + CHK(upb_put_varint(e, encode)); \ + if (tag) CHK(upb_put_varint(e, tag)); \ + } while (ptr != start); \ + if (!tag) CHK(upb_put_varint(e, e->limit - e->ptr - pre_len)); \ + } \ + break; \ + do { \ + ; \ + } while (0) + +#define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type)) switch (f->descriptortype) { case UPB_DESCRIPTOR_TYPE_DOUBLE: - CHK(upb_put_fixedarray(e, arr, sizeof(double))); + CHK(upb_put_fixedarray(e, arr, sizeof(double), TAG(UPB_WIRE_TYPE_64BIT))); break; case UPB_DESCRIPTOR_TYPE_FLOAT: - CHK(upb_put_fixedarray(e, arr, sizeof(float))); + CHK(upb_put_fixedarray(e, arr, sizeof(float), TAG(UPB_WIRE_TYPE_32BIT))); break; case UPB_DESCRIPTOR_TYPE_SFIXED64: case UPB_DESCRIPTOR_TYPE_FIXED64: - CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t))); + CHK(upb_put_fixedarray(e, arr, sizeof(uint64_t), TAG(UPB_WIRE_TYPE_64BIT))); break; case UPB_DESCRIPTOR_TYPE_FIXED32: case UPB_DESCRIPTOR_TYPE_SFIXED32: - CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t))); + CHK(upb_put_fixedarray(e, arr, sizeof(uint32_t), TAG(UPB_WIRE_TYPE_32BIT))); break; case UPB_DESCRIPTOR_TYPE_INT64: case UPB_DESCRIPTOR_TYPE_UINT64: @@ -940,8 +1015,8 @@ do { ; } while(0) VARINT_CASE(int64_t, upb_zzencode_64(*ptr)); case UPB_DESCRIPTOR_TYPE_STRING: case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview *start = arr->data; - upb_strview *ptr = start + arr->len; + const upb_strview *start = _upb_array_constptr(arr); + const upb_strview *ptr = start + arr->len; do { ptr--; CHK(upb_put_bytes(e, ptr->data, ptr->size) && @@ -951,8 +1026,8 @@ do { ; } while(0) return true; } case UPB_DESCRIPTOR_TYPE_GROUP: { - void **start = arr->data; - void **ptr = start + arr->len; + const void *const*start = _upb_array_constptr(arr); + const void *const*ptr = start + arr->len; const upb_msglayout *subm = m->submsgs[f->submsg_index]; do { size_t size; @@ -964,8 +1039,8 @@ do { ; } while(0) return true; } case UPB_DESCRIPTOR_TYPE_MESSAGE: { - void **start = arr->data; - void **ptr = start + arr->len; + const void *const*start = _upb_array_constptr(arr); + const void *const*ptr = start + arr->len; const upb_msglayout *subm = m->submsgs[f->submsg_index]; do { size_t size; @@ -979,87 +1054,46 @@ do { ; } while(0) } #undef VARINT_CASE - /* We encode all primitive arrays as packed, regardless of what was specified - * in the .proto file. Could special case 1-sized arrays. */ - CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + if (packed) { + CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); + } return true; } -static bool upb_encode_scalarfield(upb_encstate *e, const char *field_mem, - const upb_msglayout *m, - const upb_msglayout_field *f, - bool skip_zero_value) { -#define CASE(ctype, type, wire_type, encodeval) do { \ - ctype val = *(ctype*)field_mem; \ - if (skip_zero_value && val == 0) { \ - return true; \ - } \ - return upb_put_ ## type(e, encodeval) && \ - upb_put_tag(e, f->number, wire_type); \ -} while(0) +static bool upb_encode_map(upb_encstate *e, const char *field_mem, + const upb_msglayout *m, + const upb_msglayout_field *f) { + const upb_map *map = *(const upb_map**)field_mem; + const upb_msglayout *entry = m->submsgs[f->submsg_index]; + const upb_msglayout_field *key_field = &entry->fields[0]; + const upb_msglayout_field *val_field = &entry->fields[1]; + upb_strtable_iter i; + if (map == NULL) { + return true; + } - switch (f->descriptortype) { - case UPB_DESCRIPTOR_TYPE_DOUBLE: - CASE(double, double, UPB_WIRE_TYPE_64BIT, val); - case UPB_DESCRIPTOR_TYPE_FLOAT: - CASE(float, float, UPB_WIRE_TYPE_32BIT, val); - case UPB_DESCRIPTOR_TYPE_INT64: - case UPB_DESCRIPTOR_TYPE_UINT64: - CASE(uint64_t, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_UINT32: - CASE(uint32_t, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_INT32: - case UPB_DESCRIPTOR_TYPE_ENUM: - CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, (int64_t)val); - case UPB_DESCRIPTOR_TYPE_SFIXED64: - case UPB_DESCRIPTOR_TYPE_FIXED64: - CASE(uint64_t, fixed64, UPB_WIRE_TYPE_64BIT, val); - case UPB_DESCRIPTOR_TYPE_FIXED32: - case UPB_DESCRIPTOR_TYPE_SFIXED32: - CASE(uint32_t, fixed32, UPB_WIRE_TYPE_32BIT, val); - case UPB_DESCRIPTOR_TYPE_BOOL: - CASE(bool, varint, UPB_WIRE_TYPE_VARINT, val); - case UPB_DESCRIPTOR_TYPE_SINT32: - CASE(int32_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_32(val)); - case UPB_DESCRIPTOR_TYPE_SINT64: - CASE(int64_t, varint, UPB_WIRE_TYPE_VARINT, upb_zzencode_64(val)); - case UPB_DESCRIPTOR_TYPE_STRING: - case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview view = *(upb_strview*)field_mem; - if (skip_zero_value && view.size == 0) { - return true; - } - return upb_put_bytes(e, view.data, view.size) && - upb_put_varint(e, view.size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); - } - case UPB_DESCRIPTOR_TYPE_GROUP: { - size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; - if (submsg == NULL) { - return true; - } - return upb_put_tag(e, f->number, UPB_WIRE_TYPE_END_GROUP) && - upb_encode_message(e, submsg, subm, &size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_START_GROUP); - } - case UPB_DESCRIPTOR_TYPE_MESSAGE: { - size_t size; - void *submsg = *(void **)field_mem; - const upb_msglayout *subm = m->submsgs[f->submsg_index]; - if (submsg == NULL) { - return true; - } - return upb_encode_message(e, submsg, subm, &size) && - upb_put_varint(e, size) && - upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED); - } + upb_strtable_begin(&i, &map->table); + for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { + size_t pre_len = e->limit - e->ptr; + size_t size; + upb_strview key = upb_strtable_iter_key(&i); + const upb_value val = upb_strtable_iter_value(&i); + const void *keyp = + map->key_size == UPB_MAPTYPE_STRING ? (void *)&key : key.data; + const void *valp = + map->val_size == UPB_MAPTYPE_STRING ? upb_value_getptr(val) : &val; + + CHK(upb_encode_scalarfield(e, valp, entry, val_field, false)); + CHK(upb_encode_scalarfield(e, keyp, entry, key_field, false)); + size = (e->limit - e->ptr) - pre_len; + CHK(upb_put_varint(e, size)); + CHK(upb_put_tag(e, f->number, UPB_WIRE_TYPE_DELIMITED)); } -#undef CASE - UPB_UNREACHABLE(); + + return true; } + bool upb_encode_message(upb_encstate *e, const char *msg, const upb_msglayout *m, size_t *size) { int i; @@ -1067,11 +1101,19 @@ bool upb_encode_message(upb_encstate *e, const char *msg, const char *unknown; size_t unknown_size; + unknown = upb_msg_getunknown(msg, &unknown_size); + + if (unknown) { + upb_put_bytes(e, unknown, unknown_size); + } + for (i = m->field_count - 1; i >= 0; i--) { const upb_msglayout_field *f = &m->fields[i]; - if (f->label == UPB_LABEL_REPEATED) { + if (_upb_isrepeated(f)) { CHK(upb_encode_array(e, msg + f->offset, m, f)); + } else if (f->label == _UPB_LABEL_MAP) { + CHK(upb_encode_map(e, msg + f->offset, m, f)); } else { bool skip_empty = false; if (f->presence == 0) { @@ -1092,12 +1134,6 @@ bool upb_encode_message(upb_encstate *e, const char *msg, } } - unknown = upb_msg_getunknown(msg, &unknown_size); - - if (unknown) { - upb_put_bytes(e, unknown, unknown_size); - } - *size = (e->limit - e->ptr) - pre_len; return true; } @@ -1131,24 +1167,27 @@ char *upb_encode(const void *msg, const upb_msglayout *m, upb_arena *arena, -#define VOIDPTR_AT(msg, ofs) (void*)((char*)msg + (int)ofs) - -/* Internal members of a upb_msg. We can change this without breaking binary - * compatibility. We put these before the user's data. The user's upb_msg* - * points after the upb_msg_internal. */ +/** upb_msg *******************************************************************/ -/* Used when a message is not extendable. */ -typedef struct { - char *unknown; - size_t unknown_len; - size_t unknown_size; -} upb_msg_internal; +static const char _upb_fieldtype_to_sizelg2[12] = { + 0, + 0, /* UPB_TYPE_BOOL */ + 2, /* UPB_TYPE_FLOAT */ + 2, /* UPB_TYPE_INT32 */ + 2, /* UPB_TYPE_UINT32 */ + 2, /* UPB_TYPE_ENUM */ + UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */ + 3, /* UPB_TYPE_DOUBLE */ + 3, /* UPB_TYPE_INT64 */ + 3, /* UPB_TYPE_UINT64 */ + UPB_SIZE(3, 4), /* UPB_TYPE_STRING */ + UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */ +}; -/* Used when a message is extendable. */ -typedef struct { - upb_inttable *extdict; - upb_msg_internal base; -} upb_msg_internal_withext; +static uintptr_t tag_arrptr(void* ptr, int elem_size_lg2) { + UPB_ASSERT(elem_size_lg2 <= 4); + return (uintptr_t)ptr | elem_size_lg2; +} static int upb_msg_internalsize(const upb_msglayout *l) { return sizeof(upb_msg_internal) - l->extendable * sizeof(void *); @@ -1159,22 +1198,22 @@ static size_t upb_msg_sizeof(const upb_msglayout *l) { } static upb_msg_internal *upb_msg_getinternal(upb_msg *msg) { - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal)); + return UPB_PTR_AT(msg, -sizeof(upb_msg_internal), upb_msg_internal); } static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) { - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal)); + return UPB_PTR_AT(msg, -sizeof(upb_msg_internal), upb_msg_internal); } static upb_msg_internal_withext *upb_msg_getinternalwithext( upb_msg *msg, const upb_msglayout *l) { UPB_ASSERT(l->extendable); - return VOIDPTR_AT(msg, -sizeof(upb_msg_internal_withext)); + return UPB_PTR_AT(msg, -sizeof(upb_msg_internal_withext), + upb_msg_internal_withext); } -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) { - upb_alloc *alloc = upb_arena_alloc(a); - void *mem = upb_malloc(alloc, upb_msg_sizeof(l)); +upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a) { + void *mem = upb_arena_malloc(a, upb_msg_sizeof(l)); upb_msg_internal *in; upb_msg *msg; @@ -1182,7 +1221,7 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) { return NULL; } - msg = VOIDPTR_AT(mem, upb_msg_internalsize(l)); + msg = UPB_PTR_AT(mem, upb_msg_internalsize(l), upb_msg); /* Initialize normal members. */ memset(msg, 0, l->size); @@ -1200,66 +1239,122 @@ upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a) { return msg; } -upb_array *upb_array_new(upb_arena *a) { - upb_array *ret = upb_arena_malloc(a, sizeof(upb_array)); - - if (!ret) { - return NULL; - } - - ret->data = NULL; - ret->len = 0; - ret->size = 0; - - return ret; -} - -void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena) { +bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena) { upb_msg_internal *in = upb_msg_getinternal(msg); if (len > in->unknown_size - in->unknown_len) { upb_alloc *alloc = upb_arena_alloc(arena); size_t need = in->unknown_size + len; size_t newsize = UPB_MAX(in->unknown_size * 2, need); - in->unknown = upb_realloc(alloc, in->unknown, in->unknown_size, newsize); + void *mem = upb_realloc(alloc, in->unknown, in->unknown_size, newsize); + if (!mem) return false; + in->unknown = mem; in->unknown_size = newsize; } memcpy(in->unknown + in->unknown_len, data, len); in->unknown_len += len; + return true; } const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) { - const upb_msg_internal* in = upb_msg_getinternal_const(msg); + const upb_msg_internal *in = upb_msg_getinternal_const(msg); *len = in->unknown_len; return in->unknown; } -#undef VOIDPTR_AT +/** upb_array *****************************************************************/ +upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type) { + upb_array *arr = upb_arena_malloc(a, sizeof(upb_array)); -#ifdef UPB_MSVC_VSNPRINTF -/* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and - * vsnprintf. To support them, missing functions are manually implemented - * using the existing secure functions. */ -int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) { - if (!s) { - return _vscprintf(format, arg); + if (!arr) { + return NULL; } - int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg); - if (ret < 0) { - ret = _vscprintf(format, arg); + + arr->data = tag_arrptr(NULL, _upb_fieldtype_to_sizelg2[type]); + arr->len = 0; + arr->size = 0; + + return arr; +} + +bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) { + size_t new_size = UPB_MAX(arr->size, 4); + int elem_size_lg2 = arr->data & 7; + size_t old_bytes = arr->size << elem_size_lg2; + size_t new_bytes; + void* ptr = _upb_array_ptr(arr); + + /* Log2 ceiling of size. */ + while (new_size < min_size) new_size *= 2; + + new_bytes = new_size << elem_size_lg2; + ptr = upb_arena_realloc(arena, ptr, old_bytes, new_bytes); + + if (!ptr) { + return false; } - return ret; + + arr->data = tag_arrptr(ptr, elem_size_lg2); + arr->size = new_size; + return true; } -int msvc_snprintf(char* s, size_t n, const char* format, ...) { - va_list arg; - va_start(arg, format); - int ret = msvc_vsnprintf(s, n, format, arg); - va_end(arg); - return ret; +static upb_array *getorcreate_array(upb_array **arr_ptr, upb_fieldtype_t type, + upb_arena *arena) { + upb_array *arr = *arr_ptr; + if (!arr) { + arr = _upb_array_new(arena, type); + if (!arr) return NULL; + *arr_ptr = arr; + } + return arr; +} + +static bool resize_array(upb_array *arr, size_t size, upb_arena *arena) { + if (size > arr->size && !_upb_array_realloc(arr, size, arena)) { + return false; + } + + arr->len = size; + return true; +} + +void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, + upb_fieldtype_t type, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, type, arena); + return arr && resize_array(arr, size, arena) ? _upb_array_ptr(arr) : NULL; +} + +bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, + upb_fieldtype_t type, upb_arena *arena) { + upb_array *arr = getorcreate_array(arr_ptr, type, arena); + size_t elem = arr->len; + int lg2 = _upb_fieldtype_to_sizelg2[type]; + char *data; + + if (!arr || !resize_array(arr, elem + 1, arena)) return false; + + data = _upb_array_ptr(arr); + memcpy(data + (elem << lg2), value, 1 << lg2); + return true; +} + +/** upb_map *******************************************************************/ + +upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) { + upb_map *map = upb_arena_malloc(a, sizeof(upb_map)); + + if (!map) { + return NULL; + } + + upb_strtable_init2(&map->table, UPB_CTYPE_INT32, upb_arena_alloc(a)); + map->key_size = key_size; + map->val_size = value_size; + + return map; } -#endif /* ** upb_table Implementation ** @@ -1276,12 +1371,6 @@ int msvc_snprintf(char* s, size_t n, const char* format, ...) { #define ARRAY_SIZE(x) \ ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) -static void upb_check_alloc(upb_table *t, upb_alloc *a) { - UPB_UNUSED(t); - UPB_UNUSED(a); - UPB_ASSERT_DEBUGVAR(t->alloc == a); -} - static const double MAX_LOAD = 0.85; /* The minimum utilization of the array part of a mixed hash/array table. This @@ -1360,17 +1449,12 @@ static bool isfull(upb_table *t) { } } -static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2, - upb_alloc *a) { +static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) { size_t bytes; t->count = 0; - t->ctype = ctype; t->size_lg2 = size_lg2; t->mask = upb_table_size(t) ? upb_table_size(t) - 1 : 0; -#ifndef NDEBUG - t->alloc = a; -#endif bytes = upb_table_size(t) * sizeof(upb_tabent); if (bytes > 0) { t->entries = upb_malloc(a, bytes); @@ -1383,7 +1467,6 @@ static bool init(upb_table *t, upb_ctype_t ctype, uint8_t size_lg2, } static void uninit(upb_table *t, upb_alloc *a) { - upb_check_alloc(t, a); upb_free(a, mutable_entries(t)); } @@ -1419,7 +1502,7 @@ static bool lookup(const upb_table *t, lookupkey_t key, upb_value *v, const upb_tabent *e = findentry(t, key, hash, eql); if (e) { if (v) { - _upb_value_setval(v, e->val.val, t->ctype); + _upb_value_setval(v, e->val.val); } return true; } else { @@ -1435,7 +1518,6 @@ static void insert(upb_table *t, lookupkey_t key, upb_tabkey tabkey, upb_tabent *our_e; UPB_ASSERT(findentry(t, key, hash, eql) == NULL); - UPB_ASSERT_DEBUGVAR(val.ctype == t->ctype); t->count++; mainpos_e = getentry_mutable(t, hash); @@ -1481,7 +1563,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, if (eql(chain->key, key)) { /* Element to remove is at the head of its chain. */ t->count--; - if (val) _upb_value_setval(val, chain->val.val, t->ctype); + if (val) _upb_value_setval(val, chain->val.val); if (removed) *removed = chain->key; if (chain->next) { upb_tabent *move = (upb_tabent*)chain->next; @@ -1501,7 +1583,7 @@ static bool rm(upb_table *t, lookupkey_t key, upb_value *val, /* Found element to remove. */ upb_tabent *rm = (upb_tabent*)chain->next; t->count--; - if (val) _upb_value_setval(val, chain->next->val.val, t->ctype); + if (val) _upb_value_setval(val, chain->next->val.val); if (removed) *removed = rm->key; rm->key = 0; /* Make the slot empty. */ chain->next = rm->next; @@ -1554,7 +1636,13 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) { } bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype, upb_alloc *a) { - return init(&t->t, ctype, 2, a); + return init(&t->t, 2, a); +} + +void upb_strtable_clear(upb_strtable *t) { + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); } void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) { @@ -1568,18 +1656,14 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) { upb_strtable new_table; upb_strtable_iter i; - upb_check_alloc(&t->t, a); - - if (!init(&new_table.t, t->t.ctype, size_lg2, a)) + if (!init(&new_table.t, size_lg2, a)) return false; upb_strtable_begin(&i, t); for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) { + upb_strview key = upb_strtable_iter_key(&i); upb_strtable_insert3( - &new_table, - upb_strtable_iter_key(&i), - upb_strtable_iter_keylength(&i), - upb_strtable_iter_value(&i), - a); + &new_table, key.data, key.size, + upb_strtable_iter_value(&i), a); } upb_strtable_uninit2(t, a); *t = new_table; @@ -1592,8 +1676,6 @@ bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len, upb_tabkey tabkey; uint32_t hash; - upb_check_alloc(&t->t, a); - if (isfull(&t->t)) { /* Need to resize. New table of double the size, add old elements to it. */ if (!upb_strtable_resize(t, t->t.size_lg2 + 1, a)) { @@ -1621,7 +1703,10 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, uint32_t hash = upb_murmur_hash2(key, len, 0); upb_tabkey tabkey; if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) { - upb_free(alloc, (void*)tabkey); + if (alloc) { + /* Arena-based allocs don't need to free and won't pass this. */ + upb_free(alloc, (void*)tabkey); + } return true; } else { return false; @@ -1630,10 +1715,6 @@ bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len, /* Iteration */ -static const upb_tabent *str_tabent(const upb_strtable_iter *i) { - return &i->t->t.entries[i->index]; -} - void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t) { i->t = t; i->index = begin(&t->t); @@ -1646,24 +1727,21 @@ void upb_strtable_next(upb_strtable_iter *i) { bool upb_strtable_done(const upb_strtable_iter *i) { if (!i->t) return true; return i->index >= upb_table_size(&i->t->t) || - upb_tabent_isempty(str_tabent(i)); -} - -const char *upb_strtable_iter_key(const upb_strtable_iter *i) { - UPB_ASSERT(!upb_strtable_done(i)); - return upb_tabstr(str_tabent(i)->key, NULL); + upb_tabent_isempty(str_tabent(i)); } -size_t upb_strtable_iter_keylength(const upb_strtable_iter *i) { +upb_strview upb_strtable_iter_key(const upb_strtable_iter *i) { + upb_strview key; uint32_t len; UPB_ASSERT(!upb_strtable_done(i)); - upb_tabstr(str_tabent(i)->key, &len); - return len; + key.data = upb_tabstr(str_tabent(i)->key, &len); + key.size = len; + return key; } upb_value upb_strtable_iter_value(const upb_strtable_iter *i) { UPB_ASSERT(!upb_strtable_done(i)); - return _upb_value_val(str_tabent(i)->val.val, i->t->t.ctype); + return _upb_value_val(str_tabent(i)->val.val); } void upb_strtable_iter_setdone(upb_strtable_iter *i) { @@ -1729,11 +1807,11 @@ static void check(upb_inttable *t) { #endif } -bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype, - size_t asize, int hsize_lg2, upb_alloc *a) { +bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2, + upb_alloc *a) { size_t array_bytes; - if (!init(&t->t, ctype, hsize_lg2, a)) return false; + if (!init(&t->t, hsize_lg2, a)) return false; /* Always make the array part at least 1 long, so that we know key 0 * won't be in the hash part, which simplifies things. */ t->array_size = UPB_MAX(1, asize); @@ -1750,7 +1828,7 @@ bool upb_inttable_sizedinit(upb_inttable *t, upb_ctype_t ctype, } bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) { - return upb_inttable_sizedinit(t, ctype, 0, 4, a); + return upb_inttable_sizedinit(t, 0, 4, a); } void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) { @@ -1764,8 +1842,6 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, tabval.val = val.val; UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */ - upb_check_alloc(&t->t, a); - if (key < t->array_size) { UPB_ASSERT(!upb_arrhas(t->array[key])); t->array_count++; @@ -1776,7 +1852,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, size_t i; upb_table new_table; - if (!init(&new_table, t->t.ctype, t->t.size_lg2 + 1, a)) { + if (!init(&new_table, t->t.size_lg2 + 1, a)) { return false; } @@ -1785,7 +1861,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, uint32_t hash; upb_value v; - _upb_value_setval(&v, e->val.val, t->t.ctype); + _upb_value_setval(&v, e->val.val); hash = upb_inthash(e->key); insert(&new_table, intkey(e->key), e->key, v, hash, &inthash, &inteql); } @@ -1804,7 +1880,7 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val, bool upb_inttable_lookup(const upb_inttable *t, uintptr_t key, upb_value *v) { const upb_tabval *table_v = inttable_val_const(t, key); if (!table_v) return false; - if (v) _upb_value_setval(v, table_v->val, t->t.ctype); + if (v) _upb_value_setval(v, table_v->val); return true; } @@ -1822,7 +1898,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { upb_tabval empty = UPB_TABVALUE_EMPTY_INIT; t->array_count--; if (val) { - _upb_value_setval(val, t->array[key].val, t->t.ctype); + _upb_value_setval(val, t->array[key].val); } mutable_array(t)[key] = empty; success = true; @@ -1837,7 +1913,6 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) { } bool upb_inttable_push2(upb_inttable *t, upb_value val, upb_alloc *a) { - upb_check_alloc(&t->t, a); return upb_inttable_insert2(t, upb_inttable_count(t), val, a); } @@ -1850,7 +1925,6 @@ upb_value upb_inttable_pop(upb_inttable *t) { bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val, upb_alloc *a) { - upb_check_alloc(&t->t, a); return upb_inttable_insert2(t, (uintptr_t)key, val, a); } @@ -1875,8 +1949,6 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) { int size_lg2; upb_inttable new_t; - upb_check_alloc(&t->t, a); - upb_inttable_begin(&i, t); for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { uintptr_t key = upb_inttable_iter_key(&i); @@ -1909,7 +1981,7 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) { size_t hash_size = hash_count ? (hash_count / MAX_LOAD) + 1 : 0; int hashsize_lg2 = log2ceil(hash_size); - upb_inttable_sizedinit(&new_t, t->t.ctype, arr_size, hashsize_lg2, a); + upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a); upb_inttable_begin(&i, t); for (; !upb_inttable_done(&i); upb_inttable_next(&i)) { uintptr_t k = upb_inttable_iter_key(&i); @@ -1975,8 +2047,7 @@ uintptr_t upb_inttable_iter_key(const upb_inttable_iter *i) { upb_value upb_inttable_iter_value(const upb_inttable_iter *i) { UPB_ASSERT(!upb_inttable_done(i)); return _upb_value_val( - i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val, - i->t->t.ctype); + i->array_part ? i->t->array[i->index].val : int_tabent(i)->val.val); } void upb_inttable_iter_setdone(upb_inttable_iter *i) { @@ -2016,7 +2087,8 @@ uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) { /* Mix 4 bytes at a time into the hash */ const uint8_t * data = (const uint8_t *)key; while(len >= 4) { - uint32_t k = *(uint32_t *)data; + uint32_t k; + memcpy(&k, data, sizeof(k)); k *= m; k ^= k >> r; @@ -2181,17 +2253,6 @@ uint32_t upb_murmur_hash2(const void * key, size_t len, uint32_t seed) { #include -/* Guarantee null-termination and provide ellipsis truncation. - * It may be tempting to "optimize" this by initializing these final - * four bytes up-front and then being careful never to overwrite them, - * this is safer and simpler. */ -static void nullz(upb_status *status) { - const char *ellipsis = "..."; - size_t len = strlen(ellipsis); - UPB_ASSERT(sizeof(status->msg) > len); - memcpy(status->msg + sizeof(status->msg) - len, ellipsis, len); -} - /* upb_status *****************************************************************/ void upb_status_clear(upb_status *status) { @@ -2207,8 +2268,8 @@ const char *upb_status_errmsg(const upb_status *status) { return status->msg; } void upb_status_seterrmsg(upb_status *status, const char *msg) { if (!status) return; status->ok = false; - strncpy(status->msg, msg, sizeof(status->msg)); - nullz(status); + strncpy(status->msg, msg, UPB_STATUS_MAX_MESSAGE - 1); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; } void upb_status_seterrf(upb_status *status, const char *fmt, ...) { @@ -2222,7 +2283,7 @@ void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args) { if (!status) return; status->ok = false; _upb_vsnprintf(status->msg, sizeof(status->msg), fmt, args); - nullz(status); + status->msg[UPB_STATUS_MAX_MESSAGE - 1] = '\0'; } /* upb_alloc ******************************************************************/ @@ -2244,16 +2305,10 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc}; /* upb_arena ******************************************************************/ /* Be conservative and choose 16 in case anyone is using SSE. */ -static const size_t maxalign = 16; - -static size_t align_up_max(size_t size) { - return ((size + maxalign - 1) / maxalign) * maxalign; -} struct upb_arena { - /* We implement the allocator interface. - * This must be the first member of upb_arena! */ - upb_alloc alloc; + _upb_arena_head head; + char *start; /* Allocator to allocate arena blocks. We are responsible for freeing these * when we are destroyed. */ @@ -2272,8 +2327,6 @@ struct upb_arena { typedef struct mem_block { struct mem_block *next; - size_t size; - size_t used; bool owned; /* Data follows. */ } mem_block; @@ -2288,12 +2341,17 @@ static void upb_arena_addblock(upb_arena *a, void *ptr, size_t size, bool owned) { mem_block *block = ptr; + if (a->block_head) { + a->bytes_allocated += a->head.ptr - a->start; + } + block->next = a->block_head; - block->size = size; - block->used = align_up_max(sizeof(mem_block)); block->owned = owned; a->block_head = block; + a->start = (char*)block + _upb_arena_alignup(sizeof(mem_block)); + a->head.ptr = a->start; + a->head.end = (char*)block + size; /* TODO(haberman): ASAN poison. */ } @@ -2312,39 +2370,31 @@ static mem_block *upb_arena_allocblock(upb_arena *a, size_t size) { return block; } +void *_upb_arena_slowmalloc(upb_arena *a, size_t size) { + mem_block *block = upb_arena_allocblock(a, size); + if (!block) return NULL; /* Out of memory. */ + return upb_arena_malloc(a, size); +} + static void *upb_arena_doalloc(upb_alloc *alloc, void *ptr, size_t oldsize, size_t size) { upb_arena *a = (upb_arena*)alloc; /* upb_alloc is initial member. */ - mem_block *block = a->block_head; void *ret; if (size == 0) { return NULL; /* We are an arena, don't need individual frees. */ } - size = align_up_max(size); + ret = upb_arena_malloc(a, size); + if (!ret) return NULL; /* TODO(haberman): special-case if this is a realloc of the last alloc? */ - if (!block || block->size - block->used < size) { - /* Slow path: have to allocate a new block. */ - block = upb_arena_allocblock(a, size); - - if (!block) { - return NULL; /* Out of memory. */ - } - } - - ret = (char*)block + block->used; - block->used += size; - if (oldsize > 0) { memcpy(ret, ptr, oldsize); /* Preserve existing data. */ } /* TODO(haberman): ASAN unpoison. */ - - a->bytes_allocated += size; return ret; } @@ -2373,7 +2423,10 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { a = (void*)((char*)mem + n - sizeof(*a)); n -= sizeof(*a); - a->alloc.func = &upb_arena_doalloc; + a->head.alloc.func = &upb_arena_doalloc; + a->head.ptr = NULL; + a->head.end = NULL; + a->start = NULL; a->block_alloc = &upb_alloc_global; a->bytes_allocated = 0; a->next_block_size = 256; @@ -2413,7 +2466,7 @@ void upb_arena_free(upb_arena *a) { } bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { - cleanup_ent *ent = upb_malloc(&a->alloc, sizeof(cleanup_ent)); + cleanup_ent *ent = upb_malloc(&a->head.alloc, sizeof(cleanup_ent)); if (!ent) { return false; /* Out of memory. */ } @@ -2427,7 +2480,7 @@ bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) { } size_t upb_arena_bytesallocated(const upb_arena *a) { - return a->bytes_allocated; + return a->bytes_allocated + (a->head.ptr - a->start); } /* This file was generated by upbc (the upb compiler) from the input * file: @@ -2558,23 +2611,24 @@ 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}, +static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = { + {1, UPB_SIZE(36, 40), 6, 0, 9, 1}, + {2, UPB_SIZE(44, 56), 7, 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}, + {6, UPB_SIZE(52, 72), 8, 0, 9, 1}, + {7, UPB_SIZE(60, 88), 9, 0, 9, 1}, + {8, UPB_SIZE(76, 120), 11, 0, 11, 1}, {9, UPB_SIZE(28, 28), 4, 0, 5, 1}, - {10, UPB_SIZE(64, 96), 9, 0, 9, 1}, + {10, UPB_SIZE(68, 104), 10, 0, 9, 1}, + {17, UPB_SIZE(32, 32), 5, 0, 8, 1}, }; const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { &google_protobuf_FieldDescriptorProto_submsgs[0], &google_protobuf_FieldDescriptorProto__fields[0], - UPB_SIZE(80, 128), 10, false, + UPB_SIZE(80, 128), 11, false, }; static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { @@ -2869,8 +2923,8 @@ const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { }; 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}, + {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED}, + {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED}, {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}, @@ -2897,7 +2951,7 @@ const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { }; static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { - {1, UPB_SIZE(20, 32), 0, 0, 5, 3}, + {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED}, {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}, @@ -2936,6 +2990,7 @@ struct upb_fielddef { const upb_filedef *file; const upb_msgdef *msgdef; const char *full_name; + const char *json_name; union { int64_t sint; uint64_t uint; @@ -2951,16 +3006,19 @@ struct upb_fielddef { const google_protobuf_FieldDescriptorProto *unresolved; } sub; uint32_t number_; - uint32_t index_; + uint16_t index_; + uint16_t layout_index; uint32_t selector_base; /* Used to index into a upb::Handlers table. */ bool is_extension_; bool lazy_; bool packed_; + bool proto3_optional_; upb_descriptortype_t type_; upb_label_t label_; }; struct upb_msgdef { + const upb_msglayout *layout; const upb_filedef *file; const char *full_name; uint32_t selector_count; @@ -2974,6 +3032,7 @@ struct upb_msgdef { const upb_oneofdef *oneofs; int field_count; int oneof_count; + int real_oneof_count; /* Is this a map-entry message? */ bool map_entry; @@ -3024,10 +3083,15 @@ struct upb_symtab { /* Inside a symtab we store tagged pointers to specific def types. */ typedef enum { - UPB_DEFTYPE_MSG = 0, - UPB_DEFTYPE_ENUM = 1, - UPB_DEFTYPE_FIELD = 2, - UPB_DEFTYPE_ONEOF = 3 + UPB_DEFTYPE_FIELD = 0, + + /* Only inside symtab table. */ + UPB_DEFTYPE_MSG = 1, + UPB_DEFTYPE_ENUM = 2, + + /* Only inside message table. */ + UPB_DEFTYPE_ONEOF = 1, + UPB_DEFTYPE_FIELD_JSONNAME = 2 } upb_deftype_t; static const void *unpack_def(upb_value v, upb_deftype_t type) { @@ -3140,11 +3204,14 @@ static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) { return ret; } +static void upb_status_setoom(upb_status *status) { + upb_status_seterrmsg(status, "out of memory"); +} + static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the * lowest indexes, but we do not publicly guarantee this. */ upb_msg_field_iter j; - upb_msg_oneof_iter k; int i; uint32_t selector; int n = upb_msgdef_numfields(m); @@ -3185,14 +3252,38 @@ static bool assign_msg_indices(upb_msgdef *m, upb_status *s) { } m->selector_count = selector; - for(upb_msg_oneof_begin(&k, m), i = 0; - !upb_msg_oneof_done(&k); - upb_msg_oneof_next(&k), i++) { - upb_oneofdef *o = (upb_oneofdef*)upb_msg_iter_oneof(&k); - o->index = i; + upb_gfree(fields); + return true; +} + +static bool check_oneofs(upb_msgdef *m, upb_status *s) { + int i; + int first_synthetic = -1; + upb_oneofdef *mutable_oneofs = (upb_oneofdef*)m->oneofs; + + for (i = 0; i < m->oneof_count; i++) { + mutable_oneofs[i].index = i; + + if (upb_oneofdef_issynthetic(&mutable_oneofs[i])) { + if (first_synthetic == -1) { + first_synthetic = i; + } + } else { + if (first_synthetic != -1) { + upb_status_seterrf( + s, "Synthetic oneofs must be after all other oneofs: %s", + upb_oneofdef_name(&mutable_oneofs[i])); + return false; + } + } + } + + if (first_synthetic == -1) { + m->real_oneof_count = m->oneof_count; + } else { + m->real_oneof_count = first_synthetic; } - upb_gfree(fields); return true; } @@ -3260,7 +3351,7 @@ int32_t upb_enumdef_default(const upb_enumdef *e) { } int upb_enumdef_numvals(const upb_enumdef *e) { - return upb_strtable_count(&e->ntoi); + return (int)upb_strtable_count(&e->ntoi); } void upb_enum_begin(upb_enum_iter *i, const upb_enumdef *e) { @@ -3288,7 +3379,7 @@ const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) { } const char *upb_enum_iter_name(upb_enum_iter *iter) { - return upb_strtable_iter_key(iter); + return upb_strtable_iter_key(iter).data; } int32_t upb_enum_iter_number(upb_enum_iter *iter) { @@ -3369,47 +3460,16 @@ const char *upb_fielddef_name(const upb_fielddef *f) { return shortdefname(f->full_name); } +const char *upb_fielddef_jsonname(const upb_fielddef *f) { + return f->json_name; +} + uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) { return f->selector_base; } -size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len) { - const char *name = upb_fielddef_name(f); - size_t src, dst = 0; - bool ucase_next = false; - -#define WRITE(byte) \ - ++dst; \ - if (dst < len) buf[dst - 1] = byte; \ - else if (dst == len) buf[dst - 1] = '\0' - - if (!name) { - WRITE('\0'); - return 0; - } - - /* Implement the transformation as described in the spec: - * 1. upper case all letters after an underscore. - * 2. remove all underscores. - */ - for (src = 0; name[src]; src++) { - if (name[src] == '_') { - ucase_next = true; - continue; - } - - if (ucase_next) { - WRITE(toupper(name[src])); - ucase_next = false; - } else { - WRITE(name[src]); - } - } - - WRITE('\0'); - return dst; - -#undef WRITE +const upb_filedef *upb_fielddef_file(const upb_fielddef *f) { + return f->file; } const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f) { @@ -3420,6 +3480,11 @@ const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f) { return f->oneof; } +const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f) { + if (!f->oneof || upb_oneofdef_issynthetic(f->oneof)) return NULL; + return f->oneof; +} + static void chkdefaulttype(const upb_fielddef *f, int ctype) { UPB_UNUSED(f); UPB_UNUSED(ctype); @@ -3432,7 +3497,7 @@ int64_t upb_fielddef_defaultint64(const upb_fielddef *f) { int32_t upb_fielddef_defaultint32(const upb_fielddef *f) { chkdefaulttype(f, UPB_TYPE_INT32); - return f->defaultval.sint; + return (int32_t)f->defaultval.sint; } uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { @@ -3442,7 +3507,7 @@ uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f) { uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f) { chkdefaulttype(f, UPB_TYPE_UINT32); - return f->defaultval.uint; + return (uint32_t)f->defaultval.uint; } bool upb_fielddef_defaultbool(const upb_fielddef *f) { @@ -3484,6 +3549,10 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) { return f->sub.enumdef; } +const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) { + return &f->msgdef->layout->fields[f->layout_index]; +} + bool upb_fielddef_issubmsg(const upb_fielddef *f) { return upb_fielddef_type(f) == UPB_TYPE_MESSAGE; } @@ -3512,8 +3581,8 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f) { bool upb_fielddef_haspresence(const upb_fielddef *f) { if (upb_fielddef_isseq(f)) return false; - if (upb_fielddef_issubmsg(f)) return true; - return f->file->syntax == UPB_SYNTAX_PROTO2; + return upb_fielddef_issubmsg(f) || upb_fielddef_containingoneof(f) || + f->file->syntax == UPB_SYNTAX_PROTO2; } static bool between(int32_t x, int32_t low, int32_t high) { @@ -3592,18 +3661,43 @@ bool upb_msgdef_lookupname(const upb_msgdef *m, const char *name, size_t len, *o = unpack_def(val, UPB_DEFTYPE_ONEOF); *f = unpack_def(val, UPB_DEFTYPE_FIELD); - UPB_ASSERT((*o != NULL) ^ (*f != NULL)); /* Exactly one of the two should be set. */ - return true; + return *o || *f; /* False if this was a JSON name. */ +} + +const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, + const char *name, size_t len) { + upb_value val; + const upb_fielddef* f; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return NULL; + } + + f = unpack_def(val, UPB_DEFTYPE_FIELD); + if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME); + + return f; } int upb_msgdef_numfields(const upb_msgdef *m) { - /* The number table contains only fields. */ - return upb_inttable_count(&m->itof); + return m->field_count; } int upb_msgdef_numoneofs(const upb_msgdef *m) { - /* The name table includes oneofs, and the number table does not. */ - return upb_strtable_count(&m->ntof) - upb_inttable_count(&m->itof); + return m->oneof_count; +} + +int upb_msgdef_numrealoneofs(const upb_msgdef *m) { + return m->real_oneof_count; +} + +const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) { + return m->layout; +} + +const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i) { + if (i >= m->field_count) return NULL; + return &m->fields[i]; } bool upb_msgdef_mapentry(const upb_msgdef *m) { @@ -3652,80 +3746,308 @@ void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m) { } } -void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { - /* We need to skip past fields to return only oneofs. */ - do { - upb_strtable_next(iter); - } while (!upb_strtable_done(iter) && - !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)); -} +void upb_msg_oneof_next(upb_msg_oneof_iter *iter) { + /* We need to skip past fields to return only oneofs. */ + do { + upb_strtable_next(iter); + } while (!upb_strtable_done(iter) && + !unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF)); +} + +bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { + return upb_strtable_done(iter); +} + +const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { + return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); +} + +void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { + upb_strtable_iter_setdone(iter); +} + +bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, + const upb_msg_oneof_iter *iter2) { + return upb_strtable_iter_isequal(iter1, iter2); +} + +/* upb_oneofdef ***************************************************************/ + +const char *upb_oneofdef_name(const upb_oneofdef *o) { + return shortdefname(o->full_name); +} + +const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { + return o->parent; +} + +int upb_oneofdef_numfields(const upb_oneofdef *o) { + return (int)upb_strtable_count(&o->ntof); +} + +uint32_t upb_oneofdef_index(const upb_oneofdef *o) { + return o->index; +} + +bool upb_oneofdef_issynthetic(const upb_oneofdef *o) { + upb_inttable_iter iter; + const upb_fielddef *f; + upb_inttable_begin(&iter, &o->itof); + if (upb_oneofdef_numfields(o) != 1) return false; + f = upb_value_getptr(upb_inttable_iter_value(&iter)); + UPB_ASSERT(f); + return f->proto3_optional_; +} + +const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, + const char *name, size_t length) { + upb_value val; + return upb_strtable_lookup2(&o->ntof, name, length, &val) ? + upb_value_getptr(val) : NULL; +} + +const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) { + upb_value val; + return upb_inttable_lookup32(&o->itof, num, &val) ? + upb_value_getptr(val) : NULL; +} + +void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { + upb_inttable_begin(iter, &o->itof); +} + +void upb_oneof_next(upb_oneof_iter *iter) { + upb_inttable_next(iter); +} + +bool upb_oneof_done(upb_oneof_iter *iter) { + return upb_inttable_done(iter); +} + +upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { + return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); +} + +void upb_oneof_iter_setdone(upb_oneof_iter *iter) { + upb_inttable_iter_setdone(iter); +} + +/* Dynamic Layout Generation. *************************************************/ + +static bool is_power_of_two(size_t val) { + return (val & (val - 1)) == 0; +} + +/* Align up to the given power of 2. */ +static size_t align_up(size_t val, size_t align) { + UPB_ASSERT(is_power_of_two(align)); + return (val + align - 1) & ~(align - 1); +} + +static size_t div_round_up(size_t n, size_t d) { + return (n + d - 1) / d; +} + +static size_t upb_msgval_sizeof(upb_fieldtype_t type) { + switch (type) { + case UPB_TYPE_DOUBLE: + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + return 8; + case UPB_TYPE_ENUM: + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_FLOAT: + return 4; + case UPB_TYPE_BOOL: + return 1; + case UPB_TYPE_MESSAGE: + return sizeof(void*); + case UPB_TYPE_BYTES: + case UPB_TYPE_STRING: + return sizeof(upb_strview); + } + UPB_UNREACHABLE(); +} + +static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { + if (upb_msgdef_mapentry(upb_fielddef_containingtype(f))) { + upb_map_entry ent; + UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v)); + return sizeof(ent.k); + } else if (upb_fielddef_isseq(f)) { + return sizeof(void*); + } else { + return upb_msgval_sizeof(upb_fielddef_type(f)); + } +} + +static uint32_t upb_msglayout_place(upb_msglayout *l, size_t size) { + uint32_t ret; + + l->size = align_up(l->size, size); + ret = l->size; + l->size += size; + return ret; +} + +/* This function is the dynamic equivalent of message_layout.{cc,h} in upbc. + * It computes a dynamic layout for all of the fields in |m|. */ +static bool make_layout(const upb_symtab *symtab, const upb_msgdef *m) { + upb_msglayout *l = (upb_msglayout*)m->layout; + upb_msg_field_iter it; + upb_msg_oneof_iter oit; + size_t hasbit; + size_t submsg_count = m->submsg_field_count; + const upb_msglayout **submsgs; + upb_msglayout_field *fields; + upb_alloc *alloc = upb_arena_alloc(symtab->arena); + + memset(l, 0, sizeof(*l)); + + fields = upb_malloc(alloc, upb_msgdef_numfields(m) * sizeof(*fields)); + submsgs = upb_malloc(alloc, submsg_count * sizeof(*submsgs)); + + if ((!fields && upb_msgdef_numfields(m)) || + (!submsgs && submsg_count)) { + /* OOM. */ + return false; + } + + l->field_count = upb_msgdef_numfields(m); + l->fields = fields; + l->submsgs = submsgs; + + if (upb_msgdef_mapentry(m)) { + /* TODO(haberman): refactor this method so this special case is more + * elegant. */ + const upb_fielddef *key = upb_msgdef_itof(m, 1); + const upb_fielddef *val = upb_msgdef_itof(m, 2); + fields[0].number = 1; + fields[1].number = 2; + fields[0].label = UPB_LABEL_OPTIONAL; + fields[1].label = UPB_LABEL_OPTIONAL; + fields[0].presence = 0; + fields[1].presence = 0; + fields[0].descriptortype = upb_fielddef_descriptortype(key); + fields[1].descriptortype = upb_fielddef_descriptortype(val); + fields[0].offset = 0; + fields[1].offset = sizeof(upb_strview); + fields[1].submsg_index = 0; + + if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) { + submsgs[0] = upb_fielddef_msgsubdef(val)->layout; + } + + l->field_count = 2; + l->size = 2 * sizeof(upb_strview);align_up(l->size, 8); + return true; + } + + /* Allocate data offsets in three stages: + * + * 1. hasbits. + * 2. regular fields. + * 3. oneof fields. + * + * OPT: There is a lot of room for optimization here to minimize the size. + */ + + /* Allocate hasbits and set basic field attributes. */ + submsg_count = 0; + for (upb_msg_field_begin(&it, m), hasbit = 0; + !upb_msg_field_done(&it); + upb_msg_field_next(&it)) { + upb_fielddef* f = upb_msg_iter_field(&it); + upb_msglayout_field *field = &fields[upb_fielddef_index(f)]; -bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter) { - return upb_strtable_done(iter); -} + field->number = upb_fielddef_number(f); + field->descriptortype = upb_fielddef_descriptortype(f); + field->label = upb_fielddef_label(f); -const upb_oneofdef *upb_msg_iter_oneof(const upb_msg_oneof_iter *iter) { - return unpack_def(upb_strtable_iter_value(iter), UPB_DEFTYPE_ONEOF); -} + if (upb_fielddef_ismap(f)) { + field->label = _UPB_LABEL_MAP; + } else if (upb_fielddef_packed(f)) { + field->label = _UPB_LABEL_PACKED; + } -void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter *iter) { - upb_strtable_iter_setdone(iter); -} + /* TODO: we probably should sort the fields by field number to match the + * output of upbc, and to improve search speed for the table parser. */ + f->layout_index = f->index_; -bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, - const upb_msg_oneof_iter *iter2) { - return upb_strtable_iter_isequal(iter1, iter2); -} + if (upb_fielddef_issubmsg(f)) { + const upb_msgdef *subm = upb_fielddef_msgsubdef(f); + field->submsg_index = submsg_count++; + submsgs[field->submsg_index] = subm->layout; + } -/* upb_oneofdef ***************************************************************/ + if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) { + /* We don't use hasbit 0, so that 0 can indicate "no presence" in the + * table. This wastes one hasbit, but we don't worry about it for now. */ + field->presence = ++hasbit; + } else { + field->presence = 0; + } + } -const char *upb_oneofdef_name(const upb_oneofdef *o) { - return shortdefname(o->full_name); -} + /* Account for space used by hasbits. */ + l->size = div_round_up(hasbit, 8); -const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o) { - return o->parent; -} + /* Allocate non-oneof fields. */ + for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it); + upb_msg_field_next(&it)) { + const upb_fielddef* f = upb_msg_iter_field(&it); + size_t field_size = upb_msg_fielddefsize(f); + size_t index = upb_fielddef_index(f); -int upb_oneofdef_numfields(const upb_oneofdef *o) { - return upb_strtable_count(&o->ntof); -} + if (upb_fielddef_realcontainingoneof(f)) { + /* Oneofs are handled separately below. */ + continue; + } -uint32_t upb_oneofdef_index(const upb_oneofdef *o) { - return o->index; -} + fields[index].offset = upb_msglayout_place(l, field_size); + } -const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o, - const char *name, size_t length) { - upb_value val; - return upb_strtable_lookup2(&o->ntof, name, length, &val) ? - upb_value_getptr(val) : NULL; -} + /* Allocate oneof fields. Each oneof field consists of a uint32 for the case + * and space for the actual data. */ + for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit); + upb_msg_oneof_next(&oit)) { + const upb_oneofdef* o = upb_msg_iter_oneof(&oit); + upb_oneof_iter fit; -const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) { - upb_value val; - return upb_inttable_lookup32(&o->itof, num, &val) ? - upb_value_getptr(val) : NULL; -} + if (upb_oneofdef_issynthetic(o)) continue; -void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) { - upb_inttable_begin(iter, &o->itof); -} + size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ + size_t field_size = 0; + uint32_t case_offset; + uint32_t data_offset; -void upb_oneof_next(upb_oneof_iter *iter) { - upb_inttable_next(iter); -} + /* Calculate field size: the max of all field sizes. */ + for (upb_oneof_begin(&fit, o); + !upb_oneof_done(&fit); + upb_oneof_next(&fit)) { + const upb_fielddef* f = upb_oneof_iter_field(&fit); + field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f)); + } -bool upb_oneof_done(upb_oneof_iter *iter) { - return upb_inttable_done(iter); -} + /* Align and allocate case offset. */ + case_offset = upb_msglayout_place(l, case_size); + data_offset = upb_msglayout_place(l, field_size); -upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) { - return (upb_fielddef *)upb_value_getconstptr(upb_inttable_iter_value(iter)); -} + for (upb_oneof_begin(&fit, o); + !upb_oneof_done(&fit); + upb_oneof_next(&fit)) { + const upb_fielddef* f = upb_oneof_iter_field(&fit); + fields[upb_fielddef_index(f)].offset = data_offset; + fields[upb_fielddef_index(f)].presence = ~case_offset; + } + } -void upb_oneof_iter_setdone(upb_oneof_iter *iter) { - upb_inttable_iter_setdone(iter); + /* Size of the entire structure should be a multiple of its greatest + * alignment. TODO: track overall alignment for real? */ + l->size = align_up(l->size, 8); + + return true; } /* Code to build defs from descriptor protos. *********************************/ @@ -3740,11 +4062,12 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter) { typedef struct { const upb_symtab *symtab; - upb_filedef *file; /* File we are building. */ - upb_alloc *alloc; /* Allocate defs here. */ - upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */ - upb_strtable *addtab; /* full_name -> packed def ptr for new defs. */ - upb_status *status; /* Record errors here. */ + upb_filedef *file; /* File we are building. */ + upb_alloc *alloc; /* Allocate defs here. */ + upb_alloc *tmp; /* Alloc for addtab and any other tmp data. */ + upb_strtable *addtab; /* full_name -> packed def ptr for new defs */ + const upb_msglayout **layouts; /* NULL if we should build layouts. */ + upb_status *status; /* Record errors here. */ } symtab_addctx; static char* strviewdup(const symtab_addctx *ctx, upb_strview view) { @@ -3776,6 +4099,51 @@ static const char *makefullname(const symtab_addctx *ctx, const char *prefix, } } +size_t getjsonname(const char *name, char *buf, size_t len) { + size_t src, dst = 0; + bool ucase_next = false; + +#define WRITE(byte) \ + ++dst; \ + if (dst < len) buf[dst - 1] = byte; \ + else if (dst == len) buf[dst - 1] = '\0' + + if (!name) { + WRITE('\0'); + return 0; + } + + /* Implement the transformation as described in the spec: + * 1. upper case all letters after an underscore. + * 2. remove all underscores. + */ + for (src = 0; name[src]; src++) { + if (name[src] == '_') { + ucase_next = true; + continue; + } + + if (ucase_next) { + WRITE(toupper(name[src])); + ucase_next = false; + } else { + WRITE(name[src]); + } + } + + WRITE('\0'); + return dst; + +#undef WRITE +} + +static char* makejsonname(const char* name, upb_alloc *alloc) { + size_t size = getjsonname(name, NULL, 0); + char* json_name = upb_malloc(alloc, size); + getjsonname(name, json_name, size); + return json_name; +} + static bool symtab_add(const symtab_addctx *ctx, const char *name, upb_value v) { upb_value tmp; @@ -3899,7 +4267,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, } case UPB_TYPE_INT64: { /* XXX: Need to write our own strtoll, since it's not available in c89. */ - long long val = strtol(str, &end, 0); + int64_t val = strtol(str, &end, 0); CHK(val <= INT64_MAX && val >= INT64_MIN && errno != ERANGE && !*end); f->defaultval.sint = val; break; @@ -3912,7 +4280,7 @@ static bool parse_default(const symtab_addctx *ctx, const char *str, size_t len, } case UPB_TYPE_UINT64: { /* XXX: Need to write our own strtoull, since it's not available in c89. */ - unsigned long long val = strtoul(str, &end, 0); + uint64_t val = strtoul(str, &end, 0); CHK(val <= UINT64_MAX && errno != ERANGE && !*end); f->defaultval.uint = val; break; @@ -3989,6 +4357,7 @@ static bool create_fielddef( const google_protobuf_FieldOptions *options; upb_strview name; const char *full_name; + const char *json_name; const char *shortname; uint32_t field_number; @@ -4002,6 +4371,13 @@ static bool create_fielddef( full_name = makefullname(ctx, prefix, name); shortname = shortdefname(full_name); + if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) { + json_name = strviewdup( + ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto)); + } else { + json_name = makejsonname(shortname, ctx->alloc); + } + field_number = google_protobuf_FieldDescriptorProto_number(field_proto); if (field_number == 0 || field_number > UPB_MAX_FIELDNUMBER) { @@ -4011,38 +4387,72 @@ static bool create_fielddef( if (m) { /* direct message field. */ - upb_value v, packed_v; + upb_value v, field_v, json_v; + size_t json_size; f = (upb_fielddef*)&m->fields[m->field_count++]; f->msgdef = m; f->is_extension_ = false; - packed_v = pack_def(f, UPB_DEFTYPE_FIELD); - v = upb_value_constptr(f); - - if (!upb_strtable_insert3(&m->ntof, name.data, name.size, packed_v, alloc)) { + if (upb_strtable_lookup(&m->ntof, shortname, NULL)) { upb_status_seterrf(ctx->status, "duplicate field name (%s)", shortname); return false; } - if (!upb_inttable_insert2(&m->itof, field_number, v, alloc)) { + if (upb_strtable_lookup(&m->ntof, json_name, NULL)) { + upb_status_seterrf(ctx->status, "duplicate json_name (%s)", json_name); + return false; + } + + if (upb_inttable_lookup(&m->itof, field_number, NULL)) { upb_status_seterrf(ctx->status, "duplicate field number (%u)", field_number); return false; } + + field_v = pack_def(f, UPB_DEFTYPE_FIELD); + json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME); + v = upb_value_constptr(f); + json_size = strlen(json_name); + + CHK_OOM( + upb_strtable_insert3(&m->ntof, name.data, name.size, field_v, alloc)); + CHK_OOM(upb_inttable_insert2(&m->itof, field_number, v, alloc)); + + if (strcmp(shortname, json_name) != 0) { + upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc); + } + + if (ctx->layouts) { + const upb_msglayout_field *fields = m->layout->fields; + int count = m->layout->field_count; + bool found = false; + int i; + for (i = 0; i < count; i++) { + if (fields[i].number == field_number) { + f->layout_index = i; + found = true; + break; + } + } + UPB_ASSERT(found); + } } else { /* extension field. */ - f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count]; + f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++]; f->is_extension_ = true; CHK_OOM(symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD))); } f->full_name = full_name; + f->json_name = json_name; f->file = ctx->file; f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); f->number_ = field_number; f->oneof = NULL; + f->proto3_optional_ = + google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); /* We can't resolve the subdef or (in the case of extensions) the containing * message yet, because it may not have been defined yet. We stash a pointer @@ -4166,7 +4576,7 @@ static bool create_enumdef( return true; } -static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, +static bool create_msgdef(symtab_addctx *ctx, const char *prefix, const google_protobuf_DescriptorProto *msg_proto) { upb_msgdef *m; const google_protobuf_MessageOptions *options; @@ -4196,6 +4606,14 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, m->map_entry = google_protobuf_MessageOptions_map_entry(options); } + if (ctx->layouts) { + m->layout = *ctx->layouts; + ctx->layouts++; + } else { + /* Allocate now (to allow cross-linking), populate later. */ + m->layout = upb_malloc(ctx->alloc, sizeof(*m->layout)); + } + oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n); m->oneof_count = 0; m->oneofs = upb_malloc(ctx->alloc, sizeof(*m->oneofs) * n); @@ -4211,6 +4629,7 @@ static bool create_msgdef(const symtab_addctx *ctx, const char *prefix, } CHK(assign_msg_indices(m, ctx->status)); + CHK(check_oneofs(m, ctx->status)); assign_msg_wellknowntype(m); upb_inttable_compact2(&m->itof, ctx->alloc); @@ -4342,7 +4761,7 @@ static bool resolve_fielddef(const symtab_addctx *ctx, const char *prefix, } static bool build_filedef( - const symtab_addctx *ctx, upb_filedef *file, + symtab_addctx *ctx, upb_filedef *file, const google_protobuf_FileDescriptorProto *file_proto) { upb_alloc *alloc = ctx->alloc; const google_protobuf_FileOptions *file_options_proto; @@ -4396,7 +4815,8 @@ static bool build_filedef( } else if (streql_view(syntax, "proto3")) { file->syntax = UPB_SYNTAX_PROTO3; } else { - upb_status_seterrf(ctx->status, "Invalid syntax '%s'", syntax); + upb_status_seterrf(ctx->status, "Invalid syntax '" UPB_STRVIEW_FORMAT "'", + UPB_STRVIEW_ARGS(syntax)); return false; } } else { @@ -4456,7 +4876,7 @@ static bool build_filedef( CHK(create_fielddef(ctx, file->package, NULL, exts[i])); } - /* Now that all names are in the table, resolve references. */ + /* Now that all names are in the table, build layouts and resolve refs. */ for (i = 0; i < file->ext_count; i++) { CHK(resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i])); } @@ -4469,6 +4889,13 @@ static bool build_filedef( } } + if (!ctx->layouts) { + for (i = 0; i < file->msg_count; i++) { + const upb_msgdef *m = &file->msgs[i]; + make_layout(ctx->symtab, m); + } + } + return true; } @@ -4483,10 +4910,9 @@ static bool upb_symtab_addtotabs(upb_symtab *s, symtab_addctx *ctx, upb_strtable_begin(&iter, ctx->addtab); for (; !upb_strtable_done(&iter); upb_strtable_next(&iter)) { - const char *key = upb_strtable_iter_key(&iter); - size_t keylen = upb_strtable_iter_keylength(&iter); + upb_strview key = upb_strtable_iter_key(&iter); upb_value value = upb_strtable_iter_value(&iter); - CHK_OOM(upb_strtable_insert3(&s->syms, key, keylen, value, alloc)); + CHK_OOM(upb_strtable_insert3(&s->syms, key.data, key.size, value, alloc)); } return true; @@ -4588,9 +5014,13 @@ const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) : NULL; } -const upb_filedef *upb_symtab_addfile( +int upb_symtab_filecount(const upb_symtab *s) { + return (int)upb_strtable_count(&s->files); +} + +static const upb_filedef *_upb_symtab_addfile( upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, - upb_status *status) { + const upb_msglayout **layouts, upb_status *status) { upb_arena *tmparena = upb_arena_new(); upb_strtable addtab; upb_alloc *alloc = upb_arena_alloc(s->arena); @@ -4603,6 +5033,7 @@ const upb_filedef *upb_symtab_addfile( ctx.alloc = alloc; ctx.tmp = upb_arena_alloc(tmparena); ctx.addtab = &addtab; + ctx.layouts = layouts; ctx.status = status; ok = file && @@ -4614,6 +5045,12 @@ const upb_filedef *upb_symtab_addfile( return ok ? file : NULL; } +const upb_filedef *upb_symtab_addfile( + upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto, + upb_status *status) { + return _upb_symtab_addfile(s, file_proto, NULL, status); +} + /* Include here since we want most of this file to be stdio-free. */ #include @@ -4645,270 +5082,331 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { &status, "Failed to parse compiled-in descriptor for file '%s'. This should " "never happen.", - init->filename); - goto err; - } - - if (!upb_symtab_addfile(s, file, &status)) goto err; - - upb_arena_free(arena); - return true; - -err: - fprintf(stderr, "Error loading compiled-in descriptor: %s\n", - upb_status_errmsg(&status)); - upb_arena_free(arena); - return false; -} - -#undef CHK -#undef CHK_OOM - - - -static bool is_power_of_two(size_t val) { - return (val & (val - 1)) == 0; -} - -/* Align up to the given power of 2. */ -static size_t align_up(size_t val, size_t align) { - UPB_ASSERT(is_power_of_two(align)); - return (val + align - 1) & ~(align - 1); -} - -static size_t div_round_up(size_t n, size_t d) { - return (n + d - 1) / d; -} - -static size_t upb_msgval_sizeof2(upb_fieldtype_t type) { - switch (type) { - case UPB_TYPE_DOUBLE: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: - return 8; - case UPB_TYPE_ENUM: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_FLOAT: - return 4; - case UPB_TYPE_BOOL: - return 1; - case UPB_TYPE_MESSAGE: - return sizeof(void*); - case UPB_TYPE_BYTES: - case UPB_TYPE_STRING: - return sizeof(upb_strview); - } - UPB_UNREACHABLE(); -} - -static uint8_t upb_msg_fielddefsize(const upb_fielddef *f) { - if (upb_fielddef_isseq(f)) { - return sizeof(void*); - } else { - return upb_msgval_sizeof2(upb_fielddef_type(f)); + init->filename); + goto err; } + + if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err; + + upb_arena_free(arena); + return true; + +err: + fprintf(stderr, "Error loading compiled-in descriptor: %s\n", + upb_status_errmsg(&status)); + upb_arena_free(arena); + return false; } +#undef CHK +#undef CHK_OOM + + +#include + + +static char field_size[] = { + 0,/* 0 */ + 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */ + 4, /* UPB_DESCRIPTOR_TYPE_FLOAT */ + 8, /* UPB_DESCRIPTOR_TYPE_INT64 */ + 8, /* UPB_DESCRIPTOR_TYPE_UINT64 */ + 4, /* UPB_DESCRIPTOR_TYPE_INT32 */ + 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */ + 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */ + 1, /* UPB_DESCRIPTOR_TYPE_BOOL */ + sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */ + sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */ + sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */ + sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */ + 4, /* UPB_DESCRIPTOR_TYPE_UINT32 */ + 4, /* UPB_DESCRIPTOR_TYPE_ENUM */ + 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */ + 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */ + 4, /* UPB_DESCRIPTOR_TYPE_SINT32 */ + 8, /* UPB_DESCRIPTOR_TYPE_SINT64 */ +}; -/** upb_msglayout *************************************************************/ +/* Strings/bytes are special-cased in maps. */ +static char _upb_fieldtype_to_mapsize[12] = { + 0, + 1, /* UPB_TYPE_BOOL */ + 4, /* UPB_TYPE_FLOAT */ + 4, /* UPB_TYPE_INT32 */ + 4, /* UPB_TYPE_UINT32 */ + 4, /* UPB_TYPE_ENUM */ + sizeof(void*), /* UPB_TYPE_MESSAGE */ + 8, /* UPB_TYPE_DOUBLE */ + 8, /* UPB_TYPE_INT64 */ + 8, /* UPB_TYPE_UINT64 */ + 0, /* UPB_TYPE_STRING */ + 0, /* UPB_TYPE_BYTES */ +}; + +/** upb_msg *******************************************************************/ -static void upb_msglayout_free(upb_msglayout *l) { - upb_gfree(l); +upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) { + return _upb_msg_new(upb_msgdef_layout(m), a); } -static size_t upb_msglayout_place(upb_msglayout *l, size_t size) { - size_t ret; +static bool in_oneof(const upb_msglayout_field *field) { + return field->presence < 0; +} - l->size = align_up(l->size, size); - ret = l->size; - l->size += size; - return ret; +static uint32_t *oneofcase(const upb_msg *msg, + const upb_msglayout_field *field) { + UPB_ASSERT(in_oneof(field)); + return UPB_PTR_AT(msg, -field->presence, uint32_t); } -static bool upb_msglayout_init(const upb_msgdef *m, - upb_msglayout *l, - upb_msgfactory *factory) { - upb_msg_field_iter it; - upb_msg_oneof_iter oit; - size_t hasbit; - size_t submsg_count = 0; - const upb_msglayout **submsgs; - upb_msglayout_field *fields; +static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + const char *mem = UPB_PTR_AT(msg, field->offset, char); + upb_msgval val = {0}; + int size = upb_fielddef_isseq(f) ? sizeof(void *) + : field_size[field->descriptortype]; + memcpy(&val, mem, size); + return val; +} - for (upb_msg_field_begin(&it, m); - !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* f = upb_msg_iter_field(&it); - if (upb_fielddef_issubmsg(f)) { - submsg_count++; - } +bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + if (in_oneof(field)) { + return *oneofcase(msg, field) == field->number; + } else if (field->presence > 0) { + uint32_t hasbit = field->presence; + return *UPB_PTR_AT(msg, hasbit / 8, uint8_t) & (1 << (hasbit % 8)); + } else { + UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || + field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP); + return _upb_msg_getraw(msg, f).msg_val != NULL; } +} - memset(l, 0, sizeof(*l)); +bool upb_msg_hasoneof(const upb_msg *msg, const upb_oneofdef *o) { + upb_oneof_iter i; + const upb_fielddef *f; + const upb_msglayout_field *field; - fields = upb_gmalloc(upb_msgdef_numfields(m) * sizeof(*fields)); - submsgs = upb_gmalloc(submsg_count * sizeof(*submsgs)); + upb_oneof_begin(&i, o); + if (upb_oneof_done(&i)) return false; + f = upb_oneof_iter_field(&i); + field = upb_fielddef_layout(f); + return *oneofcase(msg, field) != 0; +} - if ((!fields && upb_msgdef_numfields(m)) || - (!submsgs && submsg_count)) { - /* OOM. */ - upb_gfree(fields); - upb_gfree(submsgs); - return false; +upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) { + if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) { + return _upb_msg_getraw(msg, f); + } else { + /* TODO(haberman): change upb_fielddef to not require this switch(). */ + upb_msgval val = {0}; + switch (upb_fielddef_type(f)) { + case UPB_TYPE_INT32: + case UPB_TYPE_ENUM: + val.int32_val = upb_fielddef_defaultint32(f); + break; + case UPB_TYPE_INT64: + val.int64_val = upb_fielddef_defaultint64(f); + break; + case UPB_TYPE_UINT32: + val.uint32_val = upb_fielddef_defaultuint32(f); + break; + case UPB_TYPE_UINT64: + val.uint64_val = upb_fielddef_defaultuint64(f); + break; + case UPB_TYPE_FLOAT: + val.float_val = upb_fielddef_defaultfloat(f); + break; + case UPB_TYPE_DOUBLE: + val.double_val = upb_fielddef_defaultdouble(f); + break; + case UPB_TYPE_BOOL: + val.double_val = upb_fielddef_defaultbool(f); + break; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size); + break; + case UPB_TYPE_MESSAGE: + val.msg_val = NULL; + break; + } + return val; } +} - l->field_count = upb_msgdef_numfields(m); - l->fields = fields; - l->submsgs = submsgs; - - /* Allocate data offsets in three stages: - * - * 1. hasbits. - * 2. regular fields. - * 3. oneof fields. - * - * OPT: There is a lot of room for optimization here to minimize the size. - */ - - /* Allocate hasbits and set basic field attributes. */ - submsg_count = 0; - for (upb_msg_field_begin(&it, m), hasbit = 0; - !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* f = upb_msg_iter_field(&it); - upb_msglayout_field *field = &fields[upb_fielddef_index(f)]; +upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, + upb_arena *a) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + upb_mutmsgval ret; + char *mem = UPB_PTR_AT(msg, field->offset, char); + bool wrong_oneof = in_oneof(field) && *oneofcase(msg, field) != field->number; - field->number = upb_fielddef_number(f); - field->descriptortype = upb_fielddef_descriptortype(f); - field->label = upb_fielddef_label(f); + memcpy(&ret, mem, sizeof(void*)); - if (upb_fielddef_issubmsg(f)) { - const upb_msglayout *sub_layout = - upb_msgfactory_getlayout(factory, upb_fielddef_msgsubdef(f)); - field->submsg_index = submsg_count++; - submsgs[field->submsg_index] = sub_layout; + if (a && (!ret.msg || wrong_oneof)) { + if (upb_fielddef_ismap(f)) { + const upb_msgdef *entry = upb_fielddef_msgsubdef(f); + const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY); + const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE); + ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value)); + } else if (upb_fielddef_isseq(f)) { + ret.array = upb_array_new(a, upb_fielddef_type(f)); + } else { + UPB_ASSERT(upb_fielddef_issubmsg(f)); + ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a); } - if (upb_fielddef_haspresence(f) && !upb_fielddef_containingoneof(f)) { - field->presence = (hasbit++); - } else { - field->presence = 0; + memcpy(mem, &ret, sizeof(void*)); + + if (wrong_oneof) { + *oneofcase(msg, field) = field->number; } } + return ret; +} - /* Account for space used by hasbits. */ - l->size = div_round_up(hasbit, 8); +void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, + upb_arena *a) { + const upb_msglayout_field *field = upb_fielddef_layout(f); + char *mem = UPB_PTR_AT(msg, field->offset, char); + int size = upb_fielddef_isseq(f) ? sizeof(void *) + : field_size[field->descriptortype]; + memcpy(mem, &val, size); + if (in_oneof(field)) { + *oneofcase(msg, field) = field->number; + } +} - /* Allocate non-oneof fields. */ - for (upb_msg_field_begin(&it, m); !upb_msg_field_done(&it); - upb_msg_field_next(&it)) { - const upb_fielddef* f = upb_msg_iter_field(&it); - size_t field_size = upb_msg_fielddefsize(f); - size_t index = upb_fielddef_index(f); +bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, const upb_fielddef **out_f, + upb_msgval *out_val, size_t *iter) { + size_t i = *iter; + const upb_msgval zero = {0}; + const upb_fielddef *f; + while ((f = _upb_msgdef_field(m, (int)++i)) != NULL) { + upb_msgval val = _upb_msg_getraw(msg, f); - if (upb_fielddef_containingoneof(f)) { - /* Oneofs are handled separately below. */ - continue; + /* Skip field if unset or empty. */ + if (upb_fielddef_haspresence(f)) { + if (!upb_msg_has(msg, f)) continue; + } else { + upb_msgval test = val; + if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) { + /* Clear string pointer, only size matters (ptr could be non-NULL). */ + test.str_val.data = NULL; + } + /* Continue if NULL or 0. */ + if (memcmp(&test, &zero, sizeof(test)) == 0) continue; + + /* Continue on empty array or map. */ + if (upb_fielddef_ismap(f)) { + if (upb_map_size(test.map_val) == 0) continue; + } else if (upb_fielddef_isseq(f)) { + if (upb_array_size(test.array_val) == 0) continue; + } } - fields[index].offset = upb_msglayout_place(l, field_size); + *out_val = val; + *out_f = f; + *iter = i; + return true; } + *iter = i; + return false; +} - /* Allocate oneof fields. Each oneof field consists of a uint32 for the case - * and space for the actual data. */ - for (upb_msg_oneof_begin(&oit, m); !upb_msg_oneof_done(&oit); - upb_msg_oneof_next(&oit)) { - const upb_oneofdef* o = upb_msg_iter_oneof(&oit); - upb_oneof_iter fit; - - size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */ - size_t field_size = 0; - uint32_t case_offset; - uint32_t data_offset; +/** upb_array *****************************************************************/ - /* Calculate field size: the max of all field sizes. */ - for (upb_oneof_begin(&fit, o); - !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* f = upb_oneof_iter_field(&fit); - field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f)); - } +upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) { + return _upb_array_new(a, type); +} - /* Align and allocate case offset. */ - case_offset = upb_msglayout_place(l, case_size); - data_offset = upb_msglayout_place(l, field_size); +size_t upb_array_size(const upb_array *arr) { + return arr->len; +} - for (upb_oneof_begin(&fit, o); - !upb_oneof_done(&fit); - upb_oneof_next(&fit)) { - const upb_fielddef* f = upb_oneof_iter_field(&fit); - fields[upb_fielddef_index(f)].offset = data_offset; - fields[upb_fielddef_index(f)].presence = ~case_offset; - } - } +upb_msgval upb_array_get(const upb_array *arr, size_t i) { + upb_msgval ret; + const char* data = _upb_array_constptr(arr); + int lg2 = arr->data & 7; + UPB_ASSERT(i < arr->len); + memcpy(&ret, data + (i << lg2), 1 << lg2); + return ret; +} - /* Size of the entire structure should be a multiple of its greatest - * alignment. TODO: track overall alignment for real? */ - l->size = align_up(l->size, 8); +void upb_array_set(upb_array *arr, size_t i, upb_msgval val) { + char* data = _upb_array_ptr(arr); + int lg2 = arr->data & 7; + UPB_ASSERT(i < arr->len); + memcpy(data + (i << lg2), &val, 1 << lg2); +} +bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) { + if (!_upb_array_realloc(arr, arr->len + 1, arena)) { + return false; + } + arr->len++; + upb_array_set(arr, arr->len - 1, val); return true; } +/* Resizes the array to the given size, reallocating if necessary, and returns a + * pointer to the new array elements. */ +bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) { + return _upb_array_realloc(arr, size, arena); +} -/** upb_msgfactory ************************************************************/ - -struct upb_msgfactory { - const upb_symtab *symtab; /* We own a ref. */ - upb_inttable layouts; -}; +/** upb_map *******************************************************************/ -upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab) { - upb_msgfactory *ret = upb_gmalloc(sizeof(*ret)); +upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, + upb_fieldtype_t value_type) { + return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type], + _upb_fieldtype_to_mapsize[value_type]); +} - ret->symtab = symtab; - upb_inttable_init(&ret->layouts, UPB_CTYPE_PTR); +size_t upb_map_size(const upb_map *map) { + return _upb_map_size(map); +} - return ret; +bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) { + return _upb_map_get(map, &key, map->key_size, val, map->val_size); } -void upb_msgfactory_free(upb_msgfactory *f) { - upb_inttable_iter i; - upb_inttable_begin(&i, &f->layouts); - for(; !upb_inttable_done(&i); upb_inttable_next(&i)) { - upb_msglayout *l = upb_value_getptr(upb_inttable_iter_value(&i)); - upb_msglayout_free(l); - } +bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, + upb_arena *arena) { + return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena); +} - upb_inttable_uninit(&f->layouts); - upb_gfree(f); +bool upb_map_delete(upb_map *map, upb_msgval key) { + return _upb_map_delete(map, &key, map->key_size); } -const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f) { - return f->symtab; +bool upb_mapiter_next(const upb_map *map, size_t *iter) { + return _upb_map_next(map, iter); } -const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, - const upb_msgdef *m) { - upb_value v; - UPB_ASSERT(upb_symtab_lookupmsg(f->symtab, upb_msgdef_fullname(m)) == m); - UPB_ASSERT(!upb_msgdef_mapentry(m)); +/* Returns the key and value for this entry of the map. */ +upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) { + upb_strtable_iter i; + upb_msgval ret; + i.t = &map->table; + i.index = iter; + _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size); + return ret; +} - if (upb_inttable_lookupptr(&f->layouts, m, &v)) { - UPB_ASSERT(upb_value_getptr(v)); - return upb_value_getptr(v); - } else { - /* In case of circular dependency, layout has to be inserted first. */ - upb_msglayout *l = upb_gmalloc(sizeof(*l)); - upb_msgfactory *mutable_f = (void*)f; - upb_inttable_insertptr(&mutable_f->layouts, m, upb_value_ptr(l)); - UPB_ASSERT(l); - if (!upb_msglayout_init(m, l, f)) { - upb_msglayout_free(l); - } - return l; - } +upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) { + upb_strtable_iter i; + upb_msgval ret; + i.t = &map->table; + i.index = iter; + _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size); + return ret; } + +/* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */ /* ** TODO(haberman): it's unclear whether a lot of the consistency checks should ** UPB_ASSERT() or return false. @@ -5088,7 +5586,8 @@ static upb_handlers *upb_handlers_new(const upb_msgdef *md, int extra; upb_handlers *h; - extra = sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1); + extra = + (int)(sizeof(upb_handlers_tabent) * (upb_msgdef_selectorcount(md) - 1)); h = upb_calloc(arena, sizeof(*h) + extra); if (!h) return NULL; @@ -5489,6 +5988,31 @@ bool upb_bufsrc_putbuf(const char *buf, size_t len, upb_bytessink sink) { } return ret; } + + +#ifdef UPB_MSVC_VSNPRINTF +/* Visual C++ earlier than 2015 doesn't have standard C99 snprintf and + * vsnprintf. To support them, missing functions are manually implemented + * using the existing secure functions. */ +int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg) { + if (!s) { + return _vscprintf(format, arg); + } + int ret = _vsnprintf_s(s, n, _TRUNCATE, format, arg); + if (ret < 0) { + ret = _vscprintf(format, arg); + } + return ret; +} + +int msvc_snprintf(char* s, size_t n, const char* format, ...) { + va_list arg; + va_start(arg, format); + int ret = msvc_vsnprintf(s, n, format, arg); + va_end(arg); + return ret; +} +#endif /* ** protobuf decoder bytecode compiler ** @@ -5644,7 +6168,9 @@ static void setofs(uint32_t *instruction, int32_t ofs) { UPB_ASSERT(getofs(*instruction) == ofs); /* Would fail in cases of overflow. */ } -static uint32_t pcofs(compiler *c) { return c->pc - c->group->bytecode; } +static uint32_t pcofs(compiler *c) { + return (uint32_t)(c->pc - c->group->bytecode); +} /* Defines a local label at the current PC location. All previous forward * references are updated to point to this location. The location is noted @@ -5658,7 +6184,7 @@ static void label(compiler *c, unsigned int label) { codep = (val == EMPTYLABEL) ? NULL : c->group->bytecode + val; while (codep) { int ofs = getofs(*codep); - setofs(codep, c->pc - codep - instruction_len(*codep)); + setofs(codep, (int32_t)(c->pc - codep - instruction_len(*codep))); codep = ofs ? codep + ofs : NULL; } c->fwd_labels[label] = EMPTYLABEL; @@ -5680,7 +6206,7 @@ static int32_t labelref(compiler *c, int label) { return 0; } else if (label < 0) { /* Backward local label. Relative to the next instruction. */ - uint32_t from = (c->pc + 1) - c->group->bytecode; + uint32_t from = (uint32_t)((c->pc + 1) - c->group->bytecode); return c->back_labels[-label] - from; } else { /* Forward local label: prepend to (possibly-empty) linked list. */ @@ -5714,7 +6240,7 @@ static void putop(compiler *c, int op, ...) { case OP_SETDISPATCH: { uintptr_t ptr = (uintptr_t)va_arg(ap, void*); put32(c, OP_SETDISPATCH); - put32(c, ptr); + put32(c, (uint32_t)ptr); if (sizeof(uintptr_t) > sizeof(uint32_t)) put32(c, (uint64_t)ptr >> 32); break; @@ -5773,7 +6299,7 @@ static void putop(compiler *c, int op, ...) { case OP_TAG2: { int label = va_arg(ap, int); uint64_t tag = va_arg(ap, uint64_t); - uint32_t instruction = op | (tag << 16); + uint32_t instruction = (uint32_t)(op | (tag << 16)); UPB_ASSERT(tag <= 0xffff); setofs(&instruction, labelref(c, label)); put32(c, instruction); @@ -5785,7 +6311,7 @@ static void putop(compiler *c, int op, ...) { uint32_t instruction = op | (upb_value_size(tag) << 16); setofs(&instruction, labelref(c, label)); put32(c, instruction); - put32(c, tag); + put32(c, (uint32_t)tag); put32(c, tag >> 32); break; } @@ -6398,11 +6924,11 @@ const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c, } else { g = mgroup_new(h, c->lazy); ok = upb_inttable_insertptr(&c->groups, md, upb_value_constptr(g)); - UPB_ASSERT(ok); + UPB_ASSUME(ok); } ok = upb_inttable_lookupptr(&g->methods, h, &v); - UPB_ASSERT(ok); + UPB_ASSUME(ok); return upb_value_getptr(v); } /* @@ -6589,7 +7115,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) { UPB_ASSERT(d->skip == 0); if (bytes > delim_remaining(d)) { seterr(d, "Skipped value extended beyond enclosing submessage."); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } else if (bufleft(d) >= bytes) { /* Skipped data is all in current buffer, and more is still available. */ advance(d, bytes); @@ -6602,7 +7128,7 @@ static int32_t skip(upb_pbdecoder *d, size_t bytes) { d->bufstart_ofs += (d->end - d->buf); d->residual_end = d->residual; switchtobuf(d, d->residual, d->residual_end); - return d->size_param + d->skip; + return (int32_t)(d->size_param + d->skip); } } @@ -6642,7 +7168,7 @@ int32_t upb_pbdecoder_resume(upb_pbdecoder *d, void *p, const char *buf, /* NULL buf is ok if its entire span is covered by the "skip" above, but * by this point we know that "skip" doesn't cover the buffer. */ seterr(d, "Passed NULL buffer over non-skippable region."); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } if (d->residual_end > d->residual) { @@ -6752,9 +7278,9 @@ UPB_NOINLINE static int32_t getbytes_slow(upb_pbdecoder *d, void *buf, return DECODE_OK; } else if (d->data_end == d->delim_end) { seterr(d, "Submessage ended in the middle of a value or group"); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } else { - return suspend_save(d); + return (int32_t)suspend_save(d); } } @@ -6810,7 +7336,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_decode_varint_slow(upb_pbdecoder *d, } if(bitpos == 70 && (byte & 0x80)) { seterr(d, kUnterminatedVarint); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } return DECODE_OK; } @@ -6827,7 +7353,7 @@ UPB_FORCEINLINE static int32_t decode_varint(upb_pbdecoder *d, uint64_t *u64) { upb_decoderet r = upb_vdecode_fast(d->ptr); if (r.p == NULL) { seterr(d, kUnterminatedVarint); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } advance(d, r.p - d->ptr); *u64 = r.val; @@ -6851,9 +7377,9 @@ UPB_FORCEINLINE static int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) { * Right now the size_t -> int32_t can overflow and produce negative values. */ *u32 = 0; - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } - *u32 = u64; + *u32 = (uint32_t)u64; return DECODE_OK; } @@ -6929,7 +7455,7 @@ UPB_NOINLINE int32_t upb_pbdecoder_checktag_slow(upb_pbdecoder *d, UPB_ASSERT(ok < 0); return DECODE_OK; } else if (read < bytes && memcmp(&data, &expected, read) == 0) { - return suspend_save(d); + return (int32_t)suspend_save(d); } else { return DECODE_MISMATCH; } @@ -6949,7 +7475,7 @@ int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, have_tag: if (fieldnum == 0) { seterr(d, "Saw invalid field number (0)"); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } switch (wire_type) { @@ -6971,7 +7497,9 @@ int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, break; } case UPB_WIRE_TYPE_START_GROUP: - CHECK_SUSPEND(pushtagdelim(d, -fieldnum)); + if (!pushtagdelim(d, -fieldnum)) { + return (int32_t)upb_pbdecoder_suspend(d); + } break; case UPB_WIRE_TYPE_END_GROUP: if (fieldnum == -d->top->groupnum) { @@ -6980,12 +7508,12 @@ int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum, return DECODE_ENDGROUP; } else { seterr(d, "Unmatched ENDGROUP tag."); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } break; default: seterr(d, "Invalid wire type"); - return upb_pbdecoder_suspend(d); + return (int32_t)upb_pbdecoder_suspend(d); } if (d->top->groupnum >= 0) { @@ -7153,10 +7681,11 @@ size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group, CHECK_SUSPEND(upb_sink_startsubmsg(outer->sink, arg, &d->top->sink)); ) VMCASE(OP_ENDSUBMSG, - CHECK_SUSPEND(upb_sink_endsubmsg(d->top->sink, arg)); + upb_sink subsink = (d->top + 1)->sink; + CHECK_SUSPEND(upb_sink_endsubmsg(d->top->sink, subsink, arg)); ) VMCASE(OP_STARTSTR, - uint32_t len = delim_remaining(d); + uint32_t len = (uint32_t)delim_remaining(d); upb_pbdecoder_frame *outer = outer_frame(d); CHECK_SUSPEND(upb_sink_startstr(outer->sink, arg, len, &d->top->sink)); if (len == 0) { @@ -7164,7 +7693,7 @@ size_t run_decoder_vm(upb_pbdecoder *d, const mgroup *group, } ) VMCASE(OP_STRING, - uint32_t len = curbufleft(d); + uint32_t len = (uint32_t)curbufleft(d); size_t n = upb_sink_putstring(d->top->sink, arg, d->ptr, len, handle); if (n > len) { if (n > delim_remaining(d)) { @@ -7699,7 +8228,7 @@ static bool start_delim(upb_pb_encoder *e) { e->runbegin = e->ptr; } - *e->top = e->segptr - e->segbuf; + *e->top = (int)(e->segptr - e->segbuf); e->segptr->seglen = 0; e->segptr->msglen = 0; @@ -8819,7 +9348,7 @@ 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); + UPB_ASSUME(ok); return sel; } @@ -8844,7 +9373,7 @@ static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) { const upb_json_parsermethod *method; ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v); - UPB_ASSERT(ok); + UPB_ASSUME(ok); method = upb_value_getconstptr(v); frame->name_table = &method->name_table; @@ -9163,7 +9692,7 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len, /* 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); + /* UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE); */ p->multipart_state = MULTIPART_INACTIVE; accumulate_clear(p); } @@ -9398,7 +9927,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf, } else if (val > INT32_MAX || val < INT32_MIN) { return false; } else { - upb_sink_putint32(p->top->sink, parser_getsel(p), val); + upb_sink_putint32(p->top->sink, parser_getsel(p), (int32_t)val); return true; } } @@ -9409,7 +9938,7 @@ static bool parse_number_from_buffer(upb_json_parser *p, const char *buf, } else if (val > UINT32_MAX || errno == ERANGE) { return false; } else { - upb_sink_putuint32(p->top->sink, parser_getsel(p), val); + upb_sink_putuint32(p->top->sink, parser_getsel(p), (uint32_t)val); return true; } } @@ -9697,7 +10226,7 @@ static bool start_stringval(upb_json_parser *p) { } 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 accumulate so we can convert + * current parser frame. These values must accmulate so we can convert * them all at once at the end. */ multipart_startaccum(p); return true; @@ -10117,14 +10646,18 @@ static void start_timestamp_zone(upb_json_parser *p, const char *ptr) { capture_begin(p, ptr); } +static int div_round_up2(int n, int d) { + return (n + d - 1) / d; +} + /* epoch_days(1970, 1, 1) == 1970-01-01 == 0. */ static int epoch_days(int year, int month, int day) { static const uint16_t month_yday[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; int febs_since_0 = month > 2 ? year + 1 : year; - int leap_days_since_0 = div_round_up(febs_since_0, 4) - - div_round_up(febs_since_0, 100) + - div_round_up(febs_since_0, 400); + int leap_days_since_0 = div_round_up2(febs_since_0, 4) - + div_round_up2(febs_since_0, 100) + + div_round_up2(febs_since_0, 400); int days_since_0 = 365 * year + month_yday[month - 1] + (day - 1) + leap_days_since_0; @@ -10445,8 +10978,8 @@ static void end_member(upb_json_parser *p) { /* 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); + UPB_ASSUME(ok); + upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel); } p->top->f = NULL; @@ -10560,7 +11093,7 @@ static void end_subobject(upb_json_parser *p) { p->top--; if (!is_unknown) { sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG); - upb_sink_endsubmsg(p->top->sink, sel); + upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel); } } } @@ -10999,11 +11532,11 @@ static bool does_fieldmask_end(upb_json_parser *p) { * final state once, when the closing '"' is seen. */ -#line 2794 "upb/json/parser.rl" +#line 2780 "upb/json/parser.rl" -#line 2597 "upb/json/parser.c" +#line 2583 "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, @@ -11258,7 +11791,7 @@ static const int json_en_value_machine = 78; static const int json_en_main = 1; -#line 2797 "upb/json/parser.rl" +#line 2783 "upb/json/parser.rl" size_t parse(void *closure, const void *hd, const char *buf, size_t size, const upb_bufhandle *handle) { @@ -11281,7 +11814,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, capture_resume(parser, buf); -#line 2875 "upb/json/parser.c" +#line 2861 "upb/json/parser.c" { int _klen; unsigned int _trans; @@ -11356,147 +11889,147 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, switch ( *_acts++ ) { case 1: -#line 2602 "upb/json/parser.rl" +#line 2588 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 2: -#line 2604 "upb/json/parser.rl" +#line 2590 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 23;goto _again;} } break; case 3: -#line 2608 "upb/json/parser.rl" +#line 2594 "upb/json/parser.rl" { start_text(parser, p); } break; case 4: -#line 2609 "upb/json/parser.rl" +#line 2595 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_text(parser, p)); } break; case 5: -#line 2615 "upb/json/parser.rl" +#line 2601 "upb/json/parser.rl" { start_hex(parser); } break; case 6: -#line 2616 "upb/json/parser.rl" +#line 2602 "upb/json/parser.rl" { hexdigit(parser, p); } break; case 7: -#line 2617 "upb/json/parser.rl" +#line 2603 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hex(parser)); } break; case 8: -#line 2623 "upb/json/parser.rl" +#line 2609 "upb/json/parser.rl" { CHECK_RETURN_TOP(escape(parser, p)); } break; case 9: -#line 2629 "upb/json/parser.rl" +#line 2615 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 10: -#line 2634 "upb/json/parser.rl" +#line 2620 "upb/json/parser.rl" { start_year(parser, p); } break; case 11: -#line 2635 "upb/json/parser.rl" +#line 2621 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_year(parser, p)); } break; case 12: -#line 2639 "upb/json/parser.rl" +#line 2625 "upb/json/parser.rl" { start_month(parser, p); } break; case 13: -#line 2640 "upb/json/parser.rl" +#line 2626 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_month(parser, p)); } break; case 14: -#line 2644 "upb/json/parser.rl" +#line 2630 "upb/json/parser.rl" { start_day(parser, p); } break; case 15: -#line 2645 "upb/json/parser.rl" +#line 2631 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_day(parser, p)); } break; case 16: -#line 2649 "upb/json/parser.rl" +#line 2635 "upb/json/parser.rl" { start_hour(parser, p); } break; case 17: -#line 2650 "upb/json/parser.rl" +#line 2636 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_hour(parser, p)); } break; case 18: -#line 2654 "upb/json/parser.rl" +#line 2640 "upb/json/parser.rl" { start_minute(parser, p); } break; case 19: -#line 2655 "upb/json/parser.rl" +#line 2641 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_minute(parser, p)); } break; case 20: -#line 2659 "upb/json/parser.rl" +#line 2645 "upb/json/parser.rl" { start_second(parser, p); } break; case 21: -#line 2660 "upb/json/parser.rl" +#line 2646 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_second(parser, p)); } break; case 22: -#line 2665 "upb/json/parser.rl" +#line 2651 "upb/json/parser.rl" { start_duration_base(parser, p); } break; case 23: -#line 2666 "upb/json/parser.rl" +#line 2652 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_duration_base(parser, p)); } break; case 24: -#line 2668 "upb/json/parser.rl" +#line 2654 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 25: -#line 2673 "upb/json/parser.rl" +#line 2659 "upb/json/parser.rl" { start_timestamp_base(parser); } break; case 26: -#line 2675 "upb/json/parser.rl" +#line 2661 "upb/json/parser.rl" { start_timestamp_fraction(parser, p); } break; case 27: -#line 2676 "upb/json/parser.rl" +#line 2662 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); } break; case 28: -#line 2678 "upb/json/parser.rl" +#line 2664 "upb/json/parser.rl" { start_timestamp_zone(parser, p); } break; case 29: -#line 2679 "upb/json/parser.rl" +#line 2665 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); } break; case 30: -#line 2681 "upb/json/parser.rl" +#line 2667 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 31: -#line 2686 "upb/json/parser.rl" +#line 2672 "upb/json/parser.rl" { start_fieldmask_path_text(parser, p); } break; case 32: -#line 2687 "upb/json/parser.rl" +#line 2673 "upb/json/parser.rl" { end_fieldmask_path_text(parser, p); } break; case 33: -#line 2692 "upb/json/parser.rl" +#line 2678 "upb/json/parser.rl" { start_fieldmask_path(parser); } break; case 34: -#line 2693 "upb/json/parser.rl" +#line 2679 "upb/json/parser.rl" { end_fieldmask_path(parser); } break; case 35: -#line 2699 "upb/json/parser.rl" +#line 2685 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; case 36: -#line 2704 "upb/json/parser.rl" +#line 2690 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) { {stack[top++] = cs; cs = 47;goto _again;} @@ -11510,11 +12043,11 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 37: -#line 2717 "upb/json/parser.rl" +#line 2703 "upb/json/parser.rl" { p--; {stack[top++] = cs; cs = 78;goto _again;} } break; case 38: -#line 2722 "upb/json/parser.rl" +#line 2708 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_member(parser, p); @@ -11524,11 +12057,11 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 39: -#line 2729 "upb/json/parser.rl" +#line 2715 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_membername(parser)); } break; case 40: -#line 2732 "upb/json/parser.rl" +#line 2718 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { end_any_member(parser, p); @@ -11538,7 +12071,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 41: -#line 2743 "upb/json/parser.rl" +#line 2729 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { start_any_object(parser, p); @@ -11548,7 +12081,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 42: -#line 2752 "upb/json/parser.rl" +#line 2738 "upb/json/parser.rl" { if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) { CHECK_RETURN_TOP(end_any_object(parser, p)); @@ -11558,54 +12091,54 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, } break; case 43: -#line 2764 "upb/json/parser.rl" +#line 2750 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_array(parser)); } break; case 44: -#line 2768 "upb/json/parser.rl" +#line 2754 "upb/json/parser.rl" { end_array(parser); } break; case 45: -#line 2773 "upb/json/parser.rl" +#line 2759 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_number(parser, p)); } break; case 46: -#line 2774 "upb/json/parser.rl" +#line 2760 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 47: -#line 2776 "upb/json/parser.rl" +#line 2762 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_stringval(parser)); } break; case 48: -#line 2777 "upb/json/parser.rl" +#line 2763 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_stringval(parser)); } break; case 49: -#line 2779 "upb/json/parser.rl" +#line 2765 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 50: -#line 2781 "upb/json/parser.rl" +#line 2767 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 51: -#line 2783 "upb/json/parser.rl" +#line 2769 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 52: -#line 2785 "upb/json/parser.rl" +#line 2771 "upb/json/parser.rl" { CHECK_RETURN_TOP(start_subobject_full(parser)); } break; case 53: -#line 2786 "upb/json/parser.rl" +#line 2772 "upb/json/parser.rl" { end_subobject_full(parser); } break; case 54: -#line 2791 "upb/json/parser.rl" +#line 2777 "upb/json/parser.rl" { p--; {cs = stack[--top]; goto _again;} } break; -#line 3199 "upb/json/parser.c" +#line 3185 "upb/json/parser.c" } } @@ -11622,32 +12155,32 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size, while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 0: -#line 2600 "upb/json/parser.rl" +#line 2586 "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" +#line 2760 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_number(parser, p)); } break; case 49: -#line 2779 "upb/json/parser.rl" +#line 2765 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, true)); } break; case 50: -#line 2781 "upb/json/parser.rl" +#line 2767 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_bool(parser, false)); } break; case 51: -#line 2783 "upb/json/parser.rl" +#line 2769 "upb/json/parser.rl" { CHECK_RETURN_TOP(end_null(parser)); } break; case 53: -#line 2786 "upb/json/parser.rl" +#line 2772 "upb/json/parser.rl" { end_subobject_full(parser); } break; -#line 3241 "upb/json/parser.c" +#line 3227 "upb/json/parser.c" } } } @@ -11655,7 +12188,7 @@ goto _again;} } _out: {} } -#line 2819 "upb/json/parser.rl" +#line 2805 "upb/json/parser.rl" if (p != pe) { upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p); @@ -11698,13 +12231,13 @@ static void json_parser_reset(upb_json_parser *p) { /* Emit Ragel initialization of the parser. */ -#line 3292 "upb/json/parser.c" +#line 3278 "upb/json/parser.c" { cs = json_start; top = 0; } -#line 2861 "upb/json/parser.rl" +#line 2847 "upb/json/parser.rl" p->current_state = cs; p->parser_top = top; accumulate_clear(p); @@ -11735,15 +12268,13 @@ static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c, upb_msg_field_next(&i)) { const upb_fielddef *f = upb_msg_iter_field(&i); upb_value v = upb_value_constptr(f); - char *buf; + const char *name; /* 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); + name = upb_fielddef_jsonname(f); + upb_strtable_insert3(&m->name_table, name, strlen(name), v, alloc); - if (strcmp(buf, upb_fielddef_name(f)) != 0) { + if (strcmp(name, 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). */ @@ -11869,6 +12400,7 @@ const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c, #include +#include #include #include #include @@ -11926,12 +12458,8 @@ strpc *newstrpc(upb_handlers *h, const upb_fielddef *f, ret->ptr = upb_gstrdup(upb_fielddef_name(f)); ret->len = strlen(ret->ptr); } else { - size_t len; - ret->len = upb_fielddef_getjsonname(f, NULL, 0); - ret->ptr = upb_gmalloc(ret->len); - len = upb_fielddef_getjsonname(f, ret->ptr, ret->len); - UPB_ASSERT(len == ret->len); - ret->len--; /* NULL */ + ret->ptr = upb_gstrdup(upb_fielddef_jsonname(f)); + ret->len = strlen(ret->ptr); } upb_handlers_addcleanup(h, ret, freestrpc); @@ -11950,7 +12478,7 @@ strpc *newstrpc_str(upb_handlers *h, const char * str) { /* ------------ JSON string printing: values, maps, arrays ------------------ */ static void print_data( - upb_json_printer *p, const char *buf, unsigned int len) { + upb_json_printer *p, const char *buf, size_t len) { /* TODO: Will need to change if we support pushback from the sink. */ size_t n = upb_bytessink_putbuf(p->output_, p->subc_, buf, len, NULL); UPB_ASSERT(n == len); @@ -11990,7 +12518,7 @@ UPB_INLINE const char* json_nice_escape(char c) { /* Write a properly escaped string chunk. The surrounding quotes are *not* * printed; this is so that the caller has the option of emitting the string * content in chunks. */ -static void putstring(upb_json_printer *p, const char *buf, unsigned int len) { +static void putstring(upb_json_printer *p, const char *buf, size_t len) { const char* unescaped_run = NULL; unsigned int i; for (i = 0; i < len; i++) { @@ -12070,28 +12598,26 @@ static size_t fmt_bool(bool val, char* buf, size_t length) { return n; } -static size_t fmt_int64_as_number(long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%lld", val); +static size_t fmt_int64_as_number(int64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "%" PRId64, val); CHKLENGTH(n > 0 && n < length); return n; } -static size_t fmt_uint64_as_number( - unsigned long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "%llu", val); +static size_t fmt_uint64_as_number(uint64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "%" PRIu64, val); CHKLENGTH(n > 0 && n < length); return n; } -static size_t fmt_int64_as_string(long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "\"%lld\"", val); +static size_t fmt_int64_as_string(int64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "\"%" PRId64 "\"", val); CHKLENGTH(n > 0 && n < length); return n; } -static size_t fmt_uint64_as_string( - unsigned long long val, char* buf, size_t length) { - size_t n = _upb_snprintf(buf, length, "\"%llu\"", val); +static size_t fmt_uint64_as_string(uint64_t val, char* buf, size_t length) { + size_t n = _upb_snprintf(buf, length, "\"%" PRIu64 "\"", val); CHKLENGTH(n > 0 && n < length); return n; } @@ -13268,8 +13794,9 @@ upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames) { } /* See port_def.inc. This should #undef all macros #defined there. */ +#undef UPB_MAPTYPE_STRING #undef UPB_SIZE -#undef UPB_FIELD_AT +#undef UPB_PTR_AT #undef UPB_READ_ONEOF #undef UPB_WRITE_ONEOF #undef UPB_INLINE @@ -13279,6 +13806,7 @@ upb_handlercache *upb_json_printer_newcache(bool preserve_proto_fieldnames) { #undef UPB_MAX #undef UPB_MIN #undef UPB_UNUSED +#undef UPB_ASSUME #undef UPB_ASSERT #undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE diff --git a/ruby/ext/google/protobuf_c/upb.h b/ruby/ext/google/protobuf_c/upb.h index 24943eed9086..b7da76fa0018 100644 --- a/ruby/ext/google/protobuf_c/upb.h +++ b/ruby/ext/google/protobuf_c/upb.h @@ -21,9 +21,7 @@ * * This file is private and must not be included by users! */ -#ifndef UINTPTR_MAX -#error must include stdint.h first -#endif +#include #if UINTPTR_MAX == 0xffffffff #define UPB_SIZE(size32, size64) size32 @@ -31,17 +29,21 @@ #define UPB_SIZE(size32, size64) size64 #endif -#define UPB_FIELD_AT(msg, fieldtype, offset) \ - *(fieldtype*)((const char*)(msg) + offset) +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \ - UPB_FIELD_AT(msg, int, case_offset) == case_val \ - ? UPB_FIELD_AT(msg, fieldtype, offset) \ + *UPB_PTR_AT(msg, case_offset, int) == case_val \ + ? *UPB_PTR_AT(msg, offset, fieldtype) \ : default #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \ - UPB_FIELD_AT(msg, int, case_offset) = case_val; \ - UPB_FIELD_AT(msg, fieldtype, offset) = value; + *UPB_PTR_AT(msg, case_offset, int) = case_val; \ + *UPB_PTR_AT(msg, offset, fieldtype) = value; + +#define UPB_MAPTYPE_STRING 0 /* UPB_INLINE: inline if possible, emit standalone code if required. */ #ifdef __cplusplus @@ -115,7 +117,7 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #ifdef __cplusplus #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \ (defined(_MSC_VER) && _MSC_VER >= 1900) -// C++11 is present +/* C++11 is present */ #else #error upb requires C++11 for C++ support #endif @@ -126,6 +128,18 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_UNUSED(var) (void)var +/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. + */ +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable() +#else +#define UPB_ASSUME(expr) do {} if (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + /* UPB_ASSERT(): in release mode, we use the expression without letting it be * evaluated. This prevents "unused variable" warnings. */ #ifdef NDEBUG @@ -152,10 +166,51 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_INFINITY (1.0 / 0.0) #endif /* -** This file contains shared definitions that are widely used across upb. +** upb_decode: parsing into a upb_msg using a upb_msglayout. +*/ + +#ifndef UPB_DECODE_H_ +#define UPB_DECODE_H_ + +/* +** Our memory representation for parsing tables and messages themselves. +** Functions in this file are used by generated code and possibly reflection. ** -** This is a mixed C/C++ interface that offers a full API to both languages. -** See the top-level README for more information. +** The definitions in this file are internal to upb. +**/ + +#ifndef UPB_MSG_H_ +#define UPB_MSG_H_ + +#include +#include + +/* +** upb_table +** +** This header is INTERNAL-ONLY! Its interfaces are not public or stable! +** This file defines very fast int->upb_value (inttable) and string->upb_value +** (strtable) hash tables. +** +** The table uses chained scatter with Brent's variation (inspired by the Lua +** implementation of hash tables). The hash function for strings is Austin +** Appleby's "MurmurHash." +** +** The inttable uses uintptr_t as its key, which guarantees it can be used to +** store pointers or integers of at least 32 bits (upb isn't really useful on +** systems where sizeof(void*) < 4). +** +** The table must be homogeneous (all values of the same type). In debug +** mode, we check this on insert and lookup. +*/ + +#ifndef UPB_TABLE_H_ +#define UPB_TABLE_H_ + +#include +#include +/* +** This file contains shared definitions that are widely used across upb. */ #ifndef UPB_H_ @@ -168,23 +223,13 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #include #include + #ifdef __cplusplus -#include -namespace upb { -class Arena; -class Status; -template class InlinedArena; -} +extern "C" { #endif - /* upb_status *****************************************************************/ -/* upb_status represents a success or failure status and error message. - * It owns no resources and allocates no memory, so it should work - * even in OOM situations. */ - -/* The maximum length of an error message before it will get truncated. */ #define UPB_STATUS_MAX_MESSAGE 127 typedef struct { @@ -192,59 +237,15 @@ typedef struct { char msg[UPB_STATUS_MAX_MESSAGE]; /* Error message; NULL-terminated. */ } upb_status; -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_status_errmsg(const upb_status *status); bool upb_ok(const upb_status *status); -/* Any of the functions that write to a status object allow status to be NULL, - * to support use cases where the function's caller does not care about the - * status message. */ +/* These are no-op if |status| is NULL. */ void upb_status_clear(upb_status *status); void upb_status_seterrmsg(upb_status *status, const char *msg); void upb_status_seterrf(upb_status *status, const char *fmt, ...); void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args); -UPB_INLINE void upb_status_setoom(upb_status *status) { - upb_status_seterrmsg(status, "out of memory"); -} - -#ifdef __cplusplus -} /* extern "C" */ - -class upb::Status { - public: - Status() { upb_status_clear(&status_); } - - upb_status* ptr() { return &status_; } - - /* Returns true if there is no error. */ - bool ok() const { return upb_ok(&status_); } - - /* Guaranteed to be NULL-terminated. */ - const char *error_message() const { return upb_status_errmsg(&status_); } - - /* The error message will be truncated if it is longer than - * UPB_STATUS_MAX_MESSAGE-4. */ - void SetErrorMessage(const char *msg) { upb_status_seterrmsg(&status_, msg); } - void SetFormattedErrorMessage(const char *fmt, ...) { - va_list args; - va_start(args, fmt); - upb_status_vseterrf(&status_, fmt, args); - va_end(args); - } - - /* Resets the status to a successful state with no message. */ - void Clear() { upb_status_clear(&status_); } - - private: - upb_status status_; -}; - -#endif /* __cplusplus */ - /** upb_strview ************************************************************/ typedef struct { @@ -311,16 +312,8 @@ UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr) { /* The global allocator used by upb. Uses the standard malloc()/free(). */ -#ifdef __cplusplus -extern "C" { -#endif - extern upb_alloc upb_alloc_global; -#ifdef __cplusplus -} /* extern "C" */ -#endif - /* Functions that hard-code the global malloc. * * We still get benefit because we can put custom logic into our global @@ -357,9 +350,18 @@ typedef void upb_cleanup_func(void *ud); struct upb_arena; typedef struct upb_arena upb_arena; -#ifdef __cplusplus -extern "C" { -#endif +typedef struct { + /* We implement the allocator interface. + * This must be the first member of upb_arena! */ + upb_alloc alloc; + + char *ptr, *end; +} _upb_arena_head; + +UPB_INLINE size_t _upb_arena_alignup(size_t size) { + const size_t maxalign = 16; + return ((size + maxalign - 1) / maxalign) * maxalign; +} /* Creates an arena from the given initial block (if any -- n may be 0). * Additional blocks will be allocated from |alloc|. If |alloc| is NULL, this @@ -368,82 +370,35 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc); void upb_arena_free(upb_arena *a); bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func); size_t upb_arena_bytesallocated(const upb_arena *a); +void *_upb_arena_slowmalloc(upb_arena *a, size_t size); UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; } -/* Convenience wrappers around upb_alloc functions. */ - UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) { - return upb_malloc(upb_arena_alloc(a), size); + _upb_arena_head *h = (_upb_arena_head*)a; + size = _upb_arena_alignup(size); + if (UPB_LIKELY((size_t)(h->end - h->ptr) >= size)) { + void* ret = h->ptr; + h->ptr += size; + return ret; + } else { + return _upb_arena_slowmalloc(a, size); + } } UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize, size_t size) { - return upb_realloc(upb_arena_alloc(a), ptr, oldsize, size); + if (oldsize == 0) { + return upb_arena_malloc(a, size); + } else { + return upb_realloc(upb_arena_alloc(a), ptr, oldsize, size); + } } UPB_INLINE upb_arena *upb_arena_new(void) { return upb_arena_init(NULL, 0, &upb_alloc_global); } -#ifdef __cplusplus -} /* extern "C" */ - -class upb::Arena { - public: - /* A simple arena with no initial memory block and the default allocator. */ - Arena() : ptr_(upb_arena_new(), upb_arena_free) {} - - upb_arena* ptr() { return ptr_.get(); } - - /* Allows this arena to be used as a generic allocator. - * - * The arena does not need free() calls so when using Arena as an allocator - * it is safe to skip them. However they are no-ops so there is no harm in - * calling free() either. */ - upb_alloc *allocator() { return upb_arena_alloc(ptr_.get()); } - - /* Add a cleanup function to run when the arena is destroyed. - * Returns false on out-of-memory. */ - bool AddCleanup(void *ud, upb_cleanup_func* func) { - return upb_arena_addcleanup(ptr_.get(), ud, func); - } - - /* Total number of bytes that have been allocated. It is undefined what - * Realloc() does to &arena_ counter. */ - size_t BytesAllocated() const { return upb_arena_bytesallocated(ptr_.get()); } - - private: - std::unique_ptr ptr_; -}; - -#endif - -/* upb::InlinedArena **********************************************************/ - -/* upb::InlinedArena seeds the arenas with a predefined amount of memory. No - * heap memory will be allocated until the initial block is exceeded. - * - * These types only exist in C++ */ - -#ifdef __cplusplus - -template class upb::InlinedArena : public upb::Arena { - public: - InlinedArena() : ptr_(upb_arena_new(&initial_block_, N, &upb_alloc_global)) {} - - upb_arena* ptr() { return ptr_.get(); } - - private: - InlinedArena(const InlinedArena*) = delete; - InlinedArena& operator=(const InlinedArena*) = delete; - - std::unique_ptr ptr_; - char initial_block_[N]; -}; - -#endif /* __cplusplus */ - /* Constants ******************************************************************/ /* Generic function type. */ @@ -463,21 +418,17 @@ typedef enum { * types defined in descriptor.proto, which gives INT32 and SINT32 separate * types (we distinguish the two with the "integer encoding" enum below). */ typedef enum { - /* Types stored in 1 byte. */ UPB_TYPE_BOOL = 1, - /* Types stored in 4 bytes. */ UPB_TYPE_FLOAT = 2, UPB_TYPE_INT32 = 3, UPB_TYPE_UINT32 = 4, UPB_TYPE_ENUM = 5, /* Enum values are int32. */ - /* Types stored as pointers (probably 4 or 8 bytes). */ - UPB_TYPE_STRING = 6, - UPB_TYPE_BYTES = 7, - UPB_TYPE_MESSAGE = 8, - /* Types stored as 8 bytes. */ - UPB_TYPE_DOUBLE = 9, - UPB_TYPE_INT64 = 10, - UPB_TYPE_UINT64 = 11 + UPB_TYPE_MESSAGE = 6, + UPB_TYPE_DOUBLE = 7, + UPB_TYPE_INT64 = 8, + UPB_TYPE_UINT64 = 9, + UPB_TYPE_STRING = 10, + UPB_TYPE_BYTES = 11 } upb_fieldtype_t; /* The repeated-ness of each field; this matches descriptor.proto. */ @@ -489,6 +440,7 @@ typedef enum { /* Descriptor types, as defined in descriptor.proto. */ typedef enum { + /* Old (long) names. TODO(haberman): remove */ UPB_DESCRIPTOR_TYPE_DOUBLE = 1, UPB_DESCRIPTOR_TYPE_FLOAT = 2, UPB_DESCRIPTOR_TYPE_INT64 = 3, @@ -506,145 +458,36 @@ typedef enum { UPB_DESCRIPTOR_TYPE_SFIXED32 = 15, UPB_DESCRIPTOR_TYPE_SFIXED64 = 16, UPB_DESCRIPTOR_TYPE_SINT32 = 17, - UPB_DESCRIPTOR_TYPE_SINT64 = 18 + UPB_DESCRIPTOR_TYPE_SINT64 = 18, + + UPB_DTYPE_DOUBLE = 1, + UPB_DTYPE_FLOAT = 2, + UPB_DTYPE_INT64 = 3, + UPB_DTYPE_UINT64 = 4, + UPB_DTYPE_INT32 = 5, + UPB_DTYPE_FIXED64 = 6, + UPB_DTYPE_FIXED32 = 7, + UPB_DTYPE_BOOL = 8, + UPB_DTYPE_STRING = 9, + UPB_DTYPE_GROUP = 10, + UPB_DTYPE_MESSAGE = 11, + UPB_DTYPE_BYTES = 12, + UPB_DTYPE_UINT32 = 13, + UPB_DTYPE_ENUM = 14, + UPB_DTYPE_SFIXED32 = 15, + UPB_DTYPE_SFIXED64 = 16, + UPB_DTYPE_SINT32 = 17, + UPB_DTYPE_SINT64 = 18 } upb_descriptortype_t; -extern const uint8_t upb_desctype_to_fieldtype[]; - - -#endif /* UPB_H_ */ -/* -** upb_decode: parsing into a upb_msg using a upb_msglayout. -*/ - -#ifndef UPB_DECODE_H_ -#define UPB_DECODE_H_ - -/* -** Data structures for message tables, used for parsing and serialization. -** This are much lighter-weight than full reflection, but they are do not -** have enough information to convert to text format, JSON, etc. -** -** The definitions in this file are internal to upb. -**/ - -#ifndef UPB_MSG_H_ -#define UPB_MSG_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void upb_msg; - -/** upb_msglayout *************************************************************/ - -/* upb_msglayout represents the memory layout of a given upb_msgdef. The - * members are public so generated code can initialize them, but users MUST NOT - * read or write any of its members. */ - -typedef struct { - uint32_t number; - uint16_t offset; - int16_t presence; /* If >0, hasbit_index+1. If <0, oneof_index+1. */ - uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */ - uint8_t descriptortype; - uint8_t label; -} upb_msglayout_field; - -typedef struct upb_msglayout { - const struct upb_msglayout *const* submsgs; - const upb_msglayout_field *fields; - /* Must be aligned to sizeof(void*). Doesn't include internal members like - * unknown fields, extension dict, pointer to msglayout, etc. */ - uint16_t size; - uint16_t field_count; - bool extendable; -} upb_msglayout; - -/** Message internal representation *******************************************/ - -/* Our internal representation for repeated fields. */ -typedef struct { - void *data; /* Each element is element_size. */ - size_t len; /* Measured in elements. */ - size_t size; /* Measured in elements. */ -} upb_array; - -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a); -upb_msg *upb_msg_new(const upb_msglayout *l, upb_arena *a); - -void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, - upb_arena *arena); -const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); - -upb_array *upb_array_new(upb_arena *a); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_MSG_H_ */ - -#ifdef __cplusplus -extern "C" { -#endif - -bool upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_DECODE_H_ */ -/* -** upb_encode: parsing into a upb_msg using a upb_msglayout. -*/ - -#ifndef UPB_ENCODE_H_ -#define UPB_ENCODE_H_ - - -#ifdef __cplusplus -extern "C" { -#endif +#define UPB_MAP_BEGIN -1 -char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena, - size_t *size); #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* UPB_ENCODE_H_ */ -/* -** upb_table -** -** This header is INTERNAL-ONLY! Its interfaces are not public or stable! -** This file defines very fast int->upb_value (inttable) and string->upb_value -** (strtable) hash tables. -** -** The table uses chained scatter with Brent's variation (inspired by the Lua -** implementation of hash tables). The hash function for strings is Austin -** Appleby's "MurmurHash." -** -** The inttable uses uintptr_t as its key, which guarantees it can be used to -** store pointers or integers of at least 32 bits (upb isn't really useful on -** systems where sizeof(void*) < 4). -** -** The table must be homogenous (all values of the same type). In debug -** mode, we check this on insert and lookup. -*/ - -#ifndef UPB_TABLE_H_ -#define UPB_TABLE_H_ - -#include -#include +#endif /* UPB_H_ */ #ifdef __cplusplus @@ -673,19 +516,8 @@ typedef enum { typedef struct { uint64_t val; -#ifndef NDEBUG - /* In debug mode we carry the value type around also so we can check accesses - * to be sure the right member is being read. */ - upb_ctype_t ctype; -#endif } upb_value; -#ifdef NDEBUG -#define SET_TYPE(dest, val) UPB_UNUSED(val) -#else -#define SET_TYPE(dest, val) dest = val -#endif - /* Like strdup(), which isn't always available since it's not ANSI C. */ char *upb_strdup(const char *s, upb_alloc *a); /* Variant that works with a length-delimited rather than NULL-delimited string, @@ -696,15 +528,13 @@ UPB_INLINE char *upb_gstrdup(const char *s) { return upb_strdup(s, &upb_alloc_global); } -UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val, - upb_ctype_t ctype) { +UPB_INLINE void _upb_value_setval(upb_value *v, uint64_t val) { v->val = val; - SET_TYPE(v->ctype, ctype); } -UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) { +UPB_INLINE upb_value _upb_value_val(uint64_t val) { upb_value ret; - _upb_value_setval(&ret, val, ctype); + _upb_value_setval(&ret, val); return ret; } @@ -719,7 +549,6 @@ UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) { #define FUNCS(name, membername, type_t, converter, proto_type) \ UPB_INLINE void upb_value_set ## name(upb_value *val, type_t cval) { \ val->val = (converter)cval; \ - SET_TYPE(val->ctype, proto_type); \ } \ UPB_INLINE upb_value upb_value_ ## name(type_t val) { \ upb_value ret; \ @@ -727,7 +556,6 @@ UPB_INLINE upb_value _upb_value_val(uint64_t val, upb_ctype_t ctype) { return ret; \ } \ UPB_INLINE type_t upb_value_get ## name(upb_value val) { \ - UPB_ASSERT_DEBUGVAR(val.ctype == proto_type); \ return (type_t)(converter)val.val; \ } @@ -745,12 +573,10 @@ FUNCS(fptr, fptr, upb_func*, uintptr_t, UPB_CTYPE_FPTR) UPB_INLINE void upb_value_setfloat(upb_value *val, float cval) { memcpy(&val->val, &cval, sizeof(cval)); - SET_TYPE(val->ctype, UPB_CTYPE_FLOAT); } UPB_INLINE void upb_value_setdouble(upb_value *val, double cval) { memcpy(&val->val, &cval, sizeof(cval)); - SET_TYPE(val->ctype, UPB_CTYPE_DOUBLE); } UPB_INLINE upb_value upb_value_float(float cval) { @@ -794,7 +620,6 @@ typedef struct { #define UPB_TABVALUE_EMPTY_INIT {-1} - /* upb_table ******************************************************************/ typedef struct _upb_tabent { @@ -811,7 +636,6 @@ typedef struct _upb_tabent { typedef struct { size_t count; /* Number of entries in the hash part. */ size_t mask; /* Mask to turn hash value -> bucket. */ - upb_ctype_t ctype; /* Type of all values. */ uint8_t size_lg2; /* Size of the hashtable part is 2^size_lg2 entries. */ /* Hash table entries. @@ -821,17 +645,6 @@ typedef struct { * initialize const hash tables. Then we cast away const when we have to. */ const upb_tabent *entries; - -#ifndef NDEBUG - /* This table's allocator. We make the user pass it in to every relevant - * function and only use this to check it in debug mode. We do this solely - * to keep upb_table as small as possible. This might seem slightly paranoid - * but the plan is to use upb_table for all map fields and extension sets in - * a forthcoming message representation, so there could be a lot of these. - * If this turns out to be too annoying later, we can change it (since this - * is an internal-only header file). */ - upb_alloc *alloc; -#endif } upb_table; typedef struct { @@ -845,12 +658,6 @@ typedef struct { size_t array_count; /* Array part number of elements. */ } upb_inttable; -#define UPB_INTTABLE_INIT(count, mask, ctype, size_lg2, ent, a, asize, acount) \ - {UPB_TABLE_INIT(count, mask, ctype, size_lg2, ent), a, asize, acount} - -#define UPB_EMPTY_INTTABLE_INIT(ctype) \ - UPB_INTTABLE_INIT(0, 0, ctype, 0, NULL, NULL, 0, 0) - #define UPB_ARRAY_EMPTYENT -1 UPB_INLINE size_t upb_table_size(const upb_table *t) { @@ -919,6 +726,7 @@ upb_inttable *upb_inttable_pack(const upb_inttable *t, void *p, size_t *ofs, size_t size); upb_strtable *upb_strtable_pack(const upb_strtable *t, void *p, size_t *ofs, size_t size); +void upb_strtable_clear(upb_strtable *t); /* Inserts the given key into the hashtable with the given value. The key must * not already exist in the hash table. For string tables, the key must be @@ -1020,7 +828,7 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key, if (key < t->array_size) { upb_tabval arrval = t->array[key]; if (upb_arrhas(arrval)) { - _upb_value_setval(v, arrval.val, t->t.ctype); + _upb_value_setval(v, arrval.val); return true; } else { return false; @@ -1030,7 +838,7 @@ UPB_INLINE bool upb_inttable_lookup32(const upb_inttable *t, uint32_t key, if (t->t.entries == NULL) return false; for (e = upb_getentry(&t->t, upb_inthash(key)); true; e = e->next) { if ((uint32_t)e->key == key) { - _upb_value_setval(v, e->val.val, t->t.ctype); + _upb_value_setval(v, e->val.val); return true; } if (e->next == NULL) return false; @@ -1084,8 +892,7 @@ typedef struct { void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t); void upb_strtable_next(upb_strtable_iter *i); bool upb_strtable_done(const upb_strtable_iter *i); -const char *upb_strtable_iter_key(const upb_strtable_iter *i); -size_t upb_strtable_iter_keylength(const upb_strtable_iter *i); +upb_strview upb_strtable_iter_key(const upb_strtable_iter *i); upb_value upb_strtable_iter_value(const upb_strtable_iter *i); void upb_strtable_iter_setdone(upb_strtable_iter *i); bool upb_strtable_iter_isequal(const upb_strtable_iter *i1, @@ -1109,6 +916,10 @@ typedef struct { bool array_part; } upb_inttable_iter; +UPB_INLINE const upb_tabent *str_tabent(const upb_strtable_iter *i) { + return &i->t->t.entries[i->index]; +} + void upb_inttable_begin(upb_inttable_iter *i, const upb_inttable *t); void upb_inttable_next(upb_inttable_iter *i); bool upb_inttable_done(const upb_inttable_iter *i); @@ -1125,36 +936,140 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1, #endif /* UPB_TABLE_H_ */ -/* 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_ -/* -** Functions for use by generated code. These are not public and users must -** not call them directly. -*/ +#ifdef __cplusplus +extern "C" { +#endif + +#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) -#ifndef UPB_GENERATED_UTIL_H_ -#define UPB_GENERATED_UTIL_H_ +typedef void upb_msg; -#include +/** upb_msglayout *************************************************************/ +/* upb_msglayout represents the memory layout of a given upb_msgdef. The + * members are public so generated code can initialize them, but users MUST NOT + * read or write any of its members. */ -#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) +/* These aren't real labels according to descriptor.proto, but in the table we + * use these for map/packed fields instead of UPB_LABEL_REPEATED. */ +enum { + _UPB_LABEL_MAP = 4, + _UPB_LABEL_PACKED = 7 /* Low 3 bits are common with UPB_LABEL_REPEATED. */ +}; + +typedef struct { + uint32_t number; + uint16_t offset; + int16_t presence; /* If >0, hasbit_index. If <0, -oneof_index. */ + uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */ + uint8_t descriptortype; + uint8_t label; +} upb_msglayout_field; + +typedef struct upb_msglayout { + const struct upb_msglayout *const* submsgs; + const upb_msglayout_field *fields; + /* Must be aligned to sizeof(void*). Doesn't include internal members like + * unknown fields, extension dict, pointer to msglayout, etc. */ + uint16_t size; + uint16_t field_count; + bool extendable; +} upb_msglayout; + +/** upb_msg *******************************************************************/ + +/* Internal members of a upb_msg. We can change this without breaking binary + * compatibility. We put these before the user's data. The user's upb_msg* + * points after the upb_msg_internal. */ + +/* Used when a message is not extendable. */ +typedef struct { + char *unknown; + size_t unknown_len; + size_t unknown_size; +} upb_msg_internal; + +/* Used when a message is extendable. */ +typedef struct { + upb_inttable *extdict; + upb_msg_internal base; +} upb_msg_internal_withext; + +/* Maps upb_fieldtype_t -> memory size. */ +extern char _upb_fieldtype_to_size[12]; + +/* Creates a new messages with the given layout on the given arena. */ +upb_msg *_upb_msg_new(const upb_msglayout *l, upb_arena *a); + +/* Adds unknown data (serialized protobuf data) to the given message. The data + * is copied into the message instance. */ +bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena); + +/* Returns a reference to the message's unknown data. */ +const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); + +UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; +} + +UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); +} + +UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) { + return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); +} + +UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) { + return *PTR_AT(msg, case_ofs, int32_t) == num; +} + +UPB_INLINE bool _upb_has_submsg_nohasbit(const void *msg, size_t ofs) { + return *PTR_AT(msg, ofs, const void*) != NULL; +} + +UPB_INLINE bool _upb_isrepeated(const upb_msglayout_field *field) { + return (field->label & 3) == UPB_LABEL_REPEATED; +} + +/** upb_array *****************************************************************/ + +/* Our internal representation for repeated fields. */ +typedef struct { + uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ + size_t len; /* Measured in elements. */ + size_t size; /* Measured in elements. */ +} upb_array; + +UPB_INLINE const void *_upb_array_constptr(const upb_array *arr) { + return (void*)(arr->data & ~(uintptr_t)7); +} + +UPB_INLINE void *_upb_array_ptr(upb_array *arr) { + return (void*)_upb_array_constptr(arr); +} + +/* Creates a new array on the given arena. */ +upb_array *_upb_array_new(upb_arena *a, upb_fieldtype_t type); + +/* Resizes the capacity of the array to be at least min_size. */ +bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena); + +/* Fallback functions for when the accessors require a resize. */ +void *_upb_array_resize_fallback(upb_array **arr_ptr, size_t size, + upb_fieldtype_t type, upb_arena *arena); +bool _upb_array_append_fallback(upb_array **arr_ptr, const void *value, + upb_fieldtype_t type, upb_arena *arena); UPB_INLINE const void *_upb_array_accessor(const void *msg, size_t ofs, size_t *size) { const upb_array *arr = *PTR_AT(msg, ofs, const upb_array*); if (arr) { if (size) *size = arr->len; - return arr->data; + return _upb_array_constptr(arr); } else { if (size) *size = 0; return NULL; @@ -1166,78 +1081,295 @@ UPB_INLINE void *_upb_array_mutable_accessor(void *msg, size_t ofs, upb_array *arr = *PTR_AT(msg, ofs, upb_array*); if (arr) { if (size) *size = arr->len; - return arr->data; + return _upb_array_ptr(arr); } else { if (size) *size = 0; return NULL; } } -/* TODO(haberman): this is a mess. It will improve when upb_array no longer - * carries reflective state (type, elem_size). */ UPB_INLINE void *_upb_array_resize_accessor(void *msg, size_t ofs, size_t size, - size_t elem_size, upb_fieldtype_t type, upb_arena *arena) { - upb_array *arr = *PTR_AT(msg, ofs, upb_array*); - - if (!arr) { - arr = upb_array_new(arena); - if (!arr) return NULL; - *PTR_AT(msg, ofs, upb_array*) = arr; - } - - if (size > arr->size) { - size_t new_size = UPB_MAX(arr->size, 4); - size_t old_bytes = arr->size * elem_size; - size_t new_bytes; - while (new_size < size) new_size *= 2; - new_bytes = new_size * elem_size; - arr->data = upb_arena_realloc(arena, arr->data, old_bytes, new_bytes); - if (!arr->data) { - return NULL; - } - arr->size = new_size; + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*); + upb_array *arr = *arr_ptr; + if (!arr || arr->size < size) { + return _upb_array_resize_fallback(arr_ptr, size, type, arena); } - arr->len = size; - return arr->data; + return _upb_array_ptr(arr); } + UPB_INLINE bool _upb_array_append_accessor(void *msg, size_t ofs, size_t elem_size, upb_fieldtype_t type, const void *value, upb_arena *arena) { - upb_array *arr = *PTR_AT(msg, ofs, upb_array*); - size_t i = arr ? arr->len : 0; - void *data = - _upb_array_resize_accessor(msg, ofs, i + 1, elem_size, type, arena); - if (!data) return false; - memcpy(PTR_AT(data, i * elem_size, char), value, elem_size); + upb_array **arr_ptr = PTR_AT(msg, ofs, upb_array*); + upb_array *arr = *arr_ptr; + void* ptr; + if (!arr || arr->len == arr->size) { + return _upb_array_append_fallback(arr_ptr, value, type, arena); + } + ptr = _upb_array_ptr(arr); + memcpy(PTR_AT(ptr, arr->len * elem_size, char), value, elem_size); + arr->len++; return true; } -UPB_INLINE bool _upb_has_field(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0; +/** upb_map *******************************************************************/ + +/* Right now we use strmaps for everything. We'll likely want to use + * integer-specific maps for integer-keyed maps.*/ +typedef struct { + /* Size of key and val, based on the map type. Strings are represented as '0' + * because they must be handled specially. */ + char key_size; + char val_size; + + upb_strtable table; +} upb_map; + +/* Map entries aren't actually stored, they are only used during parsing. For + * parsing, it helps a lot if all map entry messages have the same layout. + * The compiler and def.c must ensure that all map entries have this layout. */ +typedef struct { + upb_msg_internal internal; + union { + upb_strview str; /* For str/bytes. */ + upb_value val; /* For all other types. */ + } k; + union { + upb_strview str; /* For str/bytes. */ + upb_value val; /* For all other types. */ + } v; +} upb_map_entry; + +/* Creates a new map on the given arena with this key/value type. */ +upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size); + +/* Converting between internal table representation and user values. + * + * _upb_map_tokey() and _upb_map_fromkey() are inverses. + * _upb_map_tovalue() and _upb_map_fromvalue() are inverses. + * + * These functions account for the fact that strings are treated differently + * from other types when stored in a map. + */ + +UPB_INLINE upb_strview _upb_map_tokey(const void *key, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + return *(upb_strview*)key; + } else { + return upb_strview_make((const char*)key, size); + } } -UPB_INLINE bool _upb_sethas(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8)); +UPB_INLINE void _upb_map_fromkey(upb_strview key, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + memcpy(out, &key, sizeof(key)); + } else { + memcpy(out, key.data, size); + } } -UPB_INLINE bool _upb_clearhas(const void *msg, size_t idx) { - return (*PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8))); +UPB_INLINE upb_value _upb_map_tovalue(const void *val, size_t size, + upb_arena *a) { + upb_value ret = {0}; + if (size == UPB_MAPTYPE_STRING) { + upb_strview *strp = (upb_strview*)upb_arena_malloc(a, sizeof(*strp)); + *strp = *(upb_strview*)val; + memcpy(&ret, &strp, sizeof(strp)); + } else { + memcpy(&ret, val, size); + } + return ret; } -UPB_INLINE bool _upb_has_oneof_field(const void *msg, size_t case_ofs, int32_t num) { - return *PTR_AT(msg, case_ofs, int32_t) == num; +UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + const upb_strview *strp = (const upb_strview*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_strview)); + } else { + memcpy(out, &val, size); + } +} + +/* Map operations, shared by reflection and generated code. */ + +UPB_INLINE size_t _upb_map_size(const upb_map *map) { + return map->table.t.count; +} + +UPB_INLINE bool _upb_map_get(const upb_map *map, const void *key, + size_t key_size, void *val, size_t val_size) { + upb_value tabval; + upb_strview k = _upb_map_tokey(key, key_size); + bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval); + if (ret) { + _upb_map_fromvalue(tabval, val, val_size); + } + return ret; +} + +UPB_INLINE void* _upb_map_next(const upb_map *map, size_t *iter) { + upb_strtable_iter it; + it.t = &map->table; + it.index = *iter; + upb_strtable_next(&it); + if (upb_strtable_done(&it)) return NULL; + *iter = it.index; + return (void*)str_tabent(&it); +} + +UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size, + void *val, size_t val_size, upb_arena *arena) { + upb_strview strkey = _upb_map_tokey(key, key_size); + upb_value tabval = _upb_map_tovalue(val, val_size, arena); + upb_alloc *a = upb_arena_alloc(arena); + + /* TODO(haberman): add overwrite operation to minimize number of lookups. */ + upb_strtable_remove3(&map->table, strkey.data, strkey.size, NULL, a); + return upb_strtable_insert3(&map->table, strkey.data, strkey.size, tabval, a); +} + +UPB_INLINE bool _upb_map_delete(upb_map *map, const void *key, size_t key_size) { + upb_strview k = _upb_map_tokey(key, key_size); + return upb_strtable_remove3(&map->table, k.data, k.size, NULL, NULL); +} + +UPB_INLINE void _upb_map_clear(upb_map *map) { + upb_strtable_clear(&map->table); +} + +/* Message map operations, these get the map from the message first. */ + +UPB_INLINE size_t _upb_msg_map_size(const upb_msg *msg, size_t ofs) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + return map ? _upb_map_size(map) : 0; +} + +UPB_INLINE bool _upb_msg_map_get(const upb_msg *msg, size_t ofs, + const void *key, size_t key_size, void *val, + size_t val_size) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return false; + return _upb_map_get(map, key, key_size, val, val_size); +} + +UPB_INLINE void *_upb_msg_map_next(const upb_msg *msg, size_t ofs, + size_t *iter) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return NULL; + return _upb_map_next(map, iter); +} + +UPB_INLINE bool _upb_msg_map_set(upb_msg *msg, size_t ofs, const void *key, + size_t key_size, void *val, size_t val_size, + upb_arena *arena) { + upb_map **map = PTR_AT(msg, ofs, upb_map *); + if (!*map) { + *map = _upb_map_new(arena, key_size, val_size); + } + return _upb_map_set(*map, key, key_size, val, val_size, arena); +} + +UPB_INLINE bool _upb_msg_map_delete(upb_msg *msg, size_t ofs, const void *key, + size_t key_size) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return false; + return _upb_map_delete(map, key, key_size); +} + +UPB_INLINE void _upb_msg_map_clear(upb_msg *msg, size_t ofs) { + upb_map *map = *UPB_PTR_AT(msg, ofs, upb_map *); + if (!map) return; + _upb_map_clear(map); +} + +/* Accessing map key/value from a pointer, used by generated code only. */ + +UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) { + const upb_tabent *ent = (const upb_tabent*)msg; + uint32_t u32len; + upb_strview k; + k.data = upb_tabstr(ent->key, &u32len); + k.size = u32len; + _upb_map_fromkey(k, key, size); +} + +UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) { + const upb_tabent *ent = (const upb_tabent*)msg; + upb_value v; + _upb_value_setval(&v, ent->val.val); + _upb_map_fromvalue(v, val, size); +} + +UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, size_t size) { + upb_tabent *ent = (upb_tabent*)msg; + /* This is like _upb_map_tovalue() except the entry already exists so we can + * reuse the allocated upb_strview for string fields. */ + if (size == UPB_MAPTYPE_STRING) { + upb_strview *strp = (upb_strview*)ent->val.val; + memcpy(strp, val, sizeof(*strp)); + } else { + memcpy(&ent->val.val, val, size); + } } #undef PTR_AT +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MSG_H_ */ + +#ifdef __cplusplus +extern "C" { +#endif + +bool upb_decode(const char *buf, size_t size, upb_msg *msg, + const upb_msglayout *l, upb_arena *arena); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_DECODE_H_ */ +/* +** upb_encode: parsing into a upb_msg using a upb_msglayout. +*/ + +#ifndef UPB_ENCODE_H_ +#define UPB_ENCODE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +char *upb_encode(const void *msg, const upb_msglayout *l, upb_arena *arena, + size_t *size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_ENCODE_H_ */ +/* 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_ -#endif /* UPB_GENERATED_UTIL_H_ */ #ifdef __cplusplus @@ -1381,7 +1513,7 @@ typedef enum { /* 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); + 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) { @@ -1392,16 +1524,17 @@ UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protob return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len); } +UPB_INLINE bool google_protobuf_FileDescriptorSet_has_file(const google_protobuf_FileDescriptorSet *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } 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); + return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, 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); + 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; @@ -1411,7 +1544,7 @@ UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescr /* 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); + 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) { @@ -1423,49 +1556,53 @@ UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_prot } 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 upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } 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 google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } 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 bool google_protobuf_FileDescriptorProto_has_message_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } 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 bool google_protobuf_FileDescriptorProto_has_enum_type(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 88)); } 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 bool google_protobuf_FileDescriptorProto_has_service(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 96)); } 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 bool google_protobuf_FileDescriptorProto_has_extension(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(52, 104)); } 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 const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_FileOptions*); } 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 const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 64), const google_protobuf_SourceCodeInfo*); } 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 upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); } 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = 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); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, 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); + 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); + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, 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); + 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; @@ -1475,10 +1612,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorP 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); + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, 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); + 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; @@ -1488,10 +1625,10 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescript 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); + return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, 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); + 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; @@ -1501,10 +1638,10 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptor 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); + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, 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); + 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; @@ -1512,12 +1649,12 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDesc } 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_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_FileOptions*) = 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); + sub = (struct google_protobuf_FileOptions*)_upb_msg_new(&google_protobuf_FileOptions_msginit, arena); if (!sub) return NULL; google_protobuf_FileDescriptorProto_set_options(msg, sub); } @@ -1525,12 +1662,12 @@ UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorPro } 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_PTR_AT(msg, UPB_SIZE(32, 64), google_protobuf_SourceCodeInfo*) = 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); + 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); } @@ -1540,31 +1677,31 @@ UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependenc 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); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, 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); + 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); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, 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); + 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; + *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = 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); + 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) { @@ -1576,30 +1713,37 @@ UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf } 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 upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_field(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } 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 bool google_protobuf_DescriptorProto_has_nested_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } 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 bool google_protobuf_DescriptorProto_has_enum_type(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(24, 48)); } 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 bool google_protobuf_DescriptorProto_has_extension_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 56)); } 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 bool google_protobuf_DescriptorProto_has_extension(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(32, 64)); } 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_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_MessageOptions*); } +UPB_INLINE bool google_protobuf_DescriptorProto_has_oneof_decl(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(36, 72)); } 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 bool google_protobuf_DescriptorProto_has_reserved_range(const google_protobuf_DescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(40, 80)); } 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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); + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, 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); + 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; @@ -1609,10 +1753,10 @@ UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mut 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); + return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, 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); + 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; @@ -1622,10 +1766,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto 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); + return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, 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); + 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; @@ -1635,10 +1779,10 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_Desc 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); + return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, 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); + 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; @@ -1648,10 +1792,10 @@ UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProt 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); + return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, 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); + 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; @@ -1659,12 +1803,12 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_Descript } 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_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_MessageOptions*) = 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); + sub = (struct google_protobuf_MessageOptions*)_upb_msg_new(&google_protobuf_MessageOptions_msginit, arena); if (!sub) return NULL; google_protobuf_DescriptorProto_set_options(msg, sub); } @@ -1674,10 +1818,10 @@ UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProt 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); + return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, 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); + 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; @@ -1687,10 +1831,10 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_Descr 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); + return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, 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); + 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; @@ -1700,17 +1844,17 @@ UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(go 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); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, 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); + 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); + 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) { @@ -1722,28 +1866,28 @@ UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const } 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 int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } 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 int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } 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 const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const google_protobuf_ExtensionRangeOptions*); } 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_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = 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_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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_PTR_AT(msg, UPB_SIZE(12, 16), google_protobuf_ExtensionRangeOptions*) = 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); + 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); } @@ -1753,7 +1897,7 @@ UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_Descrip /* 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); + 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) { @@ -1765,23 +1909,23 @@ UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const g } 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 int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } 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 int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } 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_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = 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; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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); + 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) { @@ -1792,16 +1936,17 @@ UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_pr return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len); } +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_has_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, 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); + 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; @@ -1811,7 +1956,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_Extension /* 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); + 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) { @@ -1822,63 +1967,65 @@ UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_pro 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_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview); } 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 int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), int32_t); } 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 int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } 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 int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 11); } +UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 120), const google_protobuf_FieldOptions*); } 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 int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 28), int32_t); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); } +UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); } +UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool); } 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_sethas(msg, 6); + *UPB_PTR_AT(msg, UPB_SIZE(36, 40), upb_strview) = 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_sethas(msg, 7); + *UPB_PTR_AT(msg, UPB_SIZE(44, 56), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(24, 24), int32_t) = 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_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = 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_sethas(msg, 8); + *UPB_PTR_AT(msg, UPB_SIZE(52, 72), upb_strview) = 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_sethas(msg, 9); + *UPB_PTR_AT(msg, UPB_SIZE(60, 88), upb_strview) = 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_sethas(msg, 11); + *UPB_PTR_AT(msg, UPB_SIZE(76, 120), google_protobuf_FieldOptions*) = 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); + sub = (struct google_protobuf_FieldOptions*)_upb_msg_new(&google_protobuf_FieldOptions_msginit, arena); if (!sub) return NULL; google_protobuf_FieldDescriptorProto_set_options(msg, sub); } @@ -1886,17 +2033,21 @@ UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorP } 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_PTR_AT(msg, UPB_SIZE(28, 28), int32_t) = 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; + _upb_sethas(msg, 10); + *UPB_PTR_AT(msg, UPB_SIZE(68, 104), upb_strview) = value; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto *msg, bool value) { + _upb_sethas(msg, 5); + *UPB_PTR_AT(msg, UPB_SIZE(32, 32), bool) = 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); + 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) { @@ -1908,22 +2059,22 @@ UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_pro } 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 upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } 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 const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_OneofOptions*); } 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_OneofOptions*) = 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); + sub = (struct google_protobuf_OneofOptions*)_upb_msg_new(&google_protobuf_OneofOptions_msginit, arena); if (!sub) return NULL; google_protobuf_OneofDescriptorProto_set_options(msg, sub); } @@ -1933,7 +2084,7 @@ UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorP /* 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); + 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) { @@ -1945,25 +2096,27 @@ UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_prot } 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 upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_value(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } 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_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_EnumOptions*); } +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_reserved_range(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 40)); } 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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); + return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, 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); + 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; @@ -1971,12 +2124,12 @@ UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_Enum } 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_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_EnumOptions*) = 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); + sub = (struct google_protobuf_EnumOptions*)_upb_msg_new(&google_protobuf_EnumOptions_msginit, arena); if (!sub) return NULL; google_protobuf_EnumDescriptorProto_set_options(msg, sub); } @@ -1986,10 +2139,10 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protob 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); + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, 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); + 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; @@ -1999,17 +2152,17 @@ UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_nam 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); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, 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); + 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); + 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) { @@ -2021,23 +2174,23 @@ UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize } 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 int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } 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 int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } 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_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = 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; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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); + 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) { @@ -2049,28 +2202,28 @@ UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google } 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 upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview); } 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 int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } 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 const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const google_protobuf_EnumValueOptions*); } 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_PTR_AT(msg, UPB_SIZE(8, 8), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = 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_PTR_AT(msg, UPB_SIZE(16, 24), google_protobuf_EnumValueOptions*) = 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); + sub = (struct google_protobuf_EnumValueOptions*)_upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena); if (!sub) return NULL; google_protobuf_EnumValueDescriptorProto_set_options(msg, sub); } @@ -2080,7 +2233,7 @@ UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDes /* 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); + 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) { @@ -2092,23 +2245,24 @@ UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_p } 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 upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_method(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); } 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 const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const google_protobuf_ServiceOptions*); } 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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); + return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, 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); + 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; @@ -2116,12 +2270,12 @@ UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_Service } 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_PTR_AT(msg, UPB_SIZE(12, 24), google_protobuf_ServiceOptions*) = 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); + sub = (struct google_protobuf_ServiceOptions*)_upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena); if (!sub) return NULL; google_protobuf_ServiceDescriptorProto_set_options(msg, sub); } @@ -2131,7 +2285,7 @@ UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescrip /* 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); + 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) { @@ -2143,38 +2297,38 @@ UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_pr } 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 upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } 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 upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } 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 upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview); } 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 const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 56), const google_protobuf_MethodOptions*); } 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_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } 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 bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(20, 40), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(28, 56), google_protobuf_MethodOptions*) = 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); + sub = (struct google_protobuf_MethodOptions*)_upb_msg_new(&google_protobuf_MethodOptions_msginit, arena); if (!sub) return NULL; google_protobuf_MethodDescriptorProto_set_options(msg, sub); } @@ -2182,17 +2336,17 @@ UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescripto } 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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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; + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = 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); + 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) { @@ -2204,135 +2358,136 @@ UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_Fil } 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 upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview); } 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 upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview); } 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 int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } 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_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); } 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 upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview); } 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_cc_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(17, 17), bool); } 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_java_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(18, 18), bool); } 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_py_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(19, 19), bool); } 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_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(20, 20), bool); } 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_deprecated(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(21, 21), bool); } 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_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(22, 22), bool); } 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_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(23, 23), bool); } 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 upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview); } 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 upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview); } 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 upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview); } 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 upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview); } 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 upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview); } 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_php_generic_services(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); } 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 upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview); } 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 upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview); } +UPB_INLINE bool google_protobuf_FileOptions_has_uninterpreted_option(const google_protobuf_FileOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(108, 192)); } 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_PTR_AT(msg, UPB_SIZE(28, 32), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(36, 48), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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_PTR_AT(msg, UPB_SIZE(16, 16), bool) = 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_PTR_AT(msg, UPB_SIZE(44, 64), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(17, 17), bool) = 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_PTR_AT(msg, UPB_SIZE(18, 18), bool) = 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_PTR_AT(msg, UPB_SIZE(19, 19), bool) = 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_PTR_AT(msg, UPB_SIZE(20, 20), bool) = 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_PTR_AT(msg, UPB_SIZE(21, 21), bool) = 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_PTR_AT(msg, UPB_SIZE(22, 22), bool) = 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_PTR_AT(msg, UPB_SIZE(23, 23), bool) = 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_PTR_AT(msg, UPB_SIZE(52, 80), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(60, 96), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(68, 112), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(76, 128), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(84, 144), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(24, 24), bool) = 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_PTR_AT(msg, UPB_SIZE(92, 160), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(100, 176), upb_strview) = 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, 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); + 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; @@ -2342,7 +2497,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptio /* 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); + 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) { @@ -2354,39 +2509,40 @@ UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_ } 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_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } 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_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } 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_deprecated(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); } 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 bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), bool); } +UPB_INLINE bool google_protobuf_MessageOptions_has_uninterpreted_option(const google_protobuf_MessageOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 8)); } 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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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_PTR_AT(msg, UPB_SIZE(2, 2), bool) = 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_PTR_AT(msg, UPB_SIZE(3, 3), bool) = 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_PTR_AT(msg, UPB_SIZE(4, 4), bool) = 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, 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); + 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; @@ -2396,7 +2552,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOp /* 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); + 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) { @@ -2408,51 +2564,52 @@ UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_Fi } 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 int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } 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_packed(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), bool); } 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_deprecated(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(25, 25), bool); } 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_lazy(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(26, 26), bool); } 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 int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int32_t); } 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 bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(27, 27), bool); } +UPB_INLINE bool google_protobuf_FieldOptions_has_uninterpreted_option(const google_protobuf_FieldOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(28, 32)); } 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_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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_PTR_AT(msg, UPB_SIZE(24, 24), bool) = 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_PTR_AT(msg, UPB_SIZE(25, 25), bool) = 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_PTR_AT(msg, UPB_SIZE(26, 26), bool) = 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_PTR_AT(msg, UPB_SIZE(16, 16), int32_t) = 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_PTR_AT(msg, UPB_SIZE(27, 27), bool) = 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, 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); + 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; @@ -2462,7 +2619,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOpti /* 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); + 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) { @@ -2473,16 +2630,17 @@ UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_On return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); } +UPB_INLINE bool google_protobuf_OneofOptions_has_uninterpreted_option(const google_protobuf_OneofOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, 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); + 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; @@ -2492,7 +2650,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOpti /* 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); + 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) { @@ -2504,27 +2662,28 @@ UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_Enu } 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_allow_alias(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } 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 bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } +UPB_INLINE bool google_protobuf_EnumOptions_has_uninterpreted_option(const google_protobuf_EnumOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } 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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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_PTR_AT(msg, UPB_SIZE(2, 2), bool) = 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, 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); + 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; @@ -2534,7 +2693,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptio /* 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); + 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) { @@ -2546,21 +2705,22 @@ UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobu } 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 bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_EnumValueOptions_has_uninterpreted_option(const google_protobuf_EnumValueOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } 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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, 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); + 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; @@ -2570,7 +2730,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValue /* 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); + 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) { @@ -2582,21 +2742,22 @@ UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ } 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 bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool google_protobuf_ServiceOptions_has_uninterpreted_option(const google_protobuf_ServiceOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(4, 8)); } 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_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, 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); + 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; @@ -2606,7 +2767,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOp /* 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); + 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) { @@ -2618,27 +2779,28 @@ UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_M } 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_deprecated(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), bool); } 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 int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE bool google_protobuf_MethodOptions_has_uninterpreted_option(const google_protobuf_MethodOptions *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(20, 24)); } 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_PTR_AT(msg, UPB_SIZE(16, 16), bool) = 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_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = 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); + return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, 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); + 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; @@ -2648,7 +2810,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOpt /* 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); + 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) { @@ -2659,28 +2821,29 @@ UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_prot return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len); } +UPB_INLINE bool google_protobuf_UninterpretedOption_has_name(const google_protobuf_UninterpretedOption *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(56, 80)); } 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 upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview); } 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 uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t); } 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 int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), int64_t); } 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 double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(24, 24), double); } 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 upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview); } 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 upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview); } 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); + return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, 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); + 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; @@ -2688,33 +2851,33 @@ UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_ } 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_PTR_AT(msg, UPB_SIZE(32, 32), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(8, 8), uint64_t) = 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_PTR_AT(msg, UPB_SIZE(16, 16), int64_t) = 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_PTR_AT(msg, UPB_SIZE(24, 24), double) = 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_PTR_AT(msg, UPB_SIZE(40, 48), upb_strview) = 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; + *UPB_PTR_AT(msg, UPB_SIZE(48, 64), upb_strview) = 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); + 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) { @@ -2726,23 +2889,23 @@ UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const go } 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 upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } 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 bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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; + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = 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); + 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) { @@ -2753,16 +2916,17 @@ UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_ return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); } +UPB_INLINE bool google_protobuf_SourceCodeInfo_has_location(const google_protobuf_SourceCodeInfo *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } 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); + return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, 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); + 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; @@ -2772,7 +2936,7 @@ UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_Sourc /* 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); + 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) { @@ -2786,54 +2950,54 @@ UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_ 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 upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } 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 google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview); } 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); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, 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); + 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); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, 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); + 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_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(12, 24), upb_strview) = 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); + return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, 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); + 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); + 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) { @@ -2844,16 +3008,17 @@ UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protob return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len); } +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_has_annotation(const google_protobuf_GeneratedCodeInfo *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(0, 0)); } 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); + return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, 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); + 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; @@ -2863,7 +3028,7 @@ UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_ /* 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); + 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) { @@ -2876,33 +3041,33 @@ UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const go 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 upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview); } 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 int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } 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_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } 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); + return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, 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); + 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_PTR_AT(msg, UPB_SIZE(12, 16), upb_strview) = 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_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = 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; + *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value; } #ifdef __cplusplus @@ -2915,38 +3080,23 @@ UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_prot ** Defs are upb's internal representation of the constructs that can appear ** in a .proto file: ** -** - upb::MessageDefPtr (upb_msgdef): describes a "message" construct. -** - upb::FieldDefPtr (upb_fielddef): describes a message field. -** - upb::FileDefPtr (upb_filedef): describes a .proto file and its defs. -** - upb::EnumDefPtr (upb_enumdef): describes an enum. -** - upb::OneofDefPtr (upb_oneofdef): describes a oneof. +** - upb_msgdef: describes a "message" construct. +** - upb_fielddef: describes a message field. +** - upb_filedef: describes a .proto file and its defs. +** - upb_enumdef: describes an enum. +** - upb_oneofdef: describes a oneof. ** ** TODO: definitions of services. -** -** This is a mixed C/C++ interface that offers a full API to both languages. -** See the top-level README for more information. */ #ifndef UPB_DEF_H_ #define UPB_DEF_H_ -#ifdef __cplusplus -#include -#include -#include -#include - -namespace upb { -class EnumDefPtr; -class FieldDefPtr; -class FileDefPtr; -class MessageDefPtr; -class OneofDefPtr; -class SymbolTable; -} -#endif +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ struct upb_enumdef; typedef struct upb_enumdef upb_enumdef; @@ -2998,22 +3148,20 @@ typedef enum { * protobuf wire format. */ #define UPB_MAX_FIELDNUMBER ((1 << 29) - 1) -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_fielddef_fullname(const upb_fielddef *f); upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f); upb_descriptortype_t upb_fielddef_descriptortype(const upb_fielddef *f); upb_label_t upb_fielddef_label(const upb_fielddef *f); uint32_t upb_fielddef_number(const upb_fielddef *f); const char *upb_fielddef_name(const upb_fielddef *f); +const char *upb_fielddef_jsonname(const upb_fielddef *f); bool upb_fielddef_isextension(const upb_fielddef *f); bool upb_fielddef_lazy(const upb_fielddef *f); bool upb_fielddef_packed(const upb_fielddef *f); -size_t upb_fielddef_getjsonname(const upb_fielddef *f, char *buf, size_t len); +const upb_filedef *upb_fielddef_file(const upb_fielddef *f); const upb_msgdef *upb_fielddef_containingtype(const upb_fielddef *f); const upb_oneofdef *upb_fielddef_containingoneof(const upb_fielddef *f); +const upb_oneofdef *upb_fielddef_realcontainingoneof(const upb_fielddef *f); uint32_t upb_fielddef_index(const upb_fielddef *f); bool upb_fielddef_issubmsg(const upb_fielddef *f); bool upb_fielddef_isstring(const upb_fielddef *f); @@ -3032,155 +3180,20 @@ bool upb_fielddef_hassubdef(const upb_fielddef *f); bool upb_fielddef_haspresence(const upb_fielddef *f); const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f); const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f); +const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f); /* Internal only. */ uint32_t upb_fielddef_selectorbase(const upb_fielddef *f); -#ifdef __cplusplus -} /* extern "C" */ - -/* A upb_fielddef describes a single field in a message. It is most often - * found as a part of a upb_msgdef, but can also stand alone to represent - * an extension. */ -class upb::FieldDefPtr { - public: - FieldDefPtr() : ptr_(nullptr) {} - explicit FieldDefPtr(const upb_fielddef *ptr) : ptr_(ptr) {} - - const upb_fielddef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - typedef upb_fieldtype_t Type; - typedef upb_label_t Label; - typedef upb_descriptortype_t DescriptorType; - - const char* full_name() const { return upb_fielddef_fullname(ptr_); } - - Type type() const { return upb_fielddef_type(ptr_); } - Label label() const { return upb_fielddef_label(ptr_); } - const char* name() const { return upb_fielddef_name(ptr_); } - uint32_t number() const { return upb_fielddef_number(ptr_); } - bool is_extension() const { return upb_fielddef_isextension(ptr_); } - - /* Copies the JSON name for this field into the given buffer. Returns the - * actual size of the JSON name, including the NULL terminator. If the - * return value is 0, the JSON name is unset. If the return value is - * greater than len, the JSON name was truncated. The buffer is always - * NULL-terminated if len > 0. - * - * The JSON name always defaults to a camelCased version of the regular - * name. However if the regular name is unset, the JSON name will be unset - * also. - */ - size_t GetJsonName(char *buf, size_t len) const { - return upb_fielddef_getjsonname(ptr_, buf, len); - } - - /* Convenience version of the above function which copies the JSON name - * into the given string, returning false if the name is not set. */ - template - bool GetJsonName(T* str) { - str->resize(GetJsonName(NULL, 0)); - GetJsonName(&(*str)[0], str->size()); - return str->size() > 0; - } - - /* For UPB_TYPE_MESSAGE fields only where is_tag_delimited() == false, - * indicates whether this field should have lazy parsing handlers that yield - * the unparsed string for the submessage. - * - * TODO(haberman): I think we want to move this into a FieldOptions container - * when we add support for custom options (the FieldOptions struct will - * contain both regular FieldOptions like "lazy" *and* custom options). */ - bool lazy() const { return upb_fielddef_lazy(ptr_); } - - /* For non-string, non-submessage fields, this indicates whether binary - * protobufs are encoded in packed or non-packed format. - * - * TODO(haberman): see note above about putting options like this into a - * FieldOptions container. */ - bool packed() const { return upb_fielddef_packed(ptr_); } - - /* An integer that can be used as an index into an array of fields for - * whatever message this field belongs to. Guaranteed to be less than - * f->containing_type()->field_count(). May only be accessed once the def has - * been finalized. */ - uint32_t index() const { return upb_fielddef_index(ptr_); } - - /* The MessageDef to which this field belongs. - * - * If this field has been added to a MessageDef, that message can be retrieved - * directly (this is always the case for frozen FieldDefs). - * - * If the field has not yet been added to a MessageDef, you can set the name - * of the containing type symbolically instead. This is mostly useful for - * extensions, where the extension is declared separately from the message. */ - MessageDefPtr containing_type() const; - - /* The OneofDef to which this field belongs, or NULL if this field is not part - * of a oneof. */ - OneofDefPtr containing_oneof() const; - - /* The field's type according to the enum in descriptor.proto. This is not - * the same as UPB_TYPE_*, because it distinguishes between (for example) - * INT32 and SINT32, whereas our "type" enum does not. This return of - * descriptor_type() is a function of type(), integer_format(), and - * is_tag_delimited(). */ - DescriptorType descriptor_type() const { - return upb_fielddef_descriptortype(ptr_); - } - - /* Convenient field type tests. */ - bool IsSubMessage() const { return upb_fielddef_issubmsg(ptr_); } - bool IsString() const { return upb_fielddef_isstring(ptr_); } - bool IsSequence() const { return upb_fielddef_isseq(ptr_); } - bool IsPrimitive() const { return upb_fielddef_isprimitive(ptr_); } - bool IsMap() const { return upb_fielddef_ismap(ptr_); } - - /* Returns the non-string default value for this fielddef, which may either - * be something the client set explicitly or the "default default" (0 for - * numbers, empty for strings). The field's type indicates the type of the - * returned value, except for enum fields that are still mutable. - * - * Requires that the given function matches the field's current type. */ - int64_t default_int64() const { return upb_fielddef_defaultint64(ptr_); } - int32_t default_int32() const { return upb_fielddef_defaultint32(ptr_); } - uint64_t default_uint64() const { return upb_fielddef_defaultuint64(ptr_); } - uint32_t default_uint32() const { return upb_fielddef_defaultuint32(ptr_); } - bool default_bool() const { return upb_fielddef_defaultbool(ptr_); } - float default_float() const { return upb_fielddef_defaultfloat(ptr_); } - double default_double() const { return upb_fielddef_defaultdouble(ptr_); } - - /* The resulting string is always NULL-terminated. If non-NULL, the length - * will be stored in *len. */ - const char *default_string(size_t * len) const { - return upb_fielddef_defaultstr(ptr_, len); - } - - /* Returns the enum or submessage def for this field, if any. The field's - * type must match (ie. you may only call enum_subdef() for fields where - * type() == UPB_TYPE_ENUM). */ - EnumDefPtr enum_subdef() const; - MessageDefPtr message_subdef() const; - - private: - const upb_fielddef *ptr_; -}; - -#endif /* __cplusplus */ - /* upb_oneofdef ***************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - typedef upb_inttable_iter upb_oneof_iter; const char *upb_oneofdef_name(const upb_oneofdef *o); const upb_msgdef *upb_oneofdef_containingtype(const upb_oneofdef *o); int upb_oneofdef_numfields(const upb_oneofdef *o); uint32_t upb_oneofdef_index(const upb_oneofdef *o); +bool upb_oneofdef_issynthetic(const upb_oneofdef *o); /* Oneof lookups: * - ntof: look up a field by name. @@ -3207,92 +3220,6 @@ void upb_oneof_iter_setdone(upb_oneof_iter *iter); bool upb_oneof_iter_isequal(const upb_oneof_iter *iter1, const upb_oneof_iter *iter2); -#ifdef __cplusplus -} /* extern "C" */ - -/* Class that represents a oneof. */ -class upb::OneofDefPtr { - public: - OneofDefPtr() : ptr_(nullptr) {} - explicit OneofDefPtr(const upb_oneofdef *ptr) : ptr_(ptr) {} - - const upb_oneofdef* ptr() const { return ptr_; } - explicit operator bool() { return ptr_ != nullptr; } - - /* Returns the MessageDef that owns this OneofDef. */ - MessageDefPtr containing_type() const; - - /* Returns the name of this oneof. This is the name used to look up the oneof - * by name once added to a message def. */ - const char* name() const { return upb_oneofdef_name(ptr_); } - - /* Returns the number of fields currently defined in the oneof. */ - int field_count() const { return upb_oneofdef_numfields(ptr_); } - - /* Looks up by name. */ - FieldDefPtr FindFieldByName(const char *name, size_t len) const { - return FieldDefPtr(upb_oneofdef_ntof(ptr_, name, len)); - } - FieldDefPtr FindFieldByName(const char* name) const { - return FieldDefPtr(upb_oneofdef_ntofz(ptr_, name)); - } - - template - FieldDefPtr FindFieldByName(const T& str) const { - return FindFieldByName(str.c_str(), str.size()); - } - - /* Looks up by tag number. */ - FieldDefPtr FindFieldByNumber(uint32_t num) const { - return FieldDefPtr(upb_oneofdef_itof(ptr_, num)); - } - - class const_iterator - : public std::iterator { - public: - void operator++() { upb_oneof_next(&iter_); } - - FieldDefPtr operator*() const { - return FieldDefPtr(upb_oneof_iter_field(&iter_)); - } - - bool operator!=(const const_iterator& other) const { - return !upb_oneof_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_iterator& other) const { - return upb_oneof_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class OneofDefPtr; - - const_iterator() {} - explicit const_iterator(OneofDefPtr o) { - upb_oneof_begin(&iter_, o.ptr()); - } - static const_iterator end() { - const_iterator iter; - upb_oneof_iter_setdone(&iter.iter_); - return iter; - } - - upb_oneof_iter iter_; - }; - - const_iterator begin() const { return const_iterator(*this); } - const_iterator end() const { return const_iterator::end(); } - - private: - const upb_oneofdef *ptr_; -}; - -inline upb::OneofDefPtr upb::FieldDefPtr::containing_oneof() const { - return OneofDefPtr(upb_fielddef_containingoneof(ptr_)); -} - -#endif /* __cplusplus */ - /* upb_msgdef *****************************************************************/ typedef upb_inttable_iter upb_msg_field_iter; @@ -3314,26 +3241,23 @@ typedef upb_strtable_iter upb_msg_oneof_iter; #define UPB_TIMESTAMP_SECONDS 1 #define UPB_TIMESTAMP_NANOS 2 -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_msgdef_fullname(const upb_msgdef *m); const upb_filedef *upb_msgdef_file(const upb_msgdef *m); const char *upb_msgdef_name(const upb_msgdef *m); +int upb_msgdef_numfields(const upb_msgdef *m); int upb_msgdef_numoneofs(const upb_msgdef *m); +int upb_msgdef_numrealoneofs(const upb_msgdef *m); upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m); bool upb_msgdef_mapentry(const upb_msgdef *m); upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m); bool upb_msgdef_isnumberwrapper(const upb_msgdef *m); -bool upb_msgdef_setsyntax(upb_msgdef *m, upb_syntax_t syntax); const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i); const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name, size_t len); const upb_oneofdef *upb_msgdef_ntoo(const upb_msgdef *m, const char *name, size_t len); -int upb_msgdef_numfields(const upb_msgdef *m); -int upb_msgdef_numoneofs(const upb_msgdef *m); +const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m); +const upb_fielddef *_upb_msgdef_field(const upb_msgdef *m, int i); UPB_INLINE const upb_oneofdef *upb_msgdef_ntooz(const upb_msgdef *m, const char *name) { @@ -3361,6 +3285,10 @@ UPB_INLINE bool upb_msgdef_lookupnamez(const upb_msgdef *m, const char *name, return upb_msgdef_lookupname(m, name, strlen(name), f, o); } +/* Returns a field by either JSON name or regular proto name. */ +const upb_fielddef *upb_msgdef_lookupjsonname(const upb_msgdef *m, + const char *name, size_t len); + /* Iteration over fields and oneofs. For example: * * upb_msg_field_iter i; @@ -3392,194 +3320,6 @@ void upb_msg_oneof_iter_setdone(upb_msg_oneof_iter * iter); bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1, const upb_msg_oneof_iter *iter2); -#ifdef __cplusplus -} /* extern "C" */ - -/* Structure that describes a single .proto message type. */ -class upb::MessageDefPtr { - public: - MessageDefPtr() : ptr_(nullptr) {} - explicit MessageDefPtr(const upb_msgdef *ptr) : ptr_(ptr) {} - - const upb_msgdef *ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - const char* full_name() const { return upb_msgdef_fullname(ptr_); } - const char* name() const { return upb_msgdef_name(ptr_); } - - /* The number of fields that belong to the MessageDef. */ - int field_count() const { return upb_msgdef_numfields(ptr_); } - - /* The number of oneofs that belong to the MessageDef. */ - int oneof_count() const { return upb_msgdef_numoneofs(ptr_); } - - upb_syntax_t syntax() const { return upb_msgdef_syntax(ptr_); } - - /* These return null pointers if the field is not found. */ - FieldDefPtr FindFieldByNumber(uint32_t number) const { - return FieldDefPtr(upb_msgdef_itof(ptr_, number)); - } - FieldDefPtr FindFieldByName(const char* name, size_t len) const { - return FieldDefPtr(upb_msgdef_ntof(ptr_, name, len)); - } - FieldDefPtr FindFieldByName(const char *name) const { - return FieldDefPtr(upb_msgdef_ntofz(ptr_, name)); - } - - template - FieldDefPtr FindFieldByName(const T& str) const { - return FindFieldByName(str.c_str(), str.size()); - } - - OneofDefPtr FindOneofByName(const char* name, size_t len) const { - return OneofDefPtr(upb_msgdef_ntoo(ptr_, name, len)); - } - - OneofDefPtr FindOneofByName(const char *name) const { - return OneofDefPtr(upb_msgdef_ntooz(ptr_, name)); - } - - template - OneofDefPtr FindOneofByName(const T &str) const { - return FindOneofByName(str.c_str(), str.size()); - } - - /* Is this message a map entry? */ - bool mapentry() const { return upb_msgdef_mapentry(ptr_); } - - /* Return the type of well known type message. UPB_WELLKNOWN_UNSPECIFIED for - * non-well-known message. */ - upb_wellknowntype_t wellknowntype() const { - return upb_msgdef_wellknowntype(ptr_); - } - - /* Whether is a number wrapper. */ - bool isnumberwrapper() const { return upb_msgdef_isnumberwrapper(ptr_); } - - /* Iteration over fields. The order is undefined. */ - class const_field_iterator - : public std::iterator { - public: - void operator++() { upb_msg_field_next(&iter_); } - - FieldDefPtr operator*() const { - return FieldDefPtr(upb_msg_iter_field(&iter_)); - } - - bool operator!=(const const_field_iterator &other) const { - return !upb_msg_field_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_field_iterator &other) const { - return upb_msg_field_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class MessageDefPtr; - - explicit const_field_iterator() {} - - explicit const_field_iterator(MessageDefPtr msg) { - upb_msg_field_begin(&iter_, msg.ptr()); - } - - static const_field_iterator end() { - const_field_iterator iter; - upb_msg_field_iter_setdone(&iter.iter_); - return iter; - } - - upb_msg_field_iter iter_; - }; - - /* Iteration over oneofs. The order is undefined. */ - class const_oneof_iterator - : public std::iterator { - public: - - void operator++() { upb_msg_oneof_next(&iter_); } - - OneofDefPtr operator*() const { - return OneofDefPtr(upb_msg_iter_oneof(&iter_)); - } - - bool operator!=(const const_oneof_iterator& other) const { - return !upb_msg_oneof_iter_isequal(&iter_, &other.iter_); - } - - bool operator==(const const_oneof_iterator &other) const { - return upb_msg_oneof_iter_isequal(&iter_, &other.iter_); - } - - private: - friend class MessageDefPtr; - - const_oneof_iterator() {} - - explicit const_oneof_iterator(MessageDefPtr msg) { - upb_msg_oneof_begin(&iter_, msg.ptr()); - } - - static const_oneof_iterator end() { - const_oneof_iterator iter; - upb_msg_oneof_iter_setdone(&iter.iter_); - return iter; - } - - upb_msg_oneof_iter iter_; - }; - - class ConstFieldAccessor { - public: - explicit ConstFieldAccessor(const upb_msgdef* md) : md_(md) {} - const_field_iterator begin() { return MessageDefPtr(md_).field_begin(); } - const_field_iterator end() { return MessageDefPtr(md_).field_end(); } - private: - const upb_msgdef* md_; - }; - - class ConstOneofAccessor { - public: - explicit ConstOneofAccessor(const upb_msgdef* md) : md_(md) {} - const_oneof_iterator begin() { return MessageDefPtr(md_).oneof_begin(); } - const_oneof_iterator end() { return MessageDefPtr(md_).oneof_end(); } - private: - const upb_msgdef* md_; - }; - - const_field_iterator field_begin() const { - return const_field_iterator(*this); - } - - const_field_iterator field_end() const { return const_field_iterator::end(); } - - const_oneof_iterator oneof_begin() const { - return const_oneof_iterator(*this); - } - - const_oneof_iterator oneof_end() const { return const_oneof_iterator::end(); } - - ConstFieldAccessor fields() const { return ConstFieldAccessor(ptr()); } - ConstOneofAccessor oneofs() const { return ConstOneofAccessor(ptr()); } - - private: - const upb_msgdef* ptr_; -}; - -inline upb::MessageDefPtr upb::FieldDefPtr::message_subdef() const { - return MessageDefPtr(upb_fielddef_msgsubdef(ptr_)); -} - -inline upb::MessageDefPtr upb::FieldDefPtr::containing_type() const { - return MessageDefPtr(upb_fielddef_containingtype(ptr_)); -} - -inline upb::MessageDefPtr upb::OneofDefPtr::containing_type() const { - return MessageDefPtr(upb_oneofdef_containingtype(ptr_)); -} - -#endif /* __cplusplus */ - /* upb_enumdef ****************************************************************/ typedef upb_strtable_iter upb_enum_iter; @@ -3614,75 +3354,8 @@ bool upb_enum_done(upb_enum_iter *iter); const char *upb_enum_iter_name(upb_enum_iter *iter); int32_t upb_enum_iter_number(upb_enum_iter *iter); -#ifdef __cplusplus - -class upb::EnumDefPtr { - public: - EnumDefPtr() : ptr_(nullptr) {} - explicit EnumDefPtr(const upb_enumdef* ptr) : ptr_(ptr) {} - - const upb_enumdef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - const char* full_name() const { return upb_enumdef_fullname(ptr_); } - const char* name() const { return upb_enumdef_name(ptr_); } - - /* The value that is used as the default when no field default is specified. - * If not set explicitly, the first value that was added will be used. - * The default value must be a member of the enum. - * Requires that value_count() > 0. */ - int32_t default_value() const { return upb_enumdef_default(ptr_); } - - /* Returns the number of values currently defined in the enum. Note that - * multiple names can refer to the same number, so this may be greater than - * the total number of unique numbers. */ - int value_count() const { return upb_enumdef_numvals(ptr_); } - - /* Lookups from name to integer, returning true if found. */ - bool FindValueByName(const char *name, int32_t *num) const { - return upb_enumdef_ntoiz(ptr_, name, num); - } - - /* Finds the name corresponding to the given number, or NULL if none was - * found. If more than one name corresponds to this number, returns the - * first one that was added. */ - const char *FindValueByNumber(int32_t num) const { - return upb_enumdef_iton(ptr_, num); - } - - /* Iteration over name/value pairs. The order is undefined. - * Adding an enum val invalidates any iterators. - * - * TODO: make compatible with range-for, with elements as pairs? */ - class Iterator { - public: - explicit Iterator(EnumDefPtr e) { upb_enum_begin(&iter_, e.ptr()); } - - int32_t number() { return upb_enum_iter_number(&iter_); } - const char *name() { return upb_enum_iter_name(&iter_); } - bool Done() { return upb_enum_done(&iter_); } - void Next() { return upb_enum_next(&iter_); } - - private: - upb_enum_iter iter_; - }; - - private: - const upb_enumdef *ptr_; -}; - -inline upb::EnumDefPtr upb::FieldDefPtr::enum_subdef() const { - return EnumDefPtr(upb_fielddef_enumsubdef(ptr_)); -} - -#endif /* __cplusplus */ - /* upb_filedef ****************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - const char *upb_filedef_name(const upb_filedef *f); const char *upb_filedef_package(const upb_filedef *f); const char *upb_filedef_phpprefix(const upb_filedef *f); @@ -3695,57 +3368,8 @@ const upb_filedef *upb_filedef_dep(const upb_filedef *f, int i); const upb_msgdef *upb_filedef_msg(const upb_filedef *f, int i); const upb_enumdef *upb_filedef_enum(const upb_filedef *f, int i); -#ifdef __cplusplus -} /* extern "C" */ - -/* Class that represents a .proto file with some things defined in it. - * - * Many users won't care about FileDefs, but they are necessary if you want to - * read the values of file-level options. */ -class upb::FileDefPtr { - public: - explicit FileDefPtr(const upb_filedef *ptr) : ptr_(ptr) {} - - const upb_filedef* ptr() const { return ptr_; } - explicit operator bool() const { return ptr_ != nullptr; } - - /* Get/set name of the file (eg. "foo/bar.proto"). */ - const char* name() const { return upb_filedef_name(ptr_); } - - /* Package name for definitions inside the file (eg. "foo.bar"). */ - const char* package() const { return upb_filedef_package(ptr_); } - - /* Sets the php class prefix which is prepended to all php generated classes - * from this .proto. Default is empty. */ - const char* phpprefix() const { return upb_filedef_phpprefix(ptr_); } - - /* Use this option to change the namespace of php generated classes. Default - * is empty. When this option is empty, the package name will be used for - * determining the namespace. */ - const char* phpnamespace() const { return upb_filedef_phpnamespace(ptr_); } - - /* Syntax for the file. Defaults to proto2. */ - upb_syntax_t syntax() const { return upb_filedef_syntax(ptr_); } - - /* Get the list of dependencies from the file. These are returned in the - * order that they were added to the FileDefPtr. */ - int dependency_count() const { return upb_filedef_depcount(ptr_); } - const FileDefPtr dependency(int index) const { - return FileDefPtr(upb_filedef_dep(ptr_, index)); - } - - private: - const upb_filedef* ptr_; -}; - -#endif /* __cplusplus */ - /* upb_symtab *****************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - upb_symtab *upb_symtab_new(void); void upb_symtab_free(upb_symtab* s); const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym); @@ -3760,107 +3384,171 @@ const upb_filedef *upb_symtab_addfile( /* For generated code only: loads a generated descriptor. */ typedef struct upb_def_init { - struct upb_def_init **deps; + struct upb_def_init **deps; /* Dependencies of this file. */ + const upb_msglayout **layouts; /* Pre-order layouts of all messages. */ const char *filename; - upb_strview descriptor; + upb_strview descriptor; /* Serialized descriptor. */ } upb_def_init; bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init); + #ifdef __cplusplus } /* extern "C" */ +#endif /* __cplusplus */ -/* Non-const methods in upb::SymbolTable are NOT thread-safe. */ -class upb::SymbolTable { - public: - SymbolTable() : ptr_(upb_symtab_new(), upb_symtab_free) {} - explicit SymbolTable(upb_symtab* s) : ptr_(s, upb_symtab_free) {} +#endif /* UPB_DEF_H_ */ - const upb_symtab* ptr() const { return ptr_.get(); } - upb_symtab* ptr() { return ptr_.get(); } +#ifndef UPB_REFLECTION_H_ +#define UPB_REFLECTION_H_ - /* Finds an entry in the symbol table with this exact name. If not found, - * returns NULL. */ - MessageDefPtr LookupMessage(const char *sym) const { - return MessageDefPtr(upb_symtab_lookupmsg(ptr_.get(), sym)); - } - EnumDefPtr LookupEnum(const char *sym) const { - return EnumDefPtr(upb_symtab_lookupenum(ptr_.get(), sym)); - } - FileDefPtr LookupFile(const char *name) const { - return FileDefPtr(upb_symtab_lookupfile(ptr_.get(), name)); - } +typedef union { + bool bool_val; + float float_val; + double double_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + const upb_map* map_val; + const upb_msg* msg_val; + const upb_array* array_val; + upb_strview str_val; +} upb_msgval; - /* TODO: iteration? */ +typedef union { + upb_map* map; + upb_msg* msg; + upb_array* array; +} upb_mutmsgval; - /* Adds the given serialized FileDescriptorProto to the pool. */ - FileDefPtr AddFile(const google_protobuf_FileDescriptorProto *file_proto, - Status *status) { - return FileDefPtr( - upb_symtab_addfile(ptr_.get(), file_proto, status->ptr())); - } +/** upb_msg *******************************************************************/ - private: - std::unique_ptr ptr_; -}; +/* Creates a new message of the given type in the given arena. */ +upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a); -UPB_INLINE const char* upb_safecstr(const std::string& str) { - UPB_ASSERT(str.size() == std::strlen(str.c_str())); - return str.c_str(); -} +/* Returns the value associated with this field. */ +upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f); -#endif /* __cplusplus */ +/* Returns a mutable pointer to a map, array, or submessage value. If the given + * arena is non-NULL this will construct a new object if it was not previously + * present. May not be called for primitive fields. */ +upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f, upb_arena *a); +/* May only be called for fields where upb_fielddef_haspresence(f) == true. */ +bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f); -#endif /* UPB_DEF_H_ */ +/* Returns whether any field is set in the oneof. */ +bool upb_msg_hasoneof(const upb_msg *msg, const upb_oneofdef *o); +/* Sets the given field to the given value. For a msg/array/map/string, the + * value must be in the same arena. */ +void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val, + upb_arena *a); -#ifndef UPB_MSGFACTORY_H_ -#define UPB_MSGFACTORY_H_ +/* Clears any field presence and sets the value back to its default. */ +void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f); -/** upb_msgfactory ************************************************************/ +/* Iterate over present fields. + * + * size_t iter = UPB_MSG_BEGIN; + * const upb_fielddef *f; + * upb_msgval val; + * while (upb_msg_next(msg, m, ext_pool, &f, &val, &iter)) { + * process_field(f, val); + * } + * + * If ext_pool is NULL, no extensions will be returned. If the given symtab + * returns extensions that don't match what is in this message, those extensions + * will be skipped. + */ -struct upb_msgfactory; -typedef struct upb_msgfactory upb_msgfactory; +#define UPB_MSG_BEGIN -1 +bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m, + const upb_symtab *ext_pool, const upb_fielddef **f, + upb_msgval *val, size_t *iter); -#ifdef __cplusplus -extern "C" { -#endif +/* Adds unknown data (serialized protobuf data) to the given message. The data + * is copied into the message instance. */ +void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, + upb_arena *arena); -/* A upb_msgfactory contains a cache of upb_msglayout, upb_handlers, and - * upb_visitorplan objects. These are the objects necessary to represent, - * populate, and and visit upb_msg objects. - * - * These caches are all populated by upb_msgdef, and lazily created on demand. - */ +/* Returns a reference to the message's unknown data. */ +const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); -/* Creates and destroys a msgfactory, respectively. The messages for this - * msgfactory must come from |symtab| (which should outlive the msgfactory). */ -upb_msgfactory *upb_msgfactory_new(const upb_symtab *symtab); -void upb_msgfactory_free(upb_msgfactory *f); +/** upb_array *****************************************************************/ -const upb_symtab *upb_msgfactory_symtab(const upb_msgfactory *f); +/* Creates a new array on the given arena that holds elements of this type. */ +upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type); -/* The functions to get cached objects, lazily creating them on demand. These - * all require: - * - * - m is in upb_msgfactory_symtab(f) - * - upb_msgdef_mapentry(m) == false (since map messages can't have layouts). +/* Returns the size of the array. */ +size_t upb_array_size(const upb_array *arr); + +/* Returns the given element, which must be within the array's current size. */ +upb_msgval upb_array_get(const upb_array *arr, size_t i); + +/* Sets the given element, which must be within the array's current size. */ +void upb_array_set(upb_array *arr, size_t i, upb_msgval val); + +/* Appends an element to the array. Returns false on allocation failure. */ +bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena); + +/* Changes the size of a vector. New elements are initialized to empty/0. + * Returns false on allocation failure. */ +bool upb_array_resize(upb_array *array, size_t size, upb_arena *arena); + +/** upb_map *******************************************************************/ + +/* Creates a new map on the given arena with the given key/value size. */ +upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type, + upb_fieldtype_t value_type); + +/* Returns the number of entries in the map. */ +size_t upb_map_size(const upb_map *map); + +/* Stores a value for the given key into |*val| (or the zero value if the key is + * not present). Returns whether the key was present. The |val| pointer may be + * NULL, in which case the function tests whether the given key is present. */ +bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val); + +/* Removes all entries in the map. */ +void upb_map_clear(upb_map *map); + +/* Sets the given key to the given value. Returns true if this was a new key in + * the map, or false if an existing key was replaced. */ +bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val, + upb_arena *arena); + +/* Deletes this key from the table. Returns true if the key was present. */ +bool upb_map_delete(upb_map *map, upb_msgval key); + +/* Map iteration: * - * The returned objects will live for as long as the msgfactory does. + * size_t iter = UPB_MAP_BEGIN; + * while (upb_mapiter_next(map, &iter)) { + * upb_msgval key = upb_mapiter_key(map, iter); + * upb_msgval val = upb_mapiter_value(map, iter); * - * TODO(haberman): consider making this thread-safe and take a const - * upb_msgfactory. */ -const upb_msglayout *upb_msgfactory_getlayout(upb_msgfactory *f, - const upb_msgdef *m); + * // If mutating is desired. + * upb_mapiter_setvalue(map, iter, value2); + * } + */ + +/* Advances to the next entry. Returns false if no more entries are present. */ +bool upb_mapiter_next(const upb_map *map, size_t *iter); + +/* Returns the key and value for this entry of the map. */ +upb_msgval upb_mapiter_key(const upb_map *map, size_t iter); +upb_msgval upb_mapiter_value(const upb_map *map, size_t iter); + +/* Sets the value for this entry. The iterator must not be done, and the + * iterator must not have been initialized const. */ +void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); -#ifdef __cplusplus -} /* extern "C" */ -#endif -#endif /* UPB_MSGFACTORY_H_ */ +#endif /* UPB_REFLECTION_H_ */ /* ** upb::Handlers (upb_handlers) ** @@ -5693,15 +5381,16 @@ UPB_INLINE bool upb_sink_startsubmsg(upb_sink s, upb_selector_t sel, return sub->closure ? true : false; } -UPB_INLINE bool upb_sink_endsubmsg(upb_sink s, upb_selector_t sel) { +UPB_INLINE bool upb_sink_endsubmsg(upb_sink s, upb_sink sub, + upb_selector_t sel) { typedef upb_endfield_handlerfunc func; func *endsubmsg; const void *hd; if (!s.handlers) return true; endsubmsg = (func*)upb_handlers_gethandler(s.handlers, sel, &hd); - if (!endsubmsg) return s.closure; - return endsubmsg(s.closure, hd); + if (!endsubmsg) return true; + return endsubmsg(sub.closure, hd); } #ifdef __cplusplus @@ -5867,8 +5556,8 @@ class upb::Sink { return ret; } - bool EndSubMessage(HandlersPtr::Selector s) { - return upb_sink_endsubmsg(sink_, s); + bool EndSubMessage(HandlersPtr::Selector s, Sink sub) { + return upb_sink_endsubmsg(sink_, sub.sink_, s); } /* For repeated fields of any type, the sequence of values must be wrapped in @@ -6445,7 +6134,7 @@ struct upb_pbdecoder { char residual[UPB_DECODER_MAX_RESIDUAL_BYTES]; char *residual_end; - /* Bytes of data that should be discarded from the input before we start + /* Bytes of data that should be discarded from the input beore we start * parsing again. We set this when we internally determine that we can * safely skip the next N bytes, but this region extends past the current * user buffer. */ @@ -6567,21 +6256,22 @@ extern "C" { * descriptor type (upb_descriptortype_t). */ extern const uint8_t upb_pb_native_wire_types[]; -UPB_INLINE uint64_t byteswap64(uint64_t val) -{ - return ((((val) & 0xff00000000000000ull) >> 56) - | (((val) & 0x00ff000000000000ull) >> 40) - | (((val) & 0x0000ff0000000000ull) >> 24) - | (((val) & 0x000000ff00000000ull) >> 8) - | (((val) & 0x00000000ff000000ull) << 8) - | (((val) & 0x0000000000ff0000ull) << 24) - | (((val) & 0x000000000000ff00ull) << 40) - | (((val) & 0x00000000000000ffull) << 56)); +UPB_INLINE uint64_t byteswap64(uint64_t val) { + uint64_t byte = 0xff; + return (val & (byte << 56) >> 56) + | (val & (byte << 48) >> 40) + | (val & (byte << 40) >> 24) + | (val & (byte << 32) >> 8) + | (val & (byte << 24) << 8) + | (val & (byte << 16) << 24) + | (val & (byte << 8) << 40) + | (val & (byte << 0) << 56); } /* Zig-zag encoding/decoding **************************************************/ -UPB_INLINE int32_t upb_zzdec_32(uint32_t n) { +UPB_INLINE int32_t upb_zzdec_32(uint64_t _n) { + uint32_t n = (uint32_t)_n; return (n >> 1) ^ -(int32_t)(n & 1); } UPB_INLINE int64_t upb_zzdec_64(uint64_t n) { @@ -7064,8 +6754,9 @@ class upb::json::PrinterPtr { #endif /* UPB_JSON_TYPED_PRINTER_H_ */ /* See port_def.inc. This should #undef all macros #defined there. */ +#undef UPB_MAPTYPE_STRING #undef UPB_SIZE -#undef UPB_FIELD_AT +#undef UPB_PTR_AT #undef UPB_READ_ONEOF #undef UPB_WRITE_ONEOF #undef UPB_INLINE @@ -7075,6 +6766,7 @@ class upb::json::PrinterPtr { #undef UPB_MAX #undef UPB_MIN #undef UPB_UNUSED +#undef UPB_ASSUME #undef UPB_ASSERT #undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index ba7acbc2ac3a..1a18da3e952c 100644 --- a/ruby/google-protobuf.gemspec +++ b/ruby/google-protobuf.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "google-protobuf" - s.version = "3.11.2" + s.version = "3.14.0" git_tag = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag s.licenses = ["BSD-3-Clause"] s.summary = "Protocol Buffers" @@ -17,13 +17,13 @@ Gem::Specification.new do |s| else s.files += Dir.glob('ext/**/*') s.extensions= ["ext/google/protobuf_c/extconf.rb"] - s.add_development_dependency "rake-compiler-dock", "~> 0.6.0" + s.add_development_dependency "rake-compiler-dock", ">= 1.0.1", "< 2.0" end s.test_files = ["tests/basic.rb", "tests/stress.rb", "tests/generated_code_test.rb"] s.required_ruby_version = '>= 2.3' - s.add_development_dependency "rake-compiler", "~> 0.9.5" + s.add_development_dependency "rake-compiler", "~> 1.1.0" s.add_development_dependency "test-unit", '~> 3.0', '>= 3.0.9' s.add_development_dependency "rubygems-tasks", "~> 0.2.4" end diff --git a/ruby/lib/google/protobuf/well_known_types.rb b/ruby/lib/google/protobuf/well_known_types.rb old mode 100644 new mode 100755 diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb old mode 100644 new mode 100755 index 1cb8d3463ed4..687e1fb93458 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -32,11 +32,11 @@ def proto_module include CommonTests def test_has_field - m = TestMessage.new - assert !m.has_optional_msg? - m.optional_msg = TestMessage2.new - assert m.has_optional_msg? - assert TestMessage.descriptor.lookup('optional_msg').has?(m) + m = TestSingularFields.new + assert !m.has_singular_msg? + m.singular_msg = TestMessage2.new + assert m.has_singular_msg? + assert TestSingularFields.descriptor.lookup('singular_msg').has?(m) m = OneofMessage.new assert !m.has_my_oneof? @@ -45,32 +45,31 @@ def test_has_field assert_raise NoMethodError do m.has_a? end - assert_raise ArgumentError do - OneofMessage.descriptor.lookup('a').has?(m) - end + assert_true OneofMessage.descriptor.lookup('a').has?(m) - m = TestMessage.new + m = TestSingularFields.new assert_raise NoMethodError do - m.has_optional_int32? + m.has_singular_int32? end assert_raise ArgumentError do - TestMessage.descriptor.lookup('optional_int32').has?(m) + TestSingularFields.descriptor.lookup('singular_int32').has?(m) end assert_raise NoMethodError do - m.has_optional_string? + m.has_singular_string? end assert_raise ArgumentError do - TestMessage.descriptor.lookup('optional_string').has?(m) + TestSingularFields.descriptor.lookup('singular_string').has?(m) end assert_raise NoMethodError do - m.has_optional_bool? + m.has_singular_bool? end assert_raise ArgumentError do - TestMessage.descriptor.lookup('optional_bool').has?(m) + TestSingularFields.descriptor.lookup('singular_bool').has?(m) end + m = TestMessage.new assert_raise NoMethodError do m.has_repeated_msg? end @@ -79,40 +78,59 @@ def test_has_field end end + def test_no_presence + m = TestSingularFields.new + + # Explicitly setting to zero does not cause anything to be serialized. + m.singular_int32 = 0 + assert_equal "", TestSingularFields.encode(m) + + # Explicitly setting to a non-zero value *does* cause serialization. + m.singular_int32 = 1 + assert_not_equal "", TestSingularFields.encode(m) + + m.singular_int32 = 0 + assert_equal "", TestSingularFields.encode(m) + end + def test_set_clear_defaults - m = TestMessage.new + m = TestSingularFields.new + + m.singular_int32 = -42 + assert_equal -42, m.singular_int32 + m.clear_singular_int32 + assert_equal 0, m.singular_int32 + + m.singular_int32 = 50 + assert_equal 50, m.singular_int32 + TestSingularFields.descriptor.lookup('singular_int32').clear(m) + assert_equal 0, m.singular_int32 + + m.singular_string = "foo bar" + assert_equal "foo bar", m.singular_string + m.clear_singular_string + assert_equal "", m.singular_string + + m.singular_string = "foo" + assert_equal "foo", m.singular_string + TestSingularFields.descriptor.lookup('singular_string').clear(m) + assert_equal "", m.singular_string + + m.singular_msg = TestMessage2.new(:foo => 42) + assert_equal TestMessage2.new(:foo => 42), m.singular_msg + assert m.has_singular_msg? + m.clear_singular_msg + assert_equal nil, m.singular_msg + assert !m.has_singular_msg? + + m.singular_msg = TestMessage2.new(:foo => 42) + assert_equal TestMessage2.new(:foo => 42), m.singular_msg + TestSingularFields.descriptor.lookup('singular_msg').clear(m) + assert_equal nil, m.singular_msg + end - m.optional_int32 = -42 - assert_equal -42, m.optional_int32 - m.clear_optional_int32 - assert_equal 0, m.optional_int32 - - m.optional_int32 = 50 - assert_equal 50, m.optional_int32 - TestMessage.descriptor.lookup('optional_int32').clear(m) - assert_equal 0, m.optional_int32 - - m.optional_string = "foo bar" - assert_equal "foo bar", m.optional_string - m.clear_optional_string - assert_equal "", m.optional_string - - m.optional_string = "foo" - assert_equal "foo", m.optional_string - TestMessage.descriptor.lookup('optional_string').clear(m) - assert_equal "", m.optional_string - - m.optional_msg = TestMessage2.new(:foo => 42) - assert_equal TestMessage2.new(:foo => 42), m.optional_msg - assert m.has_optional_msg? - m.clear_optional_msg - assert_equal nil, m.optional_msg - assert !m.has_optional_msg? - - m.optional_msg = TestMessage2.new(:foo => 42) - assert_equal TestMessage2.new(:foo => 42), m.optional_msg - TestMessage.descriptor.lookup('optional_msg').clear(m) - assert_equal nil, m.optional_msg + def test_clear_repeated_fields + m = TestMessage.new m.repeated_int32.push(1) assert_equal [1], m.repeated_int32 @@ -128,6 +146,7 @@ def test_set_clear_defaults m.a = "foo" assert_equal "foo", m.a assert m.has_my_oneof? + assert_equal :a, m.my_oneof m.clear_a assert !m.has_my_oneof? @@ -143,7 +162,6 @@ def test_set_clear_defaults assert !m.has_my_oneof? end - def test_initialization_map_errors e = assert_raise ArgumentError do TestMessage.new(:hello => "world") @@ -276,6 +294,86 @@ def test_map_wrappers assert_equal m5, m end + def test_map_wrappers_with_default_values + run_asserts = ->(m) { + assert_equal 0.0, m.map_double[0].value + assert_equal 0.0, m.map_float[0].value + assert_equal 0, m.map_int32[0].value + assert_equal 0, m.map_int64[0].value + assert_equal 0, m.map_uint32[0].value + assert_equal 0, m.map_uint64[0].value + assert_equal false, m.map_bool[0].value + assert_equal '', m.map_string[0].value + assert_equal '', m.map_bytes[0].value + } + + m = proto_module::Wrapper.new( + map_double: {0 => Google::Protobuf::DoubleValue.new(value: 0.0)}, + map_float: {0 => Google::Protobuf::FloatValue.new(value: 0.0)}, + map_int32: {0 => Google::Protobuf::Int32Value.new(value: 0)}, + map_int64: {0 => Google::Protobuf::Int64Value.new(value: 0)}, + map_uint32: {0 => Google::Protobuf::UInt32Value.new(value: 0)}, + map_uint64: {0 => Google::Protobuf::UInt64Value.new(value: 0)}, + map_bool: {0 => Google::Protobuf::BoolValue.new(value: false)}, + map_string: {0 => Google::Protobuf::StringValue.new(value: '')}, + map_bytes: {0 => Google::Protobuf::BytesValue.new(value: '')}, + ) + + run_asserts.call(m) + serialized = proto_module::Wrapper::encode(m) + m2 = proto_module::Wrapper::decode(serialized) + run_asserts.call(m2) + + # Test the case where we are serializing directly from the parsed form + # (before anything lazy is materialized). + m3 = proto_module::Wrapper::decode(serialized) + serialized2 = proto_module::Wrapper::encode(m3) + m4 = proto_module::Wrapper::decode(serialized2) + run_asserts.call(m4) + + # Test that the lazy form compares equal to the expanded form. + m5 = proto_module::Wrapper::decode(serialized2) + assert_equal m5, m + end + + def test_map_wrappers_with_no_value + run_asserts = ->(m) { + assert_equal 0.0, m.map_double[0].value + assert_equal 0.0, m.map_float[0].value + assert_equal 0, m.map_int32[0].value + assert_equal 0, m.map_int64[0].value + assert_equal 0, m.map_uint32[0].value + assert_equal 0, m.map_uint64[0].value + assert_equal false, m.map_bool[0].value + assert_equal '', m.map_string[0].value + assert_equal '', m.map_bytes[0].value + } + + m = proto_module::Wrapper.new( + map_double: {0 => Google::Protobuf::DoubleValue.new()}, + map_float: {0 => Google::Protobuf::FloatValue.new()}, + map_int32: {0 => Google::Protobuf::Int32Value.new()}, + map_int64: {0 => Google::Protobuf::Int64Value.new()}, + map_uint32: {0 => Google::Protobuf::UInt32Value.new()}, + map_uint64: {0 => Google::Protobuf::UInt64Value.new()}, + map_bool: {0 => Google::Protobuf::BoolValue.new()}, + map_string: {0 => Google::Protobuf::StringValue.new()}, + map_bytes: {0 => Google::Protobuf::BytesValue.new()}, + ) + run_asserts.call(m) + + serialized = proto_module::Wrapper::encode(m) + m2 = proto_module::Wrapper::decode(serialized) + run_asserts.call(m2) + + # Test the case where we are serializing directly from the parsed form + # (before anything lazy is materialized). + m3 = proto_module::Wrapper::decode(serialized) + serialized2 = proto_module::Wrapper::encode(m3) + m4 = proto_module::Wrapper::decode(serialized2) + run_asserts.call(m4) + end + def test_concurrent_decoding o = Outer.new o.items[0] = Inner.new diff --git a/ruby/tests/basic_proto2.rb b/ruby/tests/basic_proto2.rb old mode 100644 new mode 100755 index 4c7ddd55b981..2d30a0894414 --- a/ruby/tests/basic_proto2.rb +++ b/ruby/tests/basic_proto2.rb @@ -73,10 +73,11 @@ def test_has_field m = OneofMessage.new assert !m.has_my_oneof? m.a = "foo" + assert m.has_my_oneof? + assert_equal :a, m.my_oneof assert m.has_a? assert OneofMessage.descriptor.lookup('a').has?(m) assert_equal "foo", m.a - assert m.has_my_oneof? assert !m.has_b? assert !OneofMessage.descriptor.lookup('b').has?(m) assert !m.has_c? @@ -197,6 +198,17 @@ def test_set_clear_defaults assert !m.has_my_oneof? end + def test_assign_nil + m = TestMessageDefaults.new + m.optional_msg = TestMessage2.new(:foo => 42) + + assert_equal TestMessage2.new(:foo => 42), m.optional_msg + assert m.has_optional_msg? + m.optional_msg = nil + assert_equal nil, m.optional_msg + assert !m.has_optional_msg? + end + def test_initialization_map_errors e = assert_raise ArgumentError do TestMessage.new(:hello => "world") diff --git a/ruby/tests/basic_test.proto b/ruby/tests/basic_test.proto index a91854007535..6086879d0923 100644 --- a/ruby/tests/basic_test.proto +++ b/ruby/tests/basic_test.proto @@ -21,17 +21,17 @@ message Baz { } message TestMessage { - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - bool optional_bool = 5; - float optional_float = 6; - double optional_double = 7; - string optional_string = 8; - bytes optional_bytes = 9; - TestMessage2 optional_msg = 10; - TestEnum optional_enum = 11; + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional bool optional_bool = 5; + optional float optional_float = 6; + optional double optional_double = 7; + optional string optional_string = 8; + optional bytes optional_bytes = 9; + optional TestMessage2 optional_msg = 10; + optional TestEnum optional_enum = 11; repeated int32 repeated_int32 = 12; repeated int64 repeated_int64 = 13; @@ -46,6 +46,20 @@ message TestMessage { repeated TestEnum repeated_enum = 22; } +message TestSingularFields { + int32 singular_int32 = 1; + int64 singular_int64 = 2; + uint32 singular_uint32 = 3; + uint64 singular_uint64 = 4; + bool singular_bool = 5; + float singular_float = 6; + double singular_double = 7; + string singular_string = 8; + bytes singular_bytes = 9; + TestMessage2 singular_msg = 10; + TestEnum singular_enum = 11; +} + message TestMessage2 { int32 foo = 1; } diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb index ada42432ebbc..1f5013a529ad 100644 --- a/ruby/tests/common_tests.rb +++ b/ruby/tests/common_tests.rb @@ -1265,6 +1265,37 @@ def test_comparison_with_arbitrary_object assert proto_module::TestMessage.new != nil end + def test_wrappers_set_to_default + run_asserts = ->(m) { + assert_equal 0.0, m.double.value + assert_equal 0.0, m.float.value + assert_equal 0, m.int32.value + assert_equal 0, m.int64.value + assert_equal 0, m.uint32.value + assert_equal 0, m.uint64.value + assert_equal false, m.bool.value + assert_equal '', m.string.value + assert_equal '', m.bytes.value + } + + m = proto_module::Wrapper.new( + double: Google::Protobuf::DoubleValue.new(value: 0.0), + float: Google::Protobuf::FloatValue.new(value: 0.0), + int32: Google::Protobuf::Int32Value.new(value: 0), + int64: Google::Protobuf::Int64Value.new(value: 0), + uint32: Google::Protobuf::UInt32Value.new(value: 0), + uint64: Google::Protobuf::UInt64Value.new(value: 0), + bool: Google::Protobuf::BoolValue.new(value: false), + string: Google::Protobuf::StringValue.new(value: ""), + bytes: Google::Protobuf::BytesValue.new(value: ''), + ) + + run_asserts.call(m) + m2 = proto_module::Wrapper.decode(m.to_proto) + run_asserts.call(m2) + m3 = proto_module::Wrapper.decode_json(m.to_json) + end + def test_wrapper_getters run_asserts = ->(m) { assert_equal 2.0, m.double_as_value @@ -1692,7 +1723,7 @@ def test_converts_duration m.duration = Rational(3, 2) assert_equal Google::Protobuf::Duration.new(seconds: 1, nanos: 500_000_000), m.duration - m.duration = BigDecimal.new("5") + m.duration = BigDecimal("5") assert_equal Google::Protobuf::Duration.new(seconds: 5, nanos: 0), m.duration m = proto_module::TimeMessage.new(duration: 1.1) @@ -1708,7 +1739,7 @@ def test_freeze m.freeze frozen_error = assert_raise(FrozenErrorType) { m.optional_int32 = 20 } - assert_equal "can't modify frozen #{proto_module}::TestMessage", frozen_error.message + assert_match "can't modify frozen #{proto_module}::TestMessage", frozen_error.message assert_equal 10, m.optional_int32 assert_equal true, m.frozen? diff --git a/ruby/tests/encode_decode_test.rb b/ruby/tests/encode_decode_test.rb old mode 100644 new mode 100755 diff --git a/ruby/tests/gc_test.rb b/ruby/tests/gc_test.rb old mode 100644 new mode 100755 index 55b96289e812..6ef4e2e301ed --- a/ruby/tests/gc_test.rb +++ b/ruby/tests/gc_test.rb @@ -4,7 +4,9 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) old_gc = GC.stress -GC.stress = 0x01 | 0x04 +# Ruby 2.7.0 - 2.7.1 has a GC bug in its parser, so turn off stress for now +# See https://bugs.ruby-lang.org/issues/16807 +GC.stress = 0x01 | 0x04 unless RUBY_VERSION.match?(/^2\.7\./) require 'generated_code_pb' require 'generated_code_proto2_pb' GC.stress = old_gc diff --git a/ruby/tests/generated_code_proto2_test.rb b/ruby/tests/generated_code_proto2_test.rb old mode 100644 new mode 100755 diff --git a/ruby/tests/generated_code_test.rb b/ruby/tests/generated_code_test.rb old mode 100644 new mode 100755 diff --git a/ruby/tests/repeated_field_test.rb b/ruby/tests/repeated_field_test.rb old mode 100644 new mode 100755 index ced9de83818e..6307447bc3f3 --- a/ruby/tests/repeated_field_test.rb +++ b/ruby/tests/repeated_field_test.rb @@ -20,6 +20,7 @@ def test_acts_like_an_array :iter_for_each_with_index, :dimensions, :copy_data, :copy_data_simple, :nitems, :iter_for_reverse_each, :indexes, :append, :prepend] arr_methods -= [:union, :difference, :filter!] + arr_methods -= [:intersection, :deconstruct] # ruby 2.7 methods we can ignore arr_methods.each do |method_name| assert m.repeated_string.respond_to?(method_name) == true, "does not respond to #{method_name}" end diff --git a/ruby/tests/stress.rb b/ruby/tests/stress.rb old mode 100644 new mode 100755 diff --git a/ruby/tests/type_errors.rb b/ruby/tests/type_errors.rb old mode 100644 new mode 100755 diff --git a/ruby/tests/well_known_types_test.rb b/ruby/tests/well_known_types_test.rb old mode 100644 new mode 100755 diff --git a/ruby/travis-test.sh b/ruby/travis-test.sh index 6dec0c906aa5..b39a6c5d121b 100755 --- a/ruby/travis-test.sh +++ b/ruby/travis-test.sh @@ -16,7 +16,7 @@ test_version() { git clean -f && \ gem install bundler && bundle && \ rake test" - elif [ "$version" == "ruby-2.6.0" ] ; then + elif [ "$version" == "ruby-2.6.0" -o "$version" == "ruby-2.7.0" ] ; then bash --login -c \ "rvm install $version && rvm use $version && \ which ruby && \ diff --git a/src/Makefile.am b/src/Makefile.am index 5ac489b6bc17..980a357afd37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ else PTHREAD_DEF = endif -PROTOBUF_VERSION = 22:2:0 +PROTOBUF_VERSION = 25:0:0 if GCC # Turn on all warnings except for sign comparison (we ignore sign comparison @@ -68,7 +68,6 @@ nobase_include_HEADERS = \ google/protobuf/stubs/bytestream.h \ google/protobuf/stubs/casts.h \ google/protobuf/stubs/common.h \ - google/protobuf/stubs/fastmem.h \ google/protobuf/stubs/hash.h \ google/protobuf/stubs/logging.h \ google/protobuf/stubs/macros.h \ @@ -104,7 +103,6 @@ nobase_include_HEADERS = \ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/implicit_weak_message.h \ - google/protobuf/inlined_string_field.h \ google/protobuf/io/io_win32.h \ google/protobuf/map_entry.h \ google/protobuf/map_entry_lite.h \ @@ -202,12 +200,14 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/time.h \ google/protobuf/any_lite.cc \ google/protobuf/arena.cc \ + google/protobuf/arenastring.cc \ google/protobuf/extension_set.cc \ google/protobuf/generated_enum_util.cc \ google/protobuf/generated_message_util.cc \ google/protobuf/generated_message_table_driven_lite.h \ google/protobuf/generated_message_table_driven_lite.cc \ google/protobuf/implicit_weak_message.cc \ + google/protobuf/map.cc \ google/protobuf/message_lite.cc \ google/protobuf/parse_context.cc \ google/protobuf/repeated_field.cc \ @@ -497,9 +497,6 @@ protoc_inputs = \ google/protobuf/unittest_lite.proto \ google/protobuf/unittest_mset.proto \ google/protobuf/unittest_mset_wire_format.proto \ - google/protobuf/unittest_no_arena_lite.proto \ - google/protobuf/unittest_no_arena_import.proto \ - google/protobuf/unittest_no_arena.proto \ google/protobuf/unittest_no_field_presence.proto \ google/protobuf/unittest_no_generic_services.proto \ google/protobuf/unittest_optimize_for.proto \ @@ -510,6 +507,7 @@ protoc_inputs = \ google/protobuf/unittest_proto3_arena.proto \ google/protobuf/unittest_proto3_arena_lite.proto \ google/protobuf/unittest_proto3_lite.proto \ + google/protobuf/unittest_proto3_optional.proto \ google/protobuf/unittest_well_known_types.proto \ google/protobuf/util/internal/testdata/anys.proto \ google/protobuf/util/internal/testdata/books.proto \ @@ -572,8 +570,6 @@ protoc_lite_outputs = \ google/protobuf/map_lite_unittest.pb.h \ google/protobuf/unittest_lite.pb.cc \ google/protobuf/unittest_lite.pb.h \ - google/protobuf/unittest_no_arena_lite.pb.cc \ - google/protobuf/unittest_no_arena_lite.pb.h \ google/protobuf/unittest_import_lite.pb.cc \ google/protobuf/unittest_import_lite.pb.h \ google/protobuf/unittest_import_public_lite.pb.cc \ @@ -619,10 +615,6 @@ protoc_outputs = \ google/protobuf/unittest_mset.pb.h \ google/protobuf/unittest_mset_wire_format.pb.cc \ google/protobuf/unittest_mset_wire_format.pb.h \ - google/protobuf/unittest_no_arena_import.pb.cc \ - google/protobuf/unittest_no_arena_import.pb.h \ - google/protobuf/unittest_no_arena.pb.cc \ - google/protobuf/unittest_no_arena.pb.h \ google/protobuf/unittest_no_field_presence.pb.cc \ google/protobuf/unittest_no_field_presence.pb.h \ google/protobuf/unittest_no_generic_services.pb.cc \ @@ -643,6 +635,8 @@ protoc_outputs = \ google/protobuf/unittest_proto3_arena_lite.pb.h \ google/protobuf/unittest_proto3_lite.pb.cc \ google/protobuf/unittest_proto3_lite.pb.h \ + google/protobuf/unittest_proto3_optional.pb.cc \ + google/protobuf/unittest_proto3_optional.pb.h \ google/protobuf/unittest_well_known_types.pb.cc \ google/protobuf/unittest_well_known_types.pb.h \ google/protobuf/util/internal/testdata/anys.pb.cc \ @@ -686,7 +680,7 @@ else # relative to srcdir, which may not be the same as the current directory when # building out-of-tree. unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs) - oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) ) + oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) --experimental_allow_proto3_optional ) touch unittest_proto_middleman endif diff --git a/src/README.md b/src/README.md index 007deb328ef3..78d6bb5ec72c 100644 --- a/src/README.md +++ b/src/README.md @@ -40,22 +40,21 @@ You can also get the source by "git clone" our git repository. Make sure you have also cloned the submodules and generated the configure script (skip this if you are using a release .tar.gz or .zip package): -```shell git clone https://github.com/protocolbuffers/protobuf.git cd protobuf git submodule update --init --recursive ./autogen.sh -``` + To build and install the C++ Protocol Buffer runtime and the Protocol Buffer compiler (protoc) execute the following: -```shell + ./configure make make check sudo make install sudo ldconfig # refresh shared library cache. -``` + If "make check" fails, you can still install, but it is likely that some features of this library will not work correctly on your system. Proceed at your own risk. @@ -123,15 +122,15 @@ of "protobuf" in these examples. For a Mac system, Unix tools are not available by default. You will first need to install Xcode from the Mac AppStore and then run the following command from a terminal: -```shell + sudo xcode-select --install -```shell + To install Unix tools, you can install "port" following the instructions at https://www.macports.org . This will reside in /opt/local/bin/port for most Mac installations. -```shell + sudo /opt/local/bin/port install autoconf automake libtool -``` + Then follow the Unix instructions above. **Note for cross-compiling** diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc index a79214b750b9..029ba0d9299d 100644 --- a/src/google/protobuf/any.cc +++ b/src/google/protobuf/any.cc @@ -41,24 +41,25 @@ namespace google { namespace protobuf { namespace internal { -void AnyMetadata::PackFrom(const Message& message) { - PackFrom(message, kTypeGoogleApisComPrefix); +bool AnyMetadata::PackFrom(const Message& message) { + return PackFrom(message, kTypeGoogleApisComPrefix); } -void AnyMetadata::PackFrom(const Message& message, - const std::string& type_url_prefix) { - type_url_->SetNoArena( +bool AnyMetadata::PackFrom(const Message& message, + StringPiece type_url_prefix) { + type_url_->Set( &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(), - GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix)); - message.SerializeToString(value_->MutableNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())); + GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), + nullptr); + return message.SerializeToString( + value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr)); } bool AnyMetadata::UnpackTo(Message* message) const { if (!InternalIs(message->GetDescriptor()->full_name())) { return false; } - return message->ParseFromString(value_->GetNoArena()); + return message->ParseFromString(value_->Get()); } bool GetAnyFieldDescriptors(const Message& message, @@ -79,3 +80,5 @@ bool GetAnyFieldDescriptors(const Message& message, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h index 59dd50cb21d6..684fbf158431 100644 --- a/src/google/protobuf/any.h +++ b/src/google/protobuf/any.h @@ -60,16 +60,19 @@ class PROTOBUF_EXPORT AnyMetadata { typedef ArenaStringPtr ValueType; public: // AnyMetadata does not take ownership of "type_url" and "value". - AnyMetadata(UrlType* type_url, ValueType* value); + constexpr AnyMetadata(UrlType* type_url, ValueType* value) + : type_url_(type_url), value_(value) {} // Packs a message using the default type URL prefix: "type.googleapis.com". // The resulted type URL will be "type.googleapis.com/". + // Returns false if serializing the message failed. template - void PackFrom(const T& message) { - InternalPackFrom(message, kTypeGoogleApisComPrefix, T::FullMessageName()); + bool PackFrom(const T& message) { + return InternalPackFrom(message, kTypeGoogleApisComPrefix, + T::FullMessageName()); } - void PackFrom(const Message& message); + bool PackFrom(const Message& message); // Packs a message using the given type URL prefix. The type URL will be // constructed by concatenating the message type's full name to the prefix @@ -77,12 +80,13 @@ class PROTOBUF_EXPORT AnyMetadata { // For example, both PackFrom(message, "type.googleapis.com") and // PackFrom(message, "type.googleapis.com/") yield the same result type // URL: "type.googleapis.com/". + // Returns false if serializing the message failed. template - void PackFrom(const T& message, StringPiece type_url_prefix) { - InternalPackFrom(message, type_url_prefix, T::FullMessageName()); + bool PackFrom(const T& message, StringPiece type_url_prefix) { + return InternalPackFrom(message, type_url_prefix, T::FullMessageName()); } - void PackFrom(const Message& message, const std::string& type_url_prefix); + bool PackFrom(const Message& message, StringPiece type_url_prefix); // Unpacks the payload into the given message. Returns false if the message's // type doesn't match the type specified in the type URL (i.e., the full @@ -104,7 +108,7 @@ class PROTOBUF_EXPORT AnyMetadata { } private: - void InternalPackFrom(const MessageLite& message, + bool InternalPackFrom(const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name); bool InternalUnpackTo(StringPiece type_name, @@ -124,14 +128,14 @@ class PROTOBUF_EXPORT AnyMetadata { // // NOTE: this function is available publicly as: // google::protobuf::Any() // static method on the generated message type. -bool ParseAnyTypeUrl(const std::string& type_url, std::string* full_type_name); +bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name); // Get the proto type name and prefix from Any::type_url value. For example, // passing "type.googleapis.com/rpc.QueryOrigin" will return // "type.googleapis.com/" in *url_prefix and "rpc.QueryOrigin" in // *full_type_name. Returns false if the type_url does not have a "/" in the // type url separating the full type name. -bool ParseAnyTypeUrl(const std::string& type_url, std::string* url_prefix, +bool ParseAnyTypeUrl(StringPiece type_url, std::string* url_prefix, std::string* full_type_name); // See if message is of type google.protobuf.Any, if so, return the descriptors diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 5d7ea1ccba76..c421045fba98 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class AnyDefaultTypeInternal { public: @@ -28,7 +30,6 @@ static void InitDefaultsscc_info_Any_google_2fprotobuf_2fany_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Any(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Any::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Any_google_2fprotobuf_2fany_2eproto = @@ -58,10 +59,10 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\031google/protobuf/any.proto\022\017google.prot" "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002" - " \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z" - "%github.com/golang/protobuf/ptypes/any\242\002" - "\003GPB\252\002\036Google.Protobuf.WellKnownTypesb\006p" - "roto3" + " \001(\014Bv\n\023com.google.protobufB\010AnyProtoP\001Z" + ",google.golang.org/protobuf/types/known/" + "anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownT" + "ypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fany_2eproto_deps[1] = { }; @@ -69,22 +70,19 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_Any_google_2fprotobuf_2fany_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fany_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fany_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = { - &descriptor_table_google_2fprotobuf_2fany_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", 205, + false, false, descriptor_table_protodef_google_2fprotobuf_2fany_2eproto, "google/protobuf/any.proto", 212, &descriptor_table_google_2fprotobuf_2fany_2eproto_once, descriptor_table_google_2fprotobuf_2fany_2eproto_sccs, descriptor_table_google_2fprotobuf_2fany_2eproto_deps, 1, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fany_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fany_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fany_2eproto, file_level_service_descriptors_google_2fprotobuf_2fany_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fany_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Any::InitAsDefaultInstance() { -} bool Any::GetAnyFieldDescriptors( const ::PROTOBUF_NAMESPACE_ID::Message& message, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, @@ -92,8 +90,9 @@ bool Any::GetAnyFieldDescriptors( return ::PROTOBUF_NAMESPACE_ID::internal::GetAnyFieldDescriptors( message, type_url_field, value_field); } -bool Any::ParseAnyTypeUrl(const string& type_url, - std::string* full_type_name) { +bool Any::ParseAnyTypeUrl( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url, + std::string* full_type_name) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseAnyTypeUrl(type_url, full_type_name); } @@ -102,23 +101,26 @@ class Any::_Internal { public: }; -Any::Any() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr), _any_metadata_(&type_url_, &value_) { +Any::Any(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena), + _any_metadata_(&type_url_, &value_) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Any) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.Any) } Any::Any(const Any& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _any_metadata_(&type_url_, &value_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_type_url().empty()) { - type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.type_url_); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), + GetArena()); } value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_value().empty()) { - value_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.value_); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), + GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Any) } @@ -132,13 +134,21 @@ void Any::SharedCtor() { Any::~Any() { // @@protoc_insertion_point(destructor:google.protobuf.Any) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Any::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } +void Any::ArenaDtor(void* object) { + Any* _this = reinterpret_cast< Any* >(object); + (void)_this; +} +void Any::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void Any::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -154,9 +164,9 @@ void Any::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - type_url_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - value_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _internal_metadata_.Clear(); + type_url_.ClearToEmpty(); + value_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -189,7 +199,9 @@ const char* Any::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -227,7 +239,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Any::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any) return target; @@ -282,17 +294,15 @@ void Any::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Any::MergeFrom(const Any& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; if (from.type_url().size() > 0) { - - type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.type_url_); + _internal_set_type_url(from._internal_type_url()); } if (from.value().size() > 0) { - - value_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.value_); + _internal_set_value(from._internal_value()); } } @@ -316,11 +326,9 @@ bool Any::IsInitialized() const { void Any::InternalSwap(Any* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - type_url_.Swap(&other->type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - value_.Swap(&other->value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + type_url_.Swap(&other->type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + value_.Swap(&other->value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } ::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const { @@ -332,7 +340,7 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Any::GetMetadata() const { PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::Any* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::Any >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::Any >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::Any >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index f551818e61fb..ae1151ae5534 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -45,7 +44,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fany_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -66,10 +65,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT Any : +class PROTOBUF_EXPORT Any PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ { public: - Any(); + inline Any() : Any(nullptr) {} virtual ~Any(); Any(const Any& from); @@ -83,7 +82,7 @@ class PROTOBUF_EXPORT Any : return *this; } inline Any& operator=(Any&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -102,7 +101,6 @@ class PROTOBUF_EXPORT Any : } static const Any& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Any* internal_default_instance() { return reinterpret_cast( &_Any_default_instance_); @@ -112,12 +110,12 @@ class PROTOBUF_EXPORT Any : // implements Any ----------------------------------------------- - void PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) { - _any_metadata_.PackFrom(message); + bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message) { + return _any_metadata_.PackFrom(message); } - void PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message, - const std::string& type_url_prefix) { - _any_metadata_.PackFrom(message, type_url_prefix); + bool PackFrom(const ::PROTOBUF_NAMESPACE_ID::Message& message, + ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { + return _any_metadata_.PackFrom(message, type_url_prefix); } bool UnpackTo(::PROTOBUF_NAMESPACE_ID::Message* message) const { return _any_metadata_.UnpackTo(message); @@ -127,13 +125,13 @@ class PROTOBUF_EXPORT Any : const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** type_url_field, const ::PROTOBUF_NAMESPACE_ID::FieldDescriptor** value_field); template ::value>::type> - void PackFrom(const T& message) { - _any_metadata_.PackFrom(message); + bool PackFrom(const T& message) { + return _any_metadata_.PackFrom(message); } template ::value>::type> - void PackFrom(const T& message, - const std::string& type_url_prefix) { - _any_metadata_.PackFrom(message, type_url_prefix);} + bool PackFrom(const T& message, + ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url_prefix) { + return _any_metadata_.PackFrom(message, type_url_prefix);} template ::value>::type> bool UnpackTo(T* message) const { return _any_metadata_.UnpackTo(message); @@ -141,13 +139,22 @@ class PROTOBUF_EXPORT Any : template bool Is() const { return _any_metadata_.Is(); } - static bool ParseAnyTypeUrl(const string& type_url, + static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url, std::string* full_type_name); friend void swap(Any& a, Any& b) { a.Swap(&b); } inline void Swap(Any* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Any* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -182,13 +189,11 @@ class PROTOBUF_EXPORT Any : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.Any"; } + protected: + explicit Any(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -244,7 +249,9 @@ class PROTOBUF_EXPORT Any : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; @@ -264,7 +271,7 @@ class PROTOBUF_EXPORT Any : // string type_url = 1; inline void Any::clear_type_url() { - type_url_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + type_url_.ClearToEmpty(); } inline const std::string& Any::type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Any.type_url) @@ -279,38 +286,38 @@ inline std::string* Any::mutable_type_url() { return _internal_mutable_type_url(); } inline const std::string& Any::_internal_type_url() const { - return type_url_.GetNoArena(); + return type_url_.Get(); } inline void Any::_internal_set_type_url(const std::string& value) { - type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Any::set_type_url(std::string&& value) { - type_url_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + type_url_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.type_url) } inline void Any::set_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url) } -inline void Any::set_type_url(const char* value, size_t size) { +inline void Any::set_type_url(const char* value, + size_t size) { - type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.type_url) } inline std::string* Any::_internal_mutable_type_url() { - return type_url_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Any::release_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url) - - return type_url_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Any::set_allocated_type_url(std::string* type_url) { if (type_url != nullptr) { @@ -318,13 +325,14 @@ inline void Any::set_allocated_type_url(std::string* type_url) { } else { } - type_url_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url); + type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url) } // bytes value = 2; inline void Any::clear_value() { - value_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + value_.ClearToEmpty(); } inline const std::string& Any::value() const { // @@protoc_insertion_point(field_get:google.protobuf.Any.value) @@ -339,38 +347,38 @@ inline std::string* Any::mutable_value() { return _internal_mutable_value(); } inline const std::string& Any::_internal_value() const { - return value_.GetNoArena(); + return value_.Get(); } inline void Any::_internal_set_value(const std::string& value) { - value_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Any::set_value(std::string&& value) { - value_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + value_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.value) } inline void Any::set_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - value_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value) } -inline void Any::set_value(const void* value, size_t size) { +inline void Any::set_value(const void* value, + size_t size) { - value_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.value) } inline std::string* Any::_internal_mutable_value() { - return value_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Any::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.Any.value) - - return value_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Any::set_allocated_value(std::string* value) { if (value != nullptr) { @@ -378,7 +386,8 @@ inline void Any::set_allocated_value(std::string* value) { } else { } - value_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) } diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto index c9be85416736..6ed8a23cf5a3 100644 --- a/src/google/protobuf/any.proto +++ b/src/google/protobuf/any.proto @@ -33,7 +33,7 @@ syntax = "proto3"; package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option go_package = "github.com/golang/protobuf/ptypes/any"; +option go_package = "google.golang.org/protobuf/types/known/anypb"; option java_package = "com.google.protobuf"; option java_outer_classname = "AnyProto"; option java_multiple_files = true; @@ -77,10 +77,13 @@ option objc_class_prefix = "GPB"; // Example 4: Pack and unpack a message in Go // // foo := &pb.Foo{...} -// any, err := ptypes.MarshalAny(foo) +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } // ... // foo := &pb.Foo{} -// if err := ptypes.UnmarshalAny(any, foo); err != nil { +// if err := any.UnmarshalTo(foo); err != nil { // ... // } // diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index 783938133710..55b55ee18abb 100644 --- a/src/google/protobuf/any_lite.cc +++ b/src/google/protobuf/any_lite.cc @@ -53,16 +53,13 @@ const char kAnyFullTypeName[] = "google.protobuf.Any"; const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/"; const char kTypeGoogleProdComPrefix[] = "type.googleprod.com/"; -AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value) - : type_url_(type_url), value_(value) {} - -void AnyMetadata::InternalPackFrom(const MessageLite& message, +bool AnyMetadata::InternalPackFrom(const MessageLite& message, StringPiece type_url_prefix, StringPiece type_name) { - type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(), - GetTypeUrl(type_name, type_url_prefix)); - message.SerializeToString(value_->MutableNoArena( - &::google::protobuf::internal::GetEmptyStringAlreadyInited())); + type_url_->Set(&::google::protobuf::internal::GetEmptyString(), + GetTypeUrl(type_name, type_url_prefix), nullptr); + return message.SerializeToString( + value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr)); } bool AnyMetadata::InternalUnpackTo(StringPiece type_name, @@ -70,50 +67,30 @@ bool AnyMetadata::InternalUnpackTo(StringPiece type_name, if (!InternalIs(type_name)) { return false; } - return message->ParseFromString(value_->GetNoArena()); -} - -namespace { - -// The type URL could be stored in either an ArenaStringPtr or a -// StringPieceField, so we provide these helpers to get a string_view from -// either type. We use a template function as a way to avoid depending on -// StringPieceField. - -template -StringPiece Get(const T* ptr) { - return ptr->Get(); -} - -template <> -// NOLINTNEXTLINE: clang-diagnostic-unused-function -StringPiece Get(const ArenaStringPtr* ptr) { - return ptr->GetNoArena(); + return message->ParseFromString(value_->Get()); } -} // namespace - bool AnyMetadata::InternalIs(StringPiece type_name) const { - StringPiece type_url = Get(type_url_); + StringPiece type_url = type_url_->Get(); return type_url.size() >= type_name.size() + 1 && type_url[type_url.size() - type_name.size() - 1] == '/' && HasSuffixString(type_url, type_name); } -bool ParseAnyTypeUrl(const std::string& type_url, std::string* url_prefix, +bool ParseAnyTypeUrl(StringPiece type_url, std::string* url_prefix, std::string* full_type_name) { size_t pos = type_url.find_last_of("/"); if (pos == std::string::npos || pos + 1 == type_url.size()) { return false; } if (url_prefix) { - *url_prefix = type_url.substr(0, pos + 1); + *url_prefix = std::string(type_url.substr(0, pos + 1)); } - *full_type_name = type_url.substr(pos + 1); + *full_type_name = std::string(type_url.substr(pos + 1)); return true; } -bool ParseAnyTypeUrl(const std::string& type_url, std::string* full_type_name) { +bool ParseAnyTypeUrl(StringPiece type_url, std::string* full_type_name) { return ParseAnyTypeUrl(type_url, nullptr, full_type_name); } diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc index 0d8893f7b811..1d136aa5575a 100644 --- a/src/google/protobuf/any_test.cc +++ b/src/google/protobuf/any_test.cc @@ -33,15 +33,23 @@ #include +// Must be included last. +#include + namespace google { namespace protobuf { namespace { +TEST(AnyMetadataTest, ConstInit) { + PROTOBUF_CONSTINIT static internal::AnyMetadata metadata(nullptr, nullptr); + (void)metadata; +} + TEST(AnyTest, TestPackAndUnpack) { protobuf_unittest::TestAny submessage; submessage.set_int32_value(12345); protobuf_unittest::TestAny message; - message.mutable_any_value()->PackFrom(submessage); + ASSERT_TRUE(message.mutable_any_value()->PackFrom(submessage)); std::string data = message.SerializeAsString(); @@ -52,6 +60,13 @@ TEST(AnyTest, TestPackAndUnpack) { EXPECT_EQ(12345, submessage.int32_value()); } +TEST(AnyTest, TestPackFromSerializationExceedsSizeLimit) { + protobuf_unittest::TestAny submessage; + submessage.mutable_text()->resize(INT_MAX, 'a'); + protobuf_unittest::TestAny message; + EXPECT_FALSE(message.mutable_any_value()->PackFrom(submessage)); +} + TEST(AnyTest, TestUnpackWithTypeMismatch) { protobuf_unittest::TestAny payload; payload.set_int32_value(13); @@ -165,3 +180,5 @@ TEST(AnyTest, MoveAssignment) { } // namespace } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/any_test.proto b/src/google/protobuf/any_test.proto index 0c5b30ba3e4a..256035b4467d 100644 --- a/src/google/protobuf/any_test.proto +++ b/src/google/protobuf/any_test.proto @@ -34,8 +34,11 @@ package protobuf_unittest; import "google/protobuf/any.proto"; +option java_outer_classname = "TestAnyProto"; + message TestAny { int32 int32_value = 1; google.protobuf.Any any_value = 2; repeated google.protobuf.Any repeated_any_value = 3; + string text = 4; } diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 0951c5243678..7ee673a527a7 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Method_google_2fprotobuf_2fapi_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fapi_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Mixin_google_2fprotobuf_2fapi_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto; @@ -40,7 +42,6 @@ static void InitDefaultsscc_info_Api_google_2fprotobuf_2fapi_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Api(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Api::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<4> scc_info_Api_google_2fprotobuf_2fapi_2eproto = @@ -58,7 +59,6 @@ static void InitDefaultsscc_info_Method_google_2fprotobuf_2fapi_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Method(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Method::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Method_google_2fprotobuf_2fapi_2eproto = @@ -73,7 +73,6 @@ static void InitDefaultsscc_info_Mixin_google_2fprotobuf_2fapi_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Mixin(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Mixin::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Mixin_google_2fprotobuf_2fapi_2eproto = @@ -144,10 +143,10 @@ const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_ "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013" "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001(" "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n" - "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBu\n\023com.google.pr" - "otobufB\010ApiProtoP\001Z+google.golang.org/ge" - "nproto/protobuf/api;api\242\002\003GPB\252\002\036Google.P" - "rotobuf.WellKnownTypesb\006proto3" + "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBv\n\023com.google.pr" + "otobufB\010ApiProtoP\001Z,google.golang.org/pr" + "otobuf/types/known/apipb\242\002\003GPB\252\002\036Google." + "Protobuf.WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fapi_2eproto_deps[2] = { &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, @@ -159,24 +158,19 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_Mixin_google_2fprotobuf_2fapi_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fapi_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fapi_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = { - &descriptor_table_google_2fprotobuf_2fapi_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", 750, + false, false, descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto, "google/protobuf/api.proto", 751, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, descriptor_table_google_2fprotobuf_2fapi_2eproto_sccs, descriptor_table_google_2fprotobuf_2fapi_2eproto_deps, 3, 2, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fapi_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fapi_2eproto, 3, file_level_enum_descriptors_google_2fprotobuf_2fapi_2eproto, file_level_service_descriptors_google_2fprotobuf_2fapi_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Api::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Api_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>( - PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance()); -} class Api::_Internal { public: static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Api* msg); @@ -190,30 +184,35 @@ void Api::clear_options() { options_.Clear(); } void Api::clear_source_context() { - if (GetArenaNoVirtual() == nullptr && source_context_ != nullptr) { + if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } source_context_ = nullptr; } -Api::Api() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +Api::Api(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena), + methods_(arena), + options_(arena), + mixins_(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Api) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.Api) } Api::Api(const Api& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), methods_(from.methods_), options_(from.options_), mixins_(from.mixins_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_version().empty()) { - version_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.version_); + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_version(), + GetArena()); } if (from._internal_has_source_context()) { source_context_ = new PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_); @@ -228,22 +227,31 @@ void Api::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Api_google_2fprotobuf_2fapi_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&source_context_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&source_context_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&source_context_)) + sizeof(syntax_)); } Api::~Api() { // @@protoc_insertion_point(destructor:google.protobuf.Api) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Api::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); version_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete source_context_; } +void Api::ArenaDtor(void* object) { + Api* _this = reinterpret_cast< Api* >(object); + (void)_this; +} +void Api::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void Api::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -262,14 +270,14 @@ void Api::Clear() { methods_.Clear(); options_.Clear(); mixins_.Clear(); - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - version_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - if (GetArenaNoVirtual() == nullptr && source_context_ != nullptr) { + name_.ClearToEmpty(); + version_.ClearToEmpty(); + if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } source_context_ = nullptr; syntax_ = 0; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -354,7 +362,9 @@ const char* Api::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::intern ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -435,7 +445,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Api::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api) return target; @@ -524,7 +534,7 @@ void Api::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Api::MergeFrom(const Api& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -532,12 +542,10 @@ void Api::MergeFrom(const Api& from) { options_.MergeFrom(from.options_); mixins_.MergeFrom(from.mixins_); if (from.name().size() > 0) { - - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + _internal_set_name(from._internal_name()); } if (from.version().size() > 0) { - - version_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.version_); + _internal_set_version(from._internal_version()); } if (from.has_source_context()) { _internal_mutable_source_context()->PROTOBUF_NAMESPACE_ID::SourceContext::MergeFrom(from._internal_source_context()); @@ -567,16 +575,18 @@ bool Api::IsInitialized() const { void Api::InternalSwap(Api* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); methods_.InternalSwap(&other->methods_); options_.InternalSwap(&other->options_); mixins_.InternalSwap(&other->mixins_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - version_.Swap(&other->version_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(source_context_, other->source_context_); - swap(syntax_, other->syntax_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + version_.Swap(&other->version_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Api, syntax_) + + sizeof(Api::syntax_) + - PROTOBUF_FIELD_OFFSET(Api, source_context_)>( + reinterpret_cast(&source_context_), + reinterpret_cast(&other->source_context_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const { @@ -586,8 +596,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Api::GetMetadata() const { // =================================================================== -void Method::InitAsDefaultInstance() { -} class Method::_Internal { public: }; @@ -595,27 +603,31 @@ class Method::_Internal { void Method::clear_options() { options_.Clear(); } -Method::Method() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +Method::Method(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena), + options_(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Method) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.Method) } Method::Method(const Method& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), options_(from.options_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_request_type_url().empty()) { - request_type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.request_type_url_); + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_request_type_url(), + GetArena()); } response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_response_type_url().empty()) { - response_type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.response_type_url_); + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_response_type_url(), + GetArena()); } ::memcpy(&request_streaming_, &from.request_streaming_, static_cast(reinterpret_cast(&syntax_) - @@ -628,22 +640,31 @@ void Method::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&request_streaming_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&request_streaming_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&request_streaming_)) + sizeof(syntax_)); } Method::~Method() { // @@protoc_insertion_point(destructor:google.protobuf.Method) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Method::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); request_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); response_type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } +void Method::ArenaDtor(void* object) { + Method* _this = reinterpret_cast< Method* >(object); + (void)_this; +} +void Method::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void Method::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -660,13 +681,13 @@ void Method::Clear() { (void) cached_has_bits; options_.Clear(); - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - request_type_url_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - response_type_url_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.ClearToEmpty(); + request_type_url_.ClearToEmpty(); + response_type_url_.ClearToEmpty(); ::memset(&request_streaming_, 0, static_cast( reinterpret_cast(&syntax_) - reinterpret_cast(&request_streaming_)) + sizeof(syntax_)); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -743,7 +764,9 @@ const char* Method::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -822,7 +845,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Method::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method) return target; @@ -907,22 +930,19 @@ void Method::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Method::MergeFrom(const Method& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; options_.MergeFrom(from.options_); if (from.name().size() > 0) { - - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + _internal_set_name(from._internal_name()); } if (from.request_type_url().size() > 0) { - - request_type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.request_type_url_); + _internal_set_request_type_url(from._internal_request_type_url()); } if (from.response_type_url().size() > 0) { - - response_type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.response_type_url_); + _internal_set_response_type_url(from._internal_response_type_url()); } if (from.request_streaming() != 0) { _internal_set_request_streaming(from._internal_request_streaming()); @@ -955,17 +975,17 @@ bool Method::IsInitialized() const { void Method::InternalSwap(Method* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); options_.InternalSwap(&other->options_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - request_type_url_.Swap(&other->request_type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - response_type_url_.Swap(&other->response_type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(request_streaming_, other->request_streaming_); - swap(response_streaming_, other->response_streaming_); - swap(syntax_, other->syntax_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + request_type_url_.Swap(&other->request_type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + response_type_url_.Swap(&other->response_type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Method, syntax_) + + sizeof(Method::syntax_) + - PROTOBUF_FIELD_OFFSET(Method, request_streaming_)>( + reinterpret_cast(&request_streaming_), + reinterpret_cast(&other->request_streaming_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const { @@ -975,28 +995,28 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Method::GetMetadata() const { // =================================================================== -void Mixin::InitAsDefaultInstance() { -} class Mixin::_Internal { public: }; -Mixin::Mixin() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +Mixin::Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Mixin) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin) } Mixin::Mixin(const Mixin& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_root().empty()) { - root_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.root_); + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_root(), + GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin) } @@ -1010,13 +1030,21 @@ void Mixin::SharedCtor() { Mixin::~Mixin() { // @@protoc_insertion_point(destructor:google.protobuf.Mixin) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Mixin::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); root_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } +void Mixin::ArenaDtor(void* object) { + Mixin* _this = reinterpret_cast< Mixin* >(object); + (void)_this; +} +void Mixin::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void Mixin::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -1032,9 +1060,9 @@ void Mixin::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - root_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _internal_metadata_.Clear(); + name_.ClearToEmpty(); + root_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -1068,7 +1096,9 @@ const char* Mixin::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1110,7 +1140,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Mixin::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin) return target; @@ -1165,17 +1195,15 @@ void Mixin::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Mixin::MergeFrom(const Mixin& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; if (from.name().size() > 0) { - - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + _internal_set_name(from._internal_name()); } if (from.root().size() > 0) { - - root_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.root_); + _internal_set_root(from._internal_root()); } } @@ -1199,11 +1227,9 @@ bool Mixin::IsInitialized() const { void Mixin::InternalSwap(Mixin* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - root_.Swap(&other->root_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + root_.Swap(&other->root_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } ::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const { @@ -1215,13 +1241,13 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Mixin::GetMetadata() const { PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::Api* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::Api >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::Api >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::Api >(arena); } template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::Method* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::Method >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::Method >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::Method >(arena); } template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::Mixin* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::Mixin >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::Mixin >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::Mixin >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index b00b88dc24aa..b141b549adc9 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -47,7 +46,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fapi_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[3] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -76,10 +75,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT Api : +class PROTOBUF_EXPORT Api PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ { public: - Api(); + inline Api() : Api(nullptr) {} virtual ~Api(); Api(const Api& from); @@ -93,7 +92,7 @@ class PROTOBUF_EXPORT Api : return *this; } inline Api& operator=(Api&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -112,7 +111,6 @@ class PROTOBUF_EXPORT Api : } static const Api& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Api* internal_default_instance() { return reinterpret_cast( &_Api_default_instance_); @@ -125,6 +123,15 @@ class PROTOBUF_EXPORT Api : } inline void Swap(Api* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Api* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -159,13 +166,11 @@ class PROTOBUF_EXPORT Api : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.Api"; } + protected: + explicit Api(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -290,6 +295,9 @@ class PROTOBUF_EXPORT Api : const PROTOBUF_NAMESPACE_ID::SourceContext& _internal_source_context() const; PROTOBUF_NAMESPACE_ID::SourceContext* _internal_mutable_source_context(); public: + void unsafe_arena_set_allocated_source_context( + PROTOBUF_NAMESPACE_ID::SourceContext* source_context); + PROTOBUF_NAMESPACE_ID::SourceContext* unsafe_arena_release_source_context(); // .google.protobuf.Syntax syntax = 7; void clear_syntax(); @@ -304,7 +312,9 @@ class PROTOBUF_EXPORT Api : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Method > methods_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option > options_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Mixin > mixins_; @@ -317,10 +327,10 @@ class PROTOBUF_EXPORT Api : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Method : +class PROTOBUF_EXPORT Method PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ { public: - Method(); + inline Method() : Method(nullptr) {} virtual ~Method(); Method(const Method& from); @@ -334,7 +344,7 @@ class PROTOBUF_EXPORT Method : return *this; } inline Method& operator=(Method&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -353,7 +363,6 @@ class PROTOBUF_EXPORT Method : } static const Method& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Method* internal_default_instance() { return reinterpret_cast( &_Method_default_instance_); @@ -366,6 +375,15 @@ class PROTOBUF_EXPORT Method : } inline void Swap(Method* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Method* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -400,13 +418,11 @@ class PROTOBUF_EXPORT Method : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.Method"; } + protected: + explicit Method(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -528,7 +544,9 @@ class PROTOBUF_EXPORT Method : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::Option > options_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr request_type_url_; @@ -541,10 +559,10 @@ class PROTOBUF_EXPORT Method : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Mixin : +class PROTOBUF_EXPORT Mixin PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ { public: - Mixin(); + inline Mixin() : Mixin(nullptr) {} virtual ~Mixin(); Mixin(const Mixin& from); @@ -558,7 +576,7 @@ class PROTOBUF_EXPORT Mixin : return *this; } inline Mixin& operator=(Mixin&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -577,7 +595,6 @@ class PROTOBUF_EXPORT Mixin : } static const Mixin& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Mixin* internal_default_instance() { return reinterpret_cast( &_Mixin_default_instance_); @@ -590,6 +607,15 @@ class PROTOBUF_EXPORT Mixin : } inline void Swap(Mixin* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Mixin* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -624,13 +650,11 @@ class PROTOBUF_EXPORT Mixin : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.Mixin"; } + protected: + explicit Mixin(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -686,7 +710,9 @@ class PROTOBUF_EXPORT Mixin : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr root_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; @@ -705,7 +731,7 @@ class PROTOBUF_EXPORT Mixin : // string name = 1; inline void Api::clear_name() { - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.ClearToEmpty(); } inline const std::string& Api::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.name) @@ -720,38 +746,38 @@ inline std::string* Api::mutable_name() { return _internal_mutable_name(); } inline const std::string& Api::_internal_name() const { - return name_.GetNoArena(); + return name_.Get(); } inline void Api::_internal_set_name(const std::string& value) { - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Api::set_name(std::string&& value) { - name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + name_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Api.name) } inline void Api::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name) } -inline void Api::set_name(const char* value, size_t size) { +inline void Api::set_name(const char* value, + size_t size) { - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.name) } inline std::string* Api::_internal_mutable_name() { - return name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Api::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Api.name) - - return name_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Api::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -759,7 +785,8 @@ inline void Api::set_allocated_name(std::string* name) { } else { } - name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name); + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name) } @@ -840,7 +867,7 @@ Api::options() const { // string version = 4; inline void Api::clear_version() { - version_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + version_.ClearToEmpty(); } inline const std::string& Api::version() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.version) @@ -855,38 +882,38 @@ inline std::string* Api::mutable_version() { return _internal_mutable_version(); } inline const std::string& Api::_internal_version() const { - return version_.GetNoArena(); + return version_.Get(); } inline void Api::_internal_set_version(const std::string& value) { - version_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Api::set_version(std::string&& value) { - version_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + version_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Api.version) } inline void Api::set_version(const char* value) { GOOGLE_DCHECK(value != nullptr); - version_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version) } -inline void Api::set_version(const char* value, size_t size) { +inline void Api::set_version(const char* value, + size_t size) { - version_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.version) } inline std::string* Api::_internal_mutable_version() { - return version_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return version_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Api::release_version() { // @@protoc_insertion_point(field_release:google.protobuf.Api.version) - - return version_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return version_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Api::set_allocated_version(std::string* version) { if (version != nullptr) { @@ -894,7 +921,8 @@ inline void Api::set_allocated_version(std::string* version) { } else { } - version_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version); + version_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version) } @@ -907,14 +935,36 @@ inline bool Api::has_source_context() const { } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Api::_internal_source_context() const { const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Api::source_context() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) return _internal_source_context(); } +inline void Api::unsafe_arena_set_allocated_source_context( + PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Api.source_context) +} inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() { + + PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; + if (GetArena() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + return temp; +} +inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::unsafe_arena_release_source_context() { // @@protoc_insertion_point(field_release:google.protobuf.Api.source_context) PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; @@ -924,7 +974,7 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::release_source_context() { inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::_internal_mutable_source_context() { if (source_context_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); source_context_ = p; } return source_context_; @@ -934,12 +984,13 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Api::mutable_source_context() { return _internal_mutable_source_context(); } inline void Api::set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); } if (source_context) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)->GetArena(); if (message_arena != submessage_arena) { source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, source_context, submessage_arena); @@ -1017,7 +1068,7 @@ inline void Api::set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void Method::clear_name() { - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.ClearToEmpty(); } inline const std::string& Method::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.name) @@ -1032,38 +1083,38 @@ inline std::string* Method::mutable_name() { return _internal_mutable_name(); } inline const std::string& Method::_internal_name() const { - return name_.GetNoArena(); + return name_.Get(); } inline void Method::_internal_set_name(const std::string& value) { - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Method::set_name(std::string&& value) { - name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + name_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Method.name) } inline void Method::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name) } -inline void Method::set_name(const char* value, size_t size) { +inline void Method::set_name(const char* value, + size_t size) { - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.name) } inline std::string* Method::_internal_mutable_name() { - return name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Method::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Method.name) - - return name_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Method::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1071,13 +1122,14 @@ inline void Method::set_allocated_name(std::string* name) { } else { } - name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name); + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name) } // string request_type_url = 2; inline void Method::clear_request_type_url() { - request_type_url_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + request_type_url_.ClearToEmpty(); } inline const std::string& Method::request_type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url) @@ -1092,38 +1144,38 @@ inline std::string* Method::mutable_request_type_url() { return _internal_mutable_request_type_url(); } inline const std::string& Method::_internal_request_type_url() const { - return request_type_url_.GetNoArena(); + return request_type_url_.Get(); } inline void Method::_internal_set_request_type_url(const std::string& value) { - request_type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Method::set_request_type_url(std::string&& value) { - request_type_url_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + request_type_url_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Method.request_type_url) } inline void Method::set_request_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - request_type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url) } -inline void Method::set_request_type_url(const char* value, size_t size) { +inline void Method::set_request_type_url(const char* value, + size_t size) { - request_type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.request_type_url) } inline std::string* Method::_internal_mutable_request_type_url() { - return request_type_url_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return request_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Method::release_request_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url) - - return request_type_url_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return request_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Method::set_allocated_request_type_url(std::string* request_type_url) { if (request_type_url != nullptr) { @@ -1131,7 +1183,8 @@ inline void Method::set_allocated_request_type_url(std::string* request_type_url } else { } - request_type_url_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), request_type_url); + request_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), request_type_url, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url) } @@ -1157,7 +1210,7 @@ inline void Method::set_request_streaming(bool value) { // string response_type_url = 4; inline void Method::clear_response_type_url() { - response_type_url_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + response_type_url_.ClearToEmpty(); } inline const std::string& Method::response_type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url) @@ -1172,38 +1225,38 @@ inline std::string* Method::mutable_response_type_url() { return _internal_mutable_response_type_url(); } inline const std::string& Method::_internal_response_type_url() const { - return response_type_url_.GetNoArena(); + return response_type_url_.Get(); } inline void Method::_internal_set_response_type_url(const std::string& value) { - response_type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Method::set_response_type_url(std::string&& value) { - response_type_url_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + response_type_url_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Method.response_type_url) } inline void Method::set_response_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - response_type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url) } -inline void Method::set_response_type_url(const char* value, size_t size) { +inline void Method::set_response_type_url(const char* value, + size_t size) { - response_type_url_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.response_type_url) } inline std::string* Method::_internal_mutable_response_type_url() { - return response_type_url_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return response_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Method::release_response_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url) - - return response_type_url_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return response_type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Method::set_allocated_response_type_url(std::string* response_type_url) { if (response_type_url != nullptr) { @@ -1211,7 +1264,8 @@ inline void Method::set_allocated_response_type_url(std::string* response_type_u } else { } - response_type_url_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), response_type_url); + response_type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), response_type_url, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url) } @@ -1297,7 +1351,7 @@ inline void Method::set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void Mixin::clear_name() { - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.ClearToEmpty(); } inline const std::string& Mixin::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name) @@ -1312,38 +1366,38 @@ inline std::string* Mixin::mutable_name() { return _internal_mutable_name(); } inline const std::string& Mixin::_internal_name() const { - return name_.GetNoArena(); + return name_.Get(); } inline void Mixin::_internal_set_name(const std::string& value) { - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Mixin::set_name(std::string&& value) { - name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + name_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Mixin.name) } inline void Mixin::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name) } -inline void Mixin::set_name(const char* value, size_t size) { +inline void Mixin::set_name(const char* value, + size_t size) { - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name) } inline std::string* Mixin::_internal_mutable_name() { - return name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Mixin::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name) - - return name_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Mixin::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1351,13 +1405,14 @@ inline void Mixin::set_allocated_name(std::string* name) { } else { } - name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name); + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name) } // string root = 2; inline void Mixin::clear_root() { - root_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + root_.ClearToEmpty(); } inline const std::string& Mixin::root() const { // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root) @@ -1372,38 +1427,38 @@ inline std::string* Mixin::mutable_root() { return _internal_mutable_root(); } inline const std::string& Mixin::_internal_root() const { - return root_.GetNoArena(); + return root_.Get(); } inline void Mixin::_internal_set_root(const std::string& value) { - root_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Mixin::set_root(std::string&& value) { - root_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + root_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Mixin.root) } inline void Mixin::set_root(const char* value) { GOOGLE_DCHECK(value != nullptr); - root_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root) } -inline void Mixin::set_root(const char* value, size_t size) { +inline void Mixin::set_root(const char* value, + size_t size) { - root_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root) } inline std::string* Mixin::_internal_mutable_root() { - return root_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return root_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Mixin::release_root() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root) - - return root_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return root_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Mixin::set_allocated_root(std::string* root) { if (root != nullptr) { @@ -1411,7 +1466,8 @@ inline void Mixin::set_allocated_root(std::string* root) { } else { } - root_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), root); + root_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), root, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root) } diff --git a/src/google/protobuf/api.proto b/src/google/protobuf/api.proto index f37ee2fa46ba..3d598fc8590e 100644 --- a/src/google/protobuf/api.proto +++ b/src/google/protobuf/api.proto @@ -40,7 +40,7 @@ option java_package = "com.google.protobuf"; option java_outer_classname = "ApiProto"; option java_multiple_files = true; option objc_class_prefix = "GPB"; -option go_package = "google.golang.org/genproto/protobuf/api;api"; +option go_package = "google.golang.org/protobuf/types/known/apipb"; // Api is a light-weight descriptor for an API Interface. // @@ -52,7 +52,6 @@ option go_package = "google.golang.org/genproto/protobuf/api;api"; // this message itself. See https://cloud.google.com/apis/design/glossary for // detailed terminology. message Api { - // The fully qualified name of this interface, including package name // followed by the interface's simple name. string name = 1; @@ -99,7 +98,6 @@ message Api { // Method represents a method of an API interface. message Method { - // The simple name of this method. string name = 1; @@ -169,7 +167,7 @@ message Method { // The mixin construct implies that all methods in `AccessControl` are // also declared with same name and request/response types in // `Storage`. A documentation generator or annotation processor will -// see the effective `Storage.GetAcl` method after inherting +// see the effective `Storage.GetAcl` method after inheriting // documentation and annotations as follows: // // service Storage { diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 069dcdfa36df..d4779a2c6c80 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -32,10 +32,14 @@ #include #include +#include +#include #include +#include -#include +#include +#include #ifdef ADDRESS_SANITIZER #include #endif // ADDRESS_SANITIZER @@ -49,289 +53,386 @@ namespace google { namespace protobuf { namespace internal { - -std::atomic ArenaImpl::lifecycle_id_generator_; -#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) -ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { - static internal::ThreadLocalStorage* thread_cache_ = - new internal::ThreadLocalStorage(); - return *thread_cache_->Get(); -} -#elif defined(PROTOBUF_USE_DLLS) -ArenaImpl::ThreadCache& ArenaImpl::thread_cache() { - static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = {-1, NULL}; - return thread_cache_; -} -#else -GOOGLE_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, NULL}; -#endif - -void ArenaImpl::Init() { - lifecycle_id_ = - lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed); - hint_.store(nullptr, std::memory_order_relaxed); - threads_.store(nullptr, std::memory_order_relaxed); - - if (initial_block_) { - // Thread which calls Init() owns the first block. This allows the - // single-threaded case to allocate on the first block without having to - // perform atomic operations. - new (initial_block_) Block(options_.initial_block_size, NULL); - SerialArena* serial = - SerialArena::New(initial_block_, &thread_cache(), this); - serial->set_next(NULL); - threads_.store(serial, std::memory_order_relaxed); - space_allocated_.store(options_.initial_block_size, - std::memory_order_relaxed); - CacheSerialArena(serial); - } else { - space_allocated_.store(0, std::memory_order_relaxed); - } -} - -ArenaImpl::~ArenaImpl() { - // Have to do this in a first pass, because some of the destructors might - // refer to memory in other blocks. - CleanupList(); - FreeBlocks(); -} - -uint64 ArenaImpl::Reset() { - // Have to do this in a first pass, because some of the destructors might - // refer to memory in other blocks. - CleanupList(); - uint64 space_allocated = FreeBlocks(); - Init(); - - return space_allocated; -} - -ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) { +static SerialArena::Memory AllocateMemory(const AllocationPolicy* policy_ptr, + size_t last_size, size_t min_bytes) { + AllocationPolicy policy; // default policy + if (policy_ptr) policy = *policy_ptr; size_t size; - if (last_block) { + if (last_size != 0) { // Double the current block size, up to a limit. - size = std::min(2 * last_block->size(), options_.max_block_size); + auto max_size = policy.max_block_size; + size = std::min(2 * last_size, max_size); } else { - size = options_.start_block_size; + size = policy.start_block_size; } // Verify that min_bytes + kBlockHeaderSize won't overflow. - GOOGLE_CHECK_LE(min_bytes, std::numeric_limits::max() - kBlockHeaderSize); - size = std::max(size, kBlockHeaderSize + min_bytes); + GOOGLE_CHECK_LE(min_bytes, + std::numeric_limits::max() - SerialArena::kBlockHeaderSize); + size = std::max(size, SerialArena::kBlockHeaderSize + min_bytes); - void* mem = options_.block_alloc(size); - Block* b = new (mem) Block(size, last_block); - space_allocated_.fetch_add(size, std::memory_order_relaxed); - return b; + void* mem; + if (policy.block_alloc == nullptr) { + mem = ::operator new(size); + } else { + mem = policy.block_alloc(size); + } + return {mem, size}; } -ArenaImpl::Block::Block(size_t size, Block* next) - : next_(next), pos_(kBlockHeaderSize), size_(size) {} - -PROTOBUF_NOINLINE -void ArenaImpl::SerialArena::AddCleanupFallback(void* elem, - void (*cleanup)(void*)) { - size_t size = cleanup_ ? cleanup_->size * 2 : kMinCleanupListElements; - size = std::min(size, kMaxCleanupListElements); - size_t bytes = internal::AlignUpTo8(CleanupChunk::SizeOf(size)); - CleanupChunk* list = reinterpret_cast(AllocateAligned(bytes)); - list->next = cleanup_; - list->size = size; - - cleanup_ = list; - cleanup_ptr_ = &list->nodes[0]; - cleanup_limit_ = &list->nodes[size]; - - AddCleanup(elem, cleanup); -} +class GetDeallocator { + public: + GetDeallocator(const AllocationPolicy* policy, size_t* space_allocated) + : dealloc_(policy ? policy->block_dealloc : nullptr), + space_allocated_(space_allocated) {} -void* ArenaImpl::AllocateAlignedAndAddCleanup(size_t n, - void (*cleanup)(void*)) { - SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - return arena->AllocateAlignedAndAddCleanup(n, cleanup); - } else { - return AllocateAlignedAndAddCleanupFallback(n, cleanup); + void operator()(SerialArena::Memory mem) const { +#ifdef ADDRESS_SANITIZER + // This memory was provided by the underlying allocator as unpoisoned, + // so return it in an unpoisoned state. + ASAN_UNPOISON_MEMORY_REGION(mem.ptr, mem.size); +#endif // ADDRESS_SANITIZER + if (dealloc_) { + dealloc_(mem.ptr, mem.size); + } else { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(mem.ptr, mem.size); +#else + ::operator delete(mem.ptr); +#endif + } + *space_allocated_ += mem.size; } + + private: + void (*dealloc_)(void*, size_t); + size_t* space_allocated_; +}; + +SerialArena::SerialArena(Block* b, void* owner) : space_allocated_(b->size) { + owner_ = owner; + head_ = b; + ptr_ = b->Pointer(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize); + limit_ = b->Pointer(b->size & static_cast(-8)); } -void ArenaImpl::AddCleanup(void* elem, void (*cleanup)(void*)) { - SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - arena->AddCleanup(elem, cleanup); - } else { - return AddCleanupFallback(elem, cleanup); - } +SerialArena* SerialArena::New(Memory mem, void* owner) { + GOOGLE_DCHECK_LE(kBlockHeaderSize + ThreadSafeArena::kSerialArenaSize, mem.size); + + auto b = new (mem.ptr) Block{nullptr, mem.size}; + return new (b->Pointer(kBlockHeaderSize)) SerialArena(b, owner); } -PROTOBUF_NOINLINE -void* ArenaImpl::AllocateAlignedFallback(size_t n) { - return GetSerialArena()->AllocateAligned(n); +template +SerialArena::Memory SerialArena::Free(Deallocator deallocator) { + Block* b = head_; + Memory mem = {b, b->size}; + while (b->next) { + b = b->next; // We must first advance before deleting this block + deallocator(mem); + mem = {b, b->size}; + } + return mem; } PROTOBUF_NOINLINE -void* ArenaImpl::AllocateAlignedAndAddCleanupFallback(size_t n, - void (*cleanup)(void*)) { - return GetSerialArena()->AllocateAlignedAndAddCleanup(n, cleanup); +std::pair +SerialArena::AllocateAlignedWithCleanupFallback( + size_t n, const AllocationPolicy* policy) { + AllocateNewBlock(n + kCleanupSize, policy); + return AllocateAlignedWithCleanup(n, policy); } PROTOBUF_NOINLINE -void ArenaImpl::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { - GetSerialArena()->AddCleanup(elem, cleanup); +void* SerialArena::AllocateAlignedFallback(size_t n, + const AllocationPolicy* policy) { + AllocateNewBlock(n, policy); + return AllocateAligned(n, policy); } -ArenaImpl::SerialArena* ArenaImpl::GetSerialArena() { - SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - return arena; - } else { - return GetSerialArenaFallback(&thread_cache()); - } -} +void SerialArena::AllocateNewBlock(size_t n, const AllocationPolicy* policy) { + // Sync limit to block + head_->start = reinterpret_cast(limit_); -PROTOBUF_NOINLINE -void* ArenaImpl::SerialArena::AllocateAlignedFallback(size_t n) { - // Sync back to current's pos. - head_->set_pos(head_->size() - (limit_ - ptr_)); + // Record how much used in this block. + space_used_ += ptr_ - head_->Pointer(kBlockHeaderSize); - head_ = arena_->NewBlock(head_, n); - ptr_ = head_->Pointer(head_->pos()); - limit_ = head_->Pointer(head_->size()); + auto mem = AllocateMemory(policy, head_->size, n); + // We don't want to emit an expensive RMW instruction that requires + // exclusive access to a cacheline. Hence we write it in terms of a + // regular add. + auto relaxed = std::memory_order_relaxed; + space_allocated_.store(space_allocated_.load(relaxed) + mem.size, relaxed); + head_ = new (mem.ptr) Block{head_, mem.size}; + ptr_ = head_->Pointer(kBlockHeaderSize); + limit_ = head_->Pointer(head_->size); #ifdef ADDRESS_SANITIZER ASAN_POISON_MEMORY_REGION(ptr_, limit_ - ptr_); #endif // ADDRESS_SANITIZER +} - return AllocateAligned(n); +uint64 SerialArena::SpaceUsed() const { + uint64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize); + space_used += space_used_; + // Remove the overhead of the SerialArena itself. + space_used -= ThreadSafeArena::kSerialArenaSize; + return space_used; } -uint64 ArenaImpl::SpaceAllocated() const { - return space_allocated_.load(std::memory_order_relaxed); +void SerialArena::CleanupList() { + Block* b = head_; + b->start = reinterpret_cast(limit_); + do { + auto* limit = reinterpret_cast( + b->Pointer(b->size & static_cast(-8))); + auto it = b->start; + auto num = limit - it; + if (num > 0) { + for (; it < limit; it++) { + it->cleanup(it->elem); + } + } + b = b->next; + } while (b); } -uint64 ArenaImpl::SpaceUsed() const { - SerialArena* serial = threads_.load(std::memory_order_acquire); - uint64 space_used = 0; - for (; serial; serial = serial->next()) { - space_used += serial->SpaceUsed(); + +ThreadSafeArena::CacheAlignedLifecycleIdGenerator + ThreadSafeArena::lifecycle_id_generator_; +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) +ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() { + static internal::ThreadLocalStorage* thread_cache_ = + new internal::ThreadLocalStorage(); + return *thread_cache_->Get(); +} +#elif defined(PROTOBUF_USE_DLLS) +ThreadSafeArena::ThreadCache& ThreadSafeArena::thread_cache() { + static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_ = { + 0, static_cast(-1), nullptr}; + return thread_cache_; +} +#else +PROTOBUF_THREAD_LOCAL ThreadSafeArena::ThreadCache + ThreadSafeArena::thread_cache_ = {0, static_cast(-1), + nullptr}; +#endif + +void ThreadSafeArena::InitializeFrom(void* mem, size_t size) { + GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0u); + Init(false); + + // Ignore initial block if it is too small. + if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) { + alloc_policy_ |= kUserOwnedInitialBlock; + SetInitialBlock(mem, size); } - return space_used; } -uint64 ArenaImpl::SerialArena::SpaceUsed() const { - // Get current block's size from ptr_ (since we can't trust head_->pos(). - uint64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize); - // Get subsequent block size from b->pos(). - for (Block* b = head_->next(); b; b = b->next()) { - space_used += (b->pos() - kBlockHeaderSize); +void ThreadSafeArena::InitializeWithPolicy(void* mem, size_t size, + bool record_allocs, + AllocationPolicy policy) { + GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0u); + + Init(record_allocs); + + // Ignore initial block if it is too small. We include an optional + // AllocationPolicy in this check, so that this can be allocated on the + // first block. + constexpr size_t kAPSize = internal::AlignUpTo8(sizeof(AllocationPolicy)); + constexpr size_t kMinimumSize = kBlockHeaderSize + kSerialArenaSize + kAPSize; + if (mem != nullptr && size >= kMinimumSize) { + alloc_policy_ = kUserOwnedInitialBlock; + } else { + alloc_policy_ = 0; + auto tmp = AllocateMemory(&policy, 0, kMinimumSize); + mem = tmp.ptr; + size = tmp.size; } - // Remove the overhead of the SerialArena itself. - space_used -= kSerialArenaSize; - return space_used; + SetInitialBlock(mem, size); + + auto sa = threads_.load(std::memory_order_relaxed); + // We ensured enough space so this cannot fail. + void* p; + if (!sa || !sa->MaybeAllocateAligned(kAPSize, &p)) { + GOOGLE_LOG(FATAL) << "MaybeAllocateAligned cannot fail here."; + return; + } + new (p) AllocationPolicy{policy}; + alloc_policy_ |= reinterpret_cast(p); } -uint64 ArenaImpl::FreeBlocks() { - uint64 space_allocated = 0; - // By omitting an Acquire barrier we ensure that any user code that doesn't - // properly synchronize Reset() or the destructor will throw a TSAN warning. - SerialArena* serial = threads_.load(std::memory_order_relaxed); - - while (serial) { - // This is inside a block we are freeing, so we need to read it now. - SerialArena* next = serial->next(); - space_allocated += ArenaImpl::SerialArena::Free(serial, initial_block_, - options_.block_dealloc); - // serial is dead now. - serial = next; +void ThreadSafeArena::Init(bool record_allocs) { + ThreadCache& tc = thread_cache(); + auto id = tc.next_lifecycle_id; + // We increment lifecycle_id's by multiples of two so we can use bit 0 as + // a tag. + constexpr uint64 kDelta = 2; + constexpr uint64 kInc = ThreadCache::kPerThreadIds * kDelta; + if (PROTOBUF_PREDICT_FALSE((id & (kInc - 1)) == 0)) { + constexpr auto relaxed = std::memory_order_relaxed; + // On platforms that don't support uint64 atomics we can certainly not + // afford to increment by large intervals and expect uniqueness due to + // wrapping, hence we only add by 1. + id = lifecycle_id_generator_.id.fetch_add(1, relaxed) * kInc; } + tc.next_lifecycle_id = id + kDelta; + tag_and_id_ = id | (record_allocs ? kRecordAllocs : 0); + hint_.store(nullptr, std::memory_order_relaxed); + threads_.store(nullptr, std::memory_order_relaxed); +} - return space_allocated; +void ThreadSafeArena::SetInitialBlock(void* mem, size_t size) { + SerialArena* serial = SerialArena::New({mem, size}, &thread_cache()); + serial->set_next(NULL); + threads_.store(serial, std::memory_order_relaxed); + CacheSerialArena(serial); } -uint64 ArenaImpl::SerialArena::Free(ArenaImpl::SerialArena* serial, - Block* initial_block, - void (*block_dealloc)(void*, size_t)) { - uint64 space_allocated = 0; +ThreadSafeArena::~ThreadSafeArena() { + // Have to do this in a first pass, because some of the destructors might + // refer to memory in other blocks. + CleanupList(); - // We have to be careful in this function, since we will be freeing the Block - // that contains this SerialArena. Be careful about accessing |serial|. + size_t space_allocated = 0; + auto mem = Free(&space_allocated); - for (Block* b = serial->head_; b;) { - // This is inside the block we are freeing, so we need to read it now. - Block* next_block = b->next(); - space_allocated += (b->size()); + // Policy is about to get deleted. + auto p = AllocPolicy(); + ArenaMetricsCollector* collector = p ? p->metrics_collector : nullptr; -#ifdef ADDRESS_SANITIZER - // This memory was provided by the underlying allocator as unpoisoned, so - // return it in an unpoisoned state. - ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); -#endif // ADDRESS_SANITIZER + if (alloc_policy_ & kUserOwnedInitialBlock) { + space_allocated += mem.size; + } else { + GetDeallocator(AllocPolicy(), &space_allocated)(mem); + } - if (b != initial_block) { - block_dealloc(b, b->size()); - } + if (collector) collector->OnDestroy(space_allocated); +} + +SerialArena::Memory ThreadSafeArena::Free(size_t* space_allocated) { + SerialArena::Memory mem = {nullptr, 0}; + auto deallocator = GetDeallocator(AllocPolicy(), space_allocated); + PerSerialArena([deallocator, &mem](SerialArena* a) { + if (mem.ptr) deallocator(mem); + mem = a->Free(deallocator); + }); + return mem; +} - b = next_block; +uint64 ThreadSafeArena::Reset() { + // Have to do this in a first pass, because some of the destructors might + // refer to memory in other blocks. + CleanupList(); + + // Discard all blocks except the special block (if present). + size_t space_allocated = 0; + auto mem = Free(&space_allocated); + + if (AllocPolicy()) { + auto saved_policy = *AllocPolicy(); + if (alloc_policy_ & kUserOwnedInitialBlock) { + space_allocated += mem.size; + } else { + GetDeallocator(AllocPolicy(), &space_allocated)(mem); + mem.ptr = nullptr; + mem.size = 0; + } + ArenaMetricsCollector* collector = saved_policy.metrics_collector; + if (collector) collector->OnReset(space_allocated); + InitializeWithPolicy(mem.ptr, mem.size, ShouldRecordAlloc(), saved_policy); + } else { + // Nullptr policy + if (alloc_policy_ & kUserOwnedInitialBlock) { + space_allocated += mem.size; + InitializeFrom(mem.ptr, mem.size); + } else { + GetDeallocator(AllocPolicy(), &space_allocated)(mem); + Init(false); + } } return space_allocated; } -void ArenaImpl::CleanupList() { - // By omitting an Acquire barrier we ensure that any user code that doesn't - // properly synchronize Reset() or the destructor will throw a TSAN warning. - SerialArena* serial = threads_.load(std::memory_order_relaxed); - - for (; serial; serial = serial->next()) { - serial->CleanupList(); +std::pair +ThreadSafeArena::AllocateAlignedWithCleanup(size_t n, + const std::type_info* type) { + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(tag_and_id_, &arena))) { + return arena->AllocateAlignedWithCleanup(n, AllocPolicy()); + } else { + return AllocateAlignedWithCleanupFallback(n, type); } } -void ArenaImpl::SerialArena::CleanupList() { - if (cleanup_ != NULL) { - CleanupListFallback(); +void ThreadSafeArena::AddCleanup(void* elem, void (*cleanup)(void*)) { + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(LifeCycleId(), &arena))) { + arena->AddCleanup(elem, cleanup, AllocPolicy()); + } else { + return AddCleanupFallback(elem, cleanup); } } -void ArenaImpl::SerialArena::CleanupListFallback() { - // The first chunk might be only partially full, so calculate its size - // from cleanup_ptr_. Subsequent chunks are always full, so use list->size. - size_t n = cleanup_ptr_ - &cleanup_->nodes[0]; - CleanupChunk* list = cleanup_; - while (true) { - CleanupNode* node = &list->nodes[0]; - // Cleanup newest elements first (allocated last). - for (size_t i = n; i > 0; i--) { - node[i - 1].cleanup(node[i - 1].elem); +PROTOBUF_NOINLINE +void* ThreadSafeArena::AllocateAlignedFallback(size_t n, + const std::type_info* type) { + if (ShouldRecordAlloc()) { + RecordAlloc(type, n); + SerialArena* arena; + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(LifeCycleId(), &arena))) { + return arena->AllocateAligned(n, AllocPolicy()); } - list = list->next; - if (list == nullptr) { - break; + } + return GetSerialArenaFallback(&thread_cache()) + ->AllocateAligned(n, AllocPolicy()); +} + +PROTOBUF_NOINLINE +std::pair +ThreadSafeArena::AllocateAlignedWithCleanupFallback( + size_t n, const std::type_info* type) { + if (ShouldRecordAlloc()) { + RecordAlloc(type, n); + SerialArena* arena; + if (GetSerialArenaFast(LifeCycleId(), &arena)) { + return arena->AllocateAlignedWithCleanup(n, AllocPolicy()); } - // All but the first chunk are always full. - n = list->size; } + return GetSerialArenaFallback(&thread_cache()) + ->AllocateAlignedWithCleanup(n, AllocPolicy()); } -ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner, - ArenaImpl* arena) { - GOOGLE_DCHECK_EQ(b->pos(), kBlockHeaderSize); // Should be a fresh block - GOOGLE_DCHECK_LE(kBlockHeaderSize + kSerialArenaSize, b->size()); - SerialArena* serial = - reinterpret_cast(b->Pointer(kBlockHeaderSize)); - b->set_pos(kBlockHeaderSize + kSerialArenaSize); - serial->arena_ = arena; - serial->owner_ = owner; - serial->head_ = b; - serial->ptr_ = b->Pointer(b->pos()); - serial->limit_ = b->Pointer(b->size()); - serial->cleanup_ = NULL; - serial->cleanup_ptr_ = NULL; - serial->cleanup_limit_ = NULL; - return serial; +PROTOBUF_NOINLINE +void ThreadSafeArena::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { + GetSerialArenaFallback(&thread_cache()) + ->AddCleanup(elem, cleanup, AllocPolicy()); +} + +uint64 ThreadSafeArena::SpaceAllocated() const { + SerialArena* serial = threads_.load(std::memory_order_acquire); + uint64 res = 0; + for (; serial; serial = serial->next()) { + res += serial->SpaceAllocated(); + } + return res; +} + +uint64 ThreadSafeArena::SpaceUsed() const { + SerialArena* serial = threads_.load(std::memory_order_acquire); + uint64 space_used = 0; + for (; serial; serial = serial->next()) { + space_used += serial->SpaceUsed(); + } + return space_used - (AllocPolicy() ? sizeof(AllocationPolicy) : 0); +} + +void ThreadSafeArena::CleanupList() { + PerSerialArena([](SerialArena* a) { a->CleanupList(); }); } PROTOBUF_NOINLINE -ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { +SerialArena* ThreadSafeArena::GetSerialArenaFallback(void* me) { // Look for this SerialArena in our linked list. SerialArena* serial = threads_.load(std::memory_order_acquire); for (; serial; serial = serial->next()) { @@ -343,8 +444,8 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { if (!serial) { // This thread doesn't have any SerialArena, which also means it doesn't // have any blocks yet. So we'll allocate its first block now. - Block* b = NewBlock(NULL, kSerialArenaSize); - serial = SerialArena::New(b, me, this); + serial = SerialArena::New( + AllocateMemory(AllocPolicy(), 0, kSerialArenaSize), me); SerialArena* head = threads_.load(std::memory_order_relaxed); do { @@ -361,28 +462,21 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { PROTOBUF_FUNC_ALIGN(32) void* Arena::AllocateAlignedNoHook(size_t n) { - return impl_.AllocateAligned(n); + return impl_.AllocateAligned(n, nullptr); } -void Arena::CallDestructorHooks() { - uint64 space_allocated = impl_.SpaceAllocated(); - // Call the reset hook - if (on_arena_reset_ != NULL) { - on_arena_reset_(this, hooks_cookie_, space_allocated); - } - - // Call the destruction hook - if (on_arena_destruction_ != NULL) { - on_arena_destruction_(this, hooks_cookie_, space_allocated); - } +PROTOBUF_FUNC_ALIGN(32) +void* Arena::AllocateAlignedWithHook(size_t n, const std::type_info* type) { + return impl_.AllocateAligned(n, type); } -void Arena::OnArenaAllocation(const std::type_info* allocated_type, - size_t n) const { - if (on_arena_allocation_ != NULL) { - on_arena_allocation_(allocated_type, n, hooks_cookie_); - } +PROTOBUF_FUNC_ALIGN(32) +std::pair +Arena::AllocateAlignedWithCleanup(size_t n, const std::type_info* type) { + return impl_.AllocateAlignedWithCleanup(n, type); } } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 21993b361c51..2b8782a422e2 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -93,24 +93,32 @@ class EpsCopyInputStream; // defined in parse_context.h template class GenericTypeHandler; // defined in repeated_field.h +PROTOBUF_ALWAYS_INLINE +inline void* AlignTo(void* ptr, size_t align) { + return reinterpret_cast( + (reinterpret_cast(ptr) + align - 1) & (~align + 1)); +} + // Templated cleanup methods. template void arena_destruct_object(void* object) { reinterpret_cast(object)->~T(); } + +template +struct ObjectDestructor { + constexpr static void (*destructor)(void*) = &arena_destruct_object; +}; + +template +struct ObjectDestructor { + constexpr static void (*destructor)(void*) = nullptr; +}; + template void arena_delete_object(void* object) { delete reinterpret_cast(object); } -inline void arena_free(void* object, size_t size) { -#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) - ::operator delete(object, size); -#else - (void)size; - ::operator delete(object); -#endif -} - } // namespace internal // ArenaOptions provides optional additional parameters to arena construction @@ -147,46 +155,36 @@ struct ArenaOptions { void (*block_dealloc)(void*, size_t); ArenaOptions() - : start_block_size(kDefaultStartBlockSize), - max_block_size(kDefaultMaxBlockSize), + : start_block_size(internal::AllocationPolicy::kDefaultStartBlockSize), + max_block_size(internal::AllocationPolicy::kDefaultMaxBlockSize), initial_block(NULL), initial_block_size(0), - block_alloc(&::operator new), - block_dealloc(&internal::arena_free), - on_arena_init(NULL), - on_arena_reset(NULL), - on_arena_destruction(NULL), - on_arena_allocation(NULL) {} + block_alloc(nullptr), + block_dealloc(nullptr), + make_metrics_collector(nullptr) {} private: - // Hooks for adding external functionality such as user-specific metrics - // collection, specific debugging abilities, etc. - // Init hook (if set) will always be called at Arena init time. Init hook may - // return a pointer to a cookie to be stored in the arena. Reset and - // destruction hooks will then be called with the same cookie pointer. This - // allows us to save an external object per arena instance and use it on the - // other hooks (Note: If init hook returns NULL, the other hooks will NOT be - // called on this arena instance). - // on_arena_reset and on_arena_destruction also receive the space used in the - // arena just before the reset. - void* (*on_arena_init)(Arena* arena); - void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used); - void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used); - - // type_info is promised to be static - its lifetime extends to - // match program's lifetime (It is given by typeid operator). - // Note: typeid(void) will be passed as allocated_type every time we - // intentionally want to avoid monitoring an allocation. (i.e. internal - // allocations for managing the arena) - void (*on_arena_allocation)(const std::type_info* allocated_type, - uint64 alloc_size, void* cookie); - - // Constants define default starting block size and max block size for - // arena allocator behavior -- see descriptions above. - static const size_t kDefaultStartBlockSize = 256; - static const size_t kDefaultMaxBlockSize = 8192; + // If make_metrics_collector is not nullptr, it will be called at Arena init + // time. It may return a pointer to a collector instance that will be notified + // of interesting events related to the arena. + internal::ArenaMetricsCollector* (*make_metrics_collector)(); + + internal::ArenaMetricsCollector* MetricsCollector() const { + return make_metrics_collector ? (*make_metrics_collector)() : nullptr; + } + + internal::AllocationPolicy AllocationPolicy() const { + internal::AllocationPolicy res; + res.start_block_size = start_block_size; + res.max_block_size = max_block_size; + res.block_alloc = block_alloc; + res.block_dealloc = block_dealloc; + res.metrics_collector = MetricsCollector(); + return res; + } friend void arena_metrics::EnableArenaMetrics(ArenaOptions*); + friend class Arena; friend class ArenaOptionsTestFriend; }; @@ -219,14 +217,15 @@ struct ArenaOptions { // any special requirements on the type T, and will invoke the object's // destructor when the arena is destroyed. // -// The arena message allocation protocol, required by CreateMessage, is as -// follows: +// The arena message allocation protocol, required by +// CreateMessage(Arena* arena, Args&&... args), is as follows: // -// - The type T must have (at least) two constructors: a constructor with no -// arguments, called when a T is allocated on the heap; and a constructor with -// a Arena* argument, called when a T is allocated on an arena. If the -// second constructor is called with a NULL arena pointer, it must be -// equivalent to invoking the first (no-argument) constructor. +// - The type T must have (at least) two constructors: a constructor callable +// with `args` (without `arena`), called when a T is allocated on the heap; +// and a constructor callable with `Arena* arena, Args&&... args`, called when +// a T is allocated on an arena. If the second constructor is called with a +// NULL arena pointer, it must be equivalent to invoking the first +// (`args`-only) constructor. // // - The type T must have a particular type trait: a nested type // |InternalArenaConstructable_|. This is usually a typedef to |void|. If no @@ -239,22 +238,28 @@ struct ArenaOptions { // present on the type, then its destructor is always called when the // containing arena is destroyed. // -// - One- and two-user-argument forms of CreateMessage() also exist that -// forward these constructor arguments to T's constructor: for example, -// CreateMessage(Arena*, arg1, arg2) forwards to a constructor T(Arena*, -// arg1, arg2). -// // This protocol is implemented by all arena-enabled proto2 message classes as // well as protobuf container types like RepeatedPtrField and Map. The protocol // is internal to protobuf and is not guaranteed to be stable. Non-proto types // should not rely on this protocol. -class PROTOBUF_EXPORT alignas(8) Arena final { +class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { public: - // Arena constructor taking custom options. See ArenaOptions below for + // Default constructor with sensible default options, tuned for average + // use-cases. + inline Arena() : impl_() {} + + // Construct an arena with default options, except for the supplied + // initial block. It is more efficient to use this constructor + // instead of passing ArenaOptions if the only configuration needed + // by the caller is supplying an initial block. + inline Arena(char* initial_block, size_t initial_block_size) + : impl_(initial_block, initial_block_size) {} + + // Arena constructor taking custom options. See ArenaOptions above for // descriptions of the options available. - explicit Arena(const ArenaOptions& options) : impl_(options) { - Init(options); - } + explicit Arena(const ArenaOptions& options) + : impl_(options.initial_block, options.initial_block_size, + options.AllocationPolicy()) {} // Block overhead. Use this as a guide for how much to over-allocate the // initial block if you want an allocation of size N to fit inside it. @@ -262,30 +267,14 @@ class PROTOBUF_EXPORT alignas(8) Arena final { // WARNING: if you allocate multiple objects, it is difficult to guarantee // that a series of allocations will fit in the initial block, especially if // Arena changes its alignment guarantees in the future! - static const size_t kBlockOverhead = internal::ArenaImpl::kBlockHeaderSize + - internal::ArenaImpl::kSerialArenaSize; + static const size_t kBlockOverhead = + internal::ThreadSafeArena::kBlockHeaderSize + + internal::ThreadSafeArena::kSerialArenaSize; - // Default constructor with sensible default options, tuned for average - // use-cases. - Arena() : impl_(ArenaOptions()) { Init(ArenaOptions()); } - - ~Arena() { - if (hooks_cookie_) { - CallDestructorHooks(); - } - } + inline ~Arena() {} - void Init(const ArenaOptions& options) { - on_arena_allocation_ = options.on_arena_allocation; - on_arena_reset_ = options.on_arena_reset; - on_arena_destruction_ = options.on_arena_destruction; - // Call the initialization hook - if (options.on_arena_init != NULL) { - hooks_cookie_ = options.on_arena_init(this); - } else { - hooks_cookie_ = NULL; - } - } + // TODO(protobuf-team): Fix callers to use constructor and delete this method. + void Init(const ArenaOptions&) {} // API to create proto2 message objects on the arena. If the arena passed in // is NULL, then a heap allocated object is returned. Type T must be a message @@ -325,8 +314,16 @@ class PROTOBUF_EXPORT alignas(8) Arena final { // is obtained from the arena). template PROTOBUF_ALWAYS_INLINE static T* Create(Arena* arena, Args&&... args) { - return CreateNoMessage(arena, is_arena_constructable(), - std::forward(args)...); + if (arena == NULL) { + return new T(std::forward(args)...); + } else { + auto destructor = + internal::ObjectDestructor::value, + T>::destructor; + return new (arena->AllocateInternal(sizeof(T), alignof(T), destructor, + RTTI_TYPE_ID(T))) + T(std::forward(args)...); + } } // Create an array of object type T on the arena *without* invoking the @@ -351,9 +348,12 @@ class PROTOBUF_EXPORT alignas(8) Arena final { } } + // The following are routines are for monitoring. They will approximate the + // total sum allocated and used memory, but the exact value is an + // implementation deal. For instance allocated space depends on growth + // policies. Do not use these in unit tests. // Returns the total space allocated by the arena, which is the sum of the - // sizes of the underlying blocks. This method is relatively fast; a counter - // is kept as blocks are allocated. + // sizes of the underlying blocks. uint64 SpaceAllocated() const { return impl_.SpaceAllocated(); } // Returns the total space used by the arena. Similar to SpaceAllocated but // does not include free space and block overhead. The total space returned @@ -366,19 +366,13 @@ class PROTOBUF_EXPORT alignas(8) Arena final { // Any objects allocated on this arena are unusable after this call. It also // returns the total space used by the arena which is the sums of the sizes // of the allocated blocks. This method is not thread-safe. - PROTOBUF_NOINLINE uint64 Reset() { - // Call the reset hook - if (on_arena_reset_ != NULL) { - on_arena_reset_(this, hooks_cookie_, impl_.SpaceAllocated()); - } - return impl_.Reset(); - } + uint64 Reset() { return impl_.Reset(); } // Adds |object| to a list of heap-allocated objects to be freed with |delete| // when the arena is destroyed or reset. template - PROTOBUF_NOINLINE void Own(T* object) { - OwnInternal(object, std::is_convertible()); + PROTOBUF_ALWAYS_INLINE void Own(T* object) { + OwnInternal(object, std::is_convertible()); } // Adds |object| to a list of objects whose destructors will be manually @@ -387,7 +381,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final { // normally only used for objects that are placement-newed into // arena-allocated memory. template - PROTOBUF_NOINLINE void OwnDestructor(T* object) { + PROTOBUF_ALWAYS_INLINE void OwnDestructor(T* object) { if (object != NULL) { impl_.AddCleanup(object, &internal::arena_destruct_object); } @@ -397,8 +391,8 @@ class PROTOBUF_EXPORT alignas(8) Arena final { // will be manually called when the arena is destroyed or reset. This differs // from OwnDestructor() in that any member function may be specified, not only // the class destructor. - PROTOBUF_NOINLINE void OwnCustomDestructor(void* object, - void (*destruct)(void*)) { + PROTOBUF_ALWAYS_INLINE void OwnCustomDestructor(void* object, + void (*destruct)(void*)) { impl_.AddCleanup(object, destruct); } @@ -453,7 +447,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final { return new (ptr) T(std::forward(args)...); } - static Arena* GetArena(const T* p) { return p->GetArenaNoVirtual(); } + static Arena* GetArena(const T* p) { return p->GetArena(); } friend class Arena; }; @@ -477,6 +471,8 @@ class PROTOBUF_EXPORT alignas(8) Arena final { }; private: + internal::ThreadSafeArena impl_; + template struct has_get_arena : InternalHelper::has_get_arena {}; @@ -508,38 +504,27 @@ class PROTOBUF_EXPORT alignas(8) Arena final { } } - template - PROTOBUF_ALWAYS_INLINE static T* CreateInternal(Arena* arena, - Args&&... args) { - if (arena == NULL) { - return new T(std::forward(args)...); - } else { - return arena->DoCreate(std::is_trivially_destructible::value, - std::forward(args)...); - } - } - - void CallDestructorHooks(); - void OnArenaAllocation(const std::type_info* allocated_type, size_t n) const; - inline void AllocHook(const std::type_info* allocated_type, size_t n) const { - if (PROTOBUF_PREDICT_FALSE(hooks_cookie_ != NULL)) { - OnArenaAllocation(allocated_type, n); - } - } - - // Allocate and also optionally call on_arena_allocation callback with the - // allocated type info when the hooks are in place in ArenaOptions and - // the cookie is not null. - template - PROTOBUF_ALWAYS_INLINE void* AllocateInternal(bool skip_explicit_ownership) { - const size_t n = internal::AlignUpTo8(sizeof(T)); - AllocHook(RTTI_TYPE_ID(T), n); + // Allocate and also optionally call collector with the allocated type info + // when allocation recording is enabled. + PROTOBUF_ALWAYS_INLINE void* AllocateInternal(size_t size, size_t align, + void (*destructor)(void*), + const std::type_info* type) { // Monitor allocation if needed. - if (skip_explicit_ownership) { - return AllocateAlignedNoHook(n); + if (destructor == nullptr) { + return AllocateAlignedWithHook(size, align, type); } else { - return impl_.AllocateAlignedAndAddCleanup( - n, &internal::arena_destruct_object); + if (align <= 8) { + auto res = AllocateAlignedWithCleanup(internal::AlignUpTo8(size), type); + res.second->elem = res.first; + res.second->cleanup = destructor; + return res.first; + } else { + auto res = AllocateAlignedWithCleanup(size + align - 8, type); + auto ptr = internal::AlignTo(res.first, align); + res.second->elem = ptr; + res.second->cleanup = destructor; + return ptr; + } } } @@ -559,7 +544,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final { PROTOBUF_ALWAYS_INLINE static T* DoCreateMaybeMessage(Arena* arena, std::false_type, Args&&... args) { - return CreateInternal(arena, std::forward(args)...); + return Create(arena, std::forward(args)...); } template @@ -569,71 +554,52 @@ class PROTOBUF_EXPORT alignas(8) Arena final { std::forward(args)...); } - template - PROTOBUF_ALWAYS_INLINE static T* CreateNoMessage(Arena* arena, std::true_type, - Args&&... args) { - // User is constructing with Create() despite the fact that T supports arena - // construction. In this case we have to delegate to CreateInternal(), and - // we can't use any CreateMaybeMessage() specialization that may be defined. - return CreateInternal(arena, std::forward(args)...); - } - - template - PROTOBUF_ALWAYS_INLINE static T* CreateNoMessage(Arena* arena, - std::false_type, - Args&&... args) { - // User is constructing with Create() and the type does not support arena - // construction. In this case we can delegate to CreateMaybeMessage() and - // use any specialization that may be available for that. - return CreateMaybeMessage(arena, std::forward(args)...); - } - // Just allocate the required size for the given type assuming the // type has a trivial constructor. template PROTOBUF_ALWAYS_INLINE T* CreateInternalRawArray(size_t num_elements) { GOOGLE_CHECK_LE(num_elements, std::numeric_limits::max() / sizeof(T)) << "Requested size is too large to fit into size_t."; - const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements); - // Monitor allocation if needed. - AllocHook(RTTI_TYPE_ID(T), n); - return static_cast(AllocateAlignedNoHook(n)); + // We count on compiler to realize that if sizeof(T) is a multiple of + // 8 AlignUpTo can be elided. + const size_t n = sizeof(T) * num_elements; + return static_cast( + AllocateAlignedWithHook(n, alignof(T), RTTI_TYPE_ID(T))); } - template - PROTOBUF_ALWAYS_INLINE T* DoCreate(bool skip_explicit_ownership, - Args&&... args) { - return new (AllocateInternal(skip_explicit_ownership)) - T(std::forward(args)...); - } template PROTOBUF_ALWAYS_INLINE T* DoCreateMessage(Args&&... args) { return InternalHelper::Construct( - AllocateInternal(InternalHelper::is_destructor_skippable::value), + AllocateInternal(sizeof(T), alignof(T), + internal::ObjectDestructor< + InternalHelper::is_destructor_skippable::value, + T>::destructor, + RTTI_TYPE_ID(T)), this, std::forward(args)...); } // CreateInArenaStorage is used to implement map field. Without it, // Map need to call generated message's protected arena constructor, // which needs to declare Map as friend of generated message. - template - static void CreateInArenaStorage(T* ptr, Arena* arena) { + template + static void CreateInArenaStorage(T* ptr, Arena* arena, Args&&... args) { CreateInArenaStorageInternal(ptr, arena, - typename is_arena_constructable::type()); + typename is_arena_constructable::type(), + std::forward(args)...); RegisterDestructorInternal( ptr, arena, typename InternalHelper::is_destructor_skippable::type()); } - template + template static void CreateInArenaStorageInternal(T* ptr, Arena* arena, - std::true_type) { - InternalHelper::Construct(ptr, arena); + std::true_type, Args&&... args) { + InternalHelper::Construct(ptr, arena, std::forward(args)...); } - template + template static void CreateInArenaStorageInternal(T* ptr, Arena* /* arena */, - std::false_type) { - new (ptr) T(); + std::false_type, Args&&... args) { + new (ptr) T(std::forward(args)...); } template @@ -653,7 +619,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final { template PROTOBUF_ALWAYS_INLINE void OwnInternal(T* object, std::true_type) { if (object != NULL) { - impl_.AddCleanup(object, &internal::arena_delete_object); + impl_.AddCleanup(object, &internal::arena_delete_object); } } template @@ -665,7 +631,7 @@ class PROTOBUF_EXPORT alignas(8) Arena final { // Implementation for GetArena(). Only message objects with // InternalArenaConstructable_ tags can be associated with an arena, and such - // objects must implement a GetArenaNoVirtual() method. + // objects must implement a GetArena() method. template ::value, int>::type = 0> PROTOBUF_ALWAYS_INLINE static Arena* GetArenaInternal(const T* value) { @@ -688,23 +654,38 @@ class PROTOBUF_EXPORT alignas(8) Arena final { } // For friends of arena. - void* AllocateAligned(size_t n) { - AllocHook(NULL, n); - return AllocateAlignedNoHook(internal::AlignUpTo8(n)); + void* AllocateAligned(size_t n, size_t align = 8) { + if (align <= 8) { + return AllocateAlignedNoHook(internal::AlignUpTo8(n)); + } else { + // We are wasting space by over allocating align - 8 bytes. Compared + // to a dedicated function that takes current alignment in consideration. + // Such a scheme would only waste (align - 8)/2 bytes on average, but + // requires a dedicated function in the outline arena allocation + // functions. Possibly re-evaluate tradeoffs later. + return internal::AlignTo(AllocateAlignedNoHook(n + align - 8), align); + } } - void* AllocateAlignedNoHook(size_t n); - - internal::ArenaImpl impl_; - - void (*on_arena_allocation_)(const std::type_info* allocated_type, - uint64 alloc_size, void* cookie); - void (*on_arena_reset_)(Arena* arena, void* cookie, uint64 space_used); - void (*on_arena_destruction_)(Arena* arena, void* cookie, uint64 space_used); + void* AllocateAlignedWithHook(size_t n, size_t align, + const std::type_info* type) { + if (align <= 8) { + return AllocateAlignedWithHook(internal::AlignUpTo8(n), type); + } else { + // We are wasting space by over allocating align - 8 bytes. Compared + // to a dedicated function that takes current alignment in consideration. + // Such a schemee would only waste (align - 8)/2 bytes on average, but + // requires a dedicated function in the outline arena allocation + // functions. Possibly re-evaluate tradeoffs later. + return internal::AlignTo(AllocateAlignedWithHook(n + align - 8, type), + align); + } + } - // The arena may save a cookie it receives from the external on_init hook - // and then use it when calling the on_reset and on_destruction hooks. - void* hooks_cookie_; + void* AllocateAlignedNoHook(size_t n); + void* AllocateAlignedWithHook(size_t n, const std::type_info* type); + std::pair + AllocateAlignedWithCleanup(size_t n, const std::type_info* type); template friend class internal::GenericTypeHandler; diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index d7b7ed73ed1b..84c5d058804f 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -50,12 +51,199 @@ namespace google { namespace protobuf { namespace internal { -inline size_t AlignUpTo8(size_t n) { +inline constexpr size_t AlignUpTo8(size_t n) { // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.) return (n + 7) & static_cast(-8); } -using LifecycleId = int64_t; +using LifecycleIdAtomic = uint64_t; + +// MetricsCollector collects stats for a particular arena. +class PROTOBUF_EXPORT ArenaMetricsCollector { + public: + ArenaMetricsCollector(bool record_allocs) : record_allocs_(record_allocs) {} + + // Invoked when the arena is about to be destroyed. This method will + // typically finalize any metric collection and delete the collector. + // space_allocated is the space used by the arena. + virtual void OnDestroy(uint64 space_allocated) = 0; + + // OnReset() is called when the associated arena is reset. + // space_allocated is the space used by the arena just before the reset. + virtual void OnReset(uint64 space_allocated) = 0; + + // OnAlloc is called when an allocation happens. + // type_info is promised to be static - its lifetime extends to + // match program's lifetime (It is given by typeid operator). + // Note: typeid(void) will be passed as allocated_type every time we + // intentionally want to avoid monitoring an allocation. (i.e. internal + // allocations for managing the arena) + virtual void OnAlloc(const std::type_info* allocated_type, + uint64 alloc_size) = 0; + + // Does OnAlloc() need to be called? If false, metric collection overhead + // will be reduced since we will not do extra work per allocation. + bool RecordAllocs() { return record_allocs_; } + + protected: + // This class is destructed by the call to OnDestroy(). + ~ArenaMetricsCollector() = default; + const bool record_allocs_; +}; + +struct AllocationPolicy { + static constexpr size_t kDefaultStartBlockSize = 256; + static constexpr size_t kDefaultMaxBlockSize = 8192; + + size_t start_block_size = kDefaultStartBlockSize; + size_t max_block_size = kDefaultMaxBlockSize; + void* (*block_alloc)(size_t) = nullptr; + void (*block_dealloc)(void*, size_t) = nullptr; + ArenaMetricsCollector* metrics_collector = nullptr; + + bool IsDefault() const { + return start_block_size == kDefaultMaxBlockSize && + max_block_size == kDefaultMaxBlockSize && block_alloc == nullptr && + block_dealloc == nullptr && metrics_collector == nullptr; + } +}; + +// A simple arena allocator. Calls to allocate functions must be properly +// serialized by the caller, hence this class cannot be used as a general +// purpose allocator in a multi-threaded program. It serves as a building block +// for ThreadSafeArena, which provides a thread-safe arena allocator. +// +// This class manages +// 1) Arena bump allocation + owning memory blocks. +// 2) Maintaining a cleanup list. +// It delagetes the actual memory allocation back to ThreadSafeArena, which +// contains the information on block growth policy and backing memory allocation +// used. +class PROTOBUF_EXPORT SerialArena { + public: + struct Memory { + void* ptr; + size_t size; + }; + + // Node contains the ptr of the object to be cleaned up and the associated + // cleanup function ptr. + struct CleanupNode { + void* elem; // Pointer to the object to be cleaned up. + void (*cleanup)(void*); // Function pointer to the destructor or deleter. + }; + + // Creates a new SerialArena inside mem using the remaining memory as for + // future allocations. + static SerialArena* New(SerialArena::Memory mem, void* owner); + // Free SerialArena returning the memory passed in to New + template + Memory Free(Deallocator deallocator); + + void CleanupList(); + uint64 SpaceAllocated() const { + return space_allocated_.load(std::memory_order_relaxed); + } + uint64 SpaceUsed() const; + + bool HasSpace(size_t n) { return n <= static_cast(limit_ - ptr_); } + + void* AllocateAligned(size_t n, const AllocationPolicy* policy) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + GOOGLE_DCHECK_GE(limit_, ptr_); + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { + return AllocateAlignedFallback(n, policy); + } + void* ret = ptr_; + ptr_ += n; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); +#endif // ADDRESS_SANITIZER + return ret; + } + + // Allocate space if the current region provides enough space. + bool MaybeAllocateAligned(size_t n, void** out) { + GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. + GOOGLE_DCHECK_GE(limit_, ptr_); + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false; + void* ret = ptr_; + ptr_ += n; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); +#endif // ADDRESS_SANITIZER + *out = ret; + return true; + } + + std::pair AllocateAlignedWithCleanup( + size_t n, const AllocationPolicy* policy) { + if (PROTOBUF_PREDICT_FALSE(!HasSpace(n + kCleanupSize))) { + return AllocateAlignedWithCleanupFallback(n, policy); + } + void* ret = ptr_; + ptr_ += n; + limit_ -= kCleanupSize; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(ret, n); + ASAN_UNPOISON_MEMORY_REGION(limit_, kCleanupSize); +#endif // ADDRESS_SANITIZER + return CreatePair(ret, reinterpret_cast(limit_)); + } + + void AddCleanup(void* elem, void (*cleanup)(void*), + const AllocationPolicy* policy) { + auto res = AllocateAlignedWithCleanup(0, policy); + res.second->elem = elem; + res.second->cleanup = cleanup; + } + + void* owner() const { return owner_; } + SerialArena* next() const { return next_; } + void set_next(SerialArena* next) { next_ = next; } + + private: + // Blocks are variable length malloc-ed objects. The following structure + // describes the common header for all blocks. + struct Block { + char* Pointer(size_t n) { + GOOGLE_DCHECK(n <= size); + return reinterpret_cast(this) + n; + } + + Block* next; + size_t size; + CleanupNode* start; + // data follows + }; + + void* owner_; // &ThreadCache of this thread; + Block* head_; // Head of linked list of blocks. + SerialArena* next_; // Next SerialArena in this linked list. + size_t space_used_ = 0; // Necessary for metrics. + std::atomic space_allocated_; + + // Next pointer to allocate from. Always 8-byte aligned. Points inside + // head_ (and head_->pos will always be non-canonical). We keep these + // here to reduce indirection. + char* ptr_; + char* limit_; + + // Constructor is private as only New() should be used. + inline SerialArena(Block* b, void* owner); + void* AllocateAlignedFallback(size_t n, const AllocationPolicy* policy); + std::pair AllocateAlignedWithCleanupFallback( + size_t n, const AllocationPolicy* policy); + void AllocateNewBlock(size_t n, const AllocationPolicy* policy); + + std::pair CreatePair(void* ptr, CleanupNode* node) { + return {ptr, node}; + } + + public: + static constexpr size_t kBlockHeaderSize = AlignUpTo8(sizeof(Block)); + static constexpr size_t kCleanupSize = AlignUpTo8(sizeof(CleanupNode)); +}; // This class provides the core Arena memory allocation library. Different // implementations only need to implement the public interface below. @@ -63,56 +251,43 @@ using LifecycleId = int64_t; // in turn would be templates, which will/cannot happen. However separating // the memory allocation part from the cruft of the API users expect we can // use #ifdef the select the best implementation based on hardware / OS. -class PROTOBUF_EXPORT ArenaImpl { +class PROTOBUF_EXPORT ThreadSafeArena { public: - struct Options { - size_t start_block_size; - size_t max_block_size; - char* initial_block; - size_t initial_block_size; - void* (*block_alloc)(size_t); - void (*block_dealloc)(void*, size_t); - - template - explicit Options(const O& options) - : start_block_size(options.start_block_size), - max_block_size(options.max_block_size), - initial_block(options.initial_block), - initial_block_size(options.initial_block_size), - block_alloc(options.block_alloc), - block_dealloc(options.block_dealloc) {} - }; + ThreadSafeArena() { Init(false); } - template - explicit ArenaImpl(const O& options) : options_(options) { - if (options_.initial_block != NULL && options_.initial_block_size > 0) { - GOOGLE_CHECK_GE(options_.initial_block_size, sizeof(Block)) - << ": Initial block size too small for header."; - initial_block_ = reinterpret_cast(options_.initial_block); + ThreadSafeArena(char* mem, size_t size) { InitializeFrom(mem, size); } + + explicit ThreadSafeArena(void* mem, size_t size, + const AllocationPolicy& policy) { + if (policy.IsDefault()) { + // Legacy code doesn't use the API above, but provides the initial block + // through ArenaOptions. I suspect most do not touch the allocation + // policy parameters. + InitializeFrom(mem, size); } else { - initial_block_ = NULL; + auto collector = policy.metrics_collector; + bool record_allocs = collector && collector->RecordAllocs(); + InitializeWithPolicy(mem, size, record_allocs, policy); } - - Init(); } // Destructor deletes all owned heap allocated objects, and destructs objects // that have non-trivial destructors, except for proto2 message objects whose // destructors can be skipped. Also, frees all blocks except the initial block // if it was passed in. - ~ArenaImpl(); + ~ThreadSafeArena(); uint64 Reset(); uint64 SpaceAllocated() const; uint64 SpaceUsed() const; - void* AllocateAligned(size_t n) { + void* AllocateAligned(size_t n, const std::type_info* type) { SerialArena* arena; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(&arena))) { - return arena->AllocateAligned(n); + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFast(tag_and_id_, &arena))) { + return arena->AllocateAligned(n, AllocPolicy()); } else { - return AllocateAlignedFallback(n); + return AllocateAlignedFallback(n, type); } } @@ -123,213 +298,74 @@ class PROTOBUF_EXPORT ArenaImpl { // code for the happy path. PROTOBUF_ALWAYS_INLINE bool MaybeAllocateAligned(size_t n, void** out) { SerialArena* a; - if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFromThreadCache(&a))) { + if (PROTOBUF_PREDICT_TRUE(GetSerialArenaFromThreadCache(tag_and_id_, &a))) { return a->MaybeAllocateAligned(n, out); } return false; } - void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)); + std::pair AllocateAlignedWithCleanup( + size_t n, const std::type_info* type); // Add object pointer and cleanup function pointer to the list. void AddCleanup(void* elem, void (*cleanup)(void*)); private: - void* AllocateAlignedFallback(size_t n); - void* AllocateAlignedAndAddCleanupFallback(size_t n, void (*cleanup)(void*)); - void AddCleanupFallback(void* elem, void (*cleanup)(void*)); - - // Node contains the ptr of the object to be cleaned up and the associated - // cleanup function ptr. - struct CleanupNode { - void* elem; // Pointer to the object to be cleaned up. - void (*cleanup)(void*); // Function pointer to the destructor or deleter. - }; - - // Cleanup uses a chunked linked list, to reduce pointer chasing. - struct CleanupChunk { - static size_t SizeOf(size_t i) { - return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1)); - } - size_t size; // Total elements in the list. - CleanupChunk* next; // Next node in the list. - CleanupNode nodes[1]; // True length is |size|. - }; - - class Block; - - // A thread-unsafe Arena that can only be used within its owning thread. - class PROTOBUF_EXPORT SerialArena { - public: - // The allocate/free methods here are a little strange, since SerialArena is - // allocated inside a Block which it also manages. This is to avoid doing - // an extra allocation for the SerialArena itself. - - // Creates a new SerialArena inside Block* and returns it. - static SerialArena* New(Block* b, void* owner, ArenaImpl* arena); - - // Destroys this SerialArena, freeing all blocks with the given dealloc - // function, except any block equal to |initial_block|. - static uint64 Free(SerialArena* serial, Block* initial_block, - void (*block_dealloc)(void*, size_t)); + // Unique for each arena. Changes on Reset(). + uint64 tag_and_id_; + // The LSB of tag_and_id_ indicates if allocs in this arena are recorded. + enum { kRecordAllocs = 1 }; - void CleanupList(); - uint64 SpaceUsed() const; - - bool HasSpace(size_t n) { return n <= static_cast(limit_ - ptr_); } - - void* AllocateAligned(size_t n) { - GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. - GOOGLE_DCHECK_GE(limit_, ptr_); - if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) { - return AllocateAlignedFallback(n); - } - void* ret = ptr_; - ptr_ += n; -#ifdef ADDRESS_SANITIZER - ASAN_UNPOISON_MEMORY_REGION(ret, n); -#endif // ADDRESS_SANITIZER - return ret; - } + intptr_t alloc_policy_ = 0; // Tagged pointer to AllocPolicy. + // The LSB of alloc_policy_ indicates if the user owns the initial block. + enum { kUserOwnedInitialBlock = 1 }; - // Allocate space if the current region provides enough space. - bool MaybeAllocateAligned(size_t n, void** out) { - GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned. - GOOGLE_DCHECK_GE(limit_, ptr_); - if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false; - void* ret = ptr_; - ptr_ += n; -#ifdef ADDRESS_SANITIZER - ASAN_UNPOISON_MEMORY_REGION(ret, n); -#endif // ADDRESS_SANITIZER - *out = ret; - return true; - } - - void AddCleanup(void* elem, void (*cleanup)(void*)) { - if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) { - AddCleanupFallback(elem, cleanup); - return; - } - cleanup_ptr_->elem = elem; - cleanup_ptr_->cleanup = cleanup; - cleanup_ptr_++; - } - - void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)) { - void* ret = AllocateAligned(n); - AddCleanup(ret, cleanup); - return ret; - } - - void* owner() const { return owner_; } - SerialArena* next() const { return next_; } - void set_next(SerialArena* next) { next_ = next; } - - private: - void* AllocateAlignedFallback(size_t n); - void AddCleanupFallback(void* elem, void (*cleanup)(void*)); - void CleanupListFallback(); - - ArenaImpl* arena_; // Containing arena. - void* owner_; // &ThreadCache of this thread; - Block* head_; // Head of linked list of blocks. - CleanupChunk* cleanup_; // Head of cleanup list. - SerialArena* next_; // Next SerialArena in this linked list. - - // Next pointer to allocate from. Always 8-byte aligned. Points inside - // head_ (and head_->pos will always be non-canonical). We keep these - // here to reduce indirection. - char* ptr_; - char* limit_; - - // Next CleanupList members to append to. These point inside cleanup_. - CleanupNode* cleanup_ptr_; - CleanupNode* cleanup_limit_; - }; - - // Blocks are variable length malloc-ed objects. The following structure - // describes the common header for all blocks. - class PROTOBUF_EXPORT Block { - public: - Block(size_t size, Block* next); + // Pointer to a linked list of SerialArena. + std::atomic threads_; + std::atomic hint_; // Fast thread-local block access - char* Pointer(size_t n) { - GOOGLE_DCHECK(n <= size_); - return reinterpret_cast(this) + n; - } + const AllocationPolicy* AllocPolicy() const { + return reinterpret_cast(alloc_policy_ & -8); + } + void InitializeFrom(void* mem, size_t size); + void InitializeWithPolicy(void* mem, size_t size, bool record_allocs, + AllocationPolicy policy); + void* AllocateAlignedFallback(size_t n, const std::type_info* type); + std::pair + AllocateAlignedWithCleanupFallback(size_t n, const std::type_info* type); + void AddCleanupFallback(void* elem, void (*cleanup)(void*)); - Block* next() const { return next_; } - size_t pos() const { return pos_; } - size_t size() const { return size_; } - void set_pos(size_t pos) { pos_ = pos; } + void Init(bool record_allocs); + void SetInitialBlock(void* mem, size_t size); - private: - Block* next_; // Next block for this thread. - size_t pos_; - size_t size_; - // data follows - }; + // Delete or Destruct all objects owned by the arena. + void CleanupList(); - struct ThreadCache { -#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) - // If we are using the ThreadLocalStorage class to store the ThreadCache, - // then the ThreadCache's default constructor has to be responsible for - // initializing it. - ThreadCache() : last_lifecycle_id_seen(-1), last_serial_arena(NULL) {} -#endif + inline bool ShouldRecordAlloc() const { return tag_and_id_ & kRecordAllocs; } - // The ThreadCache is considered valid as long as this matches the - // lifecycle_id of the arena being used. - LifecycleId last_lifecycle_id_seen; - SerialArena* last_serial_arena; - }; - static std::atomic lifecycle_id_generator_; -#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) - // Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread - // local storage class we implemented. - // iOS also does not support the GOOGLE_THREAD_LOCAL keyword. - static ThreadCache& thread_cache(); -#elif defined(PROTOBUF_USE_DLLS) - // Thread local variables cannot be exposed through DLL interface but we can - // wrap them in static functions. - static ThreadCache& thread_cache(); -#else - static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_; - static ThreadCache& thread_cache() { return thread_cache_; } -#endif - - void Init(); + inline uint64 LifeCycleId() const { + return tag_and_id_ & (-kRecordAllocs - 1); + } - // Free all blocks and return the total space used which is the sums of sizes - // of the all the allocated blocks. - uint64 FreeBlocks(); - // Delete or Destruct all objects owned by the arena. - void CleanupList(); + inline void RecordAlloc(const std::type_info* allocated_type, + size_t n) const { + AllocPolicy()->metrics_collector->OnAlloc(allocated_type, n); + } inline void CacheSerialArena(SerialArena* serial) { thread_cache().last_serial_arena = serial; - thread_cache().last_lifecycle_id_seen = lifecycle_id_; + thread_cache().last_lifecycle_id_seen = LifeCycleId(); // TODO(haberman): evaluate whether we would gain efficiency by getting rid - // of hint_. It's the only write we do to ArenaImpl in the allocation path, - // which will dirty the cache line. + // of hint_. It's the only write we do to ThreadSafeArena in the allocation + // path, which will dirty the cache line. hint_.store(serial, std::memory_order_release); } - std::atomic - threads_; // Pointer to a linked list of SerialArena. - std::atomic hint_; // Fast thread-local block access - std::atomic space_allocated_; // Total size of all allocated blocks. - - Block* initial_block_; // If non-NULL, points to the block that came from - // user data. - - Block* NewBlock(Block* last_block, size_t min_bytes); - - SerialArena* GetSerialArena(); - PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) { - if (GetSerialArenaFromThreadCache(arena)) return true; + PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(uint64 lifecycle_id, + SerialArena** arena) { + if (GetSerialArenaFromThreadCache(lifecycle_id, arena)) return true; + if (lifecycle_id & kRecordAllocs) return false; // Check whether we own the last accessed SerialArena on this arena. This // fast path optimizes the case where a single thread uses multiple arenas. @@ -343,34 +379,96 @@ class PROTOBUF_EXPORT ArenaImpl { } PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFromThreadCache( - SerialArena** arena) { + uint64 lifecycle_id, SerialArena** arena) { // If this thread already owns a block in this arena then try to use that. // This fast path optimizes the case where multiple threads allocate from // the same arena. ThreadCache* tc = &thread_cache(); - if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == lifecycle_id_)) { + if (PROTOBUF_PREDICT_TRUE(tc->last_lifecycle_id_seen == lifecycle_id)) { *arena = tc->last_serial_arena; return true; } return false; } SerialArena* GetSerialArenaFallback(void* me); - LifecycleId lifecycle_id_; // Unique for each arena. Changes on Reset(). - Options options_; + template + void PerSerialArena(Functor fn) { + // By omitting an Acquire barrier we ensure that any user code that doesn't + // properly synchronize Reset() or the destructor will throw a TSAN warning. + SerialArena* serial = threads_.load(std::memory_order_relaxed); + + for (; serial; serial = serial->next()) fn(serial); + } + + // Releases all memory except the first block which it returns. The first + // block might be owned by the user and thus need some extra checks before + // deleting. + SerialArena::Memory Free(size_t* space_allocated); + +#ifdef _MSC_VER +#pragma warning(disable : 4324) +#endif + struct alignas(64) ThreadCache { +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // If we are using the ThreadLocalStorage class to store the ThreadCache, + // then the ThreadCache's default constructor has to be responsible for + // initializing it. + ThreadCache() + : next_lifecycle_id(0), + last_lifecycle_id_seen(-1), + last_serial_arena(NULL) {} +#endif + + // Number of per-thread lifecycle IDs to reserve. Must be power of two. + // To reduce contention on a global atomic, each thread reserves a batch of + // IDs. The following number is calculated based on a stress test with + // ~6500 threads all frequently allocating a new arena. + static constexpr size_t kPerThreadIds = 256; + // Next lifecycle ID available to this thread. We need to reserve a new + // batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`. + uint64 next_lifecycle_id; + // The ThreadCache is considered valid as long as this matches the + // lifecycle_id of the arena being used. + uint64 last_lifecycle_id_seen; + SerialArena* last_serial_arena; + }; + + // Lifecycle_id can be highly contended variable in a situation of lots of + // arena creation. Make sure that other global variables are not sharing the + // cacheline. +#ifdef _MSC_VER +#pragma warning(disable : 4324) +#endif + struct alignas(64) CacheAlignedLifecycleIdGenerator { + std::atomic id; + }; + static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_; +#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) + // Android ndk does not support __thread keyword so we use a custom thread + // local storage class we implemented. + // iOS also does not support the __thread keyword. + static ThreadCache& thread_cache(); +#elif defined(PROTOBUF_USE_DLLS) + // Thread local variables cannot be exposed through DLL interface but we can + // wrap them in static functions. + static ThreadCache& thread_cache(); +#else + static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_; + static ThreadCache& thread_cache() { return thread_cache_; } +#endif - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl); + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadSafeArena); // All protos have pointers back to the arena hence Arena must have // pointer stability. - ArenaImpl(ArenaImpl&&) = delete; - ArenaImpl& operator=(ArenaImpl&&) = delete; + ThreadSafeArena(ThreadSafeArena&&) = delete; + ThreadSafeArena& operator=(ThreadSafeArena&&) = delete; public: // kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8 // to protect the invariant that pos is always at a multiple of 8. - static const size_t kBlockHeaderSize = - (sizeof(Block) + 7) & static_cast(-8); - static const size_t kSerialArenaSize = + static constexpr size_t kBlockHeaderSize = SerialArena::kBlockHeaderSize; + static constexpr size_t kSerialArenaSize = (sizeof(SerialArena) + 7) & static_cast(-8); static_assert(kBlockHeaderSize % 8 == 0, "kBlockHeaderSize must be a multiple of 8."); diff --git a/src/google/protobuf/arena_test_util.h b/src/google/protobuf/arena_test_util.h index 84df34989cb5..8ceab91aabc7 100644 --- a/src/google/protobuf/arena_test_util.h +++ b/src/google/protobuf/arena_test_util.h @@ -84,7 +84,7 @@ class NoHeapChecker { private: class NewDeleteCapture { public: - // TOOD(xiaofeng): Implement this for opensource protobuf. + // TODO(xiaofeng): Implement this for opensource protobuf. void Hook() {} void Unhook() {} int alloc_count() { return 0; } diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 7e5b11563388..7e9016429f64 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -44,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -58,12 +58,14 @@ #include +// Must be included last +#include + using proto2_arena_unittest::ArenaMessage; using protobuf_unittest::TestAllExtensions; using protobuf_unittest::TestAllTypes; using protobuf_unittest::TestEmptyMessage; using protobuf_unittest::TestOneof2; -using protobuf_unittest_no_arena::TestNoArenaMessage; namespace google { namespace protobuf { @@ -156,14 +158,12 @@ class MustBeConstructedWithOneThroughEight { TEST(ArenaTest, ArenaConstructable) { EXPECT_TRUE(Arena::is_arena_constructable::type::value); EXPECT_TRUE(Arena::is_arena_constructable::type::value); - EXPECT_FALSE(Arena::is_arena_constructable::type::value); EXPECT_FALSE(Arena::is_arena_constructable::type::value); } TEST(ArenaTest, DestructorSkippable) { EXPECT_TRUE(Arena::is_destructor_skippable::type::value); EXPECT_TRUE(Arena::is_destructor_skippable::type::value); - EXPECT_FALSE(Arena::is_destructor_skippable::type::value); EXPECT_FALSE(Arena::is_destructor_skippable::type::value); } @@ -273,28 +273,36 @@ TEST(ArenaTest, CreateWithMoveArguments) { } TEST(ArenaTest, InitialBlockTooSmall) { - // Construct a small (64 byte) initial block of memory to be used by the - // arena allocator; then, allocate an object which will not fit in the - // initial block. - std::vector arena_block(96); - ArenaOptions options; - options.initial_block = &arena_block[0]; - options.initial_block_size = arena_block.size(); - Arena arena(options); + // Construct a small blocks of memory to be used by the arena allocator; then, + // allocate an object which will not fit in the initial block. + for (int size = 0; size <= Arena::kBlockOverhead + 32; size++) { + std::vector arena_block(size); + ArenaOptions options; + options.initial_block = arena_block.data(); + options.initial_block_size = arena_block.size(); + + // Try sometimes with non-default block sizes so that we exercise paths + // with and without ArenaImpl::Options. + if ((size % 2) != 0) { + options.start_block_size += 8; + } + + Arena arena(options); - char* p = Arena::CreateArray(&arena, 96); - uintptr_t allocation = reinterpret_cast(p); + char* p = Arena::CreateArray(&arena, 96); + uintptr_t allocation = reinterpret_cast(p); - // Ensure that the arena allocator did not return memory pointing into the - // initial block of memory. - uintptr_t arena_start = reinterpret_cast(&arena_block[0]); - uintptr_t arena_end = arena_start + arena_block.size(); - EXPECT_FALSE(allocation >= arena_start && allocation < arena_end); + // Ensure that the arena allocator did not return memory pointing into the + // initial block of memory. + uintptr_t arena_start = reinterpret_cast(arena_block.data()); + uintptr_t arena_end = arena_start + arena_block.size(); + EXPECT_FALSE(allocation >= arena_start && allocation < arena_end); - // Write to the memory we allocated; this should (but is not guaranteed to) - // trigger a check for heap corruption if the object was allocated from the - // initially-provided block. - memset(p, '\0', 96); + // Write to the memory we allocated; this should (but is not guaranteed to) + // trigger a check for heap corruption if the object was allocated from the + // initially-provided block. + memset(p, '\0', 96); + } } TEST(ArenaTest, Parsing) { @@ -462,13 +470,6 @@ TEST(ArenaTest, SetAllocatedMessage) { nested->set_bb(118); arena_message->set_allocated_optional_nested_message(nested); EXPECT_EQ(118, arena_message->optional_nested_message().bb()); - - TestNoArenaMessage no_arena_message; - EXPECT_FALSE(no_arena_message.has_arena_message()); - no_arena_message.set_allocated_arena_message(NULL); - EXPECT_FALSE(no_arena_message.has_arena_message()); - no_arena_message.set_allocated_arena_message(new ArenaMessage); - EXPECT_TRUE(no_arena_message.has_arena_message()); } TEST(ArenaTest, ReleaseMessage) { @@ -673,15 +674,8 @@ TEST(ArenaTest, AddAllocatedWithReflection) { ArenaMessage* arena1_message = Arena::CreateMessage(&arena1); const Reflection* r = arena1_message->GetReflection(); const Descriptor* d = arena1_message->GetDescriptor(); - const FieldDescriptor* fd = - d->FindFieldByName("repeated_import_no_arena_message"); - // Message with cc_enable_arenas = false; - r->AddMessage(arena1_message, fd); - r->AddMessage(arena1_message, fd); - r->AddMessage(arena1_message, fd); - EXPECT_EQ(3, r->FieldSize(*arena1_message, fd)); // Message with cc_enable_arenas = true; - fd = d->FindFieldByName("repeated_nested_message"); + const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message"); r->AddMessage(arena1_message, fd); r->AddMessage(arena1_message, fd); r->AddMessage(arena1_message, fd); @@ -873,23 +867,6 @@ TEST(ArenaTest, ReleaseLastRepeatedField) { } } -TEST(ArenaTest, UnsafeArenaReleaseAdd) { - // Use unsafe_arena_release() and unsafe_arena_set_allocated() to transfer an - // arena-allocated string from one message to another. - const char kContent[] = "Test content"; - - Arena arena; - TestAllTypes* message1 = Arena::CreateMessage(&arena); - TestAllTypes* message2 = Arena::CreateMessage(&arena); - std::string* arena_string = Arena::Create(&arena); - *arena_string = kContent; - - message1->unsafe_arena_set_allocated_optional_string(arena_string); - message2->unsafe_arena_set_allocated_optional_string( - message1->unsafe_arena_release_optional_string()); - EXPECT_EQ(kContent, message2->optional_string()); -} - TEST(ArenaTest, UnsafeArenaAddAllocated) { Arena arena; TestAllTypes* message = Arena::CreateMessage(&arena); @@ -900,43 +877,20 @@ TEST(ArenaTest, UnsafeArenaAddAllocated) { } } -TEST(ArenaTest, UnsafeArenaRelease) { - Arena arena; - TestAllTypes* message = Arena::CreateMessage(&arena); - - std::string* s = new std::string("test string"); - message->unsafe_arena_set_allocated_optional_string(s); - EXPECT_TRUE(message->has_optional_string()); - EXPECT_EQ("test string", message->optional_string()); - s = message->unsafe_arena_release_optional_string(); - EXPECT_FALSE(message->has_optional_string()); - delete s; - - s = new std::string("test string"); - message->unsafe_arena_set_allocated_oneof_string(s); - EXPECT_TRUE(message->has_oneof_string()); - EXPECT_EQ("test string", message->oneof_string()); - s = message->unsafe_arena_release_oneof_string(); - EXPECT_FALSE(message->has_oneof_string()); - delete s; -} - TEST(ArenaTest, OneofMerge) { Arena arena; TestAllTypes* message0 = Arena::CreateMessage(&arena); TestAllTypes* message1 = Arena::CreateMessage(&arena); - message0->unsafe_arena_set_allocated_oneof_string(new std::string("x")); + message0->set_oneof_string("x"); ASSERT_TRUE(message0->has_oneof_string()); - message1->unsafe_arena_set_allocated_oneof_string(new std::string("y")); + message1->set_oneof_string("y"); ASSERT_TRUE(message1->has_oneof_string()); EXPECT_EQ("x", message0->oneof_string()); EXPECT_EQ("y", message1->oneof_string()); message0->MergeFrom(*message1); EXPECT_EQ("y", message0->oneof_string()); EXPECT_EQ("y", message1->oneof_string()); - delete message0->unsafe_arena_release_oneof_string(); - delete message1->unsafe_arena_release_oneof_string(); } TEST(ArenaTest, ArenaOneofReflection) { @@ -1043,10 +997,7 @@ TEST(ArenaTest, ExtensionsOnArena) { TEST(ArenaTest, RepeatedFieldOnArena) { // Preallocate an initial arena block to avoid mallocs during hooked region. std::vector arena_block(1024 * 1024); - ArenaOptions options; - options.initial_block = &arena_block[0]; - options.initial_block_size = arena_block.size(); - Arena arena(options); + Arena arena(arena_block.data(), arena_block.size()); { internal::NoHeapChecker no_heap; @@ -1221,7 +1172,6 @@ TEST(ArenaTest, MessageLiteOnArena) { } #endif // PROTOBUF_RTTI - // RepeatedField should support non-POD types, and invoke constructors and // destructors appropriately, because it's used this way by lots of other code // (even if this was not its original intent). @@ -1245,10 +1195,7 @@ TEST(ArenaTest, RepeatedFieldWithNonPODType) { uint64 Align8(uint64 n) { return (n + 7) & -8; } TEST(ArenaTest, SpaceAllocated_and_Used) { - ArenaOptions options; - options.start_block_size = 256; - options.max_block_size = 8192; - Arena arena_1(options); + Arena arena_1; EXPECT_EQ(0, arena_1.SpaceAllocated()); EXPECT_EQ(0, arena_1.SpaceUsed()); EXPECT_EQ(0, arena_1.Reset()); @@ -1260,6 +1207,9 @@ TEST(ArenaTest, SpaceAllocated_and_Used) { // Test with initial block. std::vector arena_block(1024); + ArenaOptions options; + options.start_block_size = 256; + options.max_block_size = 8192; options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena_2(options); @@ -1270,19 +1220,25 @@ TEST(ArenaTest, SpaceAllocated_and_Used) { EXPECT_EQ(1024, arena_2.SpaceAllocated()); EXPECT_EQ(Align8(55), arena_2.SpaceUsed()); EXPECT_EQ(1024, arena_2.Reset()); +} - // Reset options to test doubling policy explicitly. - options.initial_block = NULL; - options.initial_block_size = 0; - Arena arena_3(options); - EXPECT_EQ(0, arena_3.SpaceUsed()); - Arena::CreateArray(&arena_3, 160); - EXPECT_EQ(256, arena_3.SpaceAllocated()); - EXPECT_EQ(Align8(160), arena_3.SpaceUsed()); - Arena::CreateArray(&arena_3, 70); - EXPECT_EQ(256 + 512, arena_3.SpaceAllocated()); - EXPECT_EQ(Align8(160) + Align8(70), arena_3.SpaceUsed()); - EXPECT_EQ(256 + 512, arena_3.Reset()); +TEST(ArenaTest, BlockSizeDoubling) { + Arena arena; + EXPECT_EQ(0, arena.SpaceUsed()); + EXPECT_EQ(0, arena.SpaceAllocated()); + + // Allocate something to get initial block size. + Arena::CreateArray(&arena, 1); + auto first_block_size = arena.SpaceAllocated(); + + // Keep allocating until space used increases. + while (arena.SpaceAllocated() == first_block_size) { + Arena::CreateArray(&arena, 1); + } + ASSERT_GT(arena.SpaceAllocated(), first_block_size); + auto second_block_size = (arena.SpaceAllocated() - first_block_size); + + EXPECT_EQ(second_block_size, 2*first_block_size); } TEST(ArenaTest, Alignment) { @@ -1331,11 +1287,6 @@ TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) { } TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaCompatibleTypes) { - TestNoArenaMessage message; - const TestNoArenaMessage* const_pointer_to_message = &message; - EXPECT_EQ(nullptr, Arena::GetArena(&message)); - EXPECT_EQ(nullptr, Arena::GetArena(const_pointer_to_message)); - // Test that GetArena returns nullptr for types that have a GetArena method // that doesn't return Arena*. struct { @@ -1365,96 +1316,93 @@ TEST(ArenaTest, AddCleanup) { } } -TEST(ArenaTest, UnsafeSetAllocatedOnArena) { - Arena arena; - TestAllTypes* message = Arena::CreateMessage(&arena); - EXPECT_FALSE(message->has_optional_string()); - - std::string owned_string = "test with long enough content to heap-allocate"; - message->unsafe_arena_set_allocated_optional_string(&owned_string); - EXPECT_TRUE(message->has_optional_string()); - - message->unsafe_arena_set_allocated_optional_string(NULL); - EXPECT_FALSE(message->has_optional_string()); +namespace { +uint32 hooks_num_init = 0; +uint32 hooks_num_allocations = 0; +uint32 hooks_num_reset = 0; +uint32 hooks_num_destruct = 0; + +void ClearHookCounts() { + hooks_num_init = 0; + hooks_num_allocations = 0; + hooks_num_reset = 0; + hooks_num_destruct = 0; } +} // namespace -// A helper utility class to only contain static hook functions, some -// counters to be used to verify the counters have been called and a cookie -// value to be verified. -class ArenaHooksTestUtil { +// A helper utility class that handles arena callbacks. +class ArenaOptionsTestFriend final : public internal::ArenaMetricsCollector { public: - static void* on_init(Arena* arena) { - ++num_init; - int* cookie = new int(kCookieValue); - return static_cast(cookie); + static internal::ArenaMetricsCollector* NewWithAllocs() { + return new ArenaOptionsTestFriend(true); } - static void on_allocation(const std::type_info* /*unused*/, uint64 alloc_size, - void* cookie) { - ++num_allocations; - int cookie_value = *static_cast(cookie); - EXPECT_EQ(kCookieValue, cookie_value); + static internal::ArenaMetricsCollector* NewWithoutAllocs() { + return new ArenaOptionsTestFriend(false); } - static void on_reset(Arena* arena, void* cookie, uint64 space_used) { - ++num_reset; - int cookie_value = *static_cast(cookie); - EXPECT_EQ(kCookieValue, cookie_value); + static void Enable(ArenaOptions* options) { + ClearHookCounts(); + options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithAllocs; } - static void on_destruction(Arena* arena, void* cookie, uint64 space_used) { - ++num_destruct; - int cookie_value = *static_cast(cookie); - EXPECT_EQ(kCookieValue, cookie_value); - delete static_cast(cookie); + static void EnableWithoutAllocs(ArenaOptions* options) { + ClearHookCounts(); + options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithoutAllocs; } - static const int kCookieValue = 999; - static uint32 num_init; - static uint32 num_allocations; - static uint32 num_reset; - static uint32 num_destruct; -}; -uint32 ArenaHooksTestUtil::num_init = 0; -uint32 ArenaHooksTestUtil::num_allocations = 0; -uint32 ArenaHooksTestUtil::num_reset = 0; -uint32 ArenaHooksTestUtil::num_destruct = 0; -const int ArenaHooksTestUtil::kCookieValue; - -class ArenaOptionsTestFriend { - public: - static void Set(ArenaOptions* options) { - options->on_arena_init = ArenaHooksTestUtil::on_init; - options->on_arena_allocation = ArenaHooksTestUtil::on_allocation; - options->on_arena_reset = ArenaHooksTestUtil::on_reset; - options->on_arena_destruction = ArenaHooksTestUtil::on_destruction; + explicit ArenaOptionsTestFriend(bool record_allocs) + : ArenaMetricsCollector(record_allocs) { + ++hooks_num_init; + } + void OnDestroy(uint64 space_allocated) override { + ++hooks_num_destruct; + delete this; + } + void OnReset(uint64 space_allocated) override { ++hooks_num_reset; } + void OnAlloc(const std::type_info* allocated_type, + uint64 alloc_size) override { + ++hooks_num_allocations; } }; -// Test the hooks are correctly called and that the cookie is passed. +// Test the hooks are correctly called. TEST(ArenaTest, ArenaHooksSanity) { ArenaOptions options; - ArenaOptionsTestFriend::Set(&options); + ArenaOptionsTestFriend::Enable(&options); // Scope for defining the arena { Arena arena(options); - EXPECT_EQ(1, ArenaHooksTestUtil::num_init); - EXPECT_EQ(0, ArenaHooksTestUtil::num_allocations); + EXPECT_EQ(1, hooks_num_init); + EXPECT_EQ(0, hooks_num_allocations); Arena::Create(&arena); if (std::is_trivially_destructible::value) { - EXPECT_EQ(1, ArenaHooksTestUtil::num_allocations); + EXPECT_EQ(1, hooks_num_allocations); } else { - EXPECT_EQ(2, ArenaHooksTestUtil::num_allocations); + EXPECT_EQ(2, hooks_num_allocations); } arena.Reset(); arena.Reset(); - EXPECT_EQ(2, ArenaHooksTestUtil::num_reset); + EXPECT_EQ(2, hooks_num_reset); } - EXPECT_EQ(3, ArenaHooksTestUtil::num_reset); - EXPECT_EQ(1, ArenaHooksTestUtil::num_destruct); + EXPECT_EQ(2, hooks_num_reset); + EXPECT_EQ(1, hooks_num_destruct); +} + +// Test that allocation hooks are not called when we don't need them. +TEST(ArenaTest, ArenaHooksWhenAllocationsNotNeeded) { + ArenaOptions options; + ArenaOptionsTestFriend::EnableWithoutAllocs(&options); + + Arena arena(options); + EXPECT_EQ(0, hooks_num_allocations); + Arena::Create(&arena); + EXPECT_EQ(0, hooks_num_allocations); } } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc new file mode 100644 index 000000000000..452d2bfec846 --- /dev/null +++ b/src/google/protobuf/arenastring.cc @@ -0,0 +1,256 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// clang-format off +#include +// clang-format on + +namespace google { +namespace protobuf { +namespace internal { + +const std::string& LazyString::Init() const { + static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED}; + mu.Lock(); + const std::string* res = inited_.load(std::memory_order_acquire); + if (res == nullptr) { + auto init_value = init_value_; + res = ::new (static_cast(string_buf_)) + std::string(init_value.ptr, init_value.size); + inited_.store(res, std::memory_order_release); + } + mu.Unlock(); + return *res; +} + + +void ArenaStringPtr::Set(const std::string* default_value, + ConstStringParam value, ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + tagged_ptr_.Set(Arena::Create(arena, value)); + } else { + UnsafeMutablePointer()->assign(value.data(), value.length()); + } +} + +void ArenaStringPtr::Set(const std::string* default_value, std::string&& value, + ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + if (arena == nullptr) { + tagged_ptr_.Set(new std::string(std::move(value))); + } else { + tagged_ptr_.Set(Arena::Create(arena, std::move(value))); + } + } else if (IsDonatedString()) { + std::string* current = tagged_ptr_.Get(); + auto* s = new (current) std::string(std::move(value)); + arena->OwnDestructor(s); + tagged_ptr_.Set(s); + } else /* !IsDonatedString() */ { + *UnsafeMutablePointer() = std::move(value); + } +} + +void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value, + ::google::protobuf::Arena* arena) { + Set(&GetEmptyStringAlreadyInited(), value, arena); +} + +void ArenaStringPtr::Set(EmptyDefault, std::string&& value, + ::google::protobuf::Arena* arena) { + Set(&GetEmptyStringAlreadyInited(), std::move(value), arena); +} + +void ArenaStringPtr::Set(NonEmptyDefault, ConstStringParam value, + ::google::protobuf::Arena* arena) { + Set(nullptr, value, arena); +} + +void ArenaStringPtr::Set(NonEmptyDefault, std::string&& value, + ::google::protobuf::Arena* arena) { + Set(nullptr, std::move(value), arena); +} + +std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) { + return UnsafeMutablePointer(); + } else { + return MutableSlow(arena); + } +} + +std::string* ArenaStringPtr::Mutable(const LazyString& default_value, + ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(nullptr)) { + return UnsafeMutablePointer(); + } else { + return MutableSlow(arena, default_value); + } +} + +std::string* ArenaStringPtr::MutableNoCopy(const std::string* default_value, + ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(default_value)) { + return UnsafeMutablePointer(); + } else { + GOOGLE_DCHECK(IsDefault(default_value)); + // Allocate empty. The contents are not relevant. + std::string* new_string = Arena::Create(arena); + tagged_ptr_.Set(new_string); + return new_string; + } +} + +template +std::string* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena, + const Lazy&... lazy_default) { + const std::string* const default_value = + sizeof...(Lazy) == 0 ? &GetEmptyStringAlreadyInited() : nullptr; + GOOGLE_DCHECK(IsDefault(default_value)); + std::string* new_string = + Arena::Create(arena, lazy_default.get()...); + tagged_ptr_.Set(new_string); + return new_string; +} + +std::string* ArenaStringPtr::Release(const std::string* default_value, + ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + return nullptr; + } else { + return ReleaseNonDefault(default_value, arena); + } +} + +std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value, + ::google::protobuf::Arena* arena) { + GOOGLE_DCHECK(!IsDefault(default_value)); + + if (!IsDonatedString()) { + std::string* released; + if (arena != nullptr) { + released = new std::string; + released->swap(*UnsafeMutablePointer()); + } else { + released = UnsafeMutablePointer(); + } + tagged_ptr_.Set(const_cast(default_value)); + return released; + } else /* IsDonatedString() */ { + GOOGLE_DCHECK(arena != nullptr); + std::string* released = new std::string(Get()); + tagged_ptr_.Set(const_cast(default_value)); + return released; + } +} + +void ArenaStringPtr::SetAllocated(const std::string* default_value, + std::string* value, ::google::protobuf::Arena* arena) { + // Release what we have first. + if (arena == nullptr && !IsDefault(default_value)) { + delete UnsafeMutablePointer(); + } + if (value == nullptr) { + tagged_ptr_.Set(const_cast(default_value)); + } else { +#ifdef NDEBUG + tagged_ptr_.Set(value); + if (arena != nullptr) { + arena->Own(value); + } +#else + // On debug builds, copy the string so the address differs. delete will + // fail if value was a stack-allocated temporary/etc., which would have + // failed when arena ran its cleanup list. + std::string* new_value = Arena::Create(arena, *value); + delete value; + tagged_ptr_.Set(new_value); +#endif + } +} + +void ArenaStringPtr::Destroy(const std::string* default_value, + ::google::protobuf::Arena* arena) { + if (arena == nullptr) { + GOOGLE_DCHECK(!IsDonatedString()); + if (!IsDefault(default_value)) { + delete UnsafeMutablePointer(); + } + } +} + +void ArenaStringPtr::Destroy(EmptyDefault, ::google::protobuf::Arena* arena) { + Destroy(&GetEmptyStringAlreadyInited(), arena); +} + +void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) { + Destroy(nullptr, arena); +} + +void ArenaStringPtr::ClearToEmpty() { + if (IsDefault(&GetEmptyStringAlreadyInited())) { + // Already set to default -- do nothing. + } else { + // Unconditionally mask away the tag. + // + // UpdateDonatedString uses assign when capacity is larger than the new + // value, which is trivially true in the donated string case. + // const_cast(PtrValue())->clear(); + tagged_ptr_.Get()->clear(); + } +} + +void ArenaStringPtr::ClearToDefault(const LazyString& default_value, + ::google::protobuf::Arena* arena) { + (void)arena; + if (IsDefault(nullptr)) { + // Already set to default -- do nothing. + } else if (!IsDonatedString()) { + UnsafeMutablePointer()->assign(default_value.get()); + } +} + + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index 122f391e513c..acd177f15c91 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -37,7 +37,6 @@ #include #include -#include #include #include @@ -48,358 +47,331 @@ #endif -// This is the implementation of arena string fields written for the open-source -// release. The ArenaStringPtr struct below is an internal implementation class -// and *should not be used* by user code. It is used to collect string -// operations together into one place and abstract away the underlying -// string-field pointer representation, so that (for example) an alternate -// implementation that knew more about ::std::string's internals could integrate -// more closely with the arena allocator. - namespace google { namespace protobuf { namespace internal { +// Lazy string instance to support string fields with non-empty default. +// These are initialized on the first call to .get(). +class PROTOBUF_EXPORT LazyString { + public: + // We explicitly make LazyString an aggregate so that MSVC can do constant + // initialization on it without marking it `constexpr`. + // We do not want to use `constexpr` because it makes it harder to have extern + // storage for it and causes library bloat. + struct InitValue { + const char* ptr; + size_t size; + }; + // We keep a union of the initialization value and the std::string to save on + // space. We don't need the string array after Init() is done. + union { + mutable InitValue init_value_; + alignas(std::string) mutable char string_buf_[sizeof(std::string)]; + }; + mutable std::atomic inited_; + + const std::string& get() const { + // This check generates less code than a call-once invocation. + auto* res = inited_.load(std::memory_order_acquire); + if (PROTOBUF_PREDICT_FALSE(res == nullptr)) return Init(); + return *res; + } + + private: + // Initialize the string in `string_buf_`, update `inited_` and return it. + // We return it here to avoid having to read it again in the inlined code. + const std::string& Init() const; +}; + template class TaggedPtr { public: - void Set(T* p) { ptr_ = reinterpret_cast(p); } - T* Get() const { return reinterpret_cast(ptr_); } + TaggedPtr() = default; + explicit constexpr TaggedPtr(const std::string* ptr) + : ptr_(const_cast(ptr)) {} + + void SetTagged(T* p) { + Set(p); + ptr_ = reinterpret_cast(as_int() | 1); + } + void Set(T* p) { ptr_ = p; } + T* Get() const { return reinterpret_cast(as_int() & -2); } + bool IsTagged() const { return as_int() & 1; } - bool IsNull() { return ptr_ == 0; } + // Returned value is only safe to dereference if IsTagged() == false. + // It is safe to compare. + T* UnsafeGet() const { return static_cast(ptr_); } + + bool IsNull() { return ptr_ == nullptr; } private: - uintptr_t ptr_; + uintptr_t as_int() const { return reinterpret_cast(ptr_); } + void* ptr_; }; -struct PROTOBUF_EXPORT ArenaStringPtr { - inline void Set(const ::std::string* default_value, - const ::std::string& value, Arena* arena) { - if (ptr_ == default_value) { - CreateInstance(arena, &value); - } else { - *ptr_ = value; - } - } +static_assert(std::is_trivial>::value, + "TaggedPtr must be trivial"); - inline void SetLite(const ::std::string* default_value, - const ::std::string& value, Arena* arena) { - Set(default_value, value, arena); - } +// This class encapsulates a pointer to a std::string with or without a donated +// buffer, tagged by bottom bit. It is a high-level wrapper that almost directly +// corresponds to the interface required by string fields in generated +// code. It replaces the old std::string* pointer in such cases. +// +// The object has different but similar code paths for when the default value is +// the empty string and when it is a non-empty string. +// The empty string is handled different throughout the library and there is a +// single global instance of it we can share. +// +// For fields with an empty string default value, there are three distinct +// states: +// +// - Pointer set to 'String' tag (LSB is 0), equal to +// &GetEmptyStringAlreadyInited(): field is set to its default value. Points +// to a true std::string*, but we do not own that std::string* (it's a +// globally shared instance). +// +// - Pointer set to 'String' tag (LSB is 0), but not equal to the global empty +// string: field points to a true std::string* instance that we own. This +// instance is either on the heap or on the arena (i.e. registered on +// free()/destructor-call list) as appropriate. +// +// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string +// instance with a buffer on the arena (arena != NULL, always, in this case). +// +// For fields with a non-empty string default value, there are three distinct +// states: +// +// - Pointer set to 'String' tag (LSB is 0), equal to `nullptr`: +// Field is in "default" mode and does not point to any actual instance. +// Methods that might need to create an instance of the object will pass a +// `const LazyString&` for it. +// +// - Pointer set to 'String' tag (LSB is 0), but not equal to `nullptr`: +// field points to a true std::string* instance that we own. This instance is +// either on the heap or on the arena (i.e. registered on +// free()/destructor-call list) as appropriate. +// +// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string +// instance with a buffer on the arena (arena != NULL, always, in this case). +// +// Generated code and reflection code both ensure that ptr_ is never null for +// fields with an empty default. +// Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and +// so the field is always manually initialized via method calls. +// +// Side-note: why pass information about the default on every API call? Because +// we don't want to hold it in a member variable, or else this would go into +// every proto message instance. This would be a huge waste of space, since the +// default instance pointer is typically a global (static class field). We want +// the generated code to be as efficient as possible, and if we take +// the default value information as a parameter that's in practice taken from a +// static class field, and compare ptr_ to the default value, we end up with a +// single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also +// requires the String tag to be 0 so we can avoid the mask before comparing.) +struct PROTOBUF_EXPORT ArenaStringPtr { + ArenaStringPtr() = default; + explicit constexpr ArenaStringPtr(const std::string* default_value) + : tagged_ptr_(default_value) {} + + // Some methods below are overloaded on a `default_value` and on tags. + // The tagged overloads help reduce code size in the callers in generated + // code, while the `default_value` overloads are useful from reflection. + // By-value empty struct arguments are elided in the ABI. + struct EmptyDefault {}; + struct NonEmptyDefault {}; + + void Set(const std::string* default_value, ConstStringParam value, + ::google::protobuf::Arena* arena); + void Set(const std::string* default_value, std::string&& value, + ::google::protobuf::Arena* arena); + void Set(EmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); + void Set(EmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); + void Set(NonEmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); + void Set(NonEmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); // Basic accessors. - inline const ::std::string& Get() const { return *ptr_; } - - inline ::std::string* Mutable(const ::std::string* default_value, - Arena* arena) { - if (ptr_ == default_value) { - CreateInstance(arena, default_value); - } - return ptr_; - } - - // Release returns a ::std::string* instance that is heap-allocated and is not - // Own()'d by any arena. If the field was not set, it returns NULL. The caller - // retains ownership. Clears this field back to NULL state. Used to implement - // release_() methods on generated classes. - inline ::std::string* Release(const ::std::string* default_value, - Arena* arena) { - if (ptr_ == default_value) { - return NULL; - } - return ReleaseNonDefault(default_value, arena); + const std::string& Get() const PROTOBUF_ALWAYS_INLINE { + // Unconditionally mask away the tag. + return *tagged_ptr_.Get(); } - - // Similar to Release, but ptr_ cannot be the default_value. - inline ::std::string* ReleaseNonDefault(const ::std::string* default_value, - Arena* arena) { - GOOGLE_DCHECK(!IsDefault(default_value)); - ::std::string* released = NULL; - if (arena != NULL) { - // ptr_ is owned by the arena. - released = new ::std::string; - released->swap(*ptr_); - } else { - released = ptr_; - } - ptr_ = const_cast< ::std::string*>(default_value); - return released; + const std::string* GetPointer() const PROTOBUF_ALWAYS_INLINE { + // Unconditionally mask away the tag. + return tagged_ptr_.Get(); } - // UnsafeArenaRelease returns a ::std::string*, but it may be arena-owned - // (i.e. have its destructor already registered) if arena != NULL. If the - // field was not set, this returns NULL. This method clears this field back to - // NULL state. Used to implement unsafe_arena_release_() methods on - // generated classes. - inline ::std::string* UnsafeArenaRelease(const ::std::string* default_value, - Arena* /* arena */) { - if (ptr_ == default_value) { - return NULL; - } - ::std::string* released = ptr_; - ptr_ = const_cast< ::std::string*>(default_value); - return released; - } - - // Takes a string that is heap-allocated, and takes ownership. The string's - // destructor is registered with the arena. Used to implement + // For fields with an empty default value. + std::string* Mutable(EmptyDefault, ::google::protobuf::Arena* arena); + // For fields with a non-empty default value. + std::string* Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena); + + // Release returns a std::string* instance that is heap-allocated and is not + // Own()'d by any arena. If the field is not set, this returns NULL. The + // caller retains ownership. Clears this field back to NULL state. Used to + // implement release_() methods on generated classes. + std::string* Release(const std::string* default_value, + ::google::protobuf::Arena* arena); + std::string* ReleaseNonDefault(const std::string* default_value, + ::google::protobuf::Arena* arena); + + // Takes a std::string that is heap-allocated, and takes ownership. The + // std::string's destructor is registered with the arena. Used to implement // set_allocated_ in generated classes. - inline void SetAllocated(const ::std::string* default_value, - ::std::string* value, Arena* arena) { - if (arena == NULL && ptr_ != default_value) { - Destroy(default_value, arena); - } - if (value != NULL) { - ptr_ = value; - if (arena != NULL) { - arena->Own(value); - } - } else { - ptr_ = const_cast< ::std::string*>(default_value); - } - } - - // Takes a string that has lifetime equal to the arena's lifetime. The arena - // must be non-null. It is safe only to pass this method a value returned by - // UnsafeArenaRelease() on another field of a message in the same arena. Used - // to implement unsafe_arena_set_allocated_ in generated classes. - inline void UnsafeArenaSetAllocated(const ::std::string* default_value, - ::std::string* value, - Arena* /* arena */) { - if (value != NULL) { - ptr_ = value; - } else { - ptr_ = const_cast< ::std::string*>(default_value); - } - } + void SetAllocated(const std::string* default_value, std::string* value, + ::google::protobuf::Arena* arena); // Swaps internal pointers. Arena-safety semantics: this is guarded by the // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is // 'unsafe' if called directly. - PROTOBUF_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { - std::swap(ptr_, other->ptr_); - } - PROTOBUF_ALWAYS_INLINE void Swap(ArenaStringPtr* other, - const ::std::string* default_value, - Arena* arena) { -#ifndef NDEBUG - // For debug builds, we swap the contents of the string, rather than the - // string instances themselves. This invalidates previously taken const - // references that are (per our documentation) invalidated by calling Swap() - // on the message. - // - // If both strings are the default_value, swapping is uninteresting. - // Otherwise, we use ArenaStringPtr::Mutable() to access the string, to - // ensure that we do not try to mutate default_value itself. - if (IsDefault(default_value) && other->IsDefault(default_value)) { - return; - } - - ::std::string* this_ptr = Mutable(default_value, arena); - ::std::string* other_ptr = other->Mutable(default_value, arena); - - this_ptr->swap(*other_ptr); -#else - std::swap(ptr_, other->ptr_); - (void)default_value; - (void)arena; -#endif - } + inline void Swap(ArenaStringPtr* other, const std::string* default_value, + Arena* arena) PROTOBUF_ALWAYS_INLINE; // Frees storage (if not on an arena). - inline void Destroy(const ::std::string* default_value, Arena* arena) { - if (arena == NULL && ptr_ != default_value) { - delete ptr_; - } - } + void Destroy(const std::string* default_value, ::google::protobuf::Arena* arena); + void Destroy(EmptyDefault, ::google::protobuf::Arena* arena); + void Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena); - // Clears content, but keeps allocated string if arena != NULL, to avoid the - // overhead of heap operations. After this returns, the content (as seen by - // the user) will always be the empty string. Assumes that |default_value| - // is an empty string. - inline void ClearToEmpty(const ::std::string* default_value, - Arena* /* arena */) { - if (ptr_ == default_value) { - // Already set to default (which is empty) -- do nothing. - } else { - ptr_->clear(); - } - } + // Clears content, but keeps allocated std::string, to avoid the overhead of + // heap operations. After this returns, the content (as seen by the user) will + // always be the empty std::string. Assumes that |default_value| is an empty + // std::string. + void ClearToEmpty(); - // Clears content, assuming that the current value is not the empty string - // default. - inline void ClearNonDefaultToEmpty() { ptr_->clear(); } - inline void ClearNonDefaultToEmptyNoArena() { ptr_->clear(); } - - // Clears content, but keeps allocated string if arena != NULL, to avoid the - // overhead of heap operations. After this returns, the content (as seen by - // the user) will always be equal to |default_value|. - inline void ClearToDefault(const ::std::string* default_value, - Arena* /* arena */) { - if (ptr_ == default_value) { - // Already set to default -- do nothing. - } else { - // Have another allocated string -- rather than throwing this away and - // resetting ptr_ to the canonical default string instance, we just reuse - // this instance. - *ptr_ = *default_value; - } - } + // Clears content, assuming that the current value is not the empty + // string default. + void ClearNonDefaultToEmpty(); - // Called from generated code / reflection runtime only. Resets value to point - // to a default string pointer, with the semantics that this ArenaStringPtr - // does not own the pointed-to memory. Disregards initial value of ptr_ (so - // this is the *ONLY* safe method to call after construction or when - // reinitializing after becoming the active field in a oneof union). - inline void UnsafeSetDefault(const ::std::string* default_value) { - // Casting away 'const' is safe here: accessors ensure that ptr_ is only - // returned as a const if it is equal to default_value. - ptr_ = const_cast< ::std::string*>(default_value); - } + // Clears content, but keeps allocated std::string if arena != NULL, to avoid + // the overhead of heap operations. After this returns, the content (as seen + // by the user) will always be equal to |default_value|. + void ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena); - // The 'NoArena' variants of methods below assume arena == NULL and are - // optimized to provide very little overhead relative to a raw string pointer - // (while still being in-memory compatible with other code that assumes - // ArenaStringPtr). Note the invariant that a class instance that has only - // ever been mutated by NoArena methods must *only* be in the String state - // (i.e., tag bits are not used), *NEVER* ArenaString. This allows all - // tagged-pointer manipulations to be avoided. - inline void SetNoArena(const ::std::string* default_value, - const ::std::string& value) { - if (ptr_ == default_value) { - CreateInstanceNoArena(&value); - } else { - *ptr_ = value; - } + // Called from generated code / reflection runtime only. Resets value to point + // to a default string pointer, with the semantics that this + // ArenaStringPtr does not own the pointed-to memory. Disregards initial value + // of ptr_ (so this is the *ONLY* safe method to call after construction or + // when reinitializing after becoming the active field in a oneof union). + inline void UnsafeSetDefault(const std::string* default_value); + + // Returns a mutable pointer, but doesn't initialize the string to the + // default value. + std::string* MutableNoArenaNoDefault(const std::string* default_value); + + // Get a mutable pointer with unspecified contents. + // Similar to `MutableNoArenaNoDefault`, but also handles the arena case. + // If the value was donated, the contents are discarded. + std::string* MutableNoCopy(const std::string* default_value, + ::google::protobuf::Arena* arena); + + // Destroy the string. Assumes `arena == nullptr`. + void DestroyNoArena(const std::string* default_value); + + // Internal setter used only at parse time to directly set a donated string + // value. + void UnsafeSetTaggedPointer(TaggedPtr value) { + tagged_ptr_ = value; } - - void SetNoArena(const ::std::string* default_value, ::std::string&& value) { - if (IsDefault(default_value)) { - ptr_ = new ::std::string(std::move(value)); - } else { - *ptr_ = std::move(value); - } + // Generated code only! An optimization, in certain cases the generated + // code is certain we can obtain a std::string with no default checks and + // tag tests. + std::string* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL; + + inline bool IsDefault(const std::string* default_value) const { + // Relies on the fact that kPtrTagString == 0, so if IsString(), ptr_ is the + // actual std::string pointer (and if !IsString(), ptr_ will never be equal + // to any aligned |default_value| pointer). The key is that we want to avoid + // masking in the fastpath const-pointer Get() case for non-arena code. + return tagged_ptr_.UnsafeGet() == default_value; } - void AssignWithDefault(const ::std::string* default_value, - ArenaStringPtr value); + private: + TaggedPtr tagged_ptr_; - inline const ::std::string& GetNoArena() const { return *ptr_; } + bool IsDonatedString() const { return false; } - inline ::std::string* MutableNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - CreateInstanceNoArena(default_value); - } - return ptr_; - } + // Slow paths. - inline ::std::string* ReleaseNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - return NULL; - } else { - return ReleaseNonDefaultNoArena(default_value); - } - } + // MutableSlow requires that !IsString() || IsDefault + // Variadic to support 0 args for EmptyDefault and 1 arg for LazyString. + template + std::string* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default); - inline ::std::string* ReleaseNonDefaultNoArena( - const ::std::string* default_value) { - GOOGLE_DCHECK(!IsDefault(default_value)); - ::std::string* released = ptr_; - ptr_ = const_cast< ::std::string*>(default_value); - return released; - } +}; - inline void SetAllocatedNoArena(const ::std::string* default_value, - ::std::string* value) { - if (ptr_ != default_value) { - delete ptr_; - } - if (value != NULL) { - ptr_ = value; - } else { - ptr_ = const_cast< ::std::string*>(default_value); - } - } +inline void ArenaStringPtr::UnsafeSetDefault(const std::string* value) { + tagged_ptr_.Set(const_cast(value)); +} - inline void DestroyNoArena(const ::std::string* default_value) { - if (ptr_ != default_value) { - delete ptr_; - } +inline void ArenaStringPtr::Swap(ArenaStringPtr* other, + const std::string* default_value, + Arena* arena) { +#ifndef NDEBUG + // For debug builds, we swap the contents of the string, rather than the + // std::string instances themselves. This invalidates previously taken const + // references that are (per our documentation) invalidated by calling Swap() + // on the message. + // + // If both strings are the default_value, swapping is uninteresting. + // Otherwise, we use ArenaStringPtr::Mutable() to access the std::string, to + // ensure that we do not try to mutate default_value itself. + if (IsDefault(default_value) && other->IsDefault(default_value)) { + return; } - inline void ClearToEmptyNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - // Nothing: already equal to default (which is the empty string). - } else { - ptr_->clear(); - } - } + if (default_value == nullptr) { + // If we have non-empty default, then `default_value` is null and we can't + // call Mutable the same way. Just do the regular swap. + std::swap(tagged_ptr_, other->tagged_ptr_); + } else { + std::string* this_ptr = Mutable(EmptyDefault{}, arena); + std::string* other_ptr = other->Mutable(EmptyDefault{}, arena); - inline void ClearToDefaultNoArena(const ::std::string* default_value) { - if (ptr_ == default_value) { - // Nothing: already set to default. - } else { - // Reuse existing allocated instance. - *ptr_ = *default_value; - } + this_ptr->swap(*other_ptr); } +#else + (void) default_value; + (void) arena; + std::swap(tagged_ptr_, other->tagged_ptr_); +#endif +} - // Internal accessor used only at parse time to provide direct access to the - // raw pointer from the shared parse routine (in the non-arenas case). The - // parse routine does the string allocation in order to save code size in the - // generated parsing code. - inline ::std::string** UnsafeRawStringPointer() { return &ptr_; } - - inline bool IsDefault(const ::std::string* default_value) const { - return ptr_ == default_value; - } +inline void ArenaStringPtr::ClearNonDefaultToEmpty() { + // Unconditionally mask away the tag. + tagged_ptr_.Get()->clear(); +} - // Internal accessors!!!! - void UnsafeSetTaggedPointer(TaggedPtr< ::std::string> value) { - ptr_ = value.Get(); +inline std::string* ArenaStringPtr::MutableNoArenaNoDefault( + const std::string* default_value) { + // VERY IMPORTANT for performance and code size: this will reduce to a member + // variable load, a pointer check (against |default_value|, in practice a + // static global) and a branch to the slowpath (which calls operator new and + // the ctor). DO NOT add any tagged-pointer operations here. + if (IsDefault(default_value)) { + std::string* new_string = new std::string(); + tagged_ptr_.Set(new_string); + return new_string; + } else { + return UnsafeMutablePointer(); } - // Generated code only! An optimization, in certain cases the generated - // code is certain we can obtain a string with no default checks and - // tag tests. - ::std::string* UnsafeMutablePointer() { return ptr_; } - - private: - ::std::string* ptr_; +} - PROTOBUF_NOINLINE - void CreateInstance(Arena* arena, const ::std::string* initial_value) { - GOOGLE_DCHECK(initial_value != NULL); - // uses "new ::std::string" when arena is nullptr - ptr_ = Arena::Create< ::std::string>(arena, *initial_value); +inline void ArenaStringPtr::DestroyNoArena(const std::string* default_value) { + if (!IsDefault(default_value)) { + delete UnsafeMutablePointer(); } - PROTOBUF_NOINLINE - void CreateInstanceNoArena(const ::std::string* initial_value) { - GOOGLE_DCHECK(initial_value != NULL); - ptr_ = new ::std::string(*initial_value); - } -}; - -} // namespace internal -} // namespace protobuf - -namespace protobuf { -namespace internal { +} -inline void ArenaStringPtr::AssignWithDefault( - const ::std::string* default_value, ArenaStringPtr value) { - const ::std::string* me = *UnsafeRawStringPointer(); - const ::std::string* other = *value.UnsafeRawStringPointer(); - // If the pointers are the same then do nothing. - if (me != other) { - SetNoArena(default_value, value.GetNoArena()); - } +inline std::string* ArenaStringPtr::UnsafeMutablePointer() { + GOOGLE_DCHECK(!tagged_ptr_.IsTagged()); + GOOGLE_DCHECK(tagged_ptr_.UnsafeGet() != nullptr); + return tagged_ptr_.UnsafeGet(); } + } // namespace internal } // namespace protobuf } // namespace google - #include #endif // GOOGLE_PROTOBUF_ARENASTRING_H__ diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc index c5da4476b4db..8d7b520ac031 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -28,8 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Based on mvels@'s frankenstring. - #include #include @@ -42,10 +40,14 @@ #include #include #include +#include #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -53,84 +55,123 @@ using internal::ArenaStringPtr; static std::string WrapString(const char* value) { return value; } +using EmptyDefault = ArenaStringPtr::EmptyDefault; + +const internal::LazyString nonempty_default{{{"default", 7}}, {nullptr}}; + // Test ArenaStringPtr with arena == NULL. TEST(ArenaStringPtrTest, ArenaStringPtrOnHeap) { ArenaStringPtr field; - std::string default_value = "default"; - field.UnsafeSetDefault(&default_value); - EXPECT_EQ(std::string("default"), field.Get()); - field.Set(&default_value, WrapString("Test short"), NULL); + const std::string* empty_default = &internal::GetEmptyString(); + field.UnsafeSetDefault(empty_default); + EXPECT_EQ(std::string(""), field.Get()); + field.Set(empty_default, WrapString("Test short"), NULL); EXPECT_EQ(std::string("Test short"), field.Get()); - field.Set(&default_value, WrapString("Test long long long long value"), NULL); + field.Set(empty_default, WrapString("Test long long long long value"), NULL); EXPECT_EQ(std::string("Test long long long long value"), field.Get()); - field.Set(&default_value, std::string(""), NULL); - field.Destroy(&default_value, NULL); + field.Set(empty_default, std::string(""), NULL); + field.Destroy(empty_default, NULL); ArenaStringPtr field2; - field2.UnsafeSetDefault(&default_value); - std::string* mut = field2.Mutable(&default_value, NULL); - EXPECT_EQ(mut, field2.Mutable(&default_value, NULL)); + field2.UnsafeSetDefault(empty_default); + std::string* mut = field2.Mutable(EmptyDefault{}, NULL); + EXPECT_EQ(mut, field2.Mutable(EmptyDefault{}, NULL)); EXPECT_EQ(mut, &field2.Get()); - EXPECT_NE(&default_value, mut); - EXPECT_EQ(std::string("default"), *mut); + EXPECT_NE(empty_default, mut); + EXPECT_EQ(std::string(""), *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ(std::string("Test long long long long value"), field2.Get()); - field2.Destroy(&default_value, NULL); + field2.Destroy(empty_default, NULL); + + ArenaStringPtr field3; + field3.UnsafeSetDefault(nullptr); + mut = field3.Mutable(nonempty_default, NULL); + EXPECT_EQ(mut, field3.Mutable(nonempty_default, NULL)); + EXPECT_EQ(mut, &field3.Get()); + EXPECT_NE(nullptr, mut); + EXPECT_EQ(std::string("default"), *mut); + *mut = "Test long long long long value"; // ensure string allocates storage + EXPECT_EQ(std::string("Test long long long long value"), field3.Get()); + field3.Destroy(nullptr, NULL); } TEST(ArenaStringPtrTest, ArenaStringPtrOnArena) { Arena arena; ArenaStringPtr field; - std::string default_value = "default"; - field.UnsafeSetDefault(&default_value); - EXPECT_EQ(std::string("default"), field.Get()); - field.Set(&default_value, WrapString("Test short"), &arena); + const std::string* empty_default = &internal::GetEmptyString(); + field.UnsafeSetDefault(empty_default); + EXPECT_EQ(std::string(""), field.Get()); + field.Set(empty_default, WrapString("Test short"), &arena); EXPECT_EQ(std::string("Test short"), field.Get()); - field.Set(&default_value, WrapString("Test long long long long value"), + field.Set(empty_default, WrapString("Test long long long long value"), &arena); EXPECT_EQ(std::string("Test long long long long value"), field.Get()); - field.Set(&default_value, std::string(""), &arena); - field.Destroy(&default_value, &arena); + field.Set(empty_default, std::string(""), &arena); + field.Destroy(empty_default, &arena); ArenaStringPtr field2; - field2.UnsafeSetDefault(&default_value); - std::string* mut = field2.Mutable(&default_value, &arena); - EXPECT_EQ(mut, field2.Mutable(&default_value, &arena)); + field2.UnsafeSetDefault(empty_default); + std::string* mut = field2.Mutable(EmptyDefault{}, &arena); + EXPECT_EQ(mut, field2.Mutable(EmptyDefault{}, &arena)); EXPECT_EQ(mut, &field2.Get()); - EXPECT_NE(&default_value, mut); - EXPECT_EQ(std::string("default"), *mut); + EXPECT_NE(empty_default, mut); + EXPECT_EQ(std::string(""), *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ(std::string("Test long long long long value"), field2.Get()); - field2.Destroy(&default_value, &arena); + field2.Destroy(empty_default, &arena); + + ArenaStringPtr field3; + field3.UnsafeSetDefault(nullptr); + mut = field3.Mutable(nonempty_default, &arena); + EXPECT_EQ(mut, field3.Mutable(nonempty_default, &arena)); + EXPECT_EQ(mut, &field3.Get()); + EXPECT_NE(nullptr, mut); + EXPECT_EQ(std::string("default"), *mut); + *mut = "Test long long long long value"; // ensure string allocates storage + EXPECT_EQ(std::string("Test long long long long value"), field3.Get()); + field3.Destroy(nullptr, &arena); } TEST(ArenaStringPtrTest, ArenaStringPtrOnArenaNoSSO) { Arena arena; ArenaStringPtr field; - std::string default_value = "default"; - field.UnsafeSetDefault(&default_value); - EXPECT_EQ(std::string("default"), field.Get()); + const std::string* empty_default = &internal::GetEmptyString(); + field.UnsafeSetDefault(empty_default); + EXPECT_EQ(std::string(""), field.Get()); // Avoid triggering the SSO optimization by setting the string to something // larger than the internal buffer. - field.Set(&default_value, WrapString("Test long long long long value"), + field.Set(empty_default, WrapString("Test long long long long value"), &arena); EXPECT_EQ(std::string("Test long long long long value"), field.Get()); - field.Set(&default_value, std::string(""), &arena); - field.Destroy(&default_value, &arena); + field.Set(empty_default, std::string(""), &arena); + field.Destroy(empty_default, &arena); ArenaStringPtr field2; - field2.UnsafeSetDefault(&default_value); - std::string* mut = field2.Mutable(&default_value, &arena); - EXPECT_EQ(mut, field2.Mutable(&default_value, &arena)); + field2.UnsafeSetDefault(empty_default); + std::string* mut = field2.Mutable(EmptyDefault{}, &arena); + EXPECT_EQ(mut, field2.Mutable(EmptyDefault{}, &arena)); EXPECT_EQ(mut, &field2.Get()); - EXPECT_NE(&default_value, mut); - EXPECT_EQ(std::string("default"), *mut); + EXPECT_NE(empty_default, mut); + EXPECT_EQ(std::string(""), *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ(std::string("Test long long long long value"), field2.Get()); - field2.Destroy(&default_value, &arena); + field2.Destroy(empty_default, &arena); + + ArenaStringPtr field3; + field3.UnsafeSetDefault(nullptr); + mut = field3.Mutable(nonempty_default, &arena); + EXPECT_EQ(mut, field3.Mutable(nonempty_default, &arena)); + EXPECT_EQ(mut, &field3.Get()); + EXPECT_NE(nullptr, mut); + EXPECT_EQ(std::string("default"), *mut); + *mut = "Test long long long long value"; // ensure string allocates storage + EXPECT_EQ(std::string("Test long long long long value"), field3.Get()); + field3.Destroy(nullptr, &arena); } } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc index 693300df08e9..4544f3e71057 100644 --- a/src/google/protobuf/compiler/code_generator.cc +++ b/src/google/protobuf/compiler/code_generator.cc @@ -85,6 +85,12 @@ io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert( return NULL; // make compiler happy } +io::ZeroCopyOutputStream* GeneratorContext::OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& /*info*/) { + return OpenForInsert(filename, insertion_point); +} + void GeneratorContext::ListParsedFiles( std::vector* output) { GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles"; @@ -117,6 +123,15 @@ void ParseGeneratorParameter( } } +// Strips ".proto" or ".protodevel" from the end of a filename. +std::string StripProto(const std::string& filename) { + if (HasSuffixString(filename, ".protodevel")) { + return StripSuffixString(filename, ".protodevel"); + } else { + return StripSuffixString(filename, ".proto"); + } +} + } // namespace compiler } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 528dc76428a2..c8d9e49b5aa5 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -52,6 +52,7 @@ namespace io { class ZeroCopyOutputStream; } class FileDescriptor; +class GeneratedCodeInfo; namespace compiler { class AccessInfoMap; @@ -102,6 +103,16 @@ class PROTOC_EXPORT CodeGenerator { GeneratorContext* generator_context, std::string* error) const; + // Sync with plugin.proto. + enum Feature { + FEATURE_PROTO3_OPTIONAL = 1, + }; + + // Implement this to indicate what features this code generator supports. + // This should be a bitwise OR of features from the Features enum in + // plugin.proto. + virtual uint64_t GetSupportedFeatures() const { return 0; } + // This is no longer used, but this class is part of the opensource protobuf // library, so it has to remain to keep vtables the same for the current // version of the library. When protobufs does a api breaking change, the @@ -146,6 +157,15 @@ class PROTOC_EXPORT GeneratorContext { virtual io::ZeroCopyOutputStream* OpenForInsert( const std::string& filename, const std::string& insertion_point); + // Similar to OpenForInsert, but if `info` is non-empty, will open (or create) + // filename.pb.meta and insert info at the appropriate place with the + // necessary shifts. The default implementation ignores `info`. + // + // WARNING: This feature will be REMOVED in the near future. + virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info); + // Returns a vector of FileDescriptors for all the files being compiled // in this run. Useful for languages, such as Go, that treat files // differently when compiled as a set rather than individually. @@ -173,6 +193,9 @@ typedef GeneratorContext OutputDirectory; PROTOC_EXPORT void ParseGeneratorParameter( const std::string&, std::vector >*); +// Strips ".proto" or ".protodevel" from the end of a filename. +PROTOC_EXPORT std::string StripProto(const std::string& filename); + } // namespace compiler } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index c5b20303bba9..242cb7de4396 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -58,8 +58,10 @@ #include -#ifdef __APPLE__ +#if defined(__APPLE__) #include +#elif defined(__FreeBSD__) +#include #endif #include @@ -202,6 +204,13 @@ bool GetProtocAbsolutePath(std::string* path) { realpath(dirtybuffer, buffer); len = strlen(buffer); } +#elif defined(__FreeBSD__) + char buffer[PATH_MAX]; + size_t len = PATH_MAX; + int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; + if (sysctl(mib, 4, &buffer, &len, NULL, 0) != 0) { + len = 0; + } #else char buffer[PATH_MAX]; int len = readlink("/proc/self/exe", buffer, PATH_MAX); @@ -386,6 +395,9 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename); io::ZeroCopyOutputStream* OpenForInsert(const std::string& filename, const std::string& insertion_point); + io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info); void ListParsedFiles(std::vector* output) { *output = parsed_files_; } @@ -393,7 +405,8 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { private: friend class MemoryOutputStream; - // map instead of unordered_map so that files are written in order (good when + // The files_ field maps from path keys to file content values. It's a map + // instead of an unordered_map so that files are written in order (good when // writing zips). std::map files_; const std::vector& parsed_files_; @@ -408,6 +421,10 @@ class CommandLineInterface::MemoryOutputStream MemoryOutputStream(GeneratorContextImpl* directory, const std::string& filename, const std::string& insertion_point); + MemoryOutputStream(GeneratorContextImpl* directory, + const std::string& filename, + const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info); virtual ~MemoryOutputStream(); // implements ZeroCopyOutputStream --------------------------------- @@ -418,12 +435,23 @@ class CommandLineInterface::MemoryOutputStream int64_t ByteCount() const override { return inner_->ByteCount(); } private: - // Checks to see if "filename_.meta" exists in directory_; if so, fixes the + // Checks to see if "filename_.pb.meta" exists in directory_; if so, fixes the // offsets in that GeneratedCodeInfo record to reflect bytes inserted in // filename_ at original offset insertion_offset with length insertion_length. - // We assume that insertions will not occur within any given annotated span - // of text. - void UpdateMetadata(size_t insertion_offset, size_t insertion_length); + // Also adds in the data from info_to_insert_ with updated offsets governed by + // insertion_offset and indent_length. We assume that insertions will not + // occur within any given annotated span of text. insertion_content must end + // with an endline. + void UpdateMetadata(const std::string& insertion_content, + size_t insertion_offset, size_t insertion_length, + size_t indent_length); + + // Inserts info_to_insert_ into target_info, assuming that the relevant + // insertion was made at insertion_offset in file_content with the given + // indent_length. insertion_content must end with an endline. + void InsertShiftedInfo(const std::string& insertion_content, + size_t insertion_offset, size_t indent_length, + google::protobuf::GeneratedCodeInfo& target_info); // Where to insert the string when it's done. GeneratorContextImpl* directory_; @@ -438,6 +466,9 @@ class CommandLineInterface::MemoryOutputStream // StringOutputStream writing to data_. std::unique_ptr inner_; + + // The GeneratedCodeInfo to insert at the insertion point. + google::protobuf::GeneratedCodeInfo info_to_insert_; }; // ------------------------------------------------------------------- @@ -594,6 +625,13 @@ CommandLineInterface::GeneratorContextImpl::OpenForInsert( return new MemoryOutputStream(this, filename, insertion_point); } +io::ZeroCopyOutputStream* +CommandLineInterface::GeneratorContextImpl::OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info) { + return new MemoryOutputStream(this, filename, insertion_point, info); +} + // ------------------------------------------------------------------- CommandLineInterface::MemoryOutputStream::MemoryOutputStream( @@ -612,40 +650,114 @@ CommandLineInterface::MemoryOutputStream::MemoryOutputStream( insertion_point_(insertion_point), inner_(new io::StringOutputStream(&data_)) {} +CommandLineInterface::MemoryOutputStream::MemoryOutputStream( + GeneratorContextImpl* directory, const std::string& filename, + const std::string& insertion_point, const google::protobuf::GeneratedCodeInfo& info) + : directory_(directory), + filename_(filename), + insertion_point_(insertion_point), + inner_(new io::StringOutputStream(&data_)), + info_to_insert_(info) {} + +void CommandLineInterface::MemoryOutputStream::InsertShiftedInfo( + const std::string& insertion_content, size_t insertion_offset, + size_t indent_length, google::protobuf::GeneratedCodeInfo& target_info) { + // Keep track of how much extra data was added for indents before the + // current annotation being inserted. `pos` and `source_annotation.begin()` + // are offsets in `insertion_content`. `insertion_offset` is updated so that + // it can be added to an annotation's `begin` field to reflect that + // annotation's updated location after `insertion_content` was inserted into + // the target file. + size_t pos = 0; + insertion_offset += indent_length; + for (const auto& source_annotation : info_to_insert_.annotation()) { + GeneratedCodeInfo::Annotation* annotation = target_info.add_annotation(); + int inner_indent = 0; + // insertion_content is guaranteed to end in an endline. This last endline + // has no effect on indentation. + for (; pos < source_annotation.end() && pos < insertion_content.size() - 1; + ++pos) { + if (insertion_content[pos] == '\n') { + if (pos >= source_annotation.begin()) { + // The beginning of the annotation is at insertion_offset, but the end + // can still move further in the target file. + inner_indent += indent_length; + } else { + insertion_offset += indent_length; + } + } + } + *annotation = source_annotation; + annotation->set_begin(annotation->begin() + insertion_offset); + insertion_offset += inner_indent; + annotation->set_end(annotation->end() + insertion_offset); + } +} + void CommandLineInterface::MemoryOutputStream::UpdateMetadata( - size_t insertion_offset, size_t insertion_length) { - auto it = directory_->files_.find(filename_ + ".meta"); - if (it == directory_->files_.end()) { + const std::string& insertion_content, size_t insertion_offset, + size_t insertion_length, size_t indent_length) { + auto it = directory_->files_.find(filename_ + ".pb.meta"); + if (it == directory_->files_.end() && info_to_insert_.annotation().empty()) { // No metadata was recorded for this file. return; } - std::string& encoded_data = it->second; GeneratedCodeInfo metadata; bool is_text_format = false; - if (!metadata.ParseFromString(encoded_data)) { - if (!TextFormat::ParseFromString(encoded_data, &metadata)) { - // The metadata is invalid. - std::cerr << filename_ - << ".meta: Could not parse metadata as wire or text format." - << std::endl; - return; - } - // Generators that use the public plugin interface emit text-format - // metadata (because in the public plugin protocol, file content must be - // UTF8-encoded strings). - is_text_format = true; - } - for (int i = 0; i < metadata.annotation_size(); ++i) { - GeneratedCodeInfo::Annotation* annotation = metadata.mutable_annotation(i); - if (annotation->begin() >= insertion_offset) { - annotation->set_begin(annotation->begin() + insertion_length); - annotation->set_end(annotation->end() + insertion_length); + std::string* encoded_data = nullptr; + if (it != directory_->files_.end()) { + encoded_data = &it->second; + // Try to decode a GeneratedCodeInfo proto from the .pb.meta file. It may be + // in wire or text format. Keep the same format when the data is written out + // later. + if (!metadata.ParseFromString(*encoded_data)) { + if (!TextFormat::ParseFromString(*encoded_data, &metadata)) { + // The metadata is invalid. + std::cerr + << filename_ + << ".pb.meta: Could not parse metadata as wire or text format." + << std::endl; + return; + } + // Generators that use the public plugin interface emit text-format + // metadata (because in the public plugin protocol, file content must be + // UTF8-encoded strings). + is_text_format = true; } + } else { + // Create a new file to store the new metadata in info_to_insert_. + encoded_data = + &directory_->files_.insert({filename_ + ".pb.meta", ""}).first->second; + } + GeneratedCodeInfo new_metadata; + bool crossed_offset = false; + size_t to_add = 0; + for (const auto& source_annotation : metadata.annotation()) { + // The first time an annotation at or after the insertion point is found, + // insert the new metadata from info_to_insert_. Shift all annotations + // after the new metadata by the length of the text that was inserted + // (including any additional indent length). + if (source_annotation.begin() >= insertion_offset && !crossed_offset) { + crossed_offset = true; + InsertShiftedInfo(insertion_content, insertion_offset, indent_length, + new_metadata); + to_add += insertion_length; + } + GeneratedCodeInfo::Annotation* annotation = new_metadata.add_annotation(); + *annotation = source_annotation; + annotation->set_begin(annotation->begin() + to_add); + annotation->set_end(annotation->end() + to_add); + } + // If there were never any annotations at or after the insertion point, + // make sure to still insert the new metadata from info_to_insert_. + if (!crossed_offset) { + InsertShiftedInfo(insertion_content, insertion_offset, indent_length, + new_metadata); } if (is_text_format) { - TextFormat::PrintToString(metadata, &encoded_data); + TextFormat::PrintToString(new_metadata, encoded_data); } else { - metadata.SerializeToString(&encoded_data); + new_metadata.SerializeToString(encoded_data); } } @@ -728,7 +840,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { if (indent_.empty()) { // No indent. This makes things easier. target->insert(pos, data_); - UpdateMetadata(pos, data_.size()); + UpdateMetadata(data_, pos, data_.size(), 0); } else { // Calculate how much space we need. int indent_size = 0; @@ -738,7 +850,6 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { // Make a hole for it. target->insert(pos, data_.size() + indent_size, '\0'); - UpdateMetadata(pos, data_.size() + indent_size); // Now copy in the data. std::string::size_type data_pos = 0; @@ -757,6 +868,7 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() { target_ptr += line_length; data_pos += line_length; } + UpdateMetadata(data_, pos, data_.size() + indent_size, indent_.size()); GOOGLE_CHECK_EQ(target_ptr, ::google::protobuf::string_as_array(target) + pos + data_.size() + indent_size); @@ -773,16 +885,9 @@ const char* const CommandLineInterface::kPathSeparator = ":"; #endif CommandLineInterface::CommandLineInterface() - : mode_(MODE_COMPILE), - print_mode_(PRINT_NONE), - error_format_(ERROR_FORMAT_GCC), - direct_dependencies_explicitly_set_(false), - direct_dependencies_violation_msg_( - kDefaultDirectDependenciesViolationMsg), - imports_in_descriptor_set_(false), - source_info_in_descriptor_set_(false), - disallow_services_(false) { -} + : direct_dependencies_violation_msg_( + kDefaultDirectDependenciesViolationMsg) {} + CommandLineInterface::~CommandLineInterface() {} void CommandLineInterface::RegisterGenerator(const std::string& flag_name, @@ -811,6 +916,39 @@ void CommandLineInterface::AllowPlugins(const std::string& exe_name_prefix) { plugin_prefix_ = exe_name_prefix; } +namespace { + +bool ContainsProto3Optional(const Descriptor* desc) { + for (int i = 0; i < desc->field_count(); i++) { + if (desc->field(i)->has_optional_keyword()) { + return true; + } + } + for (int i = 0; i < desc->nested_type_count(); i++) { + if (ContainsProto3Optional(desc->nested_type(i))) { + return true; + } + } + return false; +} + +bool ContainsProto3Optional(const FileDescriptor* file) { + if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) { + for (int i = 0; i < file->message_type_count(); i++) { + if (ContainsProto3Optional(file->message_type(i))) { + return true; + } + } + } + return false; +} + +} // namespace + +namespace { +std::unique_ptr +PopulateSingleSimpleDescriptorDatabase(const std::string& descriptor_set_name); +} int CommandLineInterface::Run(int argc, const char* const argv[]) { Clear(); @@ -827,16 +965,38 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { std::unique_ptr disk_source_tree; std::unique_ptr error_collector; std::unique_ptr descriptor_pool; - std::unique_ptr descriptor_set_in_database; + + // The SimpleDescriptorDatabases here are the constituents of the + // MergedDescriptorDatabase descriptor_set_in_database, so this vector is for + // managing their lifetimes. Its scope should match descriptor_set_in_database + std::vector> + databases_per_descriptor_set; + std::unique_ptr descriptor_set_in_database; + std::unique_ptr source_tree_database; // Any --descriptor_set_in FileDescriptorSet objects will be used as a // fallback to input_files on command line, so create that db first. if (!descriptor_set_in_names_.empty()) { - descriptor_set_in_database.reset(new SimpleDescriptorDatabase()); - if (!PopulateSimpleDescriptorDatabase(descriptor_set_in_database.get())) { - return 1; + for (const std::string& name : descriptor_set_in_names_) { + std::unique_ptr database_for_descriptor_set = + PopulateSingleSimpleDescriptorDatabase(name); + if (!database_for_descriptor_set) { + return EXIT_FAILURE; + } + databases_per_descriptor_set.push_back( + std::move(database_for_descriptor_set)); + } + + std::vector raw_databases_per_descriptor_set; + raw_databases_per_descriptor_set.reserve( + databases_per_descriptor_set.size()); + for (const std::unique_ptr& db : + databases_per_descriptor_set) { + raw_databases_per_descriptor_set.push_back(db.get()); } + descriptor_set_in_database.reset( + new MergedDescriptorDatabase(raw_databases_per_descriptor_set)); } if (proto_path_.empty()) { @@ -876,6 +1036,16 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { } + for (auto fd : parsed_files) { + if (!AllowProto3Optional(*fd) && ContainsProto3Optional(fd)) { + std::cerr << fd->name() + << ": This file contains proto3 optional fields, but " + "--experimental_allow_proto3_optional was not set." + << std::endl; + return 1; + } + } + // We construct a separate GeneratorContext for each output location. Note // that two code generators may output to the same location, in which case // they should share a single GeneratorContext so that OpenForInsert() works. @@ -886,7 +1056,8 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { for (int i = 0; i < output_directives_.size(); i++) { std::string output_location = output_directives_[i].output_location; if (!HasSuffixString(output_location, ".zip") && - !HasSuffixString(output_location, ".jar")) { + !HasSuffixString(output_location, ".jar") && + !HasSuffixString(output_location, ".srcjar")) { AddTrailingSlash(&output_location); } @@ -999,48 +1170,70 @@ bool CommandLineInterface::InitializeDiskSourceTree( return true; } -bool CommandLineInterface::PopulateSimpleDescriptorDatabase( - SimpleDescriptorDatabase* database) { - for (int i = 0; i < descriptor_set_in_names_.size(); i++) { - int fd; - do { - fd = open(descriptor_set_in_names_[i].c_str(), O_RDONLY | O_BINARY); - } while (fd < 0 && errno == EINTR); - if (fd < 0) { - std::cerr << descriptor_set_in_names_[i] << ": " << strerror(ENOENT) - << std::endl; - return false; - } +namespace { +std::unique_ptr +PopulateSingleSimpleDescriptorDatabase(const std::string& descriptor_set_name) { + int fd; + do { + fd = open(descriptor_set_name.c_str(), O_RDONLY | O_BINARY); + } while (fd < 0 && errno == EINTR); + if (fd < 0) { + std::cerr << descriptor_set_name << ": " << strerror(ENOENT) << std::endl; + return nullptr; + } - FileDescriptorSet file_descriptor_set; - bool parsed = file_descriptor_set.ParseFromFileDescriptor(fd); - if (close(fd) != 0) { - std::cerr << descriptor_set_in_names_[i] << ": close: " << strerror(errno) - << std::endl; - return false; - } + FileDescriptorSet file_descriptor_set; + bool parsed = file_descriptor_set.ParseFromFileDescriptor(fd); + if (close(fd) != 0) { + std::cerr << descriptor_set_name << ": close: " << strerror(errno) + << std::endl; + return nullptr; + } - if (!parsed) { - std::cerr << descriptor_set_in_names_[i] << ": Unable to parse." - << std::endl; - return false; - } + if (!parsed) { + std::cerr << descriptor_set_name << ": Unable to parse." << std::endl; + return nullptr; + } - for (int j = 0; j < file_descriptor_set.file_size(); j++) { - FileDescriptorProto previously_added_file_descriptor_proto; - if (database->FindFileByName(file_descriptor_set.file(j).name(), - &previously_added_file_descriptor_proto)) { - // already present - skip - continue; - } - if (!database->Add(file_descriptor_set.file(j))) { - return false; - } + std::unique_ptr database{ + new SimpleDescriptorDatabase()}; + + for (int j = 0; j < file_descriptor_set.file_size(); j++) { + FileDescriptorProto previously_added_file_descriptor_proto; + if (database->FindFileByName(file_descriptor_set.file(j).name(), + &previously_added_file_descriptor_proto)) { + // already present - skip + continue; + } + if (!database->Add(file_descriptor_set.file(j))) { + return nullptr; } } - return true; + return database; } +} // namespace + +bool CommandLineInterface::AllowProto3Optional( + const FileDescriptor& file) const { + // If the --experimental_allow_proto3_optional flag was set, we allow. + if (allow_proto3_optional_) return true; + + // Whitelist all ads protos. Ads is an early adopter of this feature. + if (file.name().find("google/ads/googleads") != std::string::npos) { + return true; + } + + // Whitelist all protos testing proto3 optional. + if (file.name().find("test_proto3_optional") != std::string::npos) { + return true; + } + + + return false; +} + + bool CommandLineInterface::VerifyInputFilesInDescriptors( DescriptorDatabase* database) { for (const auto& input_file : input_files_) { @@ -1059,6 +1252,7 @@ bool CommandLineInterface::VerifyInputFilesInDescriptors( << std::endl; return false; } + } return true; } @@ -1067,10 +1261,26 @@ bool CommandLineInterface::ParseInputFiles( DescriptorPool* descriptor_pool, DiskSourceTree* source_tree, std::vector* parsed_files) { - // Track unused imports in all source files - for (const auto& input_file : input_files_) { - descriptor_pool->AddUnusedImportTrackFile(input_file); + if (!proto_path_.empty()) { + // Track unused imports in all source files that were loaded from the + // filesystem. We do not track unused imports for files loaded from + // descriptor sets as they may be programmatically generated in which case + // exerting this level of rigor is less desirable. We're also making the + // assumption that the initial parse of the proto from the filesystem + // was rigorous in checking unused imports and that the descriptor set + // being parsed was produced then and that it was subsequent mutations + // of that descriptor set that left unused imports. + // + // Note that relying on proto_path exclusively is limited in that we may + // be loading descriptors from both the filesystem and descriptor sets + // depending on the invocation. At least for invocations that are + // exclusively reading from descriptor sets, we can eliminate this failure + // condition. + for (const auto& input_file : input_files_) { + descriptor_pool->AddUnusedImportTrackFile(input_file); + } } + bool result = true; // Parse each file. for (const auto& input_file : input_files_) { @@ -1093,6 +1303,7 @@ bool CommandLineInterface::ParseInputFiles( break; } + // Enforce --direct_dependencies if (direct_dependencies_explicitly_set_) { bool indirect_imports = false; @@ -1138,6 +1349,8 @@ void CommandLineInterface::Clear() { source_info_in_descriptor_set_ = false; disallow_services_ = false; direct_dependencies_explicitly_set_ = false; + allow_proto3_optional_ = false; + deterministic_output_ = false; } bool CommandLineInterface::MakeProtoProtoPathRelative( @@ -1177,13 +1390,17 @@ bool CommandLineInterface::MakeProtoProtoPathRelative( "comes first." << std::endl; return false; - case DiskSourceTree::CANNOT_OPEN: + case DiskSourceTree::CANNOT_OPEN: { if (in_fallback_database) { return true; } + std::string error_str = source_tree->GetLastErrorMessage().empty() + ? strerror(errno) + : source_tree->GetLastErrorMessage(); std::cerr << "Could not map to virtual file: " << *proto << ": " - << strerror(errno) << std::endl; + << error_str << std::endl; return false; + } case DiskSourceTree::NO_MAPPING: { // Try to interpret the path as a virtual path. std::string disk_file; @@ -1326,13 +1543,36 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( proto_path_.push_back(std::pair("", ".")); } - // Check some error cases. - bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty(); - if (decoding_raw && !input_files_.empty()) { - std::cerr << "When using --decode_raw, no input files should be given." + // Check error cases that span multiple flag values. + bool missing_proto_definitions = false; + switch (mode_) { + case MODE_COMPILE: + missing_proto_definitions = input_files_.empty(); + break; + case MODE_DECODE: + // Handle --decode_raw separately, since it requires that no proto + // definitions are specified. + if (codec_type_.empty()) { + if (!input_files_.empty() || !descriptor_set_in_names_.empty()) { + std::cerr + << "When using --decode_raw, no input files should be given." << std::endl; - return PARSE_ARGUMENT_FAIL; - } else if (!decoding_raw && input_files_.empty()) { + return PARSE_ARGUMENT_FAIL; + } + missing_proto_definitions = false; + break; // only for --decode_raw + } + // --decode (not raw) is handled the same way as the rest of the modes. + PROTOBUF_FALLTHROUGH_INTENDED; + case MODE_ENCODE: + case MODE_PRINT: + missing_proto_definitions = + input_files_.empty() && descriptor_set_in_names_.empty(); + break; + default: + GOOGLE_LOG(FATAL) << "Unexpected mode: " << mode_; + } + if (missing_proto_definitions) { std::cerr << "Missing input file." << std::endl; return PARSE_ARGUMENT_FAIL; } @@ -1346,6 +1586,11 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( << std::endl; return PARSE_ARGUMENT_FAIL; } + if (mode_ != MODE_ENCODE && deterministic_output_) { + std::cerr << "Can only use --deterministic_output with --encode." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } if (!dependency_out_name_.empty() && input_files_.size() > 1) { std::cerr << "Can only process one input file when using --dependency_out=FILE." @@ -1413,7 +1658,9 @@ bool CommandLineInterface::ParseArgument(const char* arg, std::string* name, if (*name == "-h" || *name == "--help" || *name == "--disallow_services" || *name == "--include_imports" || *name == "--include_source_info" || *name == "--version" || *name == "--decode_raw" || - *name == "--print_free_field_numbers") { + *name == "--print_free_field_numbers" || + *name == "--experimental_allow_proto3_optional" || + *name == "--deterministic_output") { // HACK: These are the only flags that don't take a value. // They probably should not be hard-coded like this but for now it's // not worth doing better. @@ -1614,12 +1861,16 @@ CommandLineInterface::InterpretArgument(const std::string& name, std::cout << version_info_ << std::endl; } std::cout << "libprotoc " << internal::VersionString(PROTOBUF_VERSION) - << std::endl; + << PROTOBUF_VERSION_SUFFIX << std::endl; return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler. } else if (name == "--disallow_services") { disallow_services_ = true; + + } else if (name == "--experimental_allow_proto3_optional") { + allow_proto3_optional_ = true; + } else if (name == "--encode" || name == "--decode" || name == "--decode_raw") { if (mode_ != MODE_COMPILE) { @@ -1650,6 +1901,9 @@ CommandLineInterface::InterpretArgument(const std::string& name, codec_type_ = value; + } else if (name == "--deterministic_output") { + deterministic_output_ = true; + } else if (name == "--error_format") { if (value == "gcc") { error_format_ = ERROR_FORMAT_GCC; @@ -1764,124 +2018,76 @@ CommandLineInterface::InterpretArgument(const std::string& name, void CommandLineInterface::PrintHelpText() { // Sorry for indentation here; line wrapping would be uglier. - std::cout - << - "Usage: " << executable_name_ - << " [OPTION] PROTO_FILES\n" - "Parse PROTO_FILES and generate output based on the options given:\n" - " -IPATH, --proto_path=PATH Specify the directory in which to " - "search for\n" - " imports. May be specified multiple " - "times;\n" - " directories will be searched in order. " - " If not\n" - " given, the current working directory " - "is used.\n" - " If not found in any of the these " - "directories,\n" - " the --descriptor_set_in descriptors " - "will be\n" - " checked for required proto file.\n" - " --version Show version info and exit.\n" - " -h, --help Show this text and exit.\n" - " --encode=MESSAGE_TYPE Read a text-format message of the " - "given type\n" - " from standard input and write it in " - "binary\n" - " to standard output. The message type " - "must\n" - " be defined in PROTO_FILES or their " - "imports.\n" - " --decode=MESSAGE_TYPE Read a binary message of the given " - "type from\n" - " standard input and write it in text " - "format\n" - " to standard output. The message type " - "must\n" - " be defined in PROTO_FILES or their " - "imports.\n" - " --decode_raw Read an arbitrary protocol message " - "from\n" - " standard input and write the raw " - "tag/value\n" - " pairs in text format to standard " - "output. No\n" - " PROTO_FILES should be given when using " - "this\n" - " flag.\n" - " --descriptor_set_in=FILES Specifies a delimited list of FILES\n" - " each containing a FileDescriptorSet " - "(a\n" - " protocol buffer defined in " - "descriptor.proto).\n" - " The FileDescriptor for each of the " - "PROTO_FILES\n" - " provided will be loaded from these\n" - " FileDescriptorSets. If a " - "FileDescriptor\n" - " appears multiple times, the first " - "occurrence\n" - " will be used.\n" - " -oFILE, Writes a FileDescriptorSet (a protocol " - "buffer,\n" - " --descriptor_set_out=FILE defined in descriptor.proto) " - "containing all of\n" - " the input files to FILE.\n" - " --include_imports When using --descriptor_set_out, also " - "include\n" - " all dependencies of the input files in " - "the\n" - " set, so that the set is " - "self-contained.\n" - " --include_source_info When using --descriptor_set_out, do " - "not strip\n" - " SourceCodeInfo from the " - "FileDescriptorProto.\n" - " This results in vastly larger " - "descriptors that\n" - " include information about the " - "original\n" - " location of each decl in the source " - "file as\n" - " well as surrounding comments.\n" - " --dependency_out=FILE Write a dependency output file in the " - "format\n" - " expected by make. This writes the " - "transitive\n" - " set of input file paths to FILE\n" - " --error_format=FORMAT Set the format in which to print " - "errors.\n" - " FORMAT may be 'gcc' (the default) or " - "'msvs'\n" - " (Microsoft Visual Studio format).\n" - " --print_free_field_numbers Print the free field numbers of the " - "messages\n" - " defined in the given proto files. " - "Groups share\n" - " the same field number space with the " - "parent \n" - " message. Extension ranges are counted " - "as \n" - " occupied fields numbers.\n" - << std::endl; + std::cout << "Usage: " << executable_name_ << " [OPTION] PROTO_FILES"; + std::cout << R"( +Parse PROTO_FILES and generate output based on the options given: + -IPATH, --proto_path=PATH Specify the directory in which to search for + imports. May be specified multiple times; + directories will be searched in order. If not + given, the current working directory is used. + If not found in any of the these directories, + the --descriptor_set_in descriptors will be + checked for required proto file. + --version Show version info and exit. + -h, --help Show this text and exit. + --encode=MESSAGE_TYPE Read a text-format message of the given type + from standard input and write it in binary + to standard output. The message type must + be defined in PROTO_FILES or their imports. + --deterministic_output When using --encode, ensure map fields are + deterministically ordered. Note that this order + is not canonical, and changes across builds or + releases of protoc. + --decode=MESSAGE_TYPE Read a binary message of the given type from + standard input and write it in text format + to standard output. The message type must + be defined in PROTO_FILES or their imports. + --decode_raw Read an arbitrary protocol message from + standard input and write the raw tag/value + pairs in text format to standard output. No + PROTO_FILES should be given when using this + flag. + --descriptor_set_in=FILES Specifies a delimited list of FILES + each containing a FileDescriptorSet (a + protocol buffer defined in descriptor.proto). + The FileDescriptor for each of the PROTO_FILES + provided will be loaded from these + FileDescriptorSets. If a FileDescriptor + appears multiple times, the first occurrence + will be used. + -oFILE, Writes a FileDescriptorSet (a protocol buffer, + --descriptor_set_out=FILE defined in descriptor.proto) containing all of + the input files to FILE. + --include_imports When using --descriptor_set_out, also include + all dependencies of the input files in the + set, so that the set is self-contained. + --include_source_info When using --descriptor_set_out, do not strip + SourceCodeInfo from the FileDescriptorProto. + This results in vastly larger descriptors that + include information about the original + location of each decl in the source file as + well as surrounding comments. + --dependency_out=FILE Write a dependency output file in the format + expected by make. This writes the transitive + set of input file paths to FILE + --error_format=FORMAT Set the format in which to print errors. + FORMAT may be 'gcc' (the default) or 'msvs' + (Microsoft Visual Studio format). + --print_free_field_numbers Print the free field numbers of the messages + defined in the given proto files. Groups share + the same field number space with the parent + message. Extension ranges are counted as + occupied fields numbers.)"; if (!plugin_prefix_.empty()) { - std::cout - << " --plugin=EXECUTABLE Specifies a plugin executable to " - "use.\n" - " Normally, protoc searches the PATH " - "for\n" - " plugins, but you may specify " - "additional\n" - " executables not in the path using " - "this flag.\n" - " Additionally, EXECUTABLE may be of " - "the form\n" - " NAME=PATH, in which case the given " - "plugin name\n" - " is mapped to the given executable " - "even if\n" - " the executable's own name differs." - << std::endl; + std::cout << R"( + --plugin=EXECUTABLE Specifies a plugin executable to use. + Normally, protoc searches the PATH for + plugins, but you may specify additional + executables not in the path using this flag. + Additionally, EXECUTABLE may be of the form + NAME=PATH, in which case the given plugin name + is mapped to the given executable even if + the executable's own name differs.)"; } for (GeneratorMap::iterator iter = generators_by_flag_name_.begin(); @@ -1889,35 +2095,48 @@ void CommandLineInterface::PrintHelpText() { // FIXME(kenton): If the text is long enough it will wrap, which is ugly, // but fixing this nicely (e.g. splitting on spaces) is probably more // trouble than it's worth. - std::cout << " " << iter->first << "=OUT_DIR " + std::cout << std::endl + << " " << iter->first << "=OUT_DIR " << std::string(19 - iter->first.size(), ' ') // Spaces for alignment. - << iter->second.help_text << std::endl; - } - std::cout << " @ Read options and filenames from " - "file. If a\n" - " relative file path is specified, " - "the file\n" - " will be searched in the working " - "directory.\n" - " The --proto_path option will not " - "affect how\n" - " this argument file is searched. " - "Content of\n" - " the file will be expanded in the " - "position of\n" - " @ as in the argument " - "list. Note\n" - " that shell expansion is not " - "applied to the\n" - " content of the file (i.e., you " - "cannot use\n" - " quotes, wildcards, escapes, " - "commands, etc.).\n" - " Each line corresponds to a " - "single argument,\n" - " even if it contains spaces." - << std::endl; + << iter->second.help_text; + } + std::cout << R"( + @ Read options and filenames from file. If a + relative file path is specified, the file + will be searched in the working directory. + The --proto_path option will not affect how + this argument file is searched. Content of + the file will be expanded in the position of + @ as in the argument list. Note + that shell expansion is not applied to the + content of the file (i.e., you cannot use + quotes, wildcards, escapes, commands, etc.). + Each line corresponds to a single argument, + even if it contains spaces.)"; + std::cout << std::endl; +} + +bool CommandLineInterface::EnforceProto3OptionalSupport( + const std::string& codegen_name, uint64 supported_features, + const std::vector& parsed_files) const { + bool supports_proto3_optional = + supported_features & CodeGenerator::FEATURE_PROTO3_OPTIONAL; + if (!supports_proto3_optional) { + for (const auto fd : parsed_files) { + if (ContainsProto3Optional(fd)) { + std::cerr << fd->name() + << ": is a proto3 file that contains optional fields, but " + "code generator " + << codegen_name + << " hasn't been updated to support optional fields in " + "proto3. Please ask the owner of this code generator to " + "support proto3 optional."; + return false; + } + } + } + return true; } bool CommandLineInterface::GenerateOutput( @@ -1954,6 +2173,12 @@ bool CommandLineInterface::GenerateOutput( } parameters.append(generator_parameters_[output_directive.name]); } + if (!EnforceProto3OptionalSupport( + output_directive.name, + output_directive.generator->GetSupportedFeatures(), parsed_files)) { + return false; + } + if (!output_directive.generator->GenerateAll(parsed_files, parameters, generator_context, &error)) { // Generator returned an error. @@ -2091,8 +2316,10 @@ bool CommandLineInterface::GeneratePluginOutput( // We reset current_output to NULL first so that the old file is closed // before the new one is opened. current_output.reset(); - current_output.reset(generator_context->OpenForInsert( - filename, output_file.insertion_point())); + current_output.reset( + generator_context->OpenForInsertWithGeneratedCodeInfo( + filename, output_file.insertion_point(), + output_file.generated_code_info())); } else if (!output_file.name().empty()) { // Starting a new file. Open it. // We reset current_output to NULL first so that the old file is closed @@ -2118,6 +2345,9 @@ bool CommandLineInterface::GeneratePluginOutput( // Generator returned an error. *error = response.error(); return false; + } else if (!EnforceProto3OptionalSupport( + plugin_name, response.supported_features(), parsed_files)) { + return false; } return true; @@ -2171,7 +2401,9 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { if (mode_ == MODE_ENCODE) { // Output is binary. - if (!message->SerializePartialToZeroCopyStream(&out)) { + io::CodedOutputStream coded_out(&out); + coded_out.SetSerializationDeterministic(deterministic_output_); + if (!message->SerializePartialToCodedStream(&coded_out)) { std::cerr << "output: I/O error." << std::endl; return false; } @@ -2228,12 +2460,20 @@ bool CommandLineInterface::WriteDescriptorSet( } io::FileOutputStream out(fd); - if (!file_set.SerializeToZeroCopyStream(&out)) { - std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno()) - << std::endl; - out.Close(); - return false; + + { + io::CodedOutputStream coded_out(&out); + // Determinism is useful here because build outputs are sometimes checked + // into version control. + coded_out.SetSerializationDeterministic(true); + if (!file_set.SerializeToCodedStream(&coded_out)) { + std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno()) + << std::endl; + out.Close(); + return false; + } } + if (!out.Close()) { std::cerr << descriptor_set_out_name_ << ": " << strerror(out.GetErrno()) << std::endl; diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index a05c32ec9016..12ba653758d3 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -104,7 +104,7 @@ class DiskSourceTree; // importer.h // 2. protoc --proto_path=src foo.proto (virtual path relative to src) // // If a file path can be interpreted both as a physical file path and as a -// relative virtual path, the physical file path takes precendence. +// relative virtual path, the physical file path takes precedence. // // For a full description of the command-line syntax, invoke it with --help. class PROTOC_EXPORT CommandLineInterface { @@ -226,6 +226,17 @@ class PROTOC_EXPORT CommandLineInterface { bool MakeInputsBeProtoPathRelative(DiskSourceTree* source_tree, DescriptorDatabase* fallback_database); + // Is this .proto file whitelisted, or do we have a command-line flag allowing + // us to use proto3 optional? This is a temporary control to avoid people from + // using proto3 optional until code generators have implemented it. + bool AllowProto3Optional(const FileDescriptor& file) const; + + // Fails if these files use proto3 optional and the code generator doesn't + // support it. This is a permanent check. + bool EnforceProto3OptionalSupport( + const std::string& codegen_name, uint64 supported_features, + const std::vector& parsed_files) const; + // Return status for ParseArguments() and InterpretArgument(). enum ParseArgumentStatus { @@ -269,9 +280,6 @@ class PROTOC_EXPORT CommandLineInterface { // Verify that all the input files exist in the given database. bool VerifyInputFilesInDescriptors(DescriptorDatabase* fallback_database); - // Loads descriptor_set_in into the provided database - bool PopulateSimpleDescriptorDatabase(SimpleDescriptorDatabase* database); - // Parses input_files_ into parsed_files bool ParseInputFiles(DescriptorPool* descriptor_pool, DiskSourceTree* source_tree, @@ -373,21 +381,21 @@ class PROTOC_EXPORT CommandLineInterface { MODE_PRINT, // Print mode: print info of the given .proto files and exit. }; - Mode mode_; + Mode mode_ = MODE_COMPILE; enum PrintMode { PRINT_NONE, // Not in MODE_PRINT PRINT_FREE_FIELDS, // --print_free_fields }; - PrintMode print_mode_; + PrintMode print_mode_ = PRINT_NONE; enum ErrorFormat { ERROR_FORMAT_GCC, // GCC error output format (default). ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs). }; - ErrorFormat error_format_; + ErrorFormat error_format_ = ERROR_FORMAT_GCC; std::vector > proto_path_; // Search path for proto files. @@ -396,7 +404,7 @@ class PROTOC_EXPORT CommandLineInterface { // Names of proto files which are allowed to be imported. Used by build // systems to enforce depend-on-what-you-import. std::set direct_dependencies_; - bool direct_dependencies_explicitly_set_; + bool direct_dependencies_explicitly_set_ = false; // If there's a violation of depend-on-what-you-import, this string will be // presented to the user. "%s" will be replaced with the violating import. @@ -435,10 +443,16 @@ class PROTOC_EXPORT CommandLineInterface { // True if --include_source_info was given, meaning that we should not strip // SourceCodeInfo from the DescriptorSet. - bool source_info_in_descriptor_set_; + bool source_info_in_descriptor_set_ = false; // Was the --disallow_services flag used? - bool disallow_services_; + bool disallow_services_ = false; + + // Was the --experimental_allow_proto3_optional flag used? + bool allow_proto3_optional_ = false; + + // When using --encode, this will be passed to SetSerializationDeterministic. + bool deterministic_output_ = false; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); }; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index a934d7a606b3..1987e0826884 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -40,12 +40,14 @@ #include #endif #include +#include #include #include #include #include #include +#include #include #include #include @@ -59,10 +61,10 @@ #include #include #include +#include #include #include -#include namespace google { namespace protobuf { @@ -122,7 +124,7 @@ class CommandLineInterfaceTest : public testing::Test { void SwitchToTempDirectory() { File::ChangeWorkingDirectory(temp_directory_); } -#else // !PROTOBUF_OPENSOURCE +#else // !PROTOBUF_OPENSOURCE // TODO(teboring): Figure out how to change and get working directory in // google3. #endif // !PROTOBUF_OPENSOURCE @@ -205,6 +207,17 @@ class CommandLineInterfaceTest : public testing::Test { void ExpectFileContent(const std::string& filename, const std::string& content); + // The default code generators support all features. Use this to create a + // code generator that omits the given feature(s). + void CreateGeneratorWithMissingFeatures(const std::string& name, + const std::string& description, + uint64 features) { + MockCodeGenerator* generator = new MockCodeGenerator(name); + generator->SuppressFeatures(features); + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator(name, generator, description); + } + private: // The object we are testing. CommandLineInterface cli_; @@ -669,6 +682,9 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs_UnusedImport_DescriptorSetIn) { FileDescriptorProto::descriptor()->file(); descriptor_file->CopyTo(file_descriptor_set.add_file()); + FileDescriptorProto& any_proto = *file_descriptor_set.add_file(); + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + const FileDescriptor* custom_file = protobuf_unittest::AggregateMessage::descriptor()->file(); FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); @@ -913,6 +929,58 @@ TEST_F(CommandLineInterfaceTest, ExpectErrorSubstring("bar.proto: \"Baz\" is not defined."); } +TEST_F(CommandLineInterfaceTest, + InputsOnlyFromDescriptorSetIn_UnusedImportIsNotReported) { + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("unused.proto"); + file_descriptor_proto->add_message_type()->set_name("Unused"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("unused.proto"); + file_descriptor_proto->add_message_type()->set_name("Bar"); + + WriteDescriptorSet("unused_and_bar.bin", &file_descriptor_set); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/unused_and_bar.bin unused.proto bar.proto"); + ExpectNoErrors(); +} + +TEST_F(CommandLineInterfaceTest, + InputsFromDescriptorSetInAndFileSystem_UnusedImportIsReported) { + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto* file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("unused.proto"); + file_descriptor_proto->add_message_type()->set_name("Unused"); + + file_descriptor_proto = file_descriptor_set.add_file(); + file_descriptor_proto->set_name("bar.proto"); + file_descriptor_proto->add_dependency("unused.proto"); + file_descriptor_proto->add_message_type()->set_name("Bar"); + + WriteDescriptorSet("unused_and_bar.bin", &file_descriptor_set); + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "import \"bar.proto\";\n" + "message Foo {\n" + " optional Bar bar = 1;\n" + "}\n"); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--descriptor_set_in=$tmpdir/unused_and_bar.bin " + "--proto_path=$tmpdir unused.proto bar.proto foo.proto"); + // Reporting unused imports here is unfair, since it's unactionable. Notice + // the lack of a line number. + // TODO(b/144853061): If the file with unused import is from the descriptor + // set and not from the file system, suppress the warning. + ExpectWarningSubstring("bar.proto: warning: Import unused.proto is unused."); +} + TEST_F(CommandLineInterfaceTest, OnlyReportsUnusedImportsForFilesBeingGenerated) { CreateTempFile("unused.proto", @@ -975,7 +1043,6 @@ TEST_F(CommandLineInterfaceTest, ReportsTransitiveMisingImports_LeafLast) { ExpectWarningSubstring( "bar.proto:2:1: warning: Import unused.proto is unused."); } - TEST_F(CommandLineInterfaceTest, CreateDirectory) { // Test that when we output to a sub-directory, it is created. @@ -1130,8 +1197,8 @@ TEST_F(CommandLineInterfaceTest, InsertWithAnnotationFixup) { Run("protocol_compiler " "--test_out=TestParameter:$tmpdir " "--plug_out=TestPluginParameter:$tmpdir " - "--test_out=insert=test_generator,test_plugin:$tmpdir " - "--plug_out=insert=test_generator,test_plugin:$tmpdir " + "--test_out=insert_endlines=test_generator,test_plugin:$tmpdir " + "--plug_out=insert_endlines=test_generator,test_plugin:$tmpdir " "--proto_path=$tmpdir foo.proto"); ExpectNoErrors(); @@ -1325,6 +1392,7 @@ TEST_F(CommandLineInterfaceTest, AllowServicesHasService) { ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } + TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing_EmptyList) { CreateTempFile("foo.proto", "syntax = \"proto2\";\n" @@ -2310,6 +2378,80 @@ TEST_F(CommandLineInterfaceTest, MissingValueAtEndError) { ExpectErrorText("Missing value for flag: --test_out\n"); } +TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowed) { + CreateTempFile("google/foo.proto", + "syntax = \"proto3\";\n" + "message Foo {\n" + " optional int32 i = 1;\n" + "}\n"); + + Run("protocol_compiler --proto_path=$tmpdir google/foo.proto " + "-odescriptor.pb"); + + ExpectErrorSubstring("--experimental_allow_proto3_optional was not set"); +} + +TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowedDescriptor) { + CreateTempFile("google/foo.proto", + "syntax = \"proto3\";\n" + "message Foo {\n" + " optional int32 i = 1;\n" + "}\n"); + + Run("protocol_compiler --experimental_allow_proto3_optional " + "--proto_path=$tmpdir google/foo.proto " + " -o$tmpdir/descriptor.pb"); + ExpectNoErrors(); + + Run("protocol_compiler --descriptor_set_in=$tmpdir/descriptor.pb" + " google/foo.proto --test_out=$tmpdir"); + ExpectErrorSubstring("--experimental_allow_proto3_optional was not set"); +} + +TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowedGenCode) { + CreateTempFile("google/foo.proto", + "syntax = \"proto3\";\n" + "message Foo {\n" + " optional int32 i = 1;\n" + "}\n"); + + Run("protocol_compiler --proto_path=$tmpdir google/foo.proto " + "--test_out=$tmpdir"); + + ExpectErrorSubstring("--experimental_allow_proto3_optional was not set"); +} + +TEST_F(CommandLineInterfaceTest, Proto3OptionalDisallowedNoCodegenSupport) { + CreateTempFile("google/foo.proto", + "syntax = \"proto3\";\n" + "message Foo {\n" + " optional int32 i = 1;\n" + "}\n"); + + CreateGeneratorWithMissingFeatures("--no_proto3_optional_out", + "Doesn't support proto3 optional", + CodeGenerator::FEATURE_PROTO3_OPTIONAL); + + Run("protocol_compiler --experimental_allow_proto3_optional " + "--proto_path=$tmpdir google/foo.proto --no_proto3_optional_out=$tmpdir"); + + ExpectErrorSubstring( + "code generator --no_proto3_optional_out hasn't been updated to support " + "optional fields in proto3"); +} + +TEST_F(CommandLineInterfaceTest, Proto3OptionalAllowWithFlag) { + CreateTempFile("google/foo.proto", + "syntax = \"proto3\";\n" + "message Foo {\n" + " optional int32 i = 1;\n" + "}\n"); + + Run("protocol_compiler --experimental_allow_proto3_optional " + "--proto_path=$tmpdir google/foo.proto --test_out=$tmpdir"); + ExpectNoErrors(); +} + TEST_F(CommandLineInterfaceTest, PrintFreeFieldNumbers) { CreateTempFile("foo.proto", "syntax = \"proto2\";\n" @@ -2428,20 +2570,25 @@ class EncodeDecodeTest : public testing::TestWithParam { enum Type { TEXT, BINARY }; enum ReturnCode { SUCCESS, ERROR }; - bool Run(const std::string& command) { + bool Run(const std::string& command, bool specify_proto_files = true) { std::vector args; args.push_back("protoc"); - SplitStringUsing(command, " ", &args); - switch (GetParam()) { - case PROTO_PATH: - args.push_back("--proto_path=" + TestUtil::TestSourceDir()); - break; - case DESCRIPTOR_SET_IN: - args.push_back(StrCat("--descriptor_set_in=", - unittest_proto_descriptor_set_filename_)); - break; - default: - ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam(); + for (StringPiece split_piece : + Split(command, " ", true)) { + args.push_back(std::string(split_piece)); + } + if (specify_proto_files) { + switch (GetParam()) { + case PROTO_PATH: + args.push_back("--proto_path=" + TestUtil::TestSourceDir()); + break; + case DESCRIPTOR_SET_IN: + args.push_back(StrCat("--descriptor_set_in=", + unittest_proto_descriptor_set_filename_)); + break; + default: + ADD_FAILURE() << "unexpected EncodeDecodeTestMode: " << GetParam(); + } } std::unique_ptr argv(new const char*[args.size()]); @@ -2523,9 +2670,12 @@ TEST_P(EncodeDecodeTest, Encode) { RedirectStdinFromFile(TestUtil::GetTestDataPath( "net/proto2/internal/" "testdata/text_format_unittest_data_oneof_implemented.txt")); - EXPECT_TRUE( - Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") + - " --encode=protobuf_unittest.TestAllTypes")); + std::string args; + if (GetParam() != DESCRIPTOR_SET_IN) { + args.append( + TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto")); + } + EXPECT_TRUE(Run(args + " --encode=protobuf_unittest.TestAllTypes")); ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath( "net/proto2/internal/testdata/golden_message_oneof_implemented")); ExpectStderrMatchesText(""); @@ -2561,7 +2711,7 @@ TEST_P(EncodeDecodeTest, DecodeRaw) { message.SerializeToString(&data); RedirectStdinFromText(data); - EXPECT_TRUE(Run("--decode_raw")); + EXPECT_TRUE(Run("--decode_raw", /*specify_proto_files=*/false)); ExpectStdoutMatchesText( "1: 123\n" "14: \"foo\"\n"); @@ -2585,6 +2735,32 @@ TEST_P(EncodeDecodeTest, ProtoParseError) { "net/proto2/internal/no_such_file.proto: No such file or directory\n"); } +TEST_P(EncodeDecodeTest, EncodeDeterministicOutput) { + RedirectStdinFromFile(TestUtil::GetTestDataPath( + "net/proto2/internal/" + "testdata/text_format_unittest_data_oneof_implemented.txt")); + std::string args; + if (GetParam() != DESCRIPTOR_SET_IN) { + args.append( + TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto")); + } + EXPECT_TRUE(Run( + args + " --encode=protobuf_unittest.TestAllTypes --deterministic_output")); + ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath( + "net/proto2/internal/testdata/golden_message_oneof_implemented")); + ExpectStderrMatchesText(""); +} + +TEST_P(EncodeDecodeTest, DecodeDeterministicOutput) { + RedirectStdinFromFile(TestUtil::GetTestDataPath( + "net/proto2/internal/testdata/golden_message_oneof_implemented")); + EXPECT_FALSE( + Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") + + " --decode=protobuf_unittest.TestAllTypes --deterministic_output")); + ExpectStderrMatchesText( + "Can only use --deterministic_output with --encode.\n"); +} + INSTANTIATE_TEST_SUITE_P(FileDescriptorSetSource, EncodeDecodeTest, testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN)); } // anonymous namespace diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc old mode 100755 new mode 100644 index dbef8559278e..31fe5a684128 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -76,8 +76,8 @@ class MockErrorCollector : public MultiFileErrorCollector { // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, int line, int column, const std::string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, - column, message); + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, + message); } }; diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index c0a03ad40f6a..7f9754f67f4b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -180,14 +180,17 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { if (HasDescriptorMethods(descriptor_->file(), options_)) { format( "inline bool $classname$_Parse(\n" - " const std::string& name, $classname$* value) {\n" + " ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* " + "value) " + "{\n" " return ::$proto_ns$::internal::ParseNamedEnum<$classname$>(\n" " $classname$_descriptor(), name, value);\n" "}\n"); } else { format( "bool $classname$_Parse(\n" - " const std::string& name, $classname$* value);\n"); + " ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* " + "value);\n"); } } @@ -253,7 +256,8 @@ void EnumGenerator::GenerateSymbolImports(io::Printer* printer) const { " return $classname$_Name(enum_t_value);\n" "}\n"); format( - "static inline bool $nested_name$_Parse(const std::string& name,\n" + "static inline bool " + "$nested_name$_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,\n" " $resolved_name$* value) {\n" " return $classname$_Parse(name, value);\n" "}\n"); @@ -383,7 +387,9 @@ void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) { CountUniqueValues(descriptor_)); format( "bool $classname$_Parse(\n" - " const std::string& name, $classname$* value) {\n" + " ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* " + "value) " + "{\n" " int int_value;\n" " bool success = ::$proto_ns$::internal::LookUpEnumValue(\n" " $classname$_entries, $1$, name, &int_value);\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index 8a661ea7c954..3792db81a80e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -94,13 +94,12 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, variables_["constant_name"] = FieldConstantName(descriptor_); variables_["field_type"] = StrCat(static_cast(descriptor_->type())); - variables_["packed"] = descriptor_->options().packed() ? "true" : "false"; + variables_["packed"] = descriptor_->is_packed() ? "true" : "false"; std::string scope = IsScoped() ? ClassName(descriptor_->extension_scope(), false) + "::" : ""; variables_["scope"] = scope; - std::string scoped_name = scope + ResolveKeyword(name); - variables_["scoped_name"] = scoped_name; + variables_["scoped_name"] = ExtensionName(descriptor_); variables_["number"] = StrCat(descriptor_->number()); } @@ -157,6 +156,11 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { StringReplace(variables_["scoped_name"], "::", "_", true) + "_default"; format("const std::string $1$($2$);\n", default_str, DefaultValue(options_, descriptor_)); + } else if (descriptor_->message_type()) { + // We have to initialize the default instance for extensions at registration + // time. + default_str = + FieldMessageTypeName(descriptor_, options_) + "::default_instance()"; } else { default_str = DefaultValue(options_, descriptor_); } @@ -170,6 +174,7 @@ void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { } format( + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n" " $scoped_name$($constant_name$, $1$);\n", diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 5b2ca151dcaf..f95e14e58bdb 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -73,7 +73,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["set_hasbit"] = ""; (*variables)["clear_hasbit"] = ""; - if (HasFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { (*variables)["set_hasbit_io"] = "_Internal::set_has_" + FieldName(descriptor) + "(&_has_bits_);"; } else { @@ -90,7 +90,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } void FieldGenerator::SetHasBitIndex(int32 has_bit_index) { - if (!HasFieldPresence(descriptor_->file()) || has_bit_index == -1) { + if (!HasHasbit(descriptor_)) { + GOOGLE_CHECK_EQ(has_bit_index, -1); return; } variables_["set_hasbit"] = StrCat( @@ -155,7 +156,7 @@ FieldGenerator* FieldGeneratorMap::MakeGenerator( default: return new RepeatedPrimitiveFieldGenerator(field, options); } - } else if (field->containing_oneof()) { + } else if (field->real_containing_oneof()) { switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_MESSAGE: return new MessageOneofFieldGenerator(field, options, scc_analyzer); diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index aef9aaf304c9..2d11f907bce0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -164,10 +164,6 @@ class FieldGenerator { return false; } - // Generate code that allocates the fields's default instance. - virtual void GenerateDefaultInstanceAllocator( - io::Printer* /*printer*/) const {} - // Generate lines to serialize this field directly to the array "target", // which are placed within the message's SerializeWithCachedSizesToArray() // method. This must also advance "target" past the written bytes. @@ -178,11 +174,6 @@ class FieldGenerator { // are placed in the message's ByteSize() method. virtual void GenerateByteSize(io::Printer* printer) const = 0; - // Any tags about field layout decisions (such as inlining) to embed in the - // offset. - virtual uint32 CalculateFieldTag() const { return 0; } - virtual bool IsInlined() const { return false; } - void SetHasBitIndex(int32 has_bit_index); protected: diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 7b08cdd7af0e..8ca7ba2f57e1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -34,6 +34,7 @@ #include +#include #include #include #include @@ -411,11 +412,6 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { IncludeFile("net/proto2/public/reflection_ops.h", printer); IncludeFile("net/proto2/public/wire_format.h", printer); } - if (IsProto2MessageSetFile(file_, options_)) { - format( - // Implementation of proto1 MessageSet API methods. - "#include \"net/proto2/internal/message_set_util.h\"\n"); - } if (options_.proto_h) { // Use the smaller .proto.h files. @@ -433,6 +429,12 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* printer) { format("// @@protoc_insertion_point(includes)\n"); IncludeFile("net/proto2/public/port_def.inc", printer); + + // For MSVC builds, we use #pragma init_seg to move the initialization of our + // libraries to happen before the user code. + // This worksaround the fact that MSVC does not do constant initializers when + // required by the standard. + format("\nPROTOBUF_PRAGMA_INIT_SEG\n"); } void FileGenerator::GenerateSourceDefaultInstance(int idx, @@ -445,12 +447,11 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, " ::$proto_ns$::internal::ExplicitlyConstructed<$2$> _instance;\n", DefaultInstanceType(generator->descriptor_, options_), generator->classname_); - format.Indent(); - generator->GenerateExtraDefaultFields(printer); - format.Outdent(); format("} $1$;\n", DefaultInstanceName(generator->descriptor_, options_)); + if (options_.lite_implicit_weak_fields) { - format("$1$DefaultTypeInternal* $2$ = &$3$;\n", generator->classname_, + format("$1$* $2$ = &$3$;\n", + DefaultInstanceType(generator->descriptor_, options_), DefaultInstancePtr(generator->descriptor_, options_), DefaultInstanceName(generator->descriptor_, options_)); } @@ -898,18 +899,21 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { format("};\n"); // The DescriptorTable itself. + // Should be "bool eager = NeedsEagerDescriptorAssignment(file_, options_);" + // however this might cause a tsan failure in superroot b/148382879, + // so disable for now. + bool eager = false; format( "static ::$proto_ns$::internal::once_flag $desc_table$_once;\n" - "static bool $desc_table$_initialized = false;\n" "const ::$proto_ns$::internal::DescriptorTable $desc_table$ = {\n" - " &$desc_table$_initialized, $1$, \"$filename$\", $2$,\n" - " &$desc_table$_once, $desc_table$_sccs, $desc_table$_deps, $3$, $4$,\n" + " false, $1$, $2$, \"$filename$\", $3$,\n" + " &$desc_table$_once, $desc_table$_sccs, $desc_table$_deps, $4$, $5$,\n" " schemas, file_default_instances, $tablename$::offsets,\n" - " $file_level_metadata$, $5$, $file_level_enum_descriptors$, " + " $file_level_metadata$, $6$, $file_level_enum_descriptors$, " "$file_level_service_descriptors$,\n" "};\n\n", - protodef_name, file_data.size(), sccs_.size(), num_deps, - message_generators_.size()); + eager ? "true" : "false", protodef_name, file_data.size(), sccs_.size(), + num_deps, message_generators_.size()); // For descriptor.proto we want to avoid doing any dynamic initialization, // because in some situations that would otherwise pull in a lot of @@ -918,8 +922,9 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) { if (file_->name() != "net/proto2/proto/descriptor.proto") { format( "// Force running AddDescriptors() at dynamic initialization time.\n" - "static bool $1$ = (static_cast(" - "::$proto_ns$::internal::AddDescriptors(&$desc_table$)), true);\n", + "PROTOBUF_ATTRIBUTE_INIT_PRIORITY " + "static ::$proto_ns$::internal::AddDescriptorsRunner " + "$1$(&$desc_table$);\n", UniqueName("dynamic_init_dummy", file_, options_)); } } @@ -943,9 +948,6 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { continue; } - // TODO(gerbens) This requires this function to be friend. Remove - // the need for this. - message_generators_[i]->GenerateFieldDefaultInstances(printer); format( "{\n" " void* ptr = &$1$;\n" @@ -962,17 +964,6 @@ void FileGenerator::GenerateInitForSCC(const SCC* scc, } format("}\n"); } - - // TODO(gerbens) make default instances be the same as normal instances. - // Default instances differ from normal instances because they have cross - // linked message fields. - for (int i = 0; i < message_generators_.size(); i++) { - if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) { - continue; - } - format("$1$::InitAsDefaultInstance();\n", - QualifiedClassName(message_generators_[i]->descriptor_, options_)); - } format.Outdent(); format("}\n\n"); @@ -1047,7 +1038,7 @@ void FileGenerator::GenerateTables(io::Printer* printer) { "};\n" "\n" "PROTOBUF_CONSTEXPR_VAR " - "::$proto_ns$::internal::AuxillaryParseTableField\n" + "::$proto_ns$::internal::AuxiliaryParseTableField\n" " const $tablename$::aux[] " "PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {\n"); format.Indent(); @@ -1061,7 +1052,7 @@ void FileGenerator::GenerateTables(io::Printer* printer) { } if (count == 0) { - format("::$proto_ns$::internal::AuxillaryParseTableField(),\n"); + format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n"); } format.Outdent(); @@ -1213,7 +1204,6 @@ void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) { decls[Namespace(d, options_)].AddEnum(d); } - { NamespaceOpener ns(format); for (const auto& pair : decls) { @@ -1296,13 +1286,10 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { IncludeFile("net/proto2/public/arenastring.h", printer); IncludeFile("net/proto2/public/generated_message_table_driven.h", printer); IncludeFile("net/proto2/public/generated_message_util.h", printer); - IncludeFile("net/proto2/public/inlined_string_field.h", printer); + IncludeFile("net/proto2/public/metadata_lite.h", printer); if (HasDescriptorMethods(file_, options_)) { - IncludeFile("net/proto2/public/metadata.h", printer); IncludeFile("net/proto2/public/generated_message_reflection.h", printer); - } else { - IncludeFile("net/proto2/public/metadata_lite.h", printer); } if (!message_generators_.empty()) { @@ -1409,7 +1396,7 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations( // for table driven code. " static const ::$proto_ns$::internal::ParseTableField entries[]\n" " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n" - " static const ::$proto_ns$::internal::AuxillaryParseTableField aux[]\n" + " static const ::$proto_ns$::internal::AuxiliaryParseTableField aux[]\n" " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n" " static const ::$proto_ns$::internal::ParseTable schema[$1$]\n" " PROTOBUF_SECTION_VARIABLE(protodesc_cold);\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index 0d80ea2799bd..2c45ca8fa289 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -93,6 +93,8 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_options.annotation_guard_name = options[i].second; } else if (options[i].first == "speed") { file_options.enforce_mode = EnforceOptimizeMode::kSpeed; + } else if (options[i].first == "code_size") { + file_options.enforce_mode = EnforceOptimizeMode::kCodeSize; } else if (options[i].first == "lite") { file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime; } else if (options[i].first == "lite_implicit_weak_fields") { diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.h b/src/google/protobuf/compiler/cpp/cpp_generator.h index c5ff28a70ed4..97e848dc4f50 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.h +++ b/src/google/protobuf/compiler/cpp/cpp_generator.h @@ -81,7 +81,14 @@ class PROTOC_EXPORT CppGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* generator_context, std::string* error) const; + GeneratorContext* generator_context, + std::string* error) const override; + + uint64_t GetSupportedFeatures() const override { + // We don't fully support this yet, but this is needed to unblock the tests, + // and we will have full support before the experimental flag is removed. + return FEATURE_PROTO3_OPTIONAL; + } private: bool opensource_runtime_ = true; diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index e15cd3a0c343..46fe55c41dc3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -43,10 +43,13 @@ #include #include +#include +#include #include #include #include #include +#include #include #include #include @@ -244,6 +247,31 @@ void SetCommonVars(const Options& options, (*variables)["string"] = "std::string"; } +void SetUnknkownFieldsVariable(const Descriptor* descriptor, + const Options& options, + std::map* variables) { + std::string proto_ns = ProtobufNamespace(options); + std::string unknown_fields_type; + if (UseUnknownFieldSet(descriptor->file(), options)) { + unknown_fields_type = "::" + proto_ns + "::UnknownFieldSet"; + (*variables)["unknown_fields"] = + "_internal_metadata_.unknown_fields<" + unknown_fields_type + ">(" + + unknown_fields_type + "::default_instance)"; + } else { + unknown_fields_type = + PrimitiveTypeName(options, FieldDescriptor::CPPTYPE_STRING); + (*variables)["unknown_fields"] = "_internal_metadata_.unknown_fields<" + + unknown_fields_type + ">(::" + proto_ns + + "::internal::GetEmptyString)"; + } + (*variables)["unknown_fields_type"] = unknown_fields_type; + (*variables)["have_unknown_fields"] = + "_internal_metadata_.have_unknown_fields()"; + (*variables)["mutable_unknown_fields"] = + "_internal_metadata_.mutable_unknown_fields<" + unknown_fields_type + + ">()"; +} + std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) { std::string result; @@ -334,6 +362,22 @@ std::string QualifiedClassName(const EnumDescriptor* d) { return QualifiedClassName(d, Options()); } +std::string ExtensionName(const FieldDescriptor* d) { + if (const Descriptor* scope = d->extension_scope()) + return StrCat(ClassName(scope), "::", ResolveKeyword(d->name())); + return ResolveKeyword(d->name()); +} + +std::string QualifiedExtensionName(const FieldDescriptor* d, + const Options& options) { + GOOGLE_DCHECK(d->is_extension()); + return QualifiedFileLevelSymbol(d->file(), ExtensionName(d), options); +} + +std::string QualifiedExtensionName(const FieldDescriptor* d) { + return QualifiedExtensionName(d, Options()); +} + std::string Namespace(const std::string& package) { if (package.empty()) return ""; return "::" + DotsToColons(package); @@ -477,14 +521,6 @@ std::string FieldMessageTypeName(const FieldDescriptor* field, return QualifiedClassName(field->message_type(), options); } -std::string StripProto(const std::string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - const char* PrimitiveTypeName(FieldDescriptor::CppType type) { switch (type) { case FieldDescriptor::CPPTYPE_INT32: @@ -749,25 +785,6 @@ std::string SafeFunctionName(const Descriptor* descriptor, return function_name; } -bool IsStringInlined(const FieldDescriptor* descriptor, - const Options& options) { - if (options.opensource_runtime) return false; - - // TODO(ckennelly): Handle inlining for any.proto. - if (IsAnyMessage(descriptor->containing_type(), options)) return false; - if (descriptor->containing_type()->options().map_entry()) return false; - - // Limit to proto2, as we rely on has bits to distinguish field presence for - // release_$name$. On proto3, we cannot use the address of the string - // instance when the field has been inlined. - if (!HasFieldPresence(descriptor->file())) return false; - - if (options.access_info_map) { - if (descriptor->is_required()) return true; - } - return false; -} - static bool HasLazyFields(const Descriptor* descriptor, const Options& options) { for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) { @@ -1113,7 +1130,7 @@ bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options, return UsingImplicitWeakFields(field->file(), options) && field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_required() && !field->is_map() && !field->is_extension() && - field->containing_oneof() == nullptr && + !field->real_containing_oneof() && !IsWellKnownMessage(field->message_type()->file()) && field->message_type()->file()->name() != "net/proto2/proto/descriptor.proto" && @@ -1345,11 +1362,14 @@ class ParseLoopGenerator { format_.Set("GOOGLE_PROTOBUF", MacroPrefix(options_)); std::map vars; SetCommonVars(options_, &vars); + SetUnknkownFieldsVariable(descriptor, options_, &vars); format_.AddMap(vars); std::vector ordered_fields; for (auto field : FieldRange(descriptor)) { - ordered_fields.push_back(field); + if (!IsFieldStripped(field, options_)) { + ordered_fields.push_back(field); + } } std::sort(ordered_fields.begin(), ordered_fields.end(), [](const FieldDescriptor* a, const FieldDescriptor* b) { @@ -1362,7 +1382,7 @@ class ParseLoopGenerator { "#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure\n"); format_.Indent(); int hasbits_size = 0; - if (HasFieldPresence(descriptor->file())) { + if (num_hasbits_ > 0) { hasbits_size = (num_hasbits_ + 31) / 32; } // For now only optimize small hasbits. @@ -1374,13 +1394,11 @@ class ParseLoopGenerator { format_.Set("has_bits", "_has_bits_"); } - if (descriptor->file()->options().cc_enable_arenas()) { - format_("$p_ns$::Arena* arena = GetArenaNoVirtual(); (void)arena;\n"); - } GenerateParseLoop(descriptor, ordered_fields); format_.Outdent(); format_("success:\n"); if (hasbits_size) format_(" _has_bits_.Or(has_bits);\n"); + format_( " return ptr;\n" "failure:\n" @@ -1400,7 +1418,7 @@ class ParseLoopGenerator { using WireFormatLite = internal::WireFormatLite; void GenerateArenaString(const FieldDescriptor* field) { - if (HasFieldPresence(field->file())) { + if (HasHasbit(field)) { format_("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); } std::string default_string = @@ -1427,13 +1445,11 @@ class ParseLoopGenerator { // Open source doesn't support other ctypes; ctype = field->options().ctype(); } - if (field->file()->options().cc_enable_arenas() && !field->is_repeated() && - !options_.opensource_runtime && + if (!field->is_repeated() && !options_.opensource_runtime && GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME && // For now only use arena string for strings with empty defaults. field->default_value_string().empty() && - !IsStringInlined(field, options_) && - field->containing_oneof() == nullptr && ctype == FieldOptions::STRING) { + !field->real_containing_oneof() && ctype == FieldOptions::STRING) { GenerateArenaString(field); } else { std::string name; @@ -1495,12 +1511,20 @@ class ParseLoopGenerator { enum_validator = StrCat(", ", QualifiedClassName(field->enum_type(), options_), "_IsValid, &_internal_metadata_, ", field->number()); + format_( + "ptr = " + "$pi_ns$::Packed$1$Parser<$unknown_fields_type$>(_internal_mutable_" + "$2$(), ptr, " + "ctx$3$);\n", + DeclaredTypeMethodName(field->type()), FieldName(field), + enum_validator); + } else { + format_( + "ptr = $pi_ns$::Packed$1$Parser(_internal_mutable_$2$(), ptr, " + "ctx$3$);\n", + DeclaredTypeMethodName(field->type()), FieldName(field), + enum_validator); } - format_( - "ptr = $pi_ns$::Packed$1$Parser(_internal_mutable_$2$(), ptr, " - "ctx$3$);\n", - DeclaredTypeMethodName(field->type()), FieldName(field), - enum_validator); } else { auto field_type = field->type(); switch (field_type) { @@ -1515,10 +1539,12 @@ class ParseLoopGenerator { const FieldDescriptor* val = field->message_type()->FindFieldByName("value"); GOOGLE_CHECK(val); - if (HasFieldPresence(field->file()) && - val->type() == FieldDescriptor::TYPE_ENUM) { + if (val->type() == FieldDescriptor::TYPE_ENUM && + !HasPreservingUnknownEnumSemantics(field)) { format_( - "auto object = ::$proto_ns$::internal::InitEnumParseWrapper(" + "auto object = " + "::$proto_ns$::internal::InitEnumParseWrapper<$unknown_" + "fields_type$>(" "&$1$_, $2$_IsValid, $3$, &_internal_metadata_);\n" "ptr = ctx->ParseMessage(&object, ptr);\n", FieldName(field), QualifiedClassName(val->enum_type()), @@ -1528,18 +1554,17 @@ class ParseLoopGenerator { FieldName(field)); } } else if (IsLazy(field, options_)) { - if (field->containing_oneof() != nullptr) { + if (field->real_containing_oneof()) { format_( "if (!_internal_has_$1$()) {\n" " clear_$2$();\n" " $2$_.$1$_ = ::$proto_ns$::Arena::CreateMessage<\n" - " $pi_ns$::LazyField>(" - "GetArenaNoVirtual());\n" + " $pi_ns$::LazyField>(GetArena());\n" " set_has_$1$();\n" "}\n" "ptr = ctx->ParseMessage($2$_.$1$_, ptr);\n", FieldName(field), field->containing_oneof()->name()); - } else if (HasFieldPresence(field->file())) { + } else if (HasHasbit(field)) { format_( "_Internal::set_has_$1$(&$has_bits$);\n" "ptr = ctx->ParseMessage(&$1$_, ptr);\n", @@ -1564,9 +1589,13 @@ class ParseLoopGenerator { } } else if (IsWeak(field, options_)) { format_( - "ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($1$," - " _$classname$_default_instance_.$2$_), ptr);\n", - field->number(), FieldName(field)); + "{\n" + " auto* default_ = &reinterpret_cast($1$);\n" + " ptr = ctx->ParseMessage(_weak_field_map_.MutableMessage($2$," + " default_), ptr);\n" + "}\n", + QualifiedDefaultInstanceName(field->message_type(), options_), + field->number()); } else { format_("ptr = ctx->ParseMessage(_internal_$1$_$2$(), ptr);\n", field->is_repeated() ? "add" : "mutable", FieldName(field)); @@ -1624,20 +1653,23 @@ class ParseLoopGenerator { field->number()); } } else { - std::string size = (field->type() == FieldDescriptor::TYPE_SINT32 || field->type() == FieldDescriptor::TYPE_UINT32) ? "32" : "64"; + std::string size = (field->type() == FieldDescriptor::TYPE_SINT32 || + field->type() == FieldDescriptor::TYPE_UINT32) + ? "32" + : "64"; std::string zigzag; if ((field->type() == FieldDescriptor::TYPE_SINT32 || field->type() == FieldDescriptor::TYPE_SINT64)) { zigzag = "ZigZag"; } - if (field->is_repeated() || field->containing_oneof()) { + if (field->is_repeated() || field->real_containing_oneof()) { std::string prefix = field->is_repeated() ? "add" : "set"; format_( "_internal_$1$_$2$($pi_ns$::ReadVarint$3$$4$(&ptr));\n" "CHK_(ptr);\n", prefix, FieldName(field), zigzag, size); } else { - if (HasFieldPresence(field->file())) { + if (HasHasbit(field)) { format_("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); } @@ -1652,14 +1684,14 @@ class ParseLoopGenerator { case WireFormatLite::WIRETYPE_FIXED32: case WireFormatLite::WIRETYPE_FIXED64: { std::string type = PrimitiveTypeName(options_, field->cpp_type()); - if (field->is_repeated() || field->containing_oneof()) { + if (field->is_repeated() || field->real_containing_oneof()) { std::string prefix = field->is_repeated() ? "add" : "set"; format_( "_internal_$1$_$2$($pi_ns$::UnalignedLoad<$3$>(ptr));\n" "ptr += sizeof($3$);\n", prefix, FieldName(field), type); } else { - if (HasFieldPresence(field->file())) { + if (HasHasbit(field)) { format_("_Internal::set_has_$1$(&$has_bits$);\n", FieldName(field)); } format_( @@ -1807,7 +1839,10 @@ class ParseLoopGenerator { "}\n"); } format_( - " ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx);\n" + " ptr = UnknownFieldParse(tag,\n" + " _internal_metadata_.mutable_unknown_fields<$unknown_" + "fields_type$>(),\n" + " ptr, ctx);\n" " CHK_(ptr != nullptr);\n" " continue;\n"); } @@ -1827,6 +1862,130 @@ void GenerateParserLoop(const Descriptor* descriptor, int num_hasbits, generator.GenerateParserLoop(descriptor); } +static bool HasExtensionFromFile(const Message& msg, const FileDescriptor* file, + const Options& options, + bool* has_opt_codesize_extension) { + std::vector fields; + auto reflection = msg.GetReflection(); + reflection->ListFields(msg, &fields); + for (auto field : fields) { + const auto* field_msg = field->message_type(); + if (field_msg == nullptr) { + // It so happens that enums Is_Valid are still generated so enums work. + // Only messages have potential problems. + continue; + } + // If this option has an extension set AND that extension is defined in the + // same file we have bootstrap problem. + if (field->is_extension()) { + const auto* msg_extension_file = field->message_type()->file(); + if (msg_extension_file == file) return true; + if (has_opt_codesize_extension && + GetOptimizeFor(msg_extension_file, options) == + FileOptions::CODE_SIZE) { + *has_opt_codesize_extension = true; + } + } + // Recurse in this field to see if there is a problem in there + if (field->is_repeated()) { + for (int i = 0; i < reflection->FieldSize(msg, field); i++) { + if (HasExtensionFromFile(reflection->GetRepeatedMessage(msg, field, i), + file, options, has_opt_codesize_extension)) { + return true; + } + } + } else { + if (HasExtensionFromFile(reflection->GetMessage(msg, field), file, + options, has_opt_codesize_extension)) { + return true; + } + } + } + return false; +} + +static bool HasBootstrapProblem(const FileDescriptor* file, + const Options& options, + bool* has_opt_codesize_extension) { + static auto& cache = *new std::unordered_map; + auto it = cache.find(file); + if (it != cache.end()) return it->second; + // In order to build the data structures for the reflective parse, it needs + // to parse the serialized descriptor describing all the messages defined in + // this file. Obviously this presents a bootstrap problem for descriptor + // messages. + if (file->name() == "net/proto2/proto/descriptor.proto" || + file->name() == "google/protobuf/descriptor.proto") { + return true; + } + // Unfortunately we're not done yet. The descriptor option messages allow + // for extensions. So we need to be able to parse these extensions in order + // to parse the file descriptor for a file that has custom options. This is a + // problem when these custom options extensions are defined in the same file. + FileDescriptorProto linkedin_fd_proto; + const DescriptorPool* pool = file->pool(); + const Descriptor* fd_proto_descriptor = + pool->FindMessageTypeByName(linkedin_fd_proto.GetTypeName()); + // Not all pools have descriptor.proto in them. In these cases there for sure + // are no custom options. + if (fd_proto_descriptor == nullptr) return false; + + // It's easier to inspect file as a proto, because we can use reflection on + // the proto to iterate over all content. + file->CopyTo(&linkedin_fd_proto); + + // linkedin_fd_proto is a generated proto linked in the proto compiler. As + // such it doesn't know the extensions that are potentially present in the + // descriptor pool constructed from the protos that are being compiled. These + // custom options are therefore in the unknown fields. + // By building the corresponding FileDescriptorProto in the pool constructed + // by the protos that are being compiled, ie. file's pool, the unknown fields + // are converted to extensions. + DynamicMessageFactory factory(pool); + Message* fd_proto = factory.GetPrototype(fd_proto_descriptor)->New(); + fd_proto->ParseFromString(linkedin_fd_proto.SerializeAsString()); + + bool& res = cache[file]; + res = HasExtensionFromFile(*fd_proto, file, options, + has_opt_codesize_extension); + delete fd_proto; + return res; +} + +FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file, + const Options& options, + bool* has_opt_codesize_extension) { + if (has_opt_codesize_extension) *has_opt_codesize_extension = false; + switch (options.enforce_mode) { + case EnforceOptimizeMode::kSpeed: + return FileOptions::SPEED; + case EnforceOptimizeMode::kLiteRuntime: + return FileOptions::LITE_RUNTIME; + case EnforceOptimizeMode::kCodeSize: + if (file->options().optimize_for() == FileOptions::LITE_RUNTIME) { + return FileOptions::LITE_RUNTIME; + } + if (HasBootstrapProblem(file, options, has_opt_codesize_extension)) { + return FileOptions::SPEED; + } + return FileOptions::CODE_SIZE; + case EnforceOptimizeMode::kNoEnforcement: + if (file->options().optimize_for() == FileOptions::CODE_SIZE) { + if (HasBootstrapProblem(file, options, has_opt_codesize_extension)) { + GOOGLE_LOG(WARNING) << "Proto states optimize_for = CODE_SIZE, but we " + "cannot honor that because it contains custom option " + "extensions defined in the same proto."; + return FileOptions::SPEED; + } + } + return file->options().optimize_for(); + } + + GOOGLE_LOG(FATAL) << "Unknown optimization enforcement requested."; + // The phony return below serves to silence a warning from GCC 8. + return FileOptions::SPEED; +} + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 28cf78e7e625..125f0591edf5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -83,6 +83,10 @@ extern const char kThinSeparator[]; void SetCommonVars(const Options& options, std::map* variables); +void SetUnknkownFieldsVariable(const Descriptor* descriptor, + const Options& options, + std::map* variables); + bool GetBootstrapBasename(const Options& options, const std::string& basename, std::string* bootstrap_basename); bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context, @@ -130,6 +134,14 @@ inline std::string ClassName(const EnumDescriptor* descriptor, bool qualified) { : ClassName(descriptor); } +// Returns the extension name prefixed with the class name if nested but without +// the package name. +std::string ExtensionName(const FieldDescriptor* d); + +std::string QualifiedExtensionName(const FieldDescriptor* d, + const Options& options); +std::string QualifiedExtensionName(const FieldDescriptor* d); + // Type name of default instance. std::string DefaultInstanceType(const Descriptor* descriptor, const Options& options); @@ -197,9 +209,6 @@ inline const Descriptor* FieldScope(const FieldDescriptor* field) { std::string FieldMessageTypeName(const FieldDescriptor* field, const Options& options); -// Strips ".proto" or ".protodevel" from the end of a filename. -PROTOC_EXPORT std::string StripProto(const std::string& filename); - // Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.). const char* PrimitiveTypeName(FieldDescriptor::CppType type); std::string PrimitiveTypeName(const Options& options, @@ -310,8 +319,6 @@ inline bool IsWeak(const FieldDescriptor* field, const Options& options) { return false; } -bool IsStringInlined(const FieldDescriptor* descriptor, const Options& options); - // For a string field, returns the effective ctype. If the actual ctype is // not supported, returns the default of STRING. FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field, @@ -339,6 +346,16 @@ inline bool IsLazy(const FieldDescriptor* field, const Options& options) { !options.opensource_runtime; } +inline bool IsFieldUsed(const FieldDescriptor* field, const Options& options) { + return true; +} + +// Returns true if "field" is stripped. +inline bool IsFieldStripped(const FieldDescriptor* /*field*/, + const Options& /*options*/) { + return false; +} + // Does the file contain any definitions that need extension_set.h? bool HasExtensionsOrExtendableMessage(const FileDescriptor* file); @@ -392,14 +409,6 @@ inline bool IsProto2MessageSet(const Descriptor* descriptor, descriptor->full_name() == "google.protobuf.bridge.MessageSet"; } -inline bool IsProto2MessageSetFile(const FileDescriptor* file, - const Options& options) { - return !options.opensource_runtime && - options.enforce_mode != EnforceOptimizeMode::kLiteRuntime && - !options.lite_implicit_weak_fields && - file->name() == "net/proto2/bridge/proto/message_set.proto"; -} - inline bool IsMapEntryMessage(const Descriptor* descriptor) { return descriptor->options().map_entry(); } @@ -414,33 +423,33 @@ inline bool HasFieldPresence(const FileDescriptor* file) { return file->syntax() != FileDescriptor::SYNTAX_PROTO3; } +inline bool HasHasbit(const FieldDescriptor* field) { + // This predicate includes proto3 message fields only if they have "optional". + // Foo submsg1 = 1; // HasHasbit() == false + // optional Foo submsg2 = 2; // HasHasbit() == true + // This is slightly odd, as adding "optional" to a singular proto3 field does + // not change the semantics or API. However whenever any field in a message + // has a hasbit, it forces reflection to include hasbit offsets for *all* + // fields, even if almost all of them are set to -1 (no hasbit). So to avoid + // causing a sudden size regression for ~all proto3 messages, we give proto3 + // message fields a hasbit only if "optional" is present. If the user is + // explicitly writing "optional", it is likely they are writing it on + // primitive fields also. + return (field->has_optional_keyword() || field->is_required()) && + !field->options().weak(); +} + // Returns true if 'enum' semantics are such that unknown values are preserved // in the enum field itself, rather than going to the UnknownFieldSet. inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) { return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; } -inline bool SupportsArenas(const FileDescriptor* file) { - return file->options().cc_enable_arenas(); -} - -inline bool SupportsArenas(const Descriptor* desc) { - return SupportsArenas(desc->file()); -} - -inline bool SupportsArenas(const FieldDescriptor* field) { - return SupportsArenas(field->file()); -} - inline bool IsCrossFileMessage(const FieldDescriptor* field) { return field->type() == FieldDescriptor::TYPE_MESSAGE && field->message_type()->file() != field->file(); } -inline std::string MessageCreateFunction(const Descriptor* d) { - return SupportsArenas(d) ? "CreateMessage" : "Create"; -} - inline std::string MakeDefaultName(const FieldDescriptor* field) { return "_i_give_permission_to_break_this_code_default_" + FieldName(field) + "_"; @@ -475,16 +484,32 @@ inline std::string IncludeGuard(const FileDescriptor* file, bool pb_h, } } +// Returns the OptimizeMode for this file, furthermore it updates a status +// bool if has_opt_codesize_extension is non-null. If this status bool is true +// it means this file contains an extension that itself is defined as +// optimized_for = CODE_SIZE. +FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file, + const Options& options, + bool* has_opt_codesize_extension); inline FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file, const Options& options) { - switch (options.enforce_mode) { - case EnforceOptimizeMode::kSpeed: - return FileOptions::SPEED; - case EnforceOptimizeMode::kLiteRuntime: - return FileOptions::LITE_RUNTIME; - case EnforceOptimizeMode::kNoEnforcement: - default: - return file->options().optimize_for(); + return GetOptimizeFor(file, options, nullptr); +} +inline bool NeedsEagerDescriptorAssignment(const FileDescriptor* file, + const Options& options) { + bool has_opt_codesize_extension; + if (GetOptimizeFor(file, options, &has_opt_codesize_extension) == + FileOptions::CODE_SIZE && + has_opt_codesize_extension) { + // If this filedescriptor contains an extension from another file which + // is optimized_for = CODE_SIZE. We need to be careful in the ordering so + // we eagerly build the descriptors in the dependencies before building + // the descriptors of this file. + return true; + } else { + // If we have a generated code based parser we never need eager + // initialization of descriptors of our deps. + return false; } } @@ -843,7 +868,9 @@ struct OneOfRangeImpl { }; Iterator begin() const { return {0, descriptor}; } - Iterator end() const { return {descriptor->oneof_decl_count(), descriptor}; } + Iterator end() const { + return {descriptor->real_oneof_decl_count(), descriptor}; + } const Descriptor* descriptor; }; @@ -854,6 +881,14 @@ void GenerateParserLoop(const Descriptor* descriptor, int num_hasbits, const Options& options, MessageSCCAnalyzer* scc_analyzer, io::Printer* printer); +inline std::string StripProto(const std::string& filename) { + /* + * TODO(github/georgthegreat) remove this proxy method + * once Google's internal codebase will become ready + */ + return compiler::StripProto(filename); +} + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index bea315e9571c..39312b3adbf7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -29,6 +29,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include + #include #include #include @@ -80,13 +81,6 @@ void SetMessageVariables(const FieldDescriptor* descriptor, } else { (*variables)["lite"] = "Lite"; } - - if (!IsProto3Field(descriptor) && val->type() == FieldDescriptor::TYPE_ENUM) { - const EnumValueDescriptor* default_value = val->default_value_enum(); - (*variables)["default_enum_value"] = Int32ToString(default_value->number()); - } else { - (*variables)["default_enum_value"] = "0"; - } } MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, @@ -104,8 +98,8 @@ void MapFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { " $map_classname$,\n" " $key_cpp$, $val_cpp$,\n" " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n" - " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n" - " $default_enum_value$ > $name$_;\n"); + " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> " + "$name$_;\n"); } void MapFieldGenerator::GenerateAccessorDeclarations( diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index cc54f43e11dc..9bfb76e6346b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -68,14 +69,40 @@ using internal::WireFormatLite; namespace { +static constexpr int kNoHasbit = -1; + +// Create an expression that evaluates to +// "for all i, (_has_bits_[i] & masks[i]) == masks[i]" +// masks is allowed to be shorter than _has_bits_, but at least one element of +// masks must be non-zero. +std::string ConditionalToCheckBitmasks( + const std::vector& masks, bool return_success = true, + StringPiece has_bits_var = "_has_bits_") { + std::vector parts; + for (int i = 0; i < masks.size(); i++) { + if (masks[i] == 0) continue; + std::string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8)); + // Each xor evaluates to 0 if the expected bits are present. + parts.push_back( + StrCat("((", has_bits_var, "[", i, "] & ", m, ") ^ ", m, ")")); + } + GOOGLE_CHECK(!parts.empty()); + // If we have multiple parts, each expected to be 0, then bitwise-or them. + std::string result = + parts.size() == 1 + ? parts[0] + : StrCat("(", Join(parts, "\n | "), ")"); + return result + (return_success ? " == 0" : " != 0"); +} + void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field, const std::vector& has_bit_indices, - io::Printer* printer, int* cached_has_bit_index) { + io::Printer* printer, int* cached_has_word_index) { if (!field->options().weak()) { int has_bit_index = has_bit_indices[field->index()]; - if (*cached_has_bit_index != (has_bit_index / 32)) { - *cached_has_bit_index = (has_bit_index / 32); - format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_bit_index); + if (*cached_has_word_index != (has_bit_index / 32)) { + *cached_has_word_index = (has_bit_index / 32); + format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_word_index); } const std::string mask = StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); @@ -132,26 +159,53 @@ bool IsPOD(const FieldDescriptor* field) { } } -// Helper for the code that emits the SharedCtor() method. -bool CanConstructByZeroing(const FieldDescriptor* field, - const Options& options) { +// Helper for the code that emits the SharedCtor() and InternalSwap() methods. +// Anything that is a POD or a "normal" message (represented by a pointer) can +// be manipulated as raw bytes. +bool CanBeManipulatedAsRawBytes(const FieldDescriptor* field, + const Options& options) { bool ret = CanInitializeByZeroing(field); // Non-repeated, non-lazy message fields are simply raw pointers, so we can - // use memset to initialize these in SharedCtor. We cannot use this in - // Clear, as we need to potentially delete the existing value. + // swap them or use memset to initialize these in SharedCtor. We cannot use + // this in Clear, as we need to potentially delete the existing value. ret = ret || (!field->is_repeated() && !IsLazy(field, options) && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE); return ret; } +// Finds runs of fields for which `predicate` is true. +// RunMap maps from fields that start each run to the number of fields in that +// run. This is optimized for the common case that there are very few runs in +// a message and that most of the eligible fields appear together. +using RunMap = std::unordered_map; +RunMap FindRuns(const std::vector& fields, + const std::function& predicate) { + RunMap runs; + const FieldDescriptor* last_start = nullptr; + + for (auto field : fields) { + if (predicate(field)) { + if (last_start == nullptr) { + last_start = field; + } + + runs[last_start]++; + } else { + last_start = nullptr; + } + } + return runs; +} + // Emits an if-statement with a condition that evaluates to true if |field| is // considered non-default (will be sent over the wire), for message types // without true field presence. Should only be called if -// !HasFieldPresence(message_descriptor). +// !HasHasbit(field). bool EmitFieldNonDefaultCondition(io::Printer* printer, const std::string& prefix, const FieldDescriptor* field) { + GOOGLE_CHECK(!HasHasbit(field)); Formatter format(printer); format.Set("prefix", prefix); format.Set("name", FieldName(field)); @@ -172,7 +226,7 @@ bool EmitFieldNonDefaultCondition(io::Printer* printer, } format.Indent(); return true; - } else if (field->containing_oneof()) { + } else if (field->real_containing_oneof()) { format("if (_internal_has_$name$()) {\n"); format.Indent(); return true; @@ -188,7 +242,8 @@ bool HasHasMethod(const FieldDescriptor* field) { } // For message types without true field presence, only fields with a message // type have a has_$name$() method. - return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE; + return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + field->has_optional_keyword(); } // Collects map entry message type information. @@ -213,13 +268,6 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor, "TYPE_" + ToUpper(DeclaredTypeMethodName(key->type())); vars["val_wire_type"] = "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type())); - if (descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 && - val->type() == FieldDescriptor::TYPE_ENUM) { - const EnumValueDescriptor* default_value = val->default_value_enum(); - vars["default_enum_value"] = Int32ToString(default_value->number()); - } else { - vars["default_enum_value"] = "0"; - } } // Does the given field have a private (internal helper only) has_$name$() @@ -227,8 +275,7 @@ void CollectMapInfo(const Options& options, const Descriptor* descriptor, bool HasPrivateHasMethod(const FieldDescriptor* field) { // Only for oneofs in message types with no field presence. has_$name$(), // based on the oneof case, is still useful internally for generated code. - return (!HasFieldPresence(field->file()) && - field->containing_oneof() != NULL); + return (!HasFieldPresence(field->file()) && field->real_containing_oneof()); } // TODO(ckennelly): Cull these exclusions if/when these protos do not have @@ -236,7 +283,7 @@ bool HasPrivateHasMethod(const FieldDescriptor* field) { bool ShouldMarkClassAsFinal(const Descriptor* descriptor, const Options& options) { - return false; + return true; } bool ShouldMarkClearAsFinal(const Descriptor* descriptor, @@ -261,12 +308,18 @@ bool ShouldMarkIsInitializedAsFinal(const Descriptor* descriptor, bool ShouldMarkNewAsFinal(const Descriptor* descriptor, const Options& options) { - static std::set exclusions{ - }; + return true; +} - const std::string name = ClassName(descriptor, true); - return exclusions.find(name) == exclusions.end() || - options.opensource_runtime; +// Returns true to make the message serialize in order, decided by the following +// factors in the order of precedence. +// --options().message_set_wire_format() == true +// --the message is in the allowlist (true) +// --GOOGLE_PROTOBUF_SHUFFLE_SERIALIZE is defined (false) +// --a ranage of message names that are allowed to stay in order (true) +bool ShouldSerializeInOrder(const Descriptor* descriptor, + const Options& options) { + return true; } bool TableDrivenParsingEnabled(const Descriptor* descriptor, @@ -278,10 +331,16 @@ bool TableDrivenParsingEnabled(const Descriptor* descriptor, // Consider table-driven parsing. We only do this if: // - We have has_bits for fields. This avoids a check on every field we set // when are present (the common case). - if (!HasFieldPresence(descriptor->file())) { - return false; + bool has_hasbit = false; + for (int i = 0; i < descriptor->field_count(); i++) { + if (HasHasbit(descriptor->field(i))) { + has_hasbit = true; + break; + } } + if (!has_hasbit) return false; + const double table_sparseness = 0.5; int max_field_number = 0; for (auto field : FieldRange(descriptor)) { @@ -320,23 +379,6 @@ bool TableDrivenParsingEnabled(const Descriptor* descriptor, return true; } -void SetUnknkownFieldsVariable(const Descriptor* descriptor, - const Options& options, - std::map* variables) { - std::string proto_ns = ProtobufNamespace(options); - if (UseUnknownFieldSet(descriptor->file(), options)) { - (*variables)["unknown_fields_type"] = "::" + proto_ns + "::UnknownFieldSet"; - } else { - (*variables)["unknown_fields_type"] = - PrimitiveTypeName(options, FieldDescriptor::CPPTYPE_STRING); - } - (*variables)["have_unknown_fields"] = - "_internal_metadata_.have_unknown_fields()"; - (*variables)["unknown_fields"] = "_internal_metadata_.unknown_fields()"; - (*variables)["mutable_unknown_fields"] = - "_internal_metadata_.mutable_unknown_fields()"; -} - bool IsCrossFileMapField(const FieldDescriptor* field) { if (!field->is_map()) { return false; @@ -360,82 +402,17 @@ bool IsRequired(const std::vector& v) { return v.front()->is_required(); } -// Allows chunking repeated fields together and non-repeated fields if the -// fields share the same has_byte index. -// TODO(seongkim): use lambda with capture instead of functor. -class MatchRepeatedAndHasByte { - public: - MatchRepeatedAndHasByte(const std::vector* has_bit_indices, - bool has_field_presence) - : has_bit_indices_(*has_bit_indices), - has_field_presence_(has_field_presence) {} - - // Returns true if the following conditions are met: - // --both fields are repeated fields - // --both fields are non-repeated fields with either has_field_presence is - // false or have the same has_byte index. - bool operator()(const FieldDescriptor* a, const FieldDescriptor* b) const { - return a->is_repeated() == b->is_repeated() && - (!has_field_presence_ || a->is_repeated() || - has_bit_indices_[a->index()] / 8 == - has_bit_indices_[b->index()] / 8); - } - - private: - const std::vector& has_bit_indices_; - const bool has_field_presence_; -}; - -// Allows chunking required fields separately after chunking with -// MatchRepeatedAndHasByte. -class MatchRepeatedAndHasByteAndRequired : public MatchRepeatedAndHasByte { - public: - MatchRepeatedAndHasByteAndRequired(const std::vector* has_bit_indices, - bool has_field_presence) - : MatchRepeatedAndHasByte(has_bit_indices, has_field_presence) {} - - bool operator()(const FieldDescriptor* a, const FieldDescriptor* b) const { - return MatchRepeatedAndHasByte::operator()(a, b) && - a->is_required() == b->is_required(); - } -}; - -// Allows chunking zero-initializable fields separately after chunking with -// MatchRepeatedAndHasByte. -class MatchRepeatedAndHasByteAndZeroInits : public MatchRepeatedAndHasByte { - public: - MatchRepeatedAndHasByteAndZeroInits(const std::vector* has_bit_indices, - bool has_field_presence) - : MatchRepeatedAndHasByte(has_bit_indices, has_field_presence) {} - - bool operator()(const FieldDescriptor* a, const FieldDescriptor* b) const { - return MatchRepeatedAndHasByte::operator()(a, b) && - CanInitializeByZeroing(a) == CanInitializeByZeroing(b); - } -}; - // Collects neighboring fields based on a given criteria (equivalent predicate). template std::vector> CollectFields( const std::vector& fields, const Predicate& equivalent) { std::vector> chunks; - if (fields.empty()) { - return chunks; - } - - const FieldDescriptor* last_field = fields.front(); - std::vector chunk; for (auto field : fields) { - if (!equivalent(last_field, field) && !chunk.empty()) { - chunks.push_back(chunk); - chunk.clear(); + if (chunks.empty() || !equivalent(chunks.back().back(), field)) { + chunks.emplace_back(); } - chunk.push_back(field); - last_field = field; - } - if (!chunk.empty()) { - chunks.push_back(chunk); + chunks.back().push_back(field); } return chunks; } @@ -475,20 +452,18 @@ class ColdChunkSkipper { ColdChunkSkipper( const Options& options, const std::vector>& chunks, - const std::vector& has_bit_indices, const double cold_threshold, - bool has_field_presence) + const std::vector& has_bit_indices, const double cold_threshold) : chunks_(chunks), has_bit_indices_(has_bit_indices), access_info_map_(options.access_info_map), - cold_threshold_(cold_threshold), - has_field_presence_(has_field_presence) { + cold_threshold_(cold_threshold) { SetCommonVars(options, &variables_); } // May open an external if check for a batch of cold fields. "from" is the // prefix to _has_bits_ to allow MergeFrom to use "from._has_bits_". // Otherwise, it should be "". - void OnStartChunk(int chunk, int cached_has_bit_index, + void OnStartChunk(int chunk, int cached_has_word_index, const std::string& from, io::Printer* printer); bool OnEndChunk(int chunk, io::Printer* printer); @@ -505,7 +480,6 @@ class ColdChunkSkipper { const double cold_threshold_; std::map variables_; int limit_chunk_ = -1; - bool has_field_presence_; }; // Tuning parameters for ColdChunkSkipper. @@ -518,11 +492,11 @@ bool ColdChunkSkipper::IsColdChunk(int chunk) { } -void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_bit_index, +void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_word_index, const std::string& from, io::Printer* printer) { Formatter format(printer, variables_); - if (!access_info_map_ || !has_field_presence_) { + if (!access_info_map_) { return; } else if (chunk < limit_chunk_) { // We are already inside a run of cold chunks. @@ -564,7 +538,7 @@ void ColdChunkSkipper::OnStartChunk(int chunk, int cached_has_bit_index, format(" ||\n "); } format.Set("mask", strings::Hex(mask, strings::ZERO_PAD_8)); - if (this_word == cached_has_bit_index) { + if (this_word == cached_has_word_index) { format("(cached_has_bits & 0x$mask$u) != 0"); } else { format("($1$_has_bits_[$2$] & 0x$mask$u) != 0", from, this_word); @@ -616,26 +590,30 @@ MessageGenerator::MessageGenerator( // Compute optimized field order to be used for layout and initialization // purposes. for (auto field : FieldRange(descriptor_)) { + if (IsFieldStripped(field, options_)) { + continue; + } + if (IsWeak(field, options_)) { num_weak_fields_++; - } else if (!field->containing_oneof()) { + } else if (!field->real_containing_oneof()) { optimized_order_.push_back(field); } } message_layout_helper_->OptimizeLayout(&optimized_order_, options_); - if (HasFieldPresence(descriptor_->file())) { - // We use -1 as a sentinel. - has_bit_indices_.resize(descriptor_->field_count(), -1); - for (auto field : optimized_order_) { - // Skip fields that do not have has bits. - if (field->is_repeated()) { - continue; + // This message has hasbits iff one or more fields need one. + for (auto field : optimized_order_) { + if (HasHasbit(field)) { + if (has_bit_indices_.empty()) { + has_bit_indices_.resize(descriptor_->field_count(), kNoHasbit); } - has_bit_indices_[field->index()] = max_has_bit_index_++; } + } + + if (!has_bit_indices_.empty()) { field_generators_.SetHasBitIndices(has_bit_indices_); } @@ -652,16 +630,22 @@ MessageGenerator::MessageGenerator( MessageGenerator::~MessageGenerator() = default; size_t MessageGenerator::HasBitsSize() const { - size_t sizeof_has_bits = (max_has_bit_index_ + 31) / 32 * 4; - if (sizeof_has_bits == 0) { - // Zero-size arrays aren't technically allowed, and MSVC in particular - // doesn't like them. We still need to declare these arrays to make - // other code compile. Since this is an uncommon case, we'll just declare - // them with size 1 and waste some space. Oh well. - sizeof_has_bits = 4; - } + return (max_has_bit_index_ + 31) / 32; +} + +int MessageGenerator::HasBitIndex(const FieldDescriptor* field) const { + return has_bit_indices_.empty() ? kNoHasbit + : has_bit_indices_[field->index()]; +} + +int MessageGenerator::HasByteIndex(const FieldDescriptor* field) const { + int hasbit = HasBitIndex(field); + return hasbit == kNoHasbit ? kNoHasbit : hasbit / 8; +} - return sizeof_has_bits; +int MessageGenerator::HasWordIndex(const FieldDescriptor* field) const { + int hasbit = HasBitIndex(field); + return hasbit == kNoHasbit ? kNoHasbit : hasbit / 32; } void MessageGenerator::AddGenerators( @@ -682,7 +666,7 @@ void MessageGenerator::AddGenerators( void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { Formatter format(printer, variables_); // optimized_fields_ does not contain fields where - // field->containing_oneof() != NULL + // field->real_containing_oneof() // so we need to iterate over those as well. // // We place the non-oneof fields in optimized_order_, as that controls the @@ -694,7 +678,8 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { ordered_fields.insert(ordered_fields.begin(), optimized_order_.begin(), optimized_order_.end()); for (auto field : FieldRange(descriptor_)) { - if (field->containing_oneof() == NULL && !field->options().weak()) { + if (!field->real_containing_oneof() && !field->options().weak() && + !IsFieldStripped(field, options_)) { continue; } ordered_fields.push_back(field); @@ -722,28 +707,35 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { format.AddMap(vars); if (field->is_repeated()) { - format( - "$deprecated_attr$int ${1$$name$_size$}$() const;\n" - "private:\n" - "int ${1$_internal_$name$_size$}$() const;\n" - "public:\n", - field); + format("$deprecated_attr$int ${1$$name$_size$}$() const$2$\n", field, + !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}"); + if (!IsFieldStripped(field, options_)) { + format( + "private:\n" + "int ${1$_internal_$name$_size$}$() const;\n" + "public:\n", + field); + } } else if (HasHasMethod(field)) { - format( - "$deprecated_attr$bool ${1$has_$name$$}$() const;\n" - "private:\n" - "bool _internal_has_$name$() const;\n" - "public:\n", - field); + format("$deprecated_attr$bool ${1$has_$name$$}$() const$2$\n", field, + !IsFieldStripped(field, options_) ? ";" : " {__builtin_trap();}"); + if (!IsFieldStripped(field, options_)) { + format( + "private:\n" + "bool _internal_has_$name$() const;\n" + "public:\n"); + } } else if (HasPrivateHasMethod(field)) { - format( - "private:\n" - "bool ${1$_internal_has_$name$$}$() const;\n" - "public:\n", - field); + if (!IsFieldStripped(field, options_)) { + format( + "private:\n" + "bool ${1$_internal_has_$name$$}$() const;\n" + "public:\n", + field); + } } - - format("$deprecated_attr$void ${1$clear_$name$$}$();\n", field); + format("$deprecated_attr$void ${1$clear_$name$$}$()$2$\n", field, + !IsFieldStripped(field, options_) ? ";" : "{__builtin_trap();}"); // Generate type-specific accessor declarations. field_generators_.get(field).GenerateAccessorDeclarations(printer); @@ -778,6 +770,12 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* printer) { void MessageGenerator::GenerateSingularFieldHasBits( const FieldDescriptor* field, Formatter format) { + if (IsFieldStripped(field, options_)) { + format( + "inline bool $classname$::has_$name$() const { " + "__builtin_trap(); }\n"); + return; + } if (field->options().weak()) { format( "inline bool $classname$::has_$name$() const {\n" @@ -786,11 +784,9 @@ void MessageGenerator::GenerateSingularFieldHasBits( "}\n"); return; } - if (HasFieldPresence(descriptor_->file())) { - // N.B.: without field presence, we do not use has-bits or generate - // has_$name$() methods. - int has_bit_index = has_bit_indices_[field->index()]; - GOOGLE_CHECK_GE(has_bit_index, 0); + if (HasHasbit(field)) { + int has_bit_index = HasBitIndex(field); + GOOGLE_CHECK_NE(has_bit_index, kNoHasbit); format.Set("has_array_index", has_bit_index / 32); format.Set("has_mask", @@ -815,27 +811,25 @@ void MessageGenerator::GenerateSingularFieldHasBits( "$annotate_accessor$" " return _internal_has_$name$();\n" "}\n"); - } else { + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { // Message fields have a has_$name$() method. - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - if (IsLazy(field, options_)) { - format( - "inline bool $classname$::_internal_has_$name$() const {\n" - " return !$name$_.IsCleared();\n" - "}\n"); - } else { - format( - "inline bool $classname$::_internal_has_$name$() const {\n" - " return this != internal_default_instance() " - "&& $name$_ != nullptr;\n" - "}\n"); - } + if (IsLazy(field, options_)) { + format( + "inline bool $classname$::_internal_has_$name$() const {\n" + " return !$name$_.IsCleared();\n" + "}\n"); + } else { format( - "inline bool $classname$::has_$name$() const {\n" - "$annotate_accessor$" - " return _internal_has_$name$();\n" + "inline bool $classname$::_internal_has_$name$() const {\n" + " return this != internal_default_instance() " + "&& $name$_ != nullptr;\n" "}\n"); } + format( + "inline bool $classname$::has_$name$() const {\n" + "$annotate_accessor$" + " return _internal_has_$name$();\n" + "}\n"); } } @@ -857,6 +851,17 @@ void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) { void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, const Formatter& format) { + if (IsFieldStripped(field, options_)) { + if (HasHasMethod(field)) { + format( + "inline bool $classname$::has_$name$() const { " + "__builtin_trap(); }\n"); + } + format( + "inline void $classname$::set_has_$name$() { __builtin_trap(); " + "}\n"); + return; + } // Singular field in a oneof // N.B.: Without field presence, we do not use has-bits or generate // has_$name$() methods, but oneofs still have set_has_$name$(). @@ -891,6 +896,11 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, bool is_inline, Formatter format) { + if (IsFieldStripped(field, options_)) { + format("void $classname$::clear_$name$() { __builtin_trap(); }\n"); + return; + } + // Generate clear_$name$(). if (is_inline) { format("inline "); @@ -901,7 +911,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, format.Indent(); - if (field->containing_oneof()) { + if (field->real_containing_oneof()) { // Clear this field only if it is the active field in this oneof, // otherwise ignore format("if (_internal_has_$name$()) {\n"); @@ -912,16 +922,12 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, format("}\n"); } else { field_generators_.get(field).GenerateClearingCode(format.printer()); - if (HasFieldPresence(descriptor_->file())) { - if (!field->is_repeated() && !field->options().weak()) { - int has_bit_index = has_bit_indices_[field->index()]; - GOOGLE_CHECK_GE(has_bit_index, 0); - - format.Set("has_array_index", has_bit_index / 32); - format.Set("has_mask", - strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); - format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"); - } + if (HasHasbit(field)) { + int has_bit_index = HasBitIndex(field); + format.Set("has_array_index", has_bit_index / 32); + format.Set("has_mask", + strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); + format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"); } } @@ -936,6 +942,10 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { for (auto field : FieldRange(descriptor_)) { PrintFieldComment(format, field); + if (IsFieldStripped(field, options_)) { + continue; + } + std::map vars; SetCommonFieldVariables(field, &vars, options_); @@ -944,19 +954,25 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { // Generate has_$name$() or $name$_size(). if (field->is_repeated()) { - format( - "inline int $classname$::_internal_$name$_size() const {\n" - " return $name$_$1$.size();\n" - "}\n" - "inline int $classname$::$name$_size() const {\n" - "$annotate_accessor$" - " return _internal_$name$_size();\n" - "}\n", - IsImplicitWeakField(field, options_, scc_analyzer_) && - field->message_type() - ? ".weak" - : ""); - } else if (field->containing_oneof()) { + if (IsFieldStripped(field, options_)) { + format( + "inline int $classname$::$name$_size() const { " + "__builtin_trap(); }\n"); + } else { + format( + "inline int $classname$::_internal_$name$_size() const {\n" + " return $name$_$1$.size();\n" + "}\n" + "inline int $classname$::$name$_size() const {\n" + "$annotate_accessor$" + " return _internal_$name$_size();\n" + "}\n", + IsImplicitWeakField(field, options_, scc_analyzer_) && + field->message_type() + ? ".weak" + : ""); + } + } else if (field->real_containing_oneof()) { format.Set("field_name", UnderscoresToCamelCase(field->name(), true)); format.Set("oneof_name", field->containing_oneof()->name()); format.Set("oneof_index", @@ -972,7 +988,9 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { } // Generate type-specific accessors. - field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GenerateInlineAccessorDefinitions(printer); + } format("\n"); } @@ -983,8 +1001,9 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) { void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { Formatter format(printer, variables_); - format.Set("class_final", - ShouldMarkClassAsFinal(descriptor_, options_) ? "final" : ""); + format.Set("class_final", ShouldMarkClassAsFinal(descriptor_, options_) + ? "PROTOBUF_FINAL" + : ""); if (IsMapEntryMessage(descriptor_)) { std::map vars; @@ -997,16 +1016,15 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "::$proto_ns$::internal::MapEntry$lite$<$classname$, \n" " $key_cpp$, $val_cpp$,\n" " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n" - " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n" - " $default_enum_value$ > {\n" + " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> {\n" "public:\n" " typedef ::$proto_ns$::internal::MapEntry$lite$<$classname$, \n" " $key_cpp$, $val_cpp$,\n" " ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n" - " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$,\n" - " $default_enum_value$ > SuperType;\n" + " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> " + "SuperType;\n" " $classname$();\n" - " $classname$(::$proto_ns$::Arena* arena);\n" + " explicit $classname$(::$proto_ns$::Arena* arena);\n" " void MergeFrom(const $classname$& other);\n" " static const $classname$* internal_default_instance() { return " "reinterpret_castdata(), static_cast(s->size()), " "::$proto_ns$::internal::" "WireFormatLite::PARSE, \"$1$\");\n" + "#else\n" + " (void) s;\n" "#endif\n" " return true;\n" " }\n", @@ -1058,6 +1078,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { " s->data(), static_cast(s->size()), " "::$proto_ns$::internal::" "WireFormatLite::PARSE, \"$1$\");\n" + "#else\n" + " (void) s;\n" "#endif\n" " return true;\n" " }\n", @@ -1094,7 +1116,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format.Indent(); format( - "$classname$();\n" + "inline $classname$() : $classname$(nullptr) {}\n" "virtual ~$classname$();\n" "\n" "$classname$(const $classname$& from);\n" @@ -1108,7 +1130,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { " return *this;\n" "}\n" "inline $classname$& operator=($classname$&& from) noexcept {\n" - " if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n" + " if (GetArena() == from.GetArena()) {\n" " if (this != &from) InternalSwap(&from);\n" " } else {\n" " CopyFrom(from);\n" @@ -1139,21 +1161,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n"); } - // N.B.: We exclude GetArena() when arena support is disabled, falling back on - // MessageLite's implementation which returns NULL rather than generating our - // own method which returns NULL, in order to reduce code size. - if (SupportsArenas(descriptor_)) { - // virtual method version of GetArenaNoVirtual(), required for generic - // dispatch given a MessageLite* (e.g., in RepeatedField::AddAllocated()). - format( - "inline ::$proto_ns$::Arena* GetArena() const final {\n" - " return GetArenaNoVirtual();\n" - "}\n" - "inline void* GetMaybeArenaPointer() const final {\n" - " return MaybeArenaPtr();\n" - "}\n"); - } - // Only generate this member if it's not disabled. if (HasDescriptorMethods(descriptor_->file(), options_) && !descriptor_->options().no_standard_descriptor_accessor()) { @@ -1205,7 +1212,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // TODO(gerbens) make this private, while still granting other protos access. format( - "static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY\n" "static inline const $classname$* internal_default_instance() {\n" " return reinterpret_cast(\n" " &_$classname$_default_instance_);\n" @@ -1221,12 +1227,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n"); if (HasDescriptorMethods(descriptor_->file(), options_)) { format( - "void PackFrom(const ::$proto_ns$::Message& message) {\n" - " _any_metadata_.PackFrom(message);\n" + "bool PackFrom(const ::$proto_ns$::Message& message) {\n" + " return _any_metadata_.PackFrom(message);\n" "}\n" - "void PackFrom(const ::$proto_ns$::Message& message,\n" - " const std::string& type_url_prefix) {\n" - " _any_metadata_.PackFrom(message, type_url_prefix);\n" + "bool PackFrom(const ::$proto_ns$::Message& message,\n" + " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " + "type_url_prefix) {\n" + " return _any_metadata_.PackFrom(message, type_url_prefix);\n" "}\n" "bool UnpackTo(::$proto_ns$::Message* message) const {\n" " return _any_metadata_.UnpackTo(message);\n" @@ -1238,15 +1245,16 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "template " "::value>::type>\n" - "void PackFrom(const T& message) {\n" - " _any_metadata_.PackFrom(message);\n" + "bool PackFrom(const T& message) {\n" + " return _any_metadata_.PackFrom(message);\n" "}\n" "template " "::value>::type>\n" - "void PackFrom(const T& message,\n" - " const std::string& type_url_prefix) {\n" - " _any_metadata_.PackFrom(message, type_url_prefix);" + "bool PackFrom(const T& message,\n" + " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " + "type_url_prefix) {\n" + " return _any_metadata_.PackFrom(message, type_url_prefix);" "}\n" "template " @@ -1257,13 +1265,14 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { } else { format( "template \n" - "void PackFrom(const T& message) {\n" - " _any_metadata_.PackFrom(message);\n" + "bool PackFrom(const T& message) {\n" + " return _any_metadata_.PackFrom(message);\n" "}\n" "template \n" - "void PackFrom(const T& message,\n" - " const std::string& type_url_prefix) {\n" - " _any_metadata_.PackFrom(message, type_url_prefix);\n" + "bool PackFrom(const T& message,\n" + " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " + "type_url_prefix) {\n" + " return _any_metadata_.PackFrom(message, type_url_prefix);\n" "}\n" "template \n" "bool UnpackTo(T* message) const {\n" @@ -1274,7 +1283,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "template bool Is() const {\n" " return _any_metadata_.Is();\n" "}\n" - "static bool ParseAnyTypeUrl(const string& type_url,\n" + "static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam " + "type_url,\n" " std::string* full_type_name);\n"); } @@ -1284,31 +1294,21 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format( "friend void swap($classname$& a, $classname$& b) {\n" " a.Swap(&b);\n" + "}\n" + "inline void Swap($classname$* other) {\n" + " if (other == this) return;\n" + " if (GetArena() == other->GetArena()) {\n" + " InternalSwap(other);\n" + " } else {\n" + " ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n" + " }\n" + "}\n" + "void UnsafeArenaSwap($classname$* other) {\n" + " if (other == this) return;\n" + " $DCHK$(GetArena() == other->GetArena());\n" + " InternalSwap(other);\n" "}\n"); - if (SupportsArenas(descriptor_)) { - format( - "inline void Swap($classname$* other) {\n" - " if (other == this) return;\n" - " if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {\n" - " InternalSwap(other);\n" - " } else {\n" - " ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);\n" - " }\n" - "}\n" - "void UnsafeArenaSwap($classname$* other) {\n" - " if (other == this) return;\n" - " $DCHK$(GetArenaNoVirtual() == other->GetArenaNoVirtual());\n" - " InternalSwap(other);\n" - "}\n"); - } else { - format( - "inline void Swap($classname$* other) {\n" - " if (other == this) return;\n" - " InternalSwap(other);\n" - "}\n"); - } - format( "\n" "// implements Message ----------------------------------------------\n" @@ -1381,37 +1381,15 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { options_.opensource_runtime ? "::PROTOBUF_NAMESPACE_ID::StringPiece" : "::StringPiece"); - if (SupportsArenas(descriptor_)) { - format( - // TODO(gerbens) Make this private! Currently people are deriving from - // protos to give access to this constructor, breaking the invariants - // we rely on. - "protected:\n" - "explicit $classname$(::$proto_ns$::Arena* arena);\n" - "private:\n" - "static void ArenaDtor(void* object);\n" - "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); - } - - if (SupportsArenas(descriptor_)) { - format( - "private:\n" - "inline ::$proto_ns$::Arena* GetArenaNoVirtual() const {\n" - " return _internal_metadata_.arena();\n" - "}\n" - "inline void* MaybeArenaPtr() const {\n" - " return _internal_metadata_.raw_arena_ptr();\n" - "}\n"); - } else { - format( - "private:\n" - "inline ::$proto_ns$::Arena* GetArenaNoVirtual() const {\n" - " return nullptr;\n" - "}\n" - "inline void* MaybeArenaPtr() const {\n" - " return nullptr;\n" - "}\n"); - } + format( + // TODO(gerbens) Make this private! Currently people are deriving from + // protos to give access to this constructor, breaking the invariants + // we rely on. + "protected:\n" + "explicit $classname$(::$proto_ns$::Arena* arena);\n" + "private:\n" + "static void ArenaDtor(void* object);\n" + "inline void RegisterArenaDtor(::$proto_ns$::Arena* arena);\n"); format( "public:\n" @@ -1482,11 +1460,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { // TODO(seongkim): Remove hack to track field access and remove this class. format("class _Internal;\n"); - for (auto field : FieldRange(descriptor_)) { // set_has_***() generated in all oneofs. if (!field->is_repeated() && !field->options().weak() && - field->containing_oneof()) { + field->real_containing_oneof()) { format("void set_has_$1$();\n", FieldName(field)); } } @@ -1517,10 +1494,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { const size_t sizeof_has_bits = HasBitsSize(); const std::string has_bits_decl = - sizeof_has_bits == 0 - ? "" - : StrCat("::$proto_ns$::internal::HasBits<", - sizeof_has_bits / 4, "> _has_bits_;\n"); + sizeof_has_bits == 0 ? "" + : StrCat("::$proto_ns$::internal::HasBits<", + sizeof_has_bits, "> _has_bits_;\n"); // To minimize padding, data members are divided into three sections: // (1) members assumed to align to 8 bytes @@ -1536,25 +1512,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "\n"); } - if (UseUnknownFieldSet(descriptor_->file(), options_)) { - format( - "::$proto_ns$::internal::InternalMetadataWithArena " - "_internal_metadata_;\n"); - } else { - format( - "::$proto_ns$::internal::InternalMetadataWithArenaLite " - "_internal_metadata_;\n"); - } - - if (SupportsArenas(descriptor_)) { - format( - "template friend class " - "::$proto_ns$::Arena::InternalHelper;\n" - "typedef void InternalArenaConstructable_;\n" - "typedef void DestructorSkippable_;\n"); - } + format( + "template friend class " + "::$proto_ns$::Arena::InternalHelper;\n" + "typedef void InternalArenaConstructable_;\n" + "typedef void DestructorSkippable_;\n"); - if (HasFieldPresence(descriptor_->file())) { + if (!has_bit_indices_.empty()) { // _has_bits_ is frequently accessed, so to reduce code size and improve // speed, it should be close to the start of the object. Placing // _cached_size_ together with _has_bits_ improves cache locality despite @@ -1584,12 +1548,16 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { camel_oneof_name); format.Indent(); for (auto field : FieldRange(oneof)) { - field_generators_.get(field).GeneratePrivateMembers(printer); + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GeneratePrivateMembers(printer); + } } format.Outdent(); format("} $1$_;\n", oneof->name()); for (auto field : FieldRange(oneof)) { - field_generators_.get(field).GenerateStaticMembers(printer); + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GenerateStaticMembers(printer); + } } } @@ -1601,11 +1569,11 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { } // Generate _oneof_case_. - if (descriptor_->oneof_decl_count() > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { format( "$uint32$ _oneof_case_[$1$];\n" "\n", - descriptor_->oneof_decl_count()); + descriptor_->real_oneof_decl_count()); } if (num_weak_fields_) { @@ -1645,29 +1613,6 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) { } } -void MessageGenerator::GenerateExtraDefaultFields(io::Printer* printer) { - // Generate oneof default instance and weak field instances for reflection - // usage. - Formatter format(printer, variables_); - if (descriptor_->oneof_decl_count() > 0 || num_weak_fields_ > 0) { - for (auto oneof : OneOfRange(descriptor_)) { - for (auto field : FieldRange(oneof)) { - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || - (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING && - EffectiveStringCType(field, options_) != FieldOptions::STRING)) { - format("const "); - } - field_generators_.get(field).GeneratePrivateMembers(printer); - } - } - for (auto field : FieldRange(descriptor_)) { - if (field->options().weak()) { - format(" const ::$proto_ns$::Message* $1$_;\n", FieldName(field)); - } - } - } -} - bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, size_t aux_offset) { Formatter format(printer, variables_); @@ -1693,14 +1638,14 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, "$3$,\n", offset, aux_offset, max_field_number); - if (!HasFieldPresence(descriptor_->file())) { - // If we don't have field presence, then _has_bits_ does not exist. + if (has_bit_indices_.empty()) { + // If no fields have hasbits, then _has_bits_ does not exist. format("-1,\n"); } else { format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); } - if (descriptor_->oneof_decl_count() > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_),\n"); } else { format("-1, // no _oneof_case_\n"); @@ -1713,7 +1658,7 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, } // TODO(ckennelly): Consolidate this with the calculation for - // AuxillaryParseTableField. + // AuxiliaryParseTableField. format( "PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n" "&$package_ns$::_$classname$_default_instance_,\n"); @@ -1732,10 +1677,9 @@ bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, int has_offset) { Formatter format(printer, variables_); - has_offset = - HasFieldPresence(descriptor_->file()) || IsMapEntryMessage(descriptor_) - ? offset + has_offset - : -1; + has_offset = !has_bit_indices_.empty() || IsMapEntryMessage(descriptor_) + ? offset + has_offset + : -1; format("{ $1$, $2$, sizeof($classtype$)},\n", offset, has_offset); } @@ -1750,9 +1694,6 @@ uint32 CalcFieldNum(const FieldGenerator& generator, int type = field->type(); if (type == FieldDescriptor::TYPE_STRING || type == FieldDescriptor::TYPE_BYTES) { - if (generator.IsInlined()) { - type = internal::FieldMetadata::kInlinedType; - } // string field if (IsCord(field, options)) { type = internal::FieldMetadata::kCordType; @@ -1760,23 +1701,22 @@ uint32 CalcFieldNum(const FieldGenerator& generator, type = internal::FieldMetadata::kStringPieceType; } } - if (field->containing_oneof()) { + + if (field->real_containing_oneof()) { return internal::FieldMetadata::CalculateType( type, internal::FieldMetadata::kOneOf); - } - if (field->is_packed()) { + } else if (field->is_packed()) { return internal::FieldMetadata::CalculateType( type, internal::FieldMetadata::kPacked); } else if (field->is_repeated()) { return internal::FieldMetadata::CalculateType( type, internal::FieldMetadata::kRepeated); - } else if (!HasFieldPresence(field->file()) && - field->containing_oneof() == NULL && !is_a_map) { + } else if (HasHasbit(field) || field->real_containing_oneof() || is_a_map) { return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kNoPresence); + type, internal::FieldMetadata::kPresence); } else { return internal::FieldMetadata::CalculateType( - type, internal::FieldMetadata::kPresence); + type, internal::FieldMetadata::kNoPresence); } } @@ -1866,7 +1806,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { } std::string classfieldname = FieldName(field); - if (field->containing_oneof()) { + if (field->real_containing_oneof()) { classfieldname = field->containing_oneof()->name(); } format.Set("field_name", classfieldname); @@ -1902,10 +1842,9 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { type = internal::FieldMetadata::kSpecial; ptr = "reinterpret_cast(::" + variables_["proto_ns"] + "::internal::LazyFieldSerializer"; - if (field->containing_oneof()) { + if (field->real_containing_oneof()) { ptr += "OneOf"; - } else if (!HasFieldPresence(descriptor_->file()) || - has_bit_indices_[field->index()] == -1) { + } else if (!HasHasbit(field)) { ptr += "NoPresence"; } ptr += ")"; @@ -1920,7 +1859,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { "reinterpret_cast(::$proto_ns$::internal::WeakFieldSerializer)},\n", tag); - } else if (field->containing_oneof()) { + } else if (field->real_containing_oneof()) { format.Set("oneofoffset", sizeof(uint32) * field->containing_oneof()->index()); format( @@ -1928,8 +1867,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { " PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_) + " "$oneofoffset$, $2$, $3$},\n", tag, type, ptr); - } else if (HasFieldPresence(descriptor_->file()) && - has_bit_indices_[field->index()] != -1) { + } else if (HasHasbit(field)) { format.Set("hasbitsoffset", has_bit_indices_[field->index()]); format( "{PROTOBUF_FIELD_OFFSET($classtype$, $field_name$_), " @@ -1956,70 +1894,6 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) { return num_field_metadata; } -void MessageGenerator::GenerateFieldDefaultInstances(io::Printer* printer) { - // Construct the default instances for all fields that need one. - for (auto field : FieldRange(descriptor_)) { - field_generators_.get(field).GenerateDefaultInstanceAllocator(printer); - } -} - -void MessageGenerator::GenerateDefaultInstanceInitializer( - io::Printer* printer) { - Formatter format(printer, variables_); - - // The default instance needs all of its embedded message pointers - // cross-linked to other default instances. We can't do this initialization - // in the constructor because some other default instances may not have been - // constructed yet at that time. - // TODO(kenton): Maybe all message fields (even for non-default messages) - // should be initialized to point at default instances rather than NULL? - for (auto field : FieldRange(descriptor_)) { - Formatter::SaveState saver(&format); - - if (!field->is_repeated() && !IsLazy(field, options_) && - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - (field->containing_oneof() == NULL || - HasDescriptorMethods(descriptor_->file(), options_))) { - std::string name; - if (field->containing_oneof() || field->options().weak()) { - name = "_" + classname_ + "_default_instance_."; - } else { - name = - "_" + classname_ + "_default_instance_._instance.get_mutable()->"; - } - name += FieldName(field); - format.Set("name", name); - if (IsWeak(field, options_)) { - format( - "$package_ns$::$name$_ = reinterpret_cast(&$1$);\n" - "if ($package_ns$::$name$_ == nullptr) {\n" - " $package_ns$::$name$_ = " - "::$proto_ns$::Empty::internal_default_instance();\n" - "}\n", - QualifiedDefaultInstanceName(field->message_type(), - options_)); // 1 - continue; - } - if (IsImplicitWeakField(field, options_, scc_analyzer_)) { - format( - "$package_ns$::$name$_ = reinterpret_cast<$1$*>(\n" - " $2$);\n", - FieldMessageTypeName(field, options_), - QualifiedDefaultInstancePtr(field->message_type(), options_)); - } else { - format( - "$package_ns$::$name$_ = const_cast< $1$*>(\n" - " $1$::internal_default_instance());\n", - FieldMessageTypeName(field, options_)); - } - } else if (field->containing_oneof() && - HasDescriptorMethods(descriptor_->file(), options_)) { - field_generators_.get(field).GenerateConstructorCode(printer); - } - } -} - void MessageGenerator::GenerateClassMethods(io::Printer* printer) { Formatter format(printer, variables_); if (IsMapEntryMessage(descriptor_)) { @@ -2045,14 +1919,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { return; } - // TODO(gerbens) Remove this function. With a little bit of cleanup and - // refactoring this is superfluous. - format("void $classname$::InitAsDefaultInstance() {\n"); - format.Indent(); - GenerateDefaultInstanceInitializer(printer); - format.Outdent(); - format("}\n"); - if (IsAnyMessage(descriptor_, options_)) { if (HasDescriptorMethods(descriptor_->file(), options_)) { format( @@ -2065,8 +1931,9 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { "}\n"); } format( - "bool $classname$::ParseAnyTypeUrl(const string& type_url,\n" - " std::string* full_type_name) {\n" + "bool $classname$::ParseAnyTypeUrl(\n" + " ::PROTOBUF_NAMESPACE_ID::ConstStringParam type_url,\n" + " std::string* full_type_name) {\n" " return ::$proto_ns$::internal::ParseAnyTypeUrl(type_url,\n" " full_type_name);\n" "}\n" @@ -2077,16 +1944,18 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { "class $classname$::_Internal {\n" " public:\n"); format.Indent(); - if (HasFieldPresence(descriptor_->file()) && HasBitsSize() != 0) { + if (!has_bit_indices_.empty()) { format( "using HasBits = decltype(std::declval<$classname$>()._has_bits_);\n"); } for (auto field : FieldRange(descriptor_)) { field_generators_.get(field).GenerateInternalAccessorDeclarations(printer); - if (HasFieldPresence(descriptor_->file()) && !field->is_repeated() && - !field->options().weak() && !field->containing_oneof()) { - int has_bit_index = has_bit_indices_[field->index()]; - GOOGLE_CHECK_GE(has_bit_index, 0); + if (IsFieldStripped(field, options_)) { + continue; + } + if (HasHasbit(field)) { + int has_bit_index = HasBitIndex(field); + GOOGLE_CHECK_NE(has_bit_index, kNoHasbit) << field->full_name(); format( "static void set_has_$1$(HasBits* has_bits) {\n" " (*has_bits)[$2$] |= $3$u;\n" @@ -2094,20 +1963,35 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { FieldName(field), has_bit_index / 32, (1u << (has_bit_index % 32))); } } + if (num_required_fields_ > 0) { + const std::vector masks_for_has_bits = RequiredFieldsBitMask(); + format( + "static bool MissingRequiredFields(const HasBits& has_bits) " + "{\n" + " return $1$;\n" + "}\n", + ConditionalToCheckBitmasks(masks_for_has_bits, false, "has_bits")); + } + format.Outdent(); format("};\n\n"); for (auto field : FieldRange(descriptor_)) { - field_generators_.get(field).GenerateInternalAccessorDefinitions(printer); + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GenerateInternalAccessorDefinitions(printer); + } } // Generate non-inline field definitions. for (auto field : FieldRange(descriptor_)) { + if (IsFieldStripped(field, options_)) { + continue; + } field_generators_.get(field).GenerateNonInlineAccessorDefinitions(printer); if (IsCrossFileMaybeMap(field)) { Formatter::SaveState saver(&format); std::map vars; SetCommonFieldVariables(field, &vars, options_); - if (field->containing_oneof()) { + if (field->real_containing_oneof()) { SetCommonOneofFieldVariables(field, &vars); } format.AddMap(vars); @@ -2118,7 +2002,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { GenerateStructors(printer); format("\n"); - if (descriptor_->oneof_decl_count() > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { GenerateOneofClear(printer); format("\n"); } @@ -2139,6 +2023,9 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { GenerateMergeFrom(printer); format("\n"); + GenerateClassSpecificMergeFrom(printer); + format("\n"); + GenerateCopyFrom(printer); format("\n"); @@ -2209,14 +2096,9 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { } processing_type = static_cast(field->type()); - const FieldGenerator& generator = field_generators_.get(field); if (field->type() == FieldDescriptor::TYPE_STRING) { switch (EffectiveStringCType(field, options_)) { case FieldOptions::STRING: - if (generator.IsInlined()) { - processing_type = internal::TYPE_STRING_INLINED; - break; - } break; case FieldOptions::CORD: processing_type = internal::TYPE_STRING_CORD; @@ -2228,10 +2110,6 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { } else if (field->type() == FieldDescriptor::TYPE_BYTES) { switch (EffectiveStringCType(field, options_)) { case FieldOptions::STRING: - if (generator.IsInlined()) { - processing_type = internal::TYPE_BYTES_INLINED; - break; - } break; case FieldOptions::CORD: processing_type = internal::TYPE_BYTES_CORD; @@ -2245,7 +2123,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { processing_type |= static_cast( field->is_repeated() ? internal::kRepeatedMask : 0); processing_type |= static_cast( - field->containing_oneof() ? internal::kOneofMask : 0); + field->real_containing_oneof() ? internal::kOneofMask : 0); if (field->is_map()) { processing_type = internal::TYPE_MAP; @@ -2255,7 +2133,7 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { WireFormat::TagSize(field->number(), field->type()); std::map vars; - if (field->containing_oneof() != NULL) { + if (field->real_containing_oneof()) { vars["name"] = field->containing_oneof()->name(); vars["presence"] = StrCat(field->containing_oneof()->index()); } else { @@ -2290,14 +2168,14 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { std::vector ordered_fields = SortFieldsByNumber(descriptor_); - format("::$proto_ns$::internal::AuxillaryParseTableField(),\n"); + format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n"); int last_field_number = 1; for (auto field : ordered_fields) { Formatter::SaveState saver(&format); GOOGLE_CHECK_GE(field->number(), last_field_number); for (; last_field_number < field->number(); last_field_number++) { - format("::$proto_ns$::internal::AuxillaryParseTableField(),\n"); + format("::$proto_ns$::internal::AuxiliaryParseTableField(),\n"); } std::map vars; @@ -2308,11 +2186,11 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { case FieldDescriptor::CPPTYPE_ENUM: if (HasPreservingUnknownEnumSemantics(field)) { format( - "{::$proto_ns$::internal::AuxillaryParseTableField::enum_aux{" + "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{" "nullptr}},\n"); } else { format( - "{::$proto_ns$::internal::AuxillaryParseTableField::enum_aux{" + "{::$proto_ns$::internal::AuxiliaryParseTableField::enum_aux{" "$1$_IsValid}},\n", ClassName(field->enum_type(), true)); } @@ -2321,7 +2199,7 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { case FieldDescriptor::CPPTYPE_MESSAGE: { if (field->is_map()) { format( - "{::$proto_ns$::internal::AuxillaryParseTableField::map_" + "{::$proto_ns$::internal::AuxiliaryParseTableField::map_" "aux{&::$proto_ns$::internal::ParseMap<$1$>}},\n", QualifiedClassName(field->message_type(), options_)); last_field_number++; @@ -2332,7 +2210,7 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { field->message_type(), options_)); format( - "{::$proto_ns$::internal::AuxillaryParseTableField::message_aux{\n" + "{::$proto_ns$::internal::AuxiliaryParseTableField::message_aux{\n" " &$default_instance$}},\n"); last_field_number++; break; @@ -2355,7 +2233,7 @@ size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { break; } format( - "{::$proto_ns$::internal::AuxillaryParseTableField::string_aux{\n" + "{::$proto_ns$::internal::AuxiliaryParseTableField::string_aux{\n" " $1$,\n" " \"$2$\"\n" "}},\n", @@ -2375,7 +2253,7 @@ std::pair MessageGenerator::GenerateOffsets( io::Printer* printer) { Formatter format(printer, variables_); - if (HasFieldPresence(descriptor_->file()) || IsMapEntryMessage(descriptor_)) { + if (!has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)) { format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); } else { format("~0u, // no _has_bits_\n"); @@ -2386,7 +2264,7 @@ std::pair MessageGenerator::GenerateOffsets( } else { format("~0u, // no _extensions_\n"); } - if (descriptor_->oneof_decl_count() > 0) { + if (descriptor_->real_oneof_decl_count() > 0) { format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n"); } else { format("~0u, // no _oneof_case_\n"); @@ -2398,34 +2276,43 @@ std::pair MessageGenerator::GenerateOffsets( } const int kNumGenericOffsets = 5; // the number of fixed offsets above const size_t offsets = kNumGenericOffsets + descriptor_->field_count() + - descriptor_->oneof_decl_count(); + descriptor_->real_oneof_decl_count(); size_t entries = offsets; for (auto field : FieldRange(descriptor_)) { - if (field->containing_oneof() || field->options().weak()) { - format("offsetof($classtype$DefaultTypeInternal, $1$_)", - FieldName(field)); + if (IsFieldStripped(field, options_)) { + format("~0u, // stripped\n"); + continue; + } + // TODO(sbenza): We should not have an entry in the offset table for fields + // that do not use them. + if (field->options().weak() || field->real_containing_oneof()) { + // Mark the field to prevent unintentional access through reflection. + // Don't use the top bit because that is for unused fields. + format("::$proto_ns$::internal::kInvalidFieldOffsetTag"); } else { format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); } - uint32 tag = field_generators_.get(field).CalculateFieldTag(); - if (tag != 0) { - format(" | $1$", tag); + if (!IsFieldUsed(field, options_)) { + format(" | 0x80000000u, // unused\n"); + } else { + format(",\n"); } - - format(",\n"); } + int count = 0; for (auto oneof : OneOfRange(descriptor_)) { format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_),\n", oneof->name()); + count++; } + GOOGLE_CHECK_EQ(count, descriptor_->real_oneof_decl_count()); if (IsMapEntryMessage(descriptor_)) { entries += 2; format( "0,\n" "1,\n"); - } else if (HasFieldPresence(descriptor_->file())) { + } else if (!has_bit_indices_.empty()) { entries += has_bit_indices_.size(); for (int i = 0; i < has_bit_indices_.size(); i++) { const std::string index = @@ -2464,9 +2351,7 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { format("void $classname$::SharedDtor() {\n"); format.Indent(); - if (SupportsArenas(descriptor_)) { - format("$DCHK$(GetArenaNoVirtual() == nullptr);\n"); - } + format("$DCHK$(GetArena() == nullptr);\n"); // Write the destructors for each field except oneof members. // optimized_order_ does not contain oneof fields. for (auto field : optimized_order_) { @@ -2522,7 +2407,8 @@ void MessageGenerator::GenerateArenaDestructorCode(io::Printer* printer) { // and returns false for oneof fields. for (auto oneof : OneOfRange(descriptor_)) { for (auto field : FieldRange(oneof)) { - if (field_generators_.get(field).GenerateArenaDestructorCode(printer)) { + if (!IsFieldStripped(field, options_) && + field_generators_.get(field).GenerateArenaDestructorCode(printer)) { need_registration = true; } } @@ -2556,25 +2442,13 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, std::vector processed, bool copy_constructor) const { Formatter format(printer, variables_); - const FieldDescriptor* last_start = NULL; - // RunMap maps from fields that start each run to the number of fields in that - // run. This is optimized for the common case that there are very few runs in - // a message and that most of the eligible fields appear together. - typedef std::unordered_map RunMap; - RunMap runs; - for (auto field : optimized_order_) { - if ((copy_constructor && IsPOD(field)) || - (!copy_constructor && CanConstructByZeroing(field, options_))) { - if (last_start == NULL) { - last_start = field; - } - - runs[last_start]++; - } else { - last_start = NULL; - } - } + const RunMap runs = FindRuns( + optimized_order_, [copy_constructor, this](const FieldDescriptor* field) { + return (copy_constructor && IsPOD(field)) || + (!copy_constructor && + CanBeManipulatedAsRawBytes(field, options_)); + }); std::string pod_template; if (copy_constructor) { @@ -2584,8 +2458,10 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; } else { pod_template = - "::memset(&$first$_, 0, static_cast(\n" - " reinterpret_cast(&$last$_) -\n" + "::memset(reinterpret_cast(this) + static_cast(\n" + " reinterpret_cast(&$first$_) - " + "reinterpret_cast(this)),\n" + " 0, static_cast(reinterpret_cast(&$last$_) -\n" " reinterpret_cast(&$first$_)) + sizeof($last$_));\n"; } @@ -2595,7 +2471,7 @@ void MessageGenerator::GenerateConstructorBody(io::Printer* printer, } const FieldDescriptor* field = optimized_order_[i]; - RunMap::const_iterator it = runs.find(field); + const auto it = runs.find(field); // We only apply the memset technique to runs of more than one field, as // assignment is better than memset for generated code clarity. @@ -2628,18 +2504,17 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { std::string superclass; superclass = SuperClassName(descriptor_, options_); - std::string initializer_with_arena = superclass + "()"; + std::string initializer_with_arena = superclass + "(arena)"; if (descriptor_->extension_range_count() > 0) { initializer_with_arena += ",\n _extensions_(arena)"; } - initializer_with_arena += ",\n _internal_metadata_(arena)"; - // Initialize member variables with arena constructor. for (auto field : optimized_order_) { + GOOGLE_DCHECK(!IsFieldStripped(field, options_)); bool has_arena_constructor = field->is_repeated(); - if (field->containing_oneof() == NULL && + if (!field->real_containing_oneof() && (IsLazy(field, options_) || IsStringPiece(field, options_))) { has_arena_constructor = true; } @@ -2656,8 +2531,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { initializer_with_arena += ", _weak_field_map_(arena)"; } - std::string initializer_null = - superclass + "(), _internal_metadata_(nullptr)"; + std::string initializer_null = superclass + "()"; if (IsAnyMessage(descriptor_, options_)) { initializer_null += ", _any_metadata_(&type_url_, &value_)"; } @@ -2666,23 +2540,17 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { } format( - "$classname$::$classname$()\n" + "$classname$::$classname$(::$proto_ns$::Arena* arena)\n" " : $1$ {\n" " SharedCtor();\n" - " // @@protoc_insertion_point(constructor:$full_name$)\n" + " RegisterArenaDtor(arena);\n" + " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" "}\n", - initializer_null); + initializer_with_arena); - if (SupportsArenas(descriptor_)) { - format( - "$classname$::$classname$(::$proto_ns$::Arena* arena)\n" - " : $1$ {\n" - " SharedCtor();\n" - " RegisterArenaDtor(arena);\n" - " // @@protoc_insertion_point(arena_constructor:$full_name$)\n" - "}\n", - initializer_with_arena); - } + std::map vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + format.AddMap(vars); // Generate the copy constructor. if (UsingImplicitWeakFields(descriptor_->file(), options_)) { @@ -2702,12 +2570,9 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { format.Indent(); format.Indent(); format.Indent(); - format(",\n_internal_metadata_(nullptr)"); - if (HasFieldPresence(descriptor_->file())) { - if (!IsProto2MessageSet(descriptor_, options_)) { - format(",\n_has_bits_(from._has_bits_)"); - } + if (!has_bit_indices_.empty()) { + format(",\n_has_bits_(from._has_bits_)"); } std::vector processed(optimized_order_.size(), false); @@ -2733,7 +2598,9 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { format.Outdent(); format(" {\n"); - format("_internal_metadata_.MergeFrom(from._internal_metadata_);\n"); + format( + "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_" + "metadata_);\n"); if (descriptor_->extension_range_count() > 0) { format("_extensions_.MergeFrom(from._extensions_);\n"); @@ -2751,7 +2618,9 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { for (auto field : FieldRange(oneof)) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - field_generators_.get(field).GenerateMergingCode(printer); + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GenerateMergingCode(printer); + } format("break;\n"); format.Outdent(); format("}\n"); @@ -2780,6 +2649,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { "$classname$::~$classname$() {\n" " // @@protoc_insertion_point(destructor:$full_name$)\n" " SharedDtor();\n" + " _internal_metadata_.Delete<$unknown_fields_type$>();\n" "}\n" "\n"); @@ -2787,9 +2657,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { GenerateSharedDestructorCode(printer); // Generate the arena-specific destructor code. - if (SupportsArenas(descriptor_)) { - GenerateArenaDestructorCode(printer); - } + GenerateArenaDestructorCode(printer); // Generate SetCachedSize. format( @@ -2812,14 +2680,15 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* printer) { "template<> " "PROTOBUF_NOINLINE " "$classtype$* Arena::CreateMaybeMessage< $classtype$ >(Arena* arena) {\n" - " return Arena::$1$Internal< $classtype$ >(arena);\n" - "}\n", - MessageCreateFunction(descriptor_)); + " return Arena::CreateMessageInternal< $classtype$ >(arena);\n" + "}\n"); } void MessageGenerator::GenerateClear(io::Printer* printer) { Formatter format(printer, variables_); - // Performance tuning parameters + + // The maximum number of bytes we will memset to zero without checking their + // hasbit to see if a zero-init is necessary. const int kMaxUnconditionalPrimitiveBytesClear = 4; format( @@ -2834,162 +2703,118 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { "// Prevent compiler warnings about cached_has_bits being unused\n" "(void) cached_has_bits;\n\n"); - int cached_has_bit_index = -1; - - // Step 1: Extensions if (descriptor_->extension_range_count() > 0) { format("_extensions_.Clear();\n"); } - int unconditional_budget = kMaxUnconditionalPrimitiveBytesClear; - for (int i = 0; i < optimized_order_.size(); i++) { - const FieldDescriptor* field = optimized_order_[i]; - - if (!CanInitializeByZeroing(field)) { - continue; + // Collect fields into chunks. Each chunk may have an if() condition that + // checks all hasbits in the chunk and skips it if none are set. + int zero_init_bytes = 0; + for (const auto& field : optimized_order_) { + if (CanInitializeByZeroing(field)) { + zero_init_bytes += EstimateAlignmentSize(field); } - - unconditional_budget -= EstimateAlignmentSize(field); } + bool merge_zero_init = zero_init_bytes > kMaxUnconditionalPrimitiveBytesClear; + int chunk_count = 0; - std::vector> chunks_frag = CollectFields( + std::vector> chunks = CollectFields( optimized_order_, - MatchRepeatedAndHasByteAndZeroInits( - &has_bit_indices_, HasFieldPresence(descriptor_->file()))); + [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool { + chunk_count++; + // This predicate guarantees that there is only a single zero-init + // (memset) per chunk, and if present it will be at the beginning. + bool same = HasByteIndex(a) == HasByteIndex(b) && + a->is_repeated() == b->is_repeated() && + (CanInitializeByZeroing(a) == CanInitializeByZeroing(b) || + (CanInitializeByZeroing(a) && + (chunk_count == 1 || merge_zero_init))); + if (!same) chunk_count = 0; + return same; + }); + + ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio); + int cached_has_word_index = -1; - // Merge next non-zero initializable chunk if it has the same has_byte index - // and not meeting unconditional clear condition. - std::vector> chunks; - if (!HasFieldPresence(descriptor_->file())) { - // Don't bother with merging without has_bit field. - chunks = chunks_frag; - } else { - // Note that only the next chunk is considered for merging. - for (int i = 0; i < chunks_frag.size(); i++) { - chunks.push_back(chunks_frag[i]); - const FieldDescriptor* field = chunks_frag[i].front(); - const FieldDescriptor* next_field = - (i + 1) < chunks_frag.size() ? chunks_frag[i + 1].front() : nullptr; - if (CanInitializeByZeroing(field) && - (chunks_frag[i].size() == 1 || unconditional_budget < 0) && - next_field != nullptr && - has_bit_indices_[field->index()] / 8 == - has_bit_indices_[next_field->index()] / 8) { - GOOGLE_CHECK(!CanInitializeByZeroing(next_field)); - // Insert next chunk to the current one and skip next chunk. - chunks.back().insert(chunks.back().end(), chunks_frag[i + 1].begin(), - chunks_frag[i + 1].end()); - i++; - } - } - } - - ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio, - HasFieldPresence(descriptor_->file())); for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) { std::vector& chunk = chunks[chunk_index]; - GOOGLE_CHECK(!chunk.empty()); + cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer); - // Step 2: Repeated fields don't use _has_bits_; emit code to clear them - // here. - if (chunk.front()->is_repeated()) { - for (int i = 0; i < chunk.size(); i++) { - const FieldDescriptor* field = chunk[i]; - const FieldGenerator& generator = field_generators_.get(field); + const FieldDescriptor* memset_start = nullptr; + const FieldDescriptor* memset_end = nullptr; + bool saw_non_zero_init = false; - generator.GenerateMessageClearingCode(printer); - } - continue; - } - - cold_skipper.OnStartChunk(chunk_index, cached_has_bit_index, "", printer); - - // Step 3: Non-repeated fields that can be cleared by memset-to-0, then - // non-repeated, non-zero initializable fields. - int last_chunk = HasFieldPresence(descriptor_->file()) - ? has_bit_indices_[chunk.front()->index()] / 8 - : 0; - int last_chunk_start = 0; - int memset_run_start = -1; - int memset_run_end = -1; - - for (int i = 0; i < chunk.size(); i++) { - const FieldDescriptor* field = chunk[i]; + for (const auto& field : chunk) { if (CanInitializeByZeroing(field)) { - if (memset_run_start == -1) { - memset_run_start = i; - } - memset_run_end = i; + GOOGLE_CHECK(!saw_non_zero_init); + if (!memset_start) memset_start = field; + memset_end = field; + } else { + saw_non_zero_init = true; } } - const bool have_outer_if = - HasFieldPresence(descriptor_->file()) && chunk.size() > 1 && - (memset_run_end != chunk.size() - 1 || unconditional_budget < 0); + // Whether we wrap this chunk in: + // if (cached_has_bits & 1 && + (memset_end != chunk.back() || merge_zero_init); if (have_outer_if) { - uint32 last_chunk_mask = GenChunkMask(chunk, has_bit_indices_); - const int count = popcnt(last_chunk_mask); + // Emit an if() that will let us skip the whole chunk if none are set. + uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_); + std::string chunk_mask_str = + StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8)); // Check (up to) 8 has_bits at a time if we have more than one field in // this chunk. Due to field layout ordering, we may check // _has_bits_[last_chunk * 8 / 32] multiple times. - GOOGLE_DCHECK_LE(2, count); - GOOGLE_DCHECK_GE(8, count); + GOOGLE_DCHECK_LE(2, popcnt(chunk_mask)); + GOOGLE_DCHECK_GE(8, popcnt(chunk_mask)); - if (cached_has_bit_index != last_chunk / 4) { - cached_has_bit_index = last_chunk / 4; - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_bit_index); + if (cached_has_word_index != HasWordIndex(chunk.front())) { + cached_has_word_index = HasWordIndex(chunk.front()); + format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); } - format("if (cached_has_bits & 0x$1$u) {\n", - StrCat(strings::Hex(last_chunk_mask, strings::ZERO_PAD_8))); + format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); } - if (memset_run_start != -1) { - if (memset_run_start == memset_run_end) { + if (memset_start) { + if (memset_start == memset_end) { // For clarity, do not memset a single field. - const FieldGenerator& generator = - field_generators_.get(chunk[memset_run_start]); - generator.GenerateMessageClearingCode(printer); + field_generators_.get(memset_start) + .GenerateMessageClearingCode(printer); } else { - const std::string first_field_name = FieldName(chunk[memset_run_start]); - const std::string last_field_name = FieldName(chunk[memset_run_end]); - format( "::memset(&$1$_, 0, static_cast(\n" " reinterpret_cast(&$2$_) -\n" " reinterpret_cast(&$1$_)) + sizeof($2$_));\n", - first_field_name, last_field_name); + FieldName(memset_start), FieldName(memset_end)); } - - // Advance last_chunk_start to skip over the fields we zeroed/memset. - last_chunk_start = memset_run_end + 1; } - // Go back and emit clears for each of the fields we processed. - for (int j = last_chunk_start; j < chunk.size(); j++) { - const FieldDescriptor* field = chunk[j]; - const FieldGenerator& generator = field_generators_.get(field); - + // Clear all non-zero-initializable fields in the chunk. + for (const auto& field : chunk) { + if (CanInitializeByZeroing(field)) continue; // It's faster to just overwrite primitive types, but we should only // clear strings and messages if they were set. // // TODO(kenton): Let the CppFieldGenerator decide this somehow. - bool should_check_bit = - field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || - field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; + bool have_enclosing_if = + HasBitIndex(field) != kNoHasbit && + (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || + field->cpp_type() == FieldDescriptor::CPPTYPE_STRING); - bool have_enclosing_if = false; - if (should_check_bit && - // If no field presence, then always clear strings/messages as well. - HasFieldPresence(descriptor_->file())) { + if (have_enclosing_if) { PrintPresenceCheck(format, field, has_bit_indices_, printer, - &cached_has_bit_index); - have_enclosing_if = true; + &cached_has_word_index); } - generator.GenerateMessageClearingCode(printer); + field_generators_.get(field).GenerateMessageClearingCode(printer); if (have_enclosing_if) { format.Outdent(); @@ -3004,7 +2829,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { if (cold_skipper.OnEndChunk(chunk_index, printer)) { // Reset here as it may have been updated in just closed if statement. - cached_has_bit_index = -1; + cached_has_word_index = -1; } } @@ -3017,12 +2842,15 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { format("_weak_field_map_.ClearAll();\n"); } - if (HasFieldPresence(descriptor_->file())) { + if (!has_bit_indices_.empty()) { // Step 5: Everything else. format("_has_bits_.Clear();\n"); } - format("_internal_metadata_.Clear();\n"); + std::map vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + format.AddMap(vars); + format("_internal_metadata_.Clear<$unknown_fields_type$>();\n"); format.Outdent(); format("}\n"); @@ -3030,8 +2858,8 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { void MessageGenerator::GenerateOneofClear(io::Printer* printer) { // Generated function clears the active field and union case (e.g. foo_case_). - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - auto oneof = descriptor_->oneof_decl(i); + int i = 0; + for (auto oneof : OneOfRange(descriptor_)) { Formatter format(printer, variables_); format.Set("oneofname", oneof->name()); @@ -3045,7 +2873,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); // We clear only allocated objects in oneofs - if (!IsStringOrMessage(field)) { + if (!IsStringOrMessage(field) || IsFieldStripped(field, options_)) { format("// No need to clear\n"); } else { field_generators_.get(field).GenerateClearingCode(printer); @@ -3068,6 +2896,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { format( "}\n" "\n"); + i++; } } @@ -3083,26 +2912,62 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { format("_extensions_.Swap(&other->_extensions_);\n"); } - format("_internal_metadata_.Swap(&other->_internal_metadata_);\n"); + std::map vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + format.AddMap(vars); + format( + "_internal_metadata_.Swap<$unknown_fields_type$>(&other->_internal_" + "metadata_);\n"); - if (HasFieldPresence(descriptor_->file())) { - for (int i = 0; i < HasBitsSize() / 4; ++i) { + if (!has_bit_indices_.empty()) { + for (int i = 0; i < HasBitsSize(); ++i) { format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i); } } - for (int i = 0; i < optimized_order_.size(); i++) { - // optimized_order_ does not contain oneof fields, but the field - // generators for these fields do not emit swapping code on their own. + // If possible, we swap several fields at once, including padding. + const RunMap runs = + FindRuns(optimized_order_, [this](const FieldDescriptor* field) { + return CanBeManipulatedAsRawBytes(field, options_); + }); + + for (int i = 0; i < optimized_order_.size(); ++i) { const FieldDescriptor* field = optimized_order_[i]; - field_generators_.get(field).GenerateSwappingCode(printer); + const auto it = runs.find(field); + + // We only apply the memswap technique to runs of more than one field, as + // `swap(field_, other.field_)` is better than + // `memswap<...>(&field_, &other.field_)` for generated code readability. + if (it != runs.end() && it->second > 1) { + // Use a memswap, then skip run_length fields. + const size_t run_length = it->second; + const std::string first_field_name = FieldName(field); + const std::string last_field_name = + FieldName(optimized_order_[i + run_length - 1]); + + format.Set("first", first_field_name); + format.Set("last", last_field_name); + + format( + "::PROTOBUF_NAMESPACE_ID::internal::memswap<\n" + " PROTOBUF_FIELD_OFFSET($classname$, $last$_)\n" + " + sizeof($classname$::$last$_)\n" + " - PROTOBUF_FIELD_OFFSET($classname$, $first$_)>(\n" + " reinterpret_cast(&$first$_),\n" + " reinterpret_cast(&other->$first$_));\n"); + + i += run_length - 1; + // ++i at the top of the loop. + } else { + field_generators_.get(field).GenerateSwappingCode(printer); + } } for (auto oneof : OneOfRange(descriptor_)) { format("swap($1$_, other->$1$_);\n", oneof->name()); } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i); } @@ -3148,7 +3013,7 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { "}\n"); format.Outdent(); - format("}\n\n"); + format("}\n"); } else { // Generate CheckTypeAndMergeFrom(). format( @@ -3156,11 +3021,13 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { " const ::$proto_ns$::MessageLite& from) {\n" " MergeFrom(*::$proto_ns$::internal::DownCast(\n" " &from));\n" - "}\n" - "\n"); + "}\n"); } +} +void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast. + Formatter format(printer, variables_); format( "void $classname$::MergeFrom(const $classname$& from) {\n" "// @@protoc_insertion_point(class_specific_merge_from_start:" @@ -3171,91 +3038,94 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format("_extensions_.MergeFrom(from._extensions_);\n"); } - + std::map vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + format.AddMap(vars); format( - "_internal_metadata_.MergeFrom(from._internal_metadata_);\n" + "_internal_metadata_.MergeFrom<$unknown_fields_type$>(from._internal_" + "metadata_);\n" "$uint32$ cached_has_bits = 0;\n" "(void) cached_has_bits;\n\n"); - if (HasFieldPresence(descriptor_->file())) { - std::vector> chunks = CollectFields( - optimized_order_, MatchRepeatedAndHasByte(&has_bit_indices_, true)); - - ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, - kColdRatio, true); + std::vector> chunks = CollectFields( + optimized_order_, + [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool { + return HasByteIndex(a) == HasByteIndex(b); + }); - // cached_has_bit_index maintains that: - // cached_has_bits = from._has_bits_[cached_has_bit_index] - // for cached_has_bit_index >= 0 - int cached_has_bit_index = -1; + ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio); - for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) { - const std::vector& chunk = chunks[chunk_index]; - GOOGLE_CHECK(!chunk.empty()); + // cached_has_word_index maintains that: + // cached_has_bits = from._has_bits_[cached_has_word_index] + // for cached_has_word_index >= 0 + int cached_has_word_index = -1; - // Merge Repeated fields. These fields do not require a - // check as we can simply iterate over them. - if (chunk.front()->is_repeated()) { - for (int i = 0; i < chunk.size(); i++) { - const FieldDescriptor* field = chunk[i]; + for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) { + const std::vector& chunk = chunks[chunk_index]; + bool have_outer_if = + chunk.size() > 1 && HasByteIndex(chunk.front()) != kNoHasbit; + cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "from.", + printer); - const FieldGenerator& generator = field_generators_.get(field); - generator.GenerateMergingCode(printer); - } - continue; - } + if (have_outer_if) { + // Emit an if() that will let us skip the whole chunk if none are set. + uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_); + std::string chunk_mask_str = + StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8)); - // Merge Optional and Required fields (after a _has_bit_ check). - cold_skipper.OnStartChunk(chunk_index, cached_has_bit_index, "from.", - printer); + // Check (up to) 8 has_bits at a time if we have more than one field in + // this chunk. Due to field layout ordering, we may check + // _has_bits_[last_chunk * 8 / 32] multiple times. + GOOGLE_DCHECK_LE(2, popcnt(chunk_mask)); + GOOGLE_DCHECK_GE(8, popcnt(chunk_mask)); - int last_chunk = has_bit_indices_[chunk.front()->index()] / 8; - GOOGLE_DCHECK_NE(-1, last_chunk); + if (cached_has_word_index != HasWordIndex(chunk.front())) { + cached_has_word_index = HasWordIndex(chunk.front()); + format("cached_has_bits = from._has_bits_[$1$];\n", + cached_has_word_index); + } - const bool have_outer_if = chunk.size() > 1; - if (have_outer_if) { - uint32 last_chunk_mask = GenChunkMask(chunk, has_bit_indices_); - const int count = popcnt(last_chunk_mask); + format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); + format.Indent(); + } - // Check (up to) 8 has_bits at a time if we have more than one field in - // this chunk. Due to field layout ordering, we may check - // _has_bits_[last_chunk * 8 / 32] multiple times. - GOOGLE_DCHECK_LE(2, count); - GOOGLE_DCHECK_GE(8, count); + // Go back and emit merging code for each of the fields we processed. + bool deferred_has_bit_changes = false; + for (const auto field : chunk) { + const FieldGenerator& generator = field_generators_.get(field); - if (cached_has_bit_index != last_chunk / 4) { - cached_has_bit_index = last_chunk / 4; - format("cached_has_bits = from._has_bits_[$1$];\n", - cached_has_bit_index); + if (field->is_repeated()) { + generator.GenerateMergingCode(printer); + } else if (field->is_optional() && !HasHasbit(field)) { + // Merge semantics without true field presence: primitive fields are + // merged only if non-zero (numeric) or non-empty (string). + bool have_enclosing_if = + EmitFieldNonDefaultCondition(printer, "from.", field); + generator.GenerateMergingCode(printer); + if (have_enclosing_if) { + format.Outdent(); + format("}\n"); } - format("if (cached_has_bits & 0x$1$u) {\n", - StrCat(strings::Hex(last_chunk_mask, strings::ZERO_PAD_8))); + } else if (field->options().weak() || + cached_has_word_index != HasWordIndex(field)) { + // Check hasbit, not using cached bits. + GOOGLE_CHECK(HasHasbit(field)); + format("if (from._internal_has_$1$()) {\n", FieldName(field)); format.Indent(); - } - - // Go back and emit merging code for each of the fields we processed. - bool deferred_has_bit_changes = false; - for (const auto field : chunk) { - const FieldGenerator& generator = field_generators_.get(field); - - // Attempt to use the state of cached_has_bits, if possible. + generator.GenerateMergingCode(printer); + format.Outdent(); + format("}\n"); + } else { + // Check hasbit, using cached bits. + GOOGLE_CHECK(HasHasbit(field)); int has_bit_index = has_bit_indices_[field->index()]; - if (!field->options().weak() && - cached_has_bit_index == has_bit_index / 32) { - const std::string mask = StrCat( - strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); - - format("if (cached_has_bits & 0x$1$u) {\n", mask); - } else { - format("if (from._internal_has_$1$()) {\n", FieldName(field)); - } + const std::string mask = StrCat( + strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); + format("if (cached_has_bits & 0x$1$u) {\n", mask); format.Indent(); if (have_outer_if && IsPOD(field)) { - // GenerateCopyConstructorCode for enum and primitive scalar fields - // does not do _has_bits_ modifications. We defer _has_bits_ - // manipulation until the end of the outer if. - // + // Defer hasbit modification until the end of chunk. // This can reduce the number of loads/stores by up to 7 per 8 fields. deferred_has_bit_changes = true; generator.GenerateCopyConstructorCode(printer); @@ -3266,38 +3136,22 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { format.Outdent(); format("}\n"); } + } - if (have_outer_if) { - if (deferred_has_bit_changes) { - // Flush the has bits for the primitives we deferred. - GOOGLE_CHECK_LE(0, cached_has_bit_index); - format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_bit_index); - } - - format.Outdent(); - format("}\n"); + if (have_outer_if) { + if (deferred_has_bit_changes) { + // Flush the has bits for the primitives we deferred. + GOOGLE_CHECK_LE(0, cached_has_word_index); + format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index); } - if (cold_skipper.OnEndChunk(chunk_index, printer)) { - // Reset here as it may have been updated in just closed if statement. - cached_has_bit_index = -1; - } + format.Outdent(); + format("}\n"); } - } else { - // proto3 - for (const auto field : optimized_order_) { - const FieldGenerator& generator = field_generators_.get(field); - // Merge semantics without true field presence: primitive fields are - // merged only if non-zero (numeric) or non-empty (string). - bool have_enclosing_if = - EmitFieldNonDefaultCondition(printer, "from.", field); - generator.GenerateMergingCode(printer); - - if (have_enclosing_if) { - format.Outdent(); - format("}\n"); - } + if (cold_skipper.OnEndChunk(chunk_index, printer)) { + // Reset here as it may have been updated in just closed if statement. + cached_has_word_index = -1; } } @@ -3308,7 +3162,9 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* printer) { for (auto field : FieldRange(oneof)) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - field_generators_.get(field).GenerateMergingCode(printer); + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GenerateMergingCode(printer); + } format("break;\n"); format.Outdent(); format("}\n"); @@ -3455,9 +3311,9 @@ void MessageGenerator::GenerateSerializeOneField(io::Printer* printer, bool have_enclosing_if = false; if (field->options().weak()) { - } else if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) { + } else if (HasHasbit(field)) { // Attempt to use the state of cached_has_bits, if possible. - int has_bit_index = has_bit_indices_[field->index()]; + int has_bit_index = HasBitIndex(field); if (cached_has_bits_index == has_bit_index / 32) { const std::string mask = StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); @@ -3469,7 +3325,7 @@ void MessageGenerator::GenerateSerializeOneField(io::Printer* printer, format.Indent(); have_enclosing_if = true; - } else if (!HasFieldPresence(descriptor_->file())) { + } else if (field->is_optional() && !HasHasbit(field)) { have_enclosing_if = EmitFieldNonDefaultCondition(printer, "this->", field); } @@ -3526,8 +3382,26 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray( format("// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n"); + if (!ShouldSerializeInOrder(descriptor_, options_)) { + format.Outdent(); + format("#ifdef NDEBUG\n"); + format.Indent(); + } + GenerateSerializeWithCachedSizesBody(printer); + if (!ShouldSerializeInOrder(descriptor_, options_)) { + format.Outdent(); + format("#else // NDEBUG\n"); + format.Indent(); + + GenerateSerializeWithCachedSizesBodyShuffled(printer); + + format.Outdent(); + format("#endif // !NDEBUG\n"); + format.Indent(); + } + format("// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n"); format.Outdent(); @@ -3550,7 +3424,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( : mg_(mg), format_(printer), eager_(!HasFieldPresence(mg->descriptor_->file())), - cached_has_bit_index_(-1) {} + cached_has_bit_index_(kNoHasbit) {} ~LazySerializerEmitter() { Flush(); } @@ -3560,7 +3434,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( if (eager_ || MustFlush(field)) { Flush(); } - if (field->containing_oneof() == NULL) { + if (!field->real_containing_oneof()) { // TODO(ckennelly): Defer non-oneof fields similarly to oneof fields. if (!field->options().weak() && !field->is_repeated() && !eager_) { @@ -3642,8 +3516,14 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( (i < descriptor_->field_count() && ordered_fields[i]->number() < sorted_extensions[j]->start)) { const FieldDescriptor* field = ordered_fields[i++]; + if (IsFieldStripped(field, options_)) { + continue; + } if (field->options().weak()) { - last_weak_field = field; + if (last_weak_field == nullptr || + last_weak_field->number() < field->number()) { + last_weak_field = field; + } PrintFieldComment(format, field); } else { if (last_weak_field != nullptr) { @@ -3686,6 +3566,98 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( format("}\n"); } +void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( + io::Printer* printer) { + Formatter format(printer, variables_); + + std::vector ordered_fields = + SortFieldsByNumber(descriptor_); + ordered_fields.erase( + std::remove_if(ordered_fields.begin(), ordered_fields.end(), + [this](const FieldDescriptor* f) { + return !IsFieldUsed(f, options_); + }), + ordered_fields.end()); + + std::vector sorted_extensions; + sorted_extensions.reserve(descriptor_->extension_range_count()); + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeSorter()); + + int num_fields = ordered_fields.size() + sorted_extensions.size(); + constexpr int kLargePrime = 1000003; + GOOGLE_CHECK_LT(num_fields, kLargePrime) + << "Prime offset must be greater than the number of fields to ensure " + "those are coprime."; + + if (num_weak_fields_) { + format( + "::$proto_ns$::internal::WeakFieldMap::FieldWriter field_writer(" + "_weak_field_map_);\n"); + } + + format("for (int i = $1$; i >= 0; i-- ) {\n", num_fields - 1); + + format.Indent(); + format("switch(i) {\n"); + format.Indent(); + + int index = 0; + for (const auto* f : ordered_fields) { + format("case $1$: {\n", index++); + format.Indent(); + + GenerateSerializeOneField(printer, f, -1); + + format("break;\n"); + format.Outdent(); + format("}\n"); + } + + for (const auto* r : sorted_extensions) { + format("case $1$: {\n", index++); + format.Indent(); + + GenerateSerializeOneExtensionRange(printer, r); + + format("break;\n"); + format.Outdent(); + format("}\n"); + } + + format( + "default: {\n" + " $DCHK$(false) << \"Unexpected index: \" << i;\n" + "}\n"); + format.Outdent(); + format("}\n"); + + format.Outdent(); + format("}\n"); + + std::map vars; + SetUnknkownFieldsVariable(descriptor_, options_, &vars); + format.AddMap(vars); + format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); + format.Indent(); + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + format( + "target = " + "::$proto_ns$::internal::WireFormat::" + "InternalSerializeUnknownFieldsToArray(\n" + " $unknown_fields$, target, stream);\n"); + } else { + format( + "target = stream->WriteRaw($unknown_fields$.data(),\n" + " static_cast($unknown_fields$.size()), target);\n"); + } + format.Outdent(); + format("}\n"); +} + std::vector MessageGenerator::RequiredFieldsBitMask() const { const int array_size = HasBitsSize(); std::vector masks(array_size, 0); @@ -3701,29 +3673,6 @@ std::vector MessageGenerator::RequiredFieldsBitMask() const { return masks; } -// Create an expression that evaluates to -// "for all i, (_has_bits_[i] & masks[i]) == masks[i]" -// masks is allowed to be shorter than _has_bits_, but at least one element of -// masks must be non-zero. -static std::string ConditionalToCheckBitmasks( - const std::vector& masks) { - std::vector parts; - for (int i = 0; i < masks.size(); i++) { - if (masks[i] == 0) continue; - std::string m = StrCat("0x", strings::Hex(masks[i], strings::ZERO_PAD_8)); - // Each xor evaluates to 0 if the expected bits are present. - parts.push_back( - StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")")); - } - GOOGLE_CHECK(!parts.empty()); - // If we have multiple parts, each expected to be 0, then bitwise-or them. - std::string result = - parts.size() == 1 - ? parts[0] - : StrCat("(", Join(parts, "\n | "), ")"); - return result + " == 0"; -} - void MessageGenerator::GenerateByteSize(io::Printer* printer) { Formatter format(printer, variables_); @@ -3748,7 +3697,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { return; } - if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) { + if (num_required_fields_ > 1) { // Emit a function (rarely used, we hope) that handles the required fields // by checking for each one individually. format( @@ -3798,7 +3747,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { // Handle required fields (if any). We expect all of them to be // present, so emit one conditional that checks for that. If they are all // present then the fast path executes; otherwise the slow path executes. - if (num_required_fields_ > 1 && HasFieldPresence(descriptor_->file())) { + if (num_required_fields_ > 1) { // The fast path works if all required fields are present. const std::vector masks_for_has_bits = RequiredFieldsBitMask(); format("if ($1$) { // All required fields are present.\n", @@ -3832,75 +3781,45 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { std::vector> chunks = CollectFields( optimized_order_, - MatchRepeatedAndHasByteAndRequired( - &has_bit_indices_, HasFieldPresence(descriptor_->file()))); + [&](const FieldDescriptor* a, const FieldDescriptor* b) -> bool { + return a->label() == b->label() && HasByteIndex(a) == HasByteIndex(b); + }); // Remove chunks with required fields. chunks.erase(std::remove_if(chunks.begin(), chunks.end(), IsRequired), chunks.end()); - ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio, - HasFieldPresence(descriptor_->file())); + ColdChunkSkipper cold_skipper(options_, chunks, has_bit_indices_, kColdRatio); + int cached_has_word_index = -1; format( "$uint32$ cached_has_bits = 0;\n" "// Prevent compiler warnings about cached_has_bits being unused\n" "(void) cached_has_bits;\n\n"); - int cached_has_bit_index = -1; - for (int chunk_index = 0; chunk_index < chunks.size(); chunk_index++) { const std::vector& chunk = chunks[chunk_index]; - GOOGLE_CHECK(!chunk.empty()); - - // Handle repeated fields. - if (chunk.front()->is_repeated()) { - for (int i = 0; i < chunk.size(); i++) { - const FieldDescriptor* field = chunk[i]; - - PrintFieldComment(format, field); - const FieldGenerator& generator = field_generators_.get(field); - generator.GenerateByteSize(printer); - format("\n"); - } - continue; - } - - cold_skipper.OnStartChunk(chunk_index, cached_has_bit_index, "", printer); - - // Handle optional (non-repeated/oneof) fields. - // - // These are handled in chunks of 8. The first chunk is - // the non-requireds-non-repeateds-non-unions-non-extensions in - // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7), - // and the second chunk is the same for - // descriptor_->field(8), descriptor_->field(9), ... - // descriptor_->field(15), - // etc. - int last_chunk = HasFieldPresence(descriptor_->file()) - ? has_bit_indices_[chunk.front()->index()] / 8 - : 0; - GOOGLE_DCHECK_NE(-1, last_chunk); - const bool have_outer_if = - HasFieldPresence(descriptor_->file()) && chunk.size() > 1; + chunk.size() > 1 && HasWordIndex(chunk[0]) != kNoHasbit; + cold_skipper.OnStartChunk(chunk_index, cached_has_word_index, "", printer); if (have_outer_if) { - uint32 last_chunk_mask = GenChunkMask(chunk, has_bit_indices_); - const int count = popcnt(last_chunk_mask); + // Emit an if() that will let us skip the whole chunk if none are set. + uint32 chunk_mask = GenChunkMask(chunk, has_bit_indices_); + std::string chunk_mask_str = + StrCat(strings::Hex(chunk_mask, strings::ZERO_PAD_8)); // Check (up to) 8 has_bits at a time if we have more than one field in // this chunk. Due to field layout ordering, we may check // _has_bits_[last_chunk * 8 / 32] multiple times. - GOOGLE_DCHECK_LE(2, count); - GOOGLE_DCHECK_GE(8, count); + GOOGLE_DCHECK_LE(2, popcnt(chunk_mask)); + GOOGLE_DCHECK_GE(8, popcnt(chunk_mask)); - if (cached_has_bit_index != last_chunk / 4) { - cached_has_bit_index = last_chunk / 4; - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_bit_index); + if (cached_has_word_index != HasWordIndex(chunk.front())) { + cached_has_word_index = HasWordIndex(chunk.front()); + format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); } - format("if (cached_has_bits & 0x$1$u) {\n", - StrCat(strings::Hex(last_chunk_mask, strings::ZERO_PAD_8))); + format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); } @@ -3908,13 +3827,17 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { for (int j = 0; j < chunk.size(); j++) { const FieldDescriptor* field = chunk[j]; const FieldGenerator& generator = field_generators_.get(field); + bool have_enclosing_if = false; + bool need_extra_newline = false; PrintFieldComment(format, field); - bool have_enclosing_if = false; - if (HasFieldPresence(descriptor_->file())) { + if (field->is_repeated()) { + // No presence check is required. + need_extra_newline = true; + } else if (HasHasbit(field)) { PrintPresenceCheck(format, field, has_bit_indices_, printer, - &cached_has_bit_index); + &cached_has_word_index); have_enclosing_if = true; } else { // Without field presence: field is serialized only if it has a @@ -3931,6 +3854,9 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { "}\n" "\n"); } + if (need_extra_newline) { + format("\n"); + } } if (have_outer_if) { @@ -3940,7 +3866,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (cold_skipper.OnEndChunk(chunk_index, printer)) { // Reset here as it may have been updated in just closed if statement. - cached_has_bit_index = -1; + cached_has_word_index = -1; } } @@ -3953,7 +3879,9 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { PrintFieldComment(format, field); format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - field_generators_.get(field).GenerateByteSize(printer); + if (!IsFieldStripped(field, options_)) { + field_generators_.get(field).GenerateByteSize(printer); + } format("break;\n"); format.Outdent(); format("}\n"); @@ -4014,24 +3942,10 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { "}\n\n"); } - if (HasFieldPresence(descriptor_->file())) { - // Check that all required fields in this message are set. We can do this - // most efficiently by checking 32 "has bits" at a time. - const std::vector masks = RequiredFieldsBitMask(); - - for (int i = 0; i < masks.size(); i++) { - uint32 mask = masks[i]; - if (mask == 0) { - continue; - } - - // TODO(ckennelly): Consider doing something similar to ByteSizeLong(), - // where we check all of the required fields in a single branch (assuming - // that we aren't going to benefit from early termination). - format("if ((_has_bits_[$1$] & 0x$2$) != 0x$2$) return false;\n", - i, // 1 - StrCat(strings::Hex(mask, strings::ZERO_PAD_8))); // 2 - } + if (num_required_fields_ > 0) { + format( + "if (_Internal::MissingRequiredFields(_has_bits_))" + " return false;\n"); } // Now check that all non-oneof embedded messages are initialized. @@ -4057,7 +3971,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { } else if (field->options().weak()) { continue; } else { - GOOGLE_CHECK(!field->containing_oneof()); + GOOGLE_CHECK(!field->real_containing_oneof()); format( "if (_internal_has_$1$()) {\n" " if (!$1$_->IsInitialized()) return false;\n" @@ -4093,10 +4007,11 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); format.Indent(); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + if (!IsFieldStripped(field, options_) && + field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !ShouldIgnoreRequiredFieldCheck(field, options_) && scc_analyzer_->HasRequiredFields(field->message_type())) { - GOOGLE_CHECK(!(field->options().weak() || !field->containing_oneof())); + GOOGLE_CHECK(!(field->options().weak() || !field->real_containing_oneof())); if (field->options().weak()) { // Just skip. } else { diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index bc4febf5c5d8..933386fbd5fc 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -82,17 +82,6 @@ class MessageGenerator { // Source file stuff. - // Generate extra fields - void GenerateExtraDefaultFields(io::Printer* printer); - - // Generates code that creates default instances for fields. - void GenerateFieldDefaultInstances(io::Printer* printer); - - // Generates code that initializes the message's default instance. This - // is separate from allocating because all default instances must be - // allocated before any can be initialized. - void GenerateDefaultInstanceInitializer(io::Printer* printer); - // Generate all non-inline methods for this class. void GenerateClassMethods(io::Printer* printer); @@ -113,7 +102,7 @@ class MessageGenerator { bool GenerateParseTable(io::Printer* printer, size_t offset, size_t aux_offset); - // Generate the field offsets array. Returns the a pair of the total numer + // Generate the field offsets array. Returns the a pair of the total number // of entries generated and the index of the first has_bit entry. std::pair GenerateOffsets(io::Printer* printer); void GenerateSchema(io::Printer* printer, int offset, int has_offset); @@ -142,8 +131,10 @@ class MessageGenerator { void GenerateSerializeWithCachedSizes(io::Printer* printer); void GenerateSerializeWithCachedSizesToArray(io::Printer* printer); void GenerateSerializeWithCachedSizesBody(io::Printer* printer); + void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* printer); void GenerateByteSize(io::Printer* printer); void GenerateMergeFrom(io::Printer* printer); + void GenerateClassSpecificMergeFrom(io::Printer* printer); void GenerateCopyFrom(io::Printer* printer); void GenerateSwap(io::Printer* printer); void GenerateIsInitialized(io::Printer* printer); @@ -180,6 +171,10 @@ class MessageGenerator { bool copy_constructor) const; size_t HasBitsSize() const; + int HasBitIndex(const FieldDescriptor* a) const; + int HasByteIndex(const FieldDescriptor* a) const; + int HasWordIndex(const FieldDescriptor* a) const; + bool SameHasByte(const FieldDescriptor* a, const FieldDescriptor* b) const; std::vector RequiredFieldsBitMask() const; const Descriptor* descriptor_; diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 12c6524b5cfb..f1a5cef1de0c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -66,10 +66,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["type_default_instance_ptr"] = QualifiedDefaultInstancePtr(descriptor->message_type(), options); (*variables)["type_reference_function"] = - implicit_weak - ? (" " + (*variables)["proto_ns"] + "::internal::StrongReference(" + - (*variables)["type_default_instance"] + ");\n") - : ""; + implicit_weak ? (" ::" + (*variables)["proto_ns"] + + "::internal::StrongReference(reinterpret_cast(\n" + + (*variables)["type_default_instance"] + "));\n") + : ""; // NOTE: Escaped here to unblock proto1->proto2 migration. // TODO(liujisi): Extend this to apply for other conflicting methods. (*variables)["release_name"] = @@ -104,50 +105,49 @@ void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { void MessageFieldGenerator::GenerateAccessorDeclarations( io::Printer* printer) const { Formatter format(printer, variables_); + if (IsFieldStripped(descriptor_, options_)) { + format( + "$deprecated_attr$const $type$& ${1$$name$$}$() const { " + "__builtin_trap(); }\n" + "$deprecated_attr$$type$* ${1$$release_name$$}$() { " + "__builtin_trap(); }\n" + "$deprecated_attr$$type$* ${1$mutable_$name$$}$() { " + "__builtin_trap(); }\n" + "$deprecated_attr$void ${1$set_allocated_$name$$}$" + "($type$* $name$) { __builtin_trap(); }\n" + "$deprecated_attr$void " + "${1$unsafe_arena_set_allocated_$name$$}$(\n" + " $type$* $name$) { __builtin_trap(); }\n" + "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { " + "__builtin_trap(); }\n", + descriptor_); + return; + } format( "$deprecated_attr$const $type$& ${1$$name$$}$() const;\n" "$deprecated_attr$$type$* ${1$$release_name$$}$();\n" "$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n" "$deprecated_attr$void ${1$set_allocated_$name$$}$" - "($type$* $name$);\n" - "private:\n" - "const $type$& ${1$_internal_$name$$}$() const;\n" - "$type$* ${1$_internal_mutable_$name$$}$();\n" - "public:\n", + "($type$* $name$);\n", descriptor_); - if (SupportsArenas(descriptor_)) { + if (!IsFieldStripped(descriptor_, options_)) { format( - "$deprecated_attr$void " - "${1$unsafe_arena_set_allocated_$name$$}$(\n" - " $type$* $name$);\n" - "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n", + "private:\n" + "const $type$& ${1$_internal_$name$$}$() const;\n" + "$type$* ${1$_internal_mutable_$name$$}$();\n" + "public:\n", descriptor_); } + format( + "$deprecated_attr$void " + "${1$unsafe_arena_set_allocated_$name$$}$(\n" + " $type$* $name$);\n" + "$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n", + descriptor_); } void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( io::Printer* printer) const { - Formatter format(printer, variables_); - if (SupportsArenas(descriptor_)) { - format( - "void $classname$::unsafe_arena_set_allocated_$name$(\n" - " $type$* $name$) {\n" - "$annotate_accessor$" - // If we're not on an arena, free whatever we were holding before. - // (If we are on arena, we can just forget the earlier pointer.) - " if (GetArenaNoVirtual() == nullptr) {\n" - " delete $name$_;\n" - " }\n" - " $name$_ = $name$;\n" - " if ($name$) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" - ":$full_name$)\n" - "}\n"); - } } void MessageFieldGenerator::GenerateInlineAccessorDefinitions( @@ -157,8 +157,8 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$() const {\n" "$type_reference_function$" " const $type$* p = $casted_member$;\n" - " return p != nullptr ? *p : *reinterpret_cast(\n" - " &$type_default_instance$);\n" + " return p != nullptr ? *p : reinterpret_cast(\n" + " $type_default_instance$);\n" "}\n" "inline const $type$& $classname$::$name$() const {\n" "$annotate_accessor$" @@ -166,20 +166,43 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( " return _internal_$name$();\n" "}\n"); - if (SupportsArenas(descriptor_)) { + format( + "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" + " $type$* $name$) {\n" + "$annotate_accessor$" + // If we're not on an arena, free whatever we were holding before. + // (If we are on arena, we can just forget the earlier pointer.) + " if (GetArena() == nullptr) {\n" + " delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n" + " }\n"); + if (implicit_weak_field_) { format( - "inline $type$* $classname$::$release_name$() {\n" - " auto temp = unsafe_arena_release_$name$();\n" - " if (GetArenaNoVirtual() != nullptr) {\n" - " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" - " }\n" - " return temp;\n" - "}\n" - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n"); + " $name$_ = " + "reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n"); } else { - format("inline $type$* $classname$::$release_name$() {\n"); + format(" $name$_ = $name$;\n"); } format( + " if ($name$) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " // @@protoc_insertion_point(field_unsafe_arena_set_allocated" + ":$full_name$)\n" + "}\n"); + format( + "inline $type$* $classname$::$release_name$() {\n" + "$type_reference_function$" + " $clear_hasbit$\n" + " $type$* temp = $casted_member$;\n" + " $name$_ = nullptr;\n" + " if (GetArena() != nullptr) {\n" + " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" + " }\n" + " return temp;\n" + "}\n" + "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" "$annotate_accessor$" " // @@protoc_insertion_point(field_release:$full_name$)\n" "$type_reference_function$" @@ -194,7 +217,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( "$type_reference_function$" " $set_hasbit$\n" " if ($name$_ == nullptr) {\n" - " auto* p = CreateMaybeMessage<$type$>(GetArenaNoVirtual());\n"); + " auto* p = CreateMaybeMessage<$type$>(GetArena());\n"); if (implicit_weak_field_) { format(" $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n"); } else { @@ -215,7 +238,7 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline void $classname$::set_allocated_$name$($type$* $name$) {\n" "$annotate_accessor$" - " ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n"); + " ::$proto_ns$::Arena* message_arena = GetArena();\n"); format(" if (message_arena == nullptr) {\n"); if (IsCrossFileMessage(descriptor_)) { format( @@ -226,16 +249,13 @@ void MessageFieldGenerator::GenerateInlineAccessorDefinitions( format( " }\n" " if ($name$) {\n"); - if (SupportsArenas(descriptor_->message_type()) && - IsCrossFileMessage(descriptor_)) { + if (IsCrossFileMessage(descriptor_)) { // We have to read the arena through the virtual method, because the type // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" " " "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n"); - } else if (!SupportsArenas(descriptor_->message_type())) { - format(" ::$proto_ns$::Arena* submessage_arena = nullptr;\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" @@ -297,49 +317,26 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( "*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n" " }\n" "}\n"); - if (SupportsArenas(descriptor_)) { - format( - "::$proto_ns$::MessageLite*\n" - "$classname$::_Internal::mutable_$name$($classname$* msg) {\n"); - if (HasFieldPresence(descriptor_->file())) { - format(" msg->$set_hasbit$\n"); - } - format( - " if (msg->$name$_ == nullptr) {\n" - " if ($type_default_instance_ptr$ == nullptr) {\n" - " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" - " ::$proto_ns$::internal::ImplicitWeakMessage>(\n" - " msg->GetArenaNoVirtual());\n" - " } else {\n" - " msg->$name$_ = reinterpret_cast(\n" - " $type_default_instance_ptr$)->New(" - "msg->GetArenaNoVirtual());\n" - " }\n" - " }\n" - " return msg->$name$_;\n" - "}\n"); - } else { - format( - "::$proto_ns$::MessageLite*\n" - "$classname$::_Internal::mutable_$name$($classname$* msg) {\n"); - if (HasFieldPresence(descriptor_->file())) { - format(" msg->$set_hasbit$\n"); - } - format( - " if (msg->$name$_ == nullptr) {\n" - " if ($type_default_instance_ptr$ == nullptr) {\n" - " msg->$name$_ = " - "new ::$proto_ns$::internal::ImplicitWeakMessage;\n" - " } else {\n" - " msg->$name$_ = " - "reinterpret_cast(\n" - " $type_default_instance_ptr$)->New();\n" - " }\n" - " }\n" - " return msg->$name$_;\n" - "}\n"); + format( + "::$proto_ns$::MessageLite*\n" + "$classname$::_Internal::mutable_$name$($classname$* msg) {\n"); + if (HasFieldPresence(descriptor_->file())) { + format(" msg->$set_hasbit$\n"); } + format( + " if (msg->$name$_ == nullptr) {\n" + " if ($type_default_instance_ptr$ == nullptr) {\n" + " msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n" + " ::$proto_ns$::internal::ImplicitWeakMessage>(\n" + " msg->GetArena());\n" + " } else {\n" + " msg->$name$_ = reinterpret_cast(\n" + " $type_default_instance_ptr$)->New(msg->GetArena());\n" + " }\n" + " }\n" + " return msg->$name$_;\n" + "}\n"); } else { // This inline accessor directly returns member field and is used in // Serialize such that AFDO profile correctly captures access information to @@ -353,12 +350,14 @@ void MessageFieldGenerator::GenerateInternalAccessorDefinitions( } void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); if (!HasFieldPresence(descriptor_->file())) { // If we don't have has-bits, message presence is indicated only by ptr != // NULL. Thus on clear, we need to delete the object. format( - "if (GetArenaNoVirtual() == nullptr && $name$_ != nullptr) {\n" + "if (GetArena() == nullptr && $name$_ != nullptr) {\n" " delete $name$_;\n" "}\n" "$name$_ = nullptr;\n"); @@ -369,12 +368,14 @@ void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const { void MessageFieldGenerator::GenerateMessageClearingCode( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); if (!HasFieldPresence(descriptor_->file())) { // If we don't have has-bits, message presence is indicated only by ptr != // NULL. Thus on clear, we need to delete the object. format( - "if (GetArenaNoVirtual() == nullptr && $name$_ != nullptr) {\n" + "if (GetArena() == nullptr && $name$_ != nullptr) {\n" " delete $name$_;\n" "}\n" "$name$_ = nullptr;\n"); @@ -386,6 +387,8 @@ void MessageFieldGenerator::GenerateMessageClearingCode( } void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); if (implicit_weak_field_) { format( @@ -399,11 +402,15 @@ void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const { } void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format("swap($name$_, other->$name$_);\n"); } void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); if (options_.opensource_runtime) { // TODO(gerbens) Remove this when we don't need to destruct default @@ -418,12 +425,16 @@ void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { void MessageFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format("$name$_ = nullptr;\n"); } void MessageFieldGenerator::GenerateCopyConstructorCode( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format( "if (from._internal_has_$name$()) {\n" @@ -435,6 +446,8 @@ void MessageFieldGenerator::GenerateCopyConstructorCode( void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format( "target = stream->EnsureSpace(target);\n" @@ -444,6 +457,8 @@ void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( } void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format( "total_size += $tag_size$ +\n" @@ -468,19 +483,16 @@ void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( format( "void $classname$::set_allocated_$name$($type$* $name$) {\n" "$annotate_accessor$" - " ::$proto_ns$::Arena* message_arena = GetArenaNoVirtual();\n" + " ::$proto_ns$::Arena* message_arena = GetArena();\n" " clear_$oneof_name$();\n" " if ($name$) {\n"); - if (SupportsArenas(descriptor_->message_type()) && - descriptor_->file() != descriptor_->message_type()->file()) { + if (descriptor_->file() != descriptor_->message_type()->file()) { // We have to read the arena through the virtual method, because the type // isn't defined in this file. format( " ::$proto_ns$::Arena* submessage_arena =\n" " " "reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n"); - } else if (!SupportsArenas(descriptor_->message_type())) { - format(" ::$proto_ns$::Arena* submessage_arena = nullptr;\n"); } else { format( " ::$proto_ns$::Arena* submessage_arena =\n" @@ -507,14 +519,10 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n"); - if (SupportsArenas(descriptor_)) { - format( - " if (GetArenaNoVirtual() != nullptr) {\n" - " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" - " }\n"); - } - format( + " $type$* temp = $field_member$;\n" + " if (GetArena() != nullptr) {\n" + " temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n" + " }\n" " $field_member$ = nullptr;\n" " return temp;\n" " } else {\n" @@ -526,52 +534,45 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$() const {\n" " return _internal_has_$name$()\n" " ? *$field_member$\n" - " : *reinterpret_cast< $type$*>(&$type_default_instance$);\n" + " : reinterpret_cast< $type$&>($type_default_instance$);\n" "}\n" "inline const $type$& $classname$::$name$() const {\n" "$annotate_accessor$" " // @@protoc_insertion_point(field_get:$full_name$)\n" " return _internal_$name$();\n" - "}\n"); - - if (SupportsArenas(descriptor_)) { - format( - "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_unsafe_arena_release" - ":$full_name$)\n" - " if (_internal_has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " $type$* temp = $field_member$;\n" - " $field_member$ = nullptr;\n" - " return temp;\n" - " } else {\n" - " return nullptr;\n" - " }\n" - "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$" - "($type$* $name$) {\n" - "$annotate_accessor$" - // We rely on the oneof clear method to free the earlier contents of - // this oneof. We can directly use the pointer we're given to set the - // new value. - " clear_$oneof_name$();\n" - " if ($name$) {\n" - " set_has_$name$();\n" - " $field_member$ = $name$;\n" - " }\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" - "$full_name$)\n" - "}\n"); - } - - format( + "}\n" + "inline $type$* $classname$::unsafe_arena_release_$name$() {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_unsafe_arena_release" + ":$full_name$)\n" + " if (_internal_has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " $type$* temp = $field_member$;\n" + " $field_member$ = nullptr;\n" + " return temp;\n" + " } else {\n" + " return nullptr;\n" + " }\n" + "}\n" + "inline void $classname$::unsafe_arena_set_allocated_$name$" + "($type$* $name$) {\n" + "$annotate_accessor$" + // We rely on the oneof clear method to free the earlier contents of + // this oneof. We can directly use the pointer we're given to set the + // new value. + " clear_$oneof_name$();\n" + " if ($name$) {\n" + " set_has_$name$();\n" + " $field_member$ = $name$;\n" + " }\n" + " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" + "$full_name$)\n" + "}\n" "inline $type$* $classname$::_internal_mutable_$name$() {\n" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$ = CreateMaybeMessage< $type$ >(\n" - " GetArenaNoVirtual());\n" + " $field_member$ = CreateMaybeMessage< $type$ >(GetArena());\n" " }\n" " return $field_member$;\n" "}\n" @@ -584,15 +585,13 @@ void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions( void MessageOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); - if (SupportsArenas(descriptor_)) { - format( - "if (GetArenaNoVirtual() == nullptr) {\n" - " delete $field_member$;\n" - "}\n"); - } else { - format("delete $field_member$;\n"); - } + format( + "if (GetArena() == nullptr) {\n" + " delete $field_member$;\n" + "}\n"); } void MessageOneofFieldGenerator::GenerateMessageClearingCode( @@ -643,14 +642,35 @@ void RepeatedMessageFieldGenerator::GeneratePrivateMembers( void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations( io::Printer* printer) const { Formatter format(printer, variables_); + if (IsFieldStripped(descriptor_, options_)) { + format( + "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { " + "__builtin_trap(); }\n" + "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n" + " ${1$mutable_$name$$}$() { __builtin_trap(); }\n" + "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const { " + "__builtin_trap(); }\n" + "$deprecated_attr$$type$* ${1$add_$name$$}$() { " + "__builtin_trap(); }\n" + "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n" + " ${1$$name$$}$() const { __builtin_trap(); }\n", + descriptor_); + return; + } format( "$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n" "$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n" - " ${1$mutable_$name$$}$();\n" - "private:\n" - "const $type$& ${1$_internal_$name$$}$(int index) const;\n" - "$type$* ${1$_internal_add_$name$$}$();\n" - "public:\n" + " ${1$mutable_$name$$}$();\n", + descriptor_); + if (!IsFieldStripped(descriptor_, options_)) { + format( + "private:\n" + "const $type$& ${1$_internal_$name$$}$(int index) const;\n" + "$type$* ${1$_internal_add_$name$$}$();\n" + "public:\n", + descriptor_); + } + format( "$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n" "$deprecated_attr$$type$* ${1$add_$name$$}$();\n" "$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n" @@ -684,7 +704,7 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( "inline const $type$& $classname$::_internal_$name$(int index) const " "{\n" " return $name$_$weak$.InternalCheckedGet(index,\n" - " *reinterpret_cast(&$type_default_instance$));\n" + " reinterpret_cast($type_default_instance$));\n" "}\n"); } else { format( @@ -722,18 +742,24 @@ void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions( void RepeatedMessageFieldGenerator::GenerateClearingCode( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format("$name$_.Clear();\n"); } void RepeatedMessageFieldGenerator::GenerateMergingCode( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format("$name$_.MergeFrom(from.$name$_);\n"); } void RepeatedMessageFieldGenerator::GenerateSwappingCode( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format("$name$_.InternalSwap(&other->$name$_);\n"); } @@ -745,6 +771,8 @@ void RepeatedMessageFieldGenerator::GenerateConstructorCode( void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); if (implicit_weak_field_) { format( @@ -770,6 +798,8 @@ void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray( void RepeatedMessageFieldGenerator::GenerateByteSize( io::Printer* printer) const { + GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_)); + Formatter format(printer, variables_); format( "total_size += $tag_size$UL * this->_internal_$name$_size();\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index d8fe3a7aefd2..92b55484676c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -44,7 +44,8 @@ namespace cpp { enum class EnforceOptimizeMode { kNoEnforcement, // Use the runtime specified by the file specific options. - kSpeed, // This is the full runtime. + kSpeed, // Full runtime with a generated code implementation. + kCodeSize, // Full runtime with a reflective implementation. kLiteRuntime, }; @@ -62,6 +63,7 @@ struct Options { bool bootstrap = false; bool opensource_runtime = false; bool annotate_accessor = false; + bool unused_field_stripping = false; std::string runtime_include_base; int num_cc_files = 0; std::string annotation_pragma_name; diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 847f76c2176c..beed6e5107fa 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -55,12 +55,31 @@ void SetStringVariables(const FieldDescriptor* descriptor, StrCat(descriptor->default_value_string().length()); std::string default_variable_string = MakeDefaultName(descriptor); (*variables)["default_variable_name"] = default_variable_string; - (*variables)["default_variable"] = + + if (!descriptor->default_value_string().empty()) { + (*variables)["lazy_variable"] = + QualifiedClassName(descriptor->containing_type(), options) + + "::" + default_variable_string; + } + + (*variables)["default_string"] = + descriptor->default_value_string().empty() + ? "::" + (*variables)["proto_ns"] + + "::internal::GetEmptyStringAlreadyInited()" + : (*variables)["lazy_variable"] + ".get()"; + (*variables)["init_value"] = descriptor->default_value_string().empty() ? "&::" + (*variables)["proto_ns"] + "::internal::GetEmptyStringAlreadyInited()" - : "&" + QualifiedClassName(descriptor->containing_type(), options) + - "::" + default_variable_string + ".get()"; + : "nullptr"; + (*variables)["default_value_tag"] = + "::" + (*variables)["proto_ns"] + "::internal::ArenaStringPtr::" + + (descriptor->default_value_string().empty() ? "Empty" : "NonEmpty") + + "Default{}"; + (*variables)["default_variable_or_tag"] = + (*variables)[descriptor->default_value_string().empty() + ? "default_value_tag" + : "lazy_variable"]; (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; (*variables)["null_check"] = (*variables)["DCHK"] + "(value != nullptr);\n"; @@ -75,9 +94,6 @@ void SetStringVariables(const FieldDescriptor* descriptor, } else { (*variables)["string_piece"] = "::StringPiece"; } - - (*variables)["lite"] = - HasDescriptorMethods(descriptor->file(), options) ? "" : "Lite"; } } // namespace @@ -86,9 +102,7 @@ void SetStringVariables(const FieldDescriptor* descriptor, StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor, const Options& options) - : FieldGenerator(descriptor, options), - lite_(!HasDescriptorMethods(descriptor->file(), options)), - inlined_(IsStringInlined(descriptor, options)) { + : FieldGenerator(descriptor, options) { SetStringVariables(descriptor, &variables_, options); } @@ -96,35 +110,15 @@ StringFieldGenerator::~StringFieldGenerator() {} void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - format("::$proto_ns$::internal::InlinedStringField $name$_;\n"); - } else { - // N.B. that we continue to use |ArenaStringPtr| instead of |string*| for - // string fields, even when SupportArenas(descriptor_) == false. Why? The - // simple answer is to avoid unmaintainable complexity. The reflection code - // assumes ArenaStringPtrs. These are *almost* in-memory-compatible with - // string*, except for the pointer tags and related ownership semantics. We - // could modify the runtime code to use string* for the - // not-supporting-arenas case, but this would require a way to detect which - // type of class was generated (adding overhead and complexity to - // GeneratedMessageReflection) and littering the runtime code paths with - // conditionals. It's simpler to stick with this but use lightweight - // accessors that assume arena == NULL. There should be very little - // overhead anyway because it's just a tagged pointer in-memory. - format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); - } + format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); } void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const { Formatter format(printer, variables_); if (!descriptor_->default_value_string().empty()) { - // We make the default instance public, so it can be initialized by - // non-friend code. format( - "public:\n" - "static ::$proto_ns$::internal::ExplicitlyConstructed" - " $default_variable_name$;\n" - "private:\n"); + "static const ::$proto_ns$::internal::LazyString" + " $default_variable_name$;\n"); } } @@ -179,23 +173,6 @@ void StringFieldGenerator::GenerateAccessorDeclarations( "$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* " "$name$);\n", descriptor_); - if (options_.opensource_runtime) { - if (SupportsArenas(descriptor_)) { - format( - "$GOOGLE_PROTOBUF$_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors " - "for\"\n" - "\" string fields are deprecated and will be removed in a\"\n" - "\" future release.\")\n" - "std::string* ${1$unsafe_arena_release_$name$$}$();\n" - "$GOOGLE_PROTOBUF$_RUNTIME_DEPRECATED(\"The unsafe_arena_ accessors " - "for\"\n" - "\" string fields are deprecated and will be removed in a\"\n" - "\" future release.\")\n" - "void ${1$unsafe_arena_set_allocated_$name$$}$(\n" - " std::string* $name$);\n", - descriptor_); - } - } format( "private:\n" "const std::string& _internal_$name$() const;\n" @@ -216,7 +193,13 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const std::string& $classname$::$name$() const {\n" "$annotate_accessor$" - " // @@protoc_insertion_point(field_get:$full_name$)\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n"); + if (!descriptor_->default_value_string().empty()) { + format( + " if ($name$_.IsDefault(nullptr)) return " + "$default_variable_name$.get();\n"); + } + format( " return _internal_$name$();\n" "}\n" "inline void $classname$::set_$name$(const std::string& value) {\n" @@ -228,226 +211,99 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_accessor$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return _internal_mutable_$name$();\n" + "}\n" + "inline const std::string& $classname$::_internal_$name$() const {\n" + " return $name$_.Get();\n" + "}\n" + "inline void $classname$::_internal_set_$name$(const std::string& " + "value) {\n" + " $set_hasbit$\n" + " $name$_.Set($default_value_tag$, value, GetArena());\n" + "}\n" + "inline void $classname$::set_$name$(std::string&& value) {\n" + "$annotate_accessor$" + " $set_hasbit$\n" + " $name$_.Set(\n" + " $default_value_tag$, ::std::move(value), GetArena());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + "$annotate_accessor$" + " $null_check$" + " $set_hasbit$\n" + " $name$_.Set($default_value_tag$, $string_piece$(value), GetArena());\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); - if (SupportsArenas(descriptor_)) { + if (!options_.opensource_runtime) { format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " return $name$_.Get();\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, value, GetArenaNoVirtual());\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.Set$lite$(\n" - " $default_variable$, ::std::move(value), GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" + "inline void $classname$::set_$name$(::StringPiece value) {\n" "$annotate_accessor$" - " $null_check$" " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, $string_piece$(value),\n" - " GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" + " $name$_.Set($default_value_tag$, value,GetArena());\n" + " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, value, " - "GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } - format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value,\n" - " size_t size) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, $string_piece$(\n" - " reinterpret_cast(value), size), " - "GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " $set_hasbit$\n" - " return $name$_.Mutable($default_variable$, GetArenaNoVirtual());\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n"); - - if (HasFieldPresence(descriptor_->file())) { - format( - " if (!_internal_has_$name$()) {\n" - " return nullptr;\n" - " }\n" - " $clear_hasbit$\n" - " return $name$_.ReleaseNonDefault(" - "$default_variable$, GetArenaNoVirtual());\n"); - } else { - format( - " $clear_hasbit$\n" - " return $name$_.Release($default_variable$, " - "GetArenaNoVirtual());\n"); - } + } + format( + "inline " + "void $classname$::set_$name$(const $pointer_type$* value,\n" + " size_t size) {\n" + "$annotate_accessor$" + " $set_hasbit$\n" + " $name$_.Set($default_value_tag$, $string_piece$(\n" + " reinterpret_cast(value), size), GetArena());\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline std::string* $classname$::_internal_mutable_$name$() {\n" + " $set_hasbit$\n" + " return $name$_.Mutable($default_variable_or_tag$, GetArena());\n" + "}\n" + "inline std::string* $classname$::$release_name$() {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_release:$full_name$)\n"); + if (HasHasbit(descriptor_)) { format( - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if ($name$ != nullptr) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" + " if (!_internal_has_$name$()) {\n" + " return nullptr;\n" " }\n" - " $name$_.SetAllocated($default_variable$, $name$,\n" - " GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); - if (options_.opensource_runtime) { - format( - "inline std::string* $classname$::unsafe_arena_release_$name$() {\n" - "$annotate_accessor$" - " // " - "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n" - " $DCHK$(GetArenaNoVirtual() != nullptr);\n" - " $clear_hasbit$\n" - " return $name$_.UnsafeArenaRelease($default_variable$,\n" - " GetArenaNoVirtual());\n" - "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(\n" - "$annotate_accessor$" - " std::string* $name$) {\n" - " $DCHK$(GetArenaNoVirtual() != nullptr);\n" - " if ($name$ != nullptr) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " $name$_.UnsafeArenaSetAllocated($default_variable$,\n" - " $name$, GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" - "$full_name$)\n" - "}\n"); - } + " $clear_hasbit$\n" + " return $name$_.ReleaseNonDefault($init_value$, GetArena());\n"); } else { - // No-arena case. - format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " return $name$_.GetNoArena();\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$, value);\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.SetNoArena(\n" - " $default_variable$, ::std::move(value));\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - "$annotate_accessor$" - " $null_check$" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" - "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$, value);\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } - format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value, " - "size_t size) {\n" - "$annotate_accessor$" - " $set_hasbit$\n" - " $name$_.SetNoArena($default_variable$,\n" - " $string_piece$(reinterpret_cast(value), size));\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " $set_hasbit$\n" - " return $name$_.MutableNoArena($default_variable$);\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n"); - - if (HasFieldPresence(descriptor_->file())) { - format( - " if (!_internal_has_$name$()) {\n" - " return nullptr;\n" - " }\n" - " $clear_hasbit$\n" - " return $name$_.ReleaseNonDefaultNoArena($default_variable$);\n"); - } else { - format( - " $clear_hasbit$\n" - " return $name$_.ReleaseNoArena($default_variable$);\n"); - } - - format( - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if ($name$ != nullptr) {\n" - " $set_hasbit$\n" - " } else {\n" - " $clear_hasbit$\n" - " }\n" - " $name$_.SetAllocatedNoArena($default_variable$, $name$);\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); + format(" return $name$_.Release($init_value$, GetArena());\n"); } + + format( + "}\n" + "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" + "$annotate_accessor$" + " if ($name$ != nullptr) {\n" + " $set_hasbit$\n" + " } else {\n" + " $clear_hasbit$\n" + " }\n" + " $name$_.SetAllocated($init_value$, $name$,\n" + " GetArena());\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } void StringFieldGenerator::GenerateNonInlineAccessorDefinitions( io::Printer* printer) const { Formatter format(printer, variables_); if (!descriptor_->default_value_string().empty()) { - // Initialized in GenerateDefaultInstanceAllocator. format( - "::$proto_ns$::internal::ExplicitlyConstructed " - "$classname$::$default_variable_name$;\n"); + "const ::$proto_ns$::internal::LazyString " + "$classname$::$default_variable_name$" + "{{{$default$, $default_length$}}, {nullptr}};\n"); } } void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - // Two-dimension specialization here: supporting arenas or not, and default - // value is the empty string or not. Complexity here ensures the minimal - // number of branches / amount of extraneous code at runtime (given that the - // below methods are inlined one-liners)! - if (SupportsArenas(descriptor_)) { - if (descriptor_->default_value_string().empty()) { - format( - "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n"); - } else { - format( - "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n"); - } + if (descriptor_->default_value_string().empty()) { + format("$name$_.ClearToEmpty();\n"); } else { - if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmptyNoArena($default_variable$);\n"); - } else { - format("$name$_.ClearToDefaultNoArena($default_variable$);\n"); - } + format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n"); } } @@ -459,87 +315,38 @@ void StringFieldGenerator::GenerateMessageClearingCode( // the minimal number of branches / amount of extraneous code at runtime // (given that the below methods are inlined one-liners)! - // If we have field presence, then the Clear() method of the protocol buffer + // If we have a hasbit, then the Clear() method of the protocol buffer // will have checked that this field is set. If so, we can avoid redundant - // checks against default_variable. - const bool must_be_present = HasFieldPresence(descriptor_->file()); - - if (inlined_ && must_be_present) { - // Calling mutable_$name$() gives us a string reference and sets the has bit - // for $name$ (in proto2). We may get here when the string field is inlined - // but the string's contents have not been changed by the user, so we cannot - // make an assertion about the contents of the string and could never make - // an assertion about the string instance. - // - // For non-inlined strings, we distinguish from non-default by comparing - // instances, rather than contents. - format("$DCHK$(!$name$_.IsDefault($default_variable$));\n"); - } + // checks against the default variable. + const bool must_be_present = HasHasbit(descriptor_); - if (SupportsArenas(descriptor_)) { - if (descriptor_->default_value_string().empty()) { - if (must_be_present) { - format("$name$_.ClearNonDefaultToEmpty();\n"); - } else { - format( - "$name$_.ClearToEmpty($default_variable$, GetArenaNoVirtual());\n"); - } - } else { - // Clear to a non-empty default is more involved, as we try to use the - // Arena if one is present and may need to reallocate the string. - format( - "$name$_.ClearToDefault($default_variable$, GetArenaNoVirtual());\n"); - } - } else if (must_be_present) { - // When Arenas are disabled and field presence has been checked, we can - // safely treat the ArenaStringPtr as a string*. - if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearNonDefaultToEmptyNoArena();\n"); + if (descriptor_->default_value_string().empty()) { + if (must_be_present) { + format("$name$_.ClearNonDefaultToEmpty();\n"); } else { - format("$name$_.UnsafeMutablePointer()->assign(*$default_variable$);\n"); + format("$name$_.ClearToEmpty();\n"); } } else { - if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmptyNoArena($default_variable$);\n"); - } else { - format("$name$_.ClearToDefaultNoArena($default_variable$);\n"); - } + // Clear to a non-empty default is more involved, as we try to use the + // Arena if one is present and may need to reallocate the string. + format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n "); } } void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) { - // TODO(gpike): improve this - format("_internal_set_$name$(from._internal_$name$());\n"); - } else { - format( - "$set_hasbit$\n" - "$name$_.AssignWithDefault($default_variable$, from.$name$_);\n"); - } + // TODO(gpike): improve this + format("_internal_set_$name$(from._internal_$name$());\n"); } void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - format("$name$_.Swap(&other->$name$_);\n"); - } else { - format( - "$name$_.Swap(&other->$name$_, $default_variable$,\n" - " GetArenaNoVirtual());\n"); - } + format("$name$_.Swap(&other->$name$_, $init_value$, GetArena());\n"); } void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { Formatter format(printer, variables_); - // TODO(ckennelly): Construct non-empty strings as part of the initializer - // list. - if (inlined_ && descriptor_->default_value_string().empty()) { - // Automatic initialization will construct the string. - return; - } - - format("$name$_.UnsafeSetDefault($default_variable$);\n"); + format("$name$_.UnsafeSetDefault($init_value$);\n"); } void StringFieldGenerator::GenerateCopyConstructorCode( @@ -547,7 +354,7 @@ void StringFieldGenerator::GenerateCopyConstructorCode( Formatter format(printer, variables_); GenerateConstructorCode(printer); - if (HasFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { format("if (from._internal_has_$name$()) {\n"); } else { format("if (!from._internal_$name$().empty()) {\n"); @@ -555,14 +362,10 @@ void StringFieldGenerator::GenerateCopyConstructorCode( format.Indent(); - if (SupportsArenas(descriptor_) || descriptor_->containing_oneof() != NULL) { - // TODO(gpike): improve this - format( - "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n" - " GetArenaNoVirtual());\n"); - } else { - format("$name$_.AssignWithDefault($default_variable$, from.$name$_);\n"); - } + // TODO(gpike): improve this + format( + "$name$_.Set($default_value_tag$, from._internal_$name$(), \n" + " GetArena());\n"); format.Outdent(); format("}\n"); @@ -570,40 +373,7 @@ void StringFieldGenerator::GenerateCopyConstructorCode( void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - // The destructor is automatically invoked. - return; - } - - format("$name$_.DestroyNoArena($default_variable$);\n"); -} - -bool StringFieldGenerator::GenerateArenaDestructorCode( - io::Printer* printer) const { - Formatter format(printer, variables_); - if (!inlined_) { - return false; - } - - format("_this->$name$_.DestroyNoArena($default_variable$);\n"); - return true; -} - -void StringFieldGenerator::GenerateDefaultInstanceAllocator( - io::Printer* printer) const { - Formatter format(printer, variables_); - if (!descriptor_->default_value_string().empty()) { - format( - "$ns$::$classname$::$default_variable_name$.DefaultConstruct();\n" - "*$ns$::$classname$::$default_variable_name$.get_mutable() = " - "std::string($default$, $default_length$);\n" - "::$proto_ns$::internal::OnShutdownDestroyString(\n" - " $ns$::$classname$::$default_variable_name$.get_mutable());\n"); - } -} - -bool StringFieldGenerator::MergeFromCodedStreamNeedsArena() const { - return !lite_ && !inlined_ && !options_.opensource_runtime; + format("$name$_.DestroyNoArena($init_value$);\n"); } void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -629,17 +399,11 @@ void StringFieldGenerator::GenerateByteSize(io::Printer* printer) const { " this->_internal_$name$());\n"); } -uint32 StringFieldGenerator::CalculateFieldTag() const { - return inlined_ ? 1 : 0; -} - // =================================================================== StringOneofFieldGenerator::StringOneofFieldGenerator( const FieldDescriptor* descriptor, const Options& options) : StringFieldGenerator(descriptor, options) { - inlined_ = false; - SetCommonOneofFieldVariables(descriptor, &variables_); variables_["field_name"] = UnderscoresToCamelCase(descriptor->name(), true); variables_["oneof_index"] = @@ -666,252 +430,115 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( "$annotate_accessor$" " // @@protoc_insertion_point(field_mutable:$full_name$)\n" " return _internal_mutable_$name$();\n" + "}\n" + "inline const std::string& $classname$::_internal_$name$() const {\n" + " if (_internal_has_$name$()) {\n" + " return $field_member$.Get();\n" + " }\n" + " return $default_string$;\n" + "}\n" + "inline void $classname$::_internal_set_$name$(const std::string& " + "value) {\n" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" + " }\n" + " $field_member$.Set($default_value_tag$, value, GetArena());\n" + "}\n" + "inline void $classname$::set_$name$(std::string&& value) {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" + " }\n" + " $field_member$.Set(\n" + " $default_value_tag$, ::std::move(value), GetArena());\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "inline void $classname$::set_$name$(const char* value) {\n" + "$annotate_accessor$" + " $null_check$" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" + " }\n" + " $field_member$.Set($default_value_tag$,\n" + " $string_piece$(value), GetArena());\n" + " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); - if (SupportsArenas(descriptor_)) { - format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " if (_internal_has_$name$()) {\n" - " return $field_member$.Get();\n" - " }\n" - " return *$default_variable$;\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$($default_variable$, value,\n" - " GetArenaNoVirtual());\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_set:$full_name$)\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$(\n" - " $default_variable$, ::std::move(value), GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - "$annotate_accessor$" - " $null_check$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$($default_variable$,\n" - " $string_piece$(value), GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" - "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$($default_variable$, value,\n" - " GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } - format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value,\n" - " size_t size) {\n" - "$annotate_accessor$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.Set$lite$(\n" - " $default_variable$, $string_piece$(\n" - " reinterpret_cast(value), size),\n" - " GetArenaNoVirtual());\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " return $field_member$.Mutable($default_variable$,\n" - " GetArenaNoVirtual());\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " if (_internal_has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " return $field_member$.Release($default_variable$,\n" - " GetArenaNoVirtual());\n" - " } else {\n" - " return nullptr;\n" - " }\n" - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if (has_$oneof_name$()) {\n" - " clear_$oneof_name$();\n" - " }\n" - " if ($name$ != nullptr) {\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($name$);\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" - "}\n"); - if (options_.opensource_runtime) { - format( - "inline std::string* $classname$::unsafe_arena_release_$name$() {\n" - "$annotate_accessor$" - " // " - "@@protoc_insertion_point(field_unsafe_arena_release:$full_name$)\n" - " $DCHK$(GetArenaNoVirtual() != nullptr);\n" - " if (_internal_has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " return $field_member$.UnsafeArenaRelease(\n" - " $default_variable$, GetArenaNoVirtual());\n" - " } else {\n" - " return nullptr;\n" - " }\n" - "}\n" - "inline void $classname$::unsafe_arena_set_allocated_$name$(" - "std::string* $name$) {\n" - "$annotate_accessor$" - " $DCHK$(GetArenaNoVirtual() != nullptr);\n" - " if (!_internal_has_$name$()) {\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " clear_$oneof_name$();\n" - " if ($name$) {\n" - " set_has_$name$();\n" - " $field_member$.UnsafeArenaSetAllocated($default_variable$, " - "$name$, GetArenaNoVirtual());\n" - " }\n" - " // @@protoc_insertion_point(field_unsafe_arena_set_allocated:" - "$full_name$)\n" - "}\n"); - } - } else { - // No-arena case. - format( - "inline const std::string& $classname$::_internal_$name$() const {\n" - " if (_internal_has_$name$()) {\n" - " return $field_member$.GetNoArena();\n" - " }\n" - " return *$default_variable$;\n" - "}\n" - "inline void $classname$::_internal_set_$name$(const std::string& " - "value) {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, value);\n" - "}\n" - "inline void $classname$::set_$name$(std::string&& value) {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_set:$full_name$)\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, ::std::move(value));\n" - " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" - "}\n" - "inline void $classname$::set_$name$(const char* value) {\n" - "$annotate_accessor$" - " $null_check$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$,\n" - " $string_piece$(value));\n" - " // @@protoc_insertion_point(field_set_char:$full_name$)\n" - "}\n"); - if (!options_.opensource_runtime) { - format( - "inline void $classname$::set_$name$(::StringPiece value) {\n" - "$annotate_accessor$" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, value);\n" - " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" - "}\n"); - } + if (!options_.opensource_runtime) { format( - "inline " - "void $classname$::set_$name$(const $pointer_type$* value, size_t " - "size) {\n" + "inline void $classname$::set_$name$(::StringPiece value) {\n" "$annotate_accessor$" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " $field_member$.SetNoArena($default_variable$, $string_piece$(\n" - " reinterpret_cast(value), size));\n" - " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" - "}\n" - "inline std::string* $classname$::_internal_mutable_$name$() {\n" - " if (!_internal_has_$name$()) {\n" - " clear_$oneof_name$();\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" - " }\n" - " return $field_member$.MutableNoArena($default_variable$);\n" - "}\n" - "inline std::string* $classname$::$release_name$() {\n" - "$annotate_accessor$" - " // @@protoc_insertion_point(field_release:$full_name$)\n" - " if (_internal_has_$name$()) {\n" - " clear_has_$oneof_name$();\n" - " return $field_member$.ReleaseNoArena($default_variable$);\n" - " } else {\n" - " return nullptr;\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" " }\n" - "}\n" - "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" - "$annotate_accessor$" - " if (has_$oneof_name$()) {\n" - " clear_$oneof_name$();\n" - " }\n" - " if ($name$ != nullptr) {\n" - " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($name$);\n" - " }\n" - " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + " $field_member$.Set($default_value_tag$, value, GetArena());\n" + " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); } + format( + "inline " + "void $classname$::set_$name$(const $pointer_type$* value,\n" + " size_t size) {\n" + "$annotate_accessor$" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" + " }\n" + " $field_member$.Set(\n" + " $default_value_tag$, $string_piece$(\n" + " reinterpret_cast(value), size),\n" + " GetArena());\n" + " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" + "}\n" + "inline std::string* $classname$::_internal_mutable_$name$() {\n" + " if (!_internal_has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" + " }\n" + " return $field_member$.Mutable(\n" + " $default_variable_or_tag$, GetArena());\n" + "}\n" + "inline std::string* $classname$::$release_name$() {\n" + "$annotate_accessor$" + " // @@protoc_insertion_point(field_release:$full_name$)\n" + " if (_internal_has_$name$()) {\n" + " clear_has_$oneof_name$();\n" + " return $field_member$.ReleaseNonDefault($init_value$, GetArena());\n" + " } else {\n" + " return nullptr;\n" + " }\n" + "}\n" + "inline void $classname$::set_allocated_$name$(std::string* $name$) {\n" + "$annotate_accessor$" + " if (has_$oneof_name$()) {\n" + " clear_$oneof_name$();\n" + " }\n" + " if ($name$ != nullptr) {\n" + " set_has_$name$();\n" + " $field_member$.UnsafeSetDefault($name$);\n" + " ::$proto_ns$::Arena* arena = GetArena();\n" + " if (arena != nullptr) {\n" + " arena->Own($name$);\n" + " }\n" + " }\n" + " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" + "}\n"); } void StringOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - if (SupportsArenas(descriptor_)) { - format( - "$field_member$.Destroy($default_variable$,\n" - " GetArenaNoVirtual());\n"); - } else { - format("$field_member$.DestroyNoArena($default_variable$);\n"); - } + format("$field_member$.Destroy($default_value_tag$, GetArena());\n"); } void StringOneofFieldGenerator::GenerateMessageClearingCode( @@ -926,19 +553,7 @@ void StringOneofFieldGenerator::GenerateSwappingCode( void StringOneofFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { - Formatter format(printer, variables_); - format( - "$ns$::_$classname$_default_instance_.$name$_.UnsafeSetDefault(\n" - " $default_variable$);\n"); -} - -void StringOneofFieldGenerator::GenerateDestructorCode( - io::Printer* printer) const { - Formatter format(printer, variables_); - format( - "if (_internal_has_$name$()) {\n" - " $field_member$.DestroyNoArena($default_variable$);\n" - "}\n"); + // Nothing required here. } // =================================================================== diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index f39a93abe256..91424d221c53 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -63,18 +63,8 @@ class StringFieldGenerator : public FieldGenerator { void GenerateConstructorCode(io::Printer* printer) const; void GenerateCopyConstructorCode(io::Printer* printer) const; void GenerateDestructorCode(io::Printer* printer) const; - bool GenerateArenaDestructorCode(io::Printer* printer) const; - void GenerateDefaultInstanceAllocator(io::Printer* printer) const; void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; void GenerateByteSize(io::Printer* printer) const; - uint32 CalculateFieldTag() const; - bool IsInlined() const { return inlined_; } - - bool MergeFromCodedStreamNeedsArena() const; - - protected: - const bool lite_; - bool inlined_; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); @@ -95,7 +85,6 @@ class StringOneofFieldGenerator : public StringFieldGenerator { void GenerateMessageClearingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; void GenerateConstructorCode(io::Printer* printer) const; - void GenerateDestructorCode(io::Printer* printer) const; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator); diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.inc b/src/google/protobuf/compiler/cpp/cpp_unittest.inc index 2efbd6d384ab..c8238abdef3b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.inc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.inc @@ -44,12 +44,10 @@ // correctly and produces the interfaces we expect, which is why this test // is written this way. -#include - #include #include -#include +#include #include #if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) // We exclude this large proto from cmake build because it's too large for @@ -100,8 +98,8 @@ class MockErrorCollector : public MultiFileErrorCollector { // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, int line, int column, const std::string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", - filename, line, column, message); + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, + message); } }; @@ -403,69 +401,6 @@ TEST(GENERATED_MESSAGE_TEST_NAME, StringCharStarLength) { EXPECT_EQ("wx", message.repeated_string(0)); } -TEST(GENERATED_MESSAGE_TEST_NAME, StringMove) { - // Verify that we trigger the move behavior on a scalar setter. - protobuf_unittest_no_arena::TestAllTypes message; - { - std::string tmp(32, 'a'); - - const char* old_data = tmp.data(); - message.set_optional_string(std::move(tmp)); - const char* new_data = message.optional_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(std::string(32, 'a'), message.optional_string()); - - std::string tmp2(32, 'b'); - old_data = tmp2.data(); - message.set_optional_string(std::move(tmp2)); - new_data = message.optional_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(std::string(32, 'b'), message.optional_string()); - } - - // Verify that we trigger the move behavior on a oneof setter. - { - std::string tmp(32, 'a'); - - const char* old_data = tmp.data(); - message.set_oneof_string(std::move(tmp)); - const char* new_data = message.oneof_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(std::string(32, 'a'), message.oneof_string()); - - std::string tmp2(32, 'b'); - old_data = tmp2.data(); - message.set_oneof_string(std::move(tmp2)); - new_data = message.oneof_string().data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(std::string(32, 'b'), message.oneof_string()); - } - - // Verify that we trigger the move behavior on a repeated setter. - { - std::string tmp(32, 'a'); - - const char* old_data = tmp.data(); - message.add_repeated_string(std::move(tmp)); - const char* new_data = message.repeated_string(0).data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(std::string(32, 'a'), message.repeated_string(0)); - - std::string tmp2(32, 'b'); - old_data = tmp2.data(); - message.set_repeated_string(0, std::move(tmp2)); - new_data = message.repeated_string(0).data(); - - EXPECT_EQ(old_data, new_data); - EXPECT_EQ(std::string(32, 'b'), message.repeated_string(0)); - } -} - TEST(GENERATED_MESSAGE_TEST_NAME, CopyFrom) { UNITTEST::TestAllTypes message1, message2; @@ -1683,6 +1618,26 @@ TEST_F(OneofTest, SetAllocatedString) { EXPECT_EQ(kHello, message.foo_string()); } +TEST_F(OneofTest, ArenaSetAllocatedString) { + // Check that set_allocated_foo() works for strings. + Arena arena; + UNITTEST::TestOneof2* message = + Arena::CreateMessage(&arena); + + EXPECT_FALSE(message->has_foo_string()); + const std::string kHello("hello"); + message->set_foo_string(kHello); + EXPECT_TRUE(message->has_foo_string()); + + message->set_allocated_foo_string(NULL); + EXPECT_FALSE(message->has_foo_string()); + EXPECT_EQ("", message->foo_string()); + + message->set_allocated_foo_string(new std::string(kHello)); + EXPECT_TRUE(message->has_foo_string()); + EXPECT_EQ(kHello, message->foo_string()); +} + TEST_F(OneofTest, SetMessage) { // Check that setting a message field works diff --git a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc index 978fdf02b6fb..86bacf8103bd 100644 --- a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -65,11 +65,11 @@ class MockErrorCollector : public MultiFileErrorCollector { MockErrorCollector() {} ~MockErrorCollector() {} - string text_; + std::string text_; // implements ErrorCollector --------------------------------------- - void AddError(const string& filename, int line, int column, - const string& message) { + void AddError(const std::string& filename, int line, int column, + const std::string& message) { strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, message); } @@ -77,14 +77,14 @@ class MockErrorCollector : public MultiFileErrorCollector { class MockGeneratorContext : public GeneratorContext { public: - void ExpectFileMatches(const string& virtual_filename, - const string& physical_filename) { + void ExpectFileMatches(const std::string& virtual_filename, + const std::string& physical_filename) { auto it = files_.find(virtual_filename); ASSERT_TRUE(it != files_.end()) << "Generator failed to generate file: " << virtual_filename; - string expected_contents = *it->second; + std::string expected_contents = *it->second; - string actual_contents; + std::string actual_contents; GOOGLE_CHECK_OK( File::GetContentsAsText(TestSourceDir() + "/" + physical_filename, &actual_contents, true)) @@ -97,7 +97,7 @@ class MockGeneratorContext : public GeneratorContext { // implements GeneratorContext -------------------------------------- - virtual io::ZeroCopyOutputStream* Open(const string& filename) { + virtual io::ZeroCopyOutputStream* Open(const std::string& filename) { auto& map_slot = files_[filename]; map_slot.reset(new std::string); return new io::StringOutputStream(map_slot.get()); @@ -110,7 +110,7 @@ class MockGeneratorContext : public GeneratorContext { class GenerateAndTest { public: GenerateAndTest() {} - void Run(const FileDescriptor* proto_file, string file1, string file2) { + void Run(const FileDescriptor* proto_file, std::string file1, std::string file2) { ASSERT_TRUE(proto_file != NULL) << TestSourceDir(); ASSERT_TRUE(generator_.Generate(proto_file, parameter_, &context_, &error_)); @@ -123,14 +123,14 @@ class GenerateAndTest { private: Generator generator_; MockGeneratorContext context_; - string error_; - string parameter_; + std::string error_; + std::string parameter_; }; TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) { // Skip this whole test if the csharp directory doesn't exist (i.e., a C++11 // only distribution). - string descriptor_file_name = + std::string descriptor_file_name = "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs"; if (!File::Exists(TestSourceDir() + "/" + descriptor_file_name)) { return; diff --git a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc index a4e9ff407832..225d6dc54ea1 100644 --- a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc +++ b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc @@ -47,7 +47,7 @@ namespace csharp { // is inlined in the relevant code. If more control is required, that code can be moved here. void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { - string comments = location.leading_comments.empty() ? + std::string comments = location.leading_comments.empty() ? location.trailing_comments : location.leading_comments; if (comments.empty()) { return; @@ -56,7 +56,7 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { // node of a summary element, not part of an attribute. comments = StringReplace(comments, "&", "&", true); comments = StringReplace(comments, "<", "<", true); - std::vector lines; + std::vector lines; lines = Split(comments, "\n", false); // TODO: We really should work out which part to put in the summary and which to put in the remarks... // but that needs to be part of a bigger effort to understand the markdown better anyway. @@ -66,17 +66,18 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { // to preserve the blank lines themselves, as this is relevant in the markdown. // Note that we can't remove leading or trailing whitespace as *that's* relevant in markdown too. // (We don't skip "just whitespace" lines, either.) - for (std::vector::iterator it = lines.begin(); it != lines.end(); ++it) { - string line = *it; - if (line.empty()) { - last_was_empty = true; - } else { - if (last_was_empty) { - printer->Print("///\n"); - } - last_was_empty = false; - printer->Print("///$line$\n", "line", *it); + for (std::vector::iterator it = lines.begin(); + it != lines.end(); ++it) { + std::string line = *it; + if (line.empty()) { + last_was_empty = true; + } else { + if (last_was_empty) { + printer->Print("///\n"); } + last_was_empty = false; + printer->Print("///$line$\n", "line", *it); + } } printer->Print("/// \n"); } diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc index 2baefd84ed93..6d379235ce2c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum.cc +++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc @@ -61,12 +61,13 @@ void EnumGenerator::Generate(io::Printer* printer) { "access_level", class_access_level(), "name", descriptor_->name()); printer->Indent(); - std::set used_names; + std::set used_names; std::set used_number; for (int i = 0; i < descriptor_->value_count(); i++) { WriteEnumValueDocComment(printer, descriptor_->value(i)); - string original_name = descriptor_->value(i)->name(); - string name = GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name()); + std::string original_name = descriptor_->value(i)->name(); + std::string name = + GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name()); // Make sure we don't get any duplicate names due to prefix removal. while (!used_names.insert(name).second) { // It's possible we'll end up giving this warning multiple times, but that's better than not at all. diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index 454f4cb14413..f5f4c2391ea7 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -51,7 +51,7 @@ namespace compiler { namespace csharp { void FieldGeneratorBase::SetCommonFieldVariables( - std::map* variables) { + std::map* variables) { // Note: this will be valid even though the tag emitted for packed and unpacked versions of // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which // never effects the tag size. @@ -63,7 +63,7 @@ void FieldGeneratorBase::SetCommonFieldVariables( uint tag = internal::WireFormat::MakeTag(descriptor_); uint8 tag_array[5]; io::CodedOutputStream::WriteTagToArray(tag, tag_array); - string tag_bytes = StrCat(tag_array[0]); + std::string tag_bytes = StrCat(tag_array[0]); for (int i = 1; i < part_tag_size; i++) { tag_bytes += ", " + StrCat(tag_array[i]); } @@ -96,20 +96,20 @@ void FieldGeneratorBase::SetCommonFieldVariables( (*variables)["default_value"] = default_value(); (*variables)["capitalized_type_name"] = capitalized_type_name(); (*variables)["number"] = number(); - if (has_default_value() && !IsProto2(descriptor_->file())) { + if (has_default_value() && !SupportsPresenceApi(descriptor_)) { (*variables)["name_def_message"] = (*variables)["name"] + "_ = " + (*variables)["default_value"]; } else { (*variables)["name_def_message"] = (*variables)["name"] + "_"; } - if (IsProto2(descriptor_->file())) { + if (SupportsPresenceApi(descriptor_)) { (*variables)["has_property_check"] = "Has" + (*variables)["property_name"]; (*variables)["other_has_property_check"] = "other.Has" + (*variables)["property_name"]; (*variables)["has_not_property_check"] = "!" + (*variables)["has_property_check"]; (*variables)["other_has_not_property_check"] = "!" + (*variables)["other_has_property_check"]; if (presenceIndex_ != -1) { - string hasBitsNumber = StrCat(presenceIndex_ / 32); - string hasBitsMask = StrCat(1 << (presenceIndex_ % 32)); + std::string hasBitsNumber = StrCat(presenceIndex_ / 32); + std::string hasBitsMask = StrCat(1 << (presenceIndex_ % 32)); (*variables)["has_field_check"] = "(_hasBits" + hasBitsNumber + " & " + hasBitsMask + ") != 0"; (*variables)["set_has_field"] = "_hasBits" + hasBitsNumber + " |= " + hasBitsMask; (*variables)["clear_has_field"] = "_hasBits" + hasBitsNumber + " &= ~" + hasBitsMask; @@ -123,9 +123,9 @@ void FieldGeneratorBase::SetCommonFieldVariables( } void FieldGeneratorBase::SetCommonOneofFieldVariables( - std::map* variables) { + std::map* variables) { (*variables)["oneof_name"] = oneof_name(); - if (IsProto2(descriptor_->file())) { + if (SupportsPresenceApi(descriptor_)) { (*variables)["has_property_check"] = "Has" + property_name(); } else { (*variables)["has_property_check"] = @@ -161,6 +161,18 @@ void FieldGeneratorBase::GenerateExtensionCode(io::Printer* printer) { // and repeated fields need this default is to not generate any code } +void FieldGeneratorBase::GenerateParsingCode(io::Printer* printer, bool use_parse_context) { + // for some field types the value of "use_parse_context" doesn't matter, + // so we fallback to the default implementation. + GenerateParsingCode(printer); +} + +void FieldGeneratorBase::GenerateSerializationCode(io::Printer* printer, bool use_write_context) { + // for some field types the value of "use_write_context" doesn't matter, + // so we fallback to the default implementation. + GenerateSerializationCode(printer); +} + void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) { if (descriptor_->options().deprecated()) { printer->Print("[global::System.ObsoleteAttribute]\n"); @@ -204,7 +216,7 @@ std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) { if (IsWrapperType(descriptor)) { const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0); - string wrapped_field_type_name = type_name(wrapped_field); + std::string wrapped_field_type_name = type_name(wrapped_field); // String and ByteString go to the same type; other wrapped types // go to the nullable equivalent. if (wrapped_field->type() == FieldDescriptor::TYPE_STRING || diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h index 594461da7845..f875fa11ace4 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.h +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h @@ -61,7 +61,9 @@ class FieldGeneratorBase : public SourceGeneratorBase { virtual void GenerateMembers(io::Printer* printer) = 0; virtual void GenerateMergingCode(io::Printer* printer) = 0; virtual void GenerateParsingCode(io::Printer* printer) = 0; + virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context); virtual void GenerateSerializationCode(io::Printer* printer) = 0; + virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context); virtual void GenerateSerializedSizeCode(io::Printer* printer) = 0; virtual void WriteHash(io::Printer* printer) = 0; @@ -72,14 +74,15 @@ class FieldGeneratorBase : public SourceGeneratorBase { protected: const FieldDescriptor* descriptor_; const int presenceIndex_; - std::map variables_; + std::map variables_; void AddDeprecatedFlag(io::Printer* printer); void AddNullCheck(io::Printer* printer); void AddNullCheck(io::Printer* printer, const std::string& name); void AddPublicMemberAttributes(io::Printer* printer); - void SetCommonOneofFieldVariables(std::map* variables); + void SetCommonOneofFieldVariables( + std::map* variables); std::string oneof_property_name(); std::string oneof_name(); @@ -94,7 +97,7 @@ class FieldGeneratorBase : public SourceGeneratorBase { std::string capitalized_type_name(); private: - void SetCommonFieldVariables(std::map* variables); + void SetCommonFieldVariables(std::map* variables); std::string GetStringDefaultValueInternal(const FieldDescriptor* descriptor); std::string GetBytesDefaultValueInternal(const FieldDescriptor* descriptor); }; diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc index b335522032f3..5ce0651738b2 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc @@ -48,19 +48,24 @@ namespace protobuf { namespace compiler { namespace csharp { +Generator::Generator() {} +Generator::~Generator() {} + +uint64_t Generator::GetSupportedFeatures() const { + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; +} + void GenerateFile(const FileDescriptor* file, io::Printer* printer, const Options* options) { ReflectionClassGenerator reflectionClassGenerator(file, options); reflectionClassGenerator.Generate(printer); } -bool Generator::Generate( - const FileDescriptor* file, - const string& parameter, - GeneratorContext* generator_context, - string* error) const { - - std::vector > options; +bool Generator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const { + std::vector > options; ParseGeneratorParameter(parameter, &options); struct Options cli_options; @@ -81,7 +86,7 @@ bool Generator::Generate( } } - string filename_error = ""; + std::string filename_error = ""; std::string filename = GetOutputFile(file, cli_options.file_extension, cli_options.base_namespace_specified, diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.h b/src/google/protobuf/compiler/csharp/csharp_generator.h index da72e0e776cb..f41f9b8358ad 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.h +++ b/src/google/protobuf/compiler/csharp/csharp_generator.h @@ -50,11 +50,14 @@ namespace csharp { // CodeGenerator with the CommandLineInterface in your main() function. class PROTOC_EXPORT Generator : public CodeGenerator { public: - virtual bool Generate( - const FileDescriptor* file, - const string& parameter, - GeneratorContext* generator_context, - string* error) const; + Generator(); + ~Generator(); + bool Generate( + const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + uint64_t GetSupportedFeatures() const override; }; } // namespace csharp diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index 98aa246c2851..32ef3994f16e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -143,7 +143,7 @@ std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor) { std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter, bool preserve_period) { - string result; + std::string result; // Note: I distrust ctype.h due to locales. for (int i = 0; i < input.size(); i++) { if ('a' <= input[i] && input[i] <= 'z') { @@ -195,7 +195,7 @@ std::string UnderscoresToPascalCase(const std::string& input) { // Lower letter Alphanumeric Same as current // Upper letter Alphanumeric Lower std::string ShoutyToPascalCase(const std::string& input) { - string result; + std::string result; // Simple way of implementing "always start with upper" char previous = '_'; for (int i = 0; i < input.size(); i++) { @@ -325,7 +325,7 @@ std::string ToCSharpName(const std::string& name, const FileDescriptor* file) { if (!result.empty()) { result += '.'; } - string classname; + std::string classname; if (file->package().empty()) { classname = name; } else { @@ -396,19 +396,20 @@ std::string GetPropertyName(const FieldDescriptor* descriptor) { std::string GetOutputFile(const FileDescriptor* descriptor, const std::string file_extension, const bool generate_directories, - const std::string base_namespace, string* error) { - string relative_filename = GetFileNameBase(descriptor) + file_extension; + const std::string base_namespace, + std::string* error) { + std::string relative_filename = GetFileNameBase(descriptor) + file_extension; if (!generate_directories) { return relative_filename; } - string ns = GetFileNamespace(descriptor); - string namespace_suffix = ns; + std::string ns = GetFileNamespace(descriptor); + std::string namespace_suffix = ns; if (!base_namespace.empty()) { // Check that the base_namespace is either equal to or a leading part of // the file namespace. This isn't just a simple prefix; "Foo.B" shouldn't // be regarded as a prefix of "Foo.Bar". The simplest option is to add "." // to both. - string extended_ns = ns + "."; + std::string extended_ns = ns + "."; if (extended_ns.find(base_namespace + ".") != 0) { *error = "Namespace " + ns + " is not a prefix namespace of base namespace " + base_namespace; return ""; // This will be ignored, because we've set an error. @@ -419,7 +420,7 @@ std::string GetOutputFile(const FileDescriptor* descriptor, } } - string namespace_dir = StringReplace(namespace_suffix, ".", "/", true); + std::string namespace_dir = StringReplace(namespace_suffix, ".", "/", true); if (!namespace_dir.empty()) { namespace_dir += "/"; } @@ -515,13 +516,13 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, } } else { if (IsWrapperType(descriptor)) { - if (descriptor->containing_oneof()) { + if (descriptor->real_containing_oneof()) { return new WrapperOneofFieldGenerator(descriptor, presenceIndex, options); } else { return new WrapperFieldGenerator(descriptor, presenceIndex, options); } } else { - if (descriptor->containing_oneof()) { + if (descriptor->real_containing_oneof()) { return new MessageOneofFieldGenerator(descriptor, presenceIndex, options); } else { return new MessageFieldGenerator(descriptor, presenceIndex, options); @@ -532,7 +533,7 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, if (descriptor->is_repeated()) { return new RepeatedEnumFieldGenerator(descriptor, presenceIndex, options); } else { - if (descriptor->containing_oneof()) { + if (descriptor->real_containing_oneof()) { return new EnumOneofFieldGenerator(descriptor, presenceIndex, options); } else { return new EnumFieldGenerator(descriptor, presenceIndex, options); @@ -542,7 +543,7 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, if (descriptor->is_repeated()) { return new RepeatedPrimitiveFieldGenerator(descriptor, presenceIndex, options); } else { - if (descriptor->containing_oneof()) { + if (descriptor->real_containing_oneof()) { return new PrimitiveOneofFieldGenerator(descriptor, presenceIndex, options); } else { return new PrimitiveFieldGenerator(descriptor, presenceIndex, options); diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h index 6354e9e6aafc..a6009c8b1e4e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.h +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -138,7 +138,7 @@ inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) { if (!IsDescriptorProto(descriptor->file())) { return false; } - const string name = descriptor->full_name(); + const std::string name = descriptor->full_name(); return name == "google.protobuf.FileOptions" || name == "google.protobuf.MessageOptions" || name == "google.protobuf.FieldOptions" || @@ -158,6 +158,33 @@ inline bool IsProto2(const FileDescriptor* descriptor) { return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2; } +inline bool SupportsPresenceApi(const FieldDescriptor* descriptor) { + // Unlike most languages, we don't generate Has/Clear members for message + // types, because they can always be set to null in C#. They're not really + // needed for oneof fields in proto2 either, as everything can be done via + // oneof case, but we follow the convention from other languages. Proto3 + // oneof fields never have Has/Clear members - but will also never have + // the explicit optional keyword either. + // + // None of the built-in helpers (descriptor->has_presence() etc) describe + // quite the behavior we want, so the rules are explicit below. + + if (descriptor->is_repeated() || + descriptor->type() == FieldDescriptor::TYPE_MESSAGE) { + return false; + } + // has_optional_keyword() has more complex rules for proto2, but that + // doesn't matter given the first part of this condition. + return IsProto2(descriptor->file()) || descriptor->has_optional_keyword(); +} + +inline bool RequiresPresenceBit(const FieldDescriptor* descriptor) { + return SupportsPresenceApi(descriptor) && + !IsNullable(descriptor) && + !descriptor->is_extension() && + !descriptor->real_containing_oneof(); +} + } // namespace csharp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index f3f09ea4546b..44c13e2f637a 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -94,15 +94,27 @@ void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) { } void MapFieldGenerator::GenerateParsingCode(io::Printer* printer) { + GenerateParsingCode(printer, true); +} + +void MapFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) { printer->Print( variables_, - "$name$_.AddEntriesFrom(input, _map_$name$_codec);\n"); + use_parse_context + ? "$name$_.AddEntriesFrom(ref input, _map_$name$_codec);\n" + : "$name$_.AddEntriesFrom(input, _map_$name$_codec);\n"); } void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + GenerateSerializationCode(printer, true); +} + +void MapFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) { printer->Print( variables_, - "$name$_.WriteTo(output, _map_$name$_codec);\n"); + use_write_context + ? "$name$_.WriteTo(ref output, _map_$name$_codec);\n" + : "$name$_.WriteTo(output, _map_$name$_codec);\n"); } void MapFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.h b/src/google/protobuf/compiler/csharp/csharp_map_field.h index b920b9f2257b..54156ecf5408 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.h @@ -56,7 +56,9 @@ class MapFieldGenerator : public FieldGeneratorBase { virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context); virtual void GenerateSerializationCode(io::Printer* printer); + virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context); virtual void GenerateSerializedSizeCode(io::Printer* printer); virtual void WriteHash(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index 67f28929196c..5aec7ca743e0 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -72,15 +72,13 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, std::sort(fields_by_number_.begin(), fields_by_number_.end(), CompareFieldNumbers); - if (IsProto2(descriptor_->file())) { - int primitiveCount = 0; - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - if (!IsNullable(field)) { - primitiveCount++; - if (has_bit_field_count_ == 0 || (primitiveCount % 32) == 0) { - has_bit_field_count_++; - } + int presence_bit_count = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (RequiresPresenceBit(field)) { + presence_bit_count++; + if (has_bit_field_count_ == 0 || (presence_bit_count % 32) == 0) { + has_bit_field_count_++; } } } @@ -114,7 +112,7 @@ void MessageGenerator::AddSerializableAttribute(io::Printer* printer) { } void MessageGenerator::Generate(io::Printer* printer) { - std::map vars; + std::map vars; vars["class_name"] = class_name(); vars["access_level"] = class_access_level(); @@ -127,12 +125,15 @@ void MessageGenerator::Generate(io::Printer* printer) { "$access_level$ sealed partial class $class_name$ : "); if (has_extension_ranges_) { - printer->Print(vars, "pb::IExtendableMessage<$class_name$>"); + printer->Print(vars, "pb::IExtendableMessage<$class_name$>\n"); } else { - printer->Print(vars, "pb::IMessage<$class_name$>"); + printer->Print(vars, "pb::IMessage<$class_name$>\n"); } - printer->Print(" {\n"); + printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n"); + printer->Print(" , pb::IBufferMessage\n"); + printer->Print("#endif\n"); + printer->Print("{\n"); printer->Indent(); // All static fields and properties @@ -222,11 +223,12 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print("\n"); } - // oneof properties - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); - vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); - vars["original_name"] = descriptor_->oneof_decl(i)->name(); + // oneof properties (for real oneofs, which come before synthetic ones) + for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + vars["name"] = UnderscoresToCamelCase(oneof->name(), false); + vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true); + vars["original_name"] = oneof->name(); printer->Print( vars, "private object $name$_;\n" @@ -234,8 +236,8 @@ void MessageGenerator::Generate(io::Printer* printer) { "public enum $property_name$OneofCase {\n"); printer->Indent(); printer->Print("None = 0,\n"); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < oneof->field_count(); j++) { + const FieldDescriptor* field = oneof->field(j); printer->Print("$field_property_name$ = $index$,\n", "field_property_name", GetPropertyName(field), "index", StrCat(field->number())); @@ -372,7 +374,7 @@ bool MessageGenerator::HasNestedGeneratedTypes() } void MessageGenerator::GenerateCloningCode(io::Printer* printer) { - std::map vars; + std::map vars; WriteGeneratedCodeAttributes(printer); vars["class_name"] = class_name(); printer->Print( @@ -382,23 +384,24 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { for (int i = 0; i < has_bit_field_count_; i++) { printer->Print("_hasBits$i$ = other._hasBits$i$;\n", "i", StrCat(i)); } - // Clone non-oneof fields first + // Clone non-oneof fields first (treating optional proto3 fields as non-oneof) for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { - std::unique_ptr generator( - CreateFieldGeneratorInternal(descriptor_->field(i))); - generator->GenerateCloningCode(printer); + const FieldDescriptor* field = descriptor_->field(i); + if (field->real_containing_oneof()) { + continue; } - } - // Clone just the right field for each oneof - for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { - vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); - vars["property_name"] = UnderscoresToCamelCase( - descriptor_->oneof_decl(i)->name(), true); + std::unique_ptr generator(CreateFieldGeneratorInternal(field)); + generator->GenerateCloningCode(printer); + } + // Clone just the right field for each real oneof + for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) { + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + vars["name"] = UnderscoresToCamelCase(oneof->name(), false); + vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true); printer->Print(vars, "switch (other.$property_name$Case) {\n"); printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < oneof->field_count(); j++) { + const FieldDescriptor* field = oneof->field(j); std::unique_ptr generator(CreateFieldGeneratorInternal(field)); vars["field_property_name"] = GetPropertyName(field); printer->Print( @@ -435,7 +438,7 @@ void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { } void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { - std::map vars; + std::map vars; vars["class_name"] = class_name(); // Equality @@ -461,9 +464,9 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { CreateFieldGeneratorInternal(descriptor_->field(i))); generator->WriteEquals(printer); } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n", - "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); + for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { + printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n", + "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); } if (has_extension_ranges_) { printer->Print( @@ -488,9 +491,9 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { CreateFieldGeneratorInternal(descriptor_->field(i))); generator->WriteHash(printer); } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print("hash ^= (int) $name$Case_;\n", - "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false)); + for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { + printer->Print("hash ^= (int) $name$Case_;\n", + "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false)); } if (has_extension_ranges_) { printer->Print( @@ -517,34 +520,26 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) WriteGeneratedCodeAttributes(printer); printer->Print( "public void WriteTo(pb::CodedOutputStream output) {\n"); + printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n"); printer->Indent(); + printer->Print("output.WriteRawMessage(this);\n"); + printer->Outdent(); + printer->Print("#else\n"); + printer->Indent(); + GenerateWriteToBody(printer, false); + printer->Outdent(); + printer->Print("#endif\n"); + printer->Print("}\n\n"); - // Serialize all the fields - for (int i = 0; i < fields_by_number().size(); i++) { - std::unique_ptr generator( - CreateFieldGeneratorInternal(fields_by_number()[i])); - generator->GenerateSerializationCode(printer); - } - - if (has_extension_ranges_) { - // Serialize extensions - printer->Print( - "if (_extensions != null) {\n" - " _extensions.WriteTo(output);\n" - "}\n"); - } - - // Serialize unknown fields - printer->Print( - "if (_unknownFields != null) {\n" - " _unknownFields.WriteTo(output);\n" - "}\n"); - - // TODO(jonskeet): Memoize size of frozen messages? + printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print("void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {\n"); + printer->Indent(); + GenerateWriteToBody(printer, true); printer->Outdent(); - printer->Print( - "}\n" - "\n"); + printer->Print("}\n"); + printer->Print("#endif\n\n"); + WriteGeneratedCodeAttributes(printer); printer->Print( "public int CalculateSize() {\n"); @@ -573,11 +568,44 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) printer->Print("}\n\n"); } +void MessageGenerator::GenerateWriteToBody(io::Printer* printer, bool use_write_context) { + // Serialize all the fields + for (int i = 0; i < fields_by_number().size(); i++) { + std::unique_ptr generator( + CreateFieldGeneratorInternal(fields_by_number()[i])); + generator->GenerateSerializationCode(printer, use_write_context); + } + + if (has_extension_ranges_) { + // Serialize extensions + printer->Print( + use_write_context + ? "if (_extensions != null) {\n" + " _extensions.WriteTo(ref output);\n" + "}\n" + : "if (_extensions != null) {\n" + " _extensions.WriteTo(output);\n" + "}\n"); + } + + // Serialize unknown fields + printer->Print( + use_write_context + ? "if (_unknownFields != null) {\n" + " _unknownFields.WriteTo(ref output);\n" + "}\n" + : "if (_unknownFields != null) {\n" + " _unknownFields.WriteTo(output);\n" + "}\n"); + + // TODO(jonskeet): Memoize size of frozen messages? +} + void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { // Note: These are separate from GenerateMessageSerializationMethods() // because they need to be generated even for messages that are optimized // for code size. - std::map vars; + std::map vars; vars["class_name"] = class_name(); WriteGeneratedCodeAttributes(printer); @@ -589,22 +617,24 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { "if (other == null) {\n" " return;\n" "}\n"); - // Merge non-oneof fields + // Merge non-oneof fields, treating optional proto3 fields as normal fields for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { - std::unique_ptr generator( - CreateFieldGeneratorInternal(descriptor_->field(i))); - generator->GenerateMergingCode(printer); + const FieldDescriptor* field = descriptor_->field(i); + if (field->real_containing_oneof()) { + continue; } - } - // Merge oneof fields - for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { - vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); - vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); + std::unique_ptr generator(CreateFieldGeneratorInternal(field)); + generator->GenerateMergingCode(printer); + } + // Merge oneof fields (for non-synthetic oneofs) + for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) { + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + vars["name"] = UnderscoresToCamelCase(oneof->name(), false); + vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true); printer->Print(vars, "switch (other.$property_name$Case) {\n"); printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < oneof->field_count(); j++) { + const FieldDescriptor* field = oneof->field(j); vars["field_property_name"] = GetPropertyName(field); printer->Print( vars, @@ -630,10 +660,34 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Outdent(); printer->Print("}\n\n"); - WriteGeneratedCodeAttributes(printer); printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n"); + printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n"); + printer->Indent(); + printer->Print("input.ReadRawMessage(this);\n"); + printer->Outdent(); + printer->Print("#else\n"); + printer->Indent(); + GenerateMainParseLoop(printer, false); + printer->Outdent(); + printer->Print("#endif\n"); + printer->Print("}\n\n"); + + printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print("void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {\n"); printer->Indent(); + GenerateMainParseLoop(printer, true); + printer->Outdent(); + printer->Print("}\n"); // method + printer->Print("#endif\n\n"); + +} + +void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_parse_context) { + std::map vars; + vars["maybe_ref_input"] = use_parse_context ? "ref input" : "input"; + printer->Print( "uint tag;\n" "while ((tag = input.ReadTag()) != 0) {\n" @@ -647,16 +701,16 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { "end_tag", StrCat(end_tag_)); } if (has_extension_ranges_) { - printer->Print( + printer->Print(vars, "default:\n" - " if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {\n" - " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n" + " if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, $maybe_ref_input$)) {\n" + " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, $maybe_ref_input$);\n" " }\n" " break;\n"); } else { - printer->Print( + printer->Print(vars, "default:\n" - " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n" + " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, $maybe_ref_input$);\n" " break;\n"); } for (int i = 0; i < fields_by_number().size(); i++) { @@ -683,7 +737,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Indent(); std::unique_ptr generator( CreateFieldGeneratorInternal(field)); - generator->GenerateParsingCode(printer); + generator->GenerateParsingCode(printer, use_parse_context); printer->Print("break;\n"); printer->Outdent(); printer->Print("}\n"); @@ -692,14 +746,11 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Print("}\n"); // switch printer->Outdent(); printer->Print("}\n"); // while - printer->Outdent(); - printer->Print("}\n\n"); // method } // it's a waste of space to track presence for all values, so we only track them if they're not nullable int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) { - if (IsNullable(descriptor) || !IsProto2(descriptor->file()) || - descriptor->is_extension()) { + if (!RequiresPresenceBit(descriptor)) { return -1; } @@ -709,7 +760,7 @@ int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) { if (field == descriptor) { return index; } - if (!IsNullable(field)) { + if (RequiresPresenceBit(field)) { index++; } } diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h index 5642dc88120c..d02767e44b48 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.h +++ b/src/google/protobuf/compiler/csharp/csharp_message.h @@ -66,7 +66,9 @@ class MessageGenerator : public SourceGeneratorBase { bool has_extension_ranges_; void GenerateMessageSerializationMethods(io::Printer* printer); + void GenerateWriteToBody(io::Printer* printer, bool use_write_context); void GenerateMergingMethods(io::Printer* printer); + void GenerateMainParseLoop(io::Printer* printer, bool use_parse_context); int GetPresenceIndex(const FieldDescriptor* descriptor); FieldGeneratorBase* CreateFieldGeneratorInternal( diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index 412579831258..034fbd924270 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -53,7 +53,7 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, int presenceIndex, const Options *options) : FieldGeneratorBase(descriptor, presenceIndex, options) { - if (!IsProto2(descriptor_->file())) { + if (!SupportsPresenceApi(descriptor_)) { variables_["has_property_check"] = name() + "_ != null"; variables_["has_not_property_check"] = name() + "_ == null"; } @@ -77,7 +77,7 @@ void MessageFieldGenerator::GenerateMembers(io::Printer* printer) { " $name$_ = value;\n" " }\n" "}\n"); - if (IsProto2(descriptor_->file())) { + if (SupportsPresenceApi(descriptor_)) { printer->Print( variables_, "/// Gets whether the $descriptor_name$ field is set\n"); @@ -228,7 +228,7 @@ void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) { " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" " }\n" "}\n"); - if (IsProto2(descriptor_->file())) { + if (SupportsPresenceApi(descriptor_)) { printer->Print( variables_, "/// Gets whether the \"$descriptor_name$\" field is set\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_names.h b/src/google/protobuf/compiler/csharp/csharp_names.h index 44852721a85e..67e53b640108 100644 --- a/src/google/protobuf/compiler/csharp/csharp_names.h +++ b/src/google/protobuf/compiler/csharp/csharp_names.h @@ -60,14 +60,14 @@ namespace csharp { // // Returns: // The namespace to use for given file descriptor. -string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor); +std::string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor); // Requires: // descriptor != NULL // // Returns: // The fully-qualified C# class name. -string PROTOC_EXPORT GetClassName(const Descriptor* descriptor); +std::string PROTOC_EXPORT GetClassName(const Descriptor* descriptor); // Requires: // descriptor != NULL @@ -76,7 +76,8 @@ string PROTOC_EXPORT GetClassName(const Descriptor* descriptor); // The fully-qualified name of the C# class that provides // access to the file descriptor. Proto compiler generates // such class for each .proto file processed. -string PROTOC_EXPORT GetReflectionClassName(const FileDescriptor* descriptor); +std::string PROTOC_EXPORT +GetReflectionClassName(const FileDescriptor* descriptor); // Generates output file name for given file descriptor. If generate_directories // is true, the output file will be put under directory corresponding to file's @@ -92,10 +93,11 @@ string PROTOC_EXPORT GetReflectionClassName(const FileDescriptor* descriptor); // The file name to use as output file for given file descriptor. In case // of failure, this function will return empty string and error parameter // will contain the error message. -string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor, - const string file_extension, - const bool generate_directories, - const string base_namespace, string* error); +std::string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor, + const std::string file_extension, + const bool generate_directories, + const std::string base_namespace, + std::string* error); } // namespace csharp } // namespace compiler diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index eb7f70dda6b5..9df1dd6abd73 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -53,7 +53,7 @@ PrimitiveFieldGenerator::PrimitiveFieldGenerator( // TODO(jonskeet): Make this cleaner... is_value_type = descriptor->type() != FieldDescriptor::TYPE_STRING && descriptor->type() != FieldDescriptor::TYPE_BYTES; - if (!is_value_type && !IsProto2(descriptor_->file())) { + if (!is_value_type && !SupportsPresenceApi(descriptor_)) { variables_["has_property_check"] = variables_["property_name"] + ".Length != 0"; variables_["other_has_property_check"] = "other." + variables_["property_name"] + ".Length != 0"; } @@ -63,42 +63,65 @@ PrimitiveFieldGenerator::~PrimitiveFieldGenerator() { } void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { - // TODO(jonskeet): Work out whether we want to prevent the fields from ever being - // null, or whether we just handle it, in the cases of bytes and string. - // (Basically, should null-handling code be in the getter or the setter?) + + // Note: in multiple places, this code assumes that all fields + // that support presence are either nullable, or use a presence field bit. + // Fields which are oneof members are not generated here; they're generated in PrimitiveOneofFieldGenerator below. + // Extensions are not generated here either. + + + // Proto2 allows different default values to be specified. These are retained + // via static fields. They don't particularly need to be, but we don't need + // to change that. In Proto3 the default value we don't generate these + // fields, just using the literal instead. if (IsProto2(descriptor_->file())) { + // Note: "private readonly static" isn't as idiomatic as + // "private static readonly", but changing this now would create a lot of + // churn in generated code with near-to-zero benefit. printer->Print( variables_, "private readonly static $type_name$ $property_name$DefaultValue = $default_value$;\n\n"); + variables_["default_value_access"] = + variables_["property_name"] + "DefaultValue"; + } else { + variables_["default_value_access"] = variables_["default_value"]; } + // Declare the field itself. printer->Print( variables_, "private $type_name$ $name_def_message$;\n"); WritePropertyDocComment(printer, descriptor_); AddPublicMemberAttributes(printer); - if (IsProto2(descriptor_->file())) { - if (presenceIndex_ == -1) { + + // Most of the work is done in the property: + // Declare the property itself (the same for all options) + printer->Print(variables_, "$access_level$ $type_name$ $property_name$ {\n"); + + // Specify the "getter", which may need to check for a presence field. + if (SupportsPresenceApi(descriptor_)) { + if (IsNullable(descriptor_)) { printer->Print( variables_, - "$access_level$ $type_name$ $property_name$ {\n" - " get { return $name$_ ?? $property_name$DefaultValue; }\n" - " set {\n"); + " get { return $name$_ ?? $default_value_access$; }\n"); } else { printer->Print( variables_, - "$access_level$ $type_name$ $property_name$ {\n" - " get { if ($has_field_check$) { return $name$_; } else { return $property_name$DefaultValue; } }\n" - " set {\n"); + // Note: it's possible that this could be rewritten as a + // conditional ?: expression, but there's no significant benefit + // to changing it. + " get { if ($has_field_check$) { return $name$_; } else { return $default_value_access$; } }\n"); } } else { printer->Print( variables_, - "$access_level$ $type_name$ $property_name$ {\n" - " get { return $name$_; }\n" - " set {\n"); + " get { return $name$_; }\n"); } + + // Specify the "setter", which may need to set a field bit as well as the + // value. + printer->Print(" set {\n"); if (presenceIndex_ != -1) { printer->Print( variables_, @@ -116,8 +139,11 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( " }\n" "}\n"); - if (IsProto2(descriptor_->file())) { - printer->Print(variables_, "/// Gets whether the \"$descriptor_name$\" field is set\n"); + + // The "HasFoo" property, where required. + if (SupportsPresenceApi(descriptor_)) { + printer->Print(variables_, + "/// Gets whether the \"$descriptor_name$\" field is set\n"); AddPublicMemberAttributes(printer); printer->Print( variables_, @@ -133,8 +159,11 @@ void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { "$has_field_check$; }\n}\n"); } } - if (IsProto2(descriptor_->file())) { - printer->Print(variables_, "/// Clears the value of the \"$descriptor_name$\" field\n"); + + // The "ClearFoo" method, where required. + if (SupportsPresenceApi(descriptor_)) { + printer->Print(variables_, + "/// Clears the value of the \"$descriptor_name$\" field\n"); AddPublicMemberAttributes(printer); printer->Print( variables_, @@ -270,7 +299,7 @@ void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) { " $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n" " }\n" "}\n"); - if (IsProto2(descriptor_->file())) { + if (SupportsPresenceApi(descriptor_)) { printer->Print( variables_, "/// Gets whether the \"$descriptor_name$\" field is set\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc index 73309a7edd1e..04bc7bbb1bd2 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -78,15 +78,27 @@ void RepeatedEnumFieldGenerator::GenerateMergingCode(io::Printer* printer) { } void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) { + GenerateParsingCode(printer, true); +} + +void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) { printer->Print( variables_, - "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); + use_parse_context + ? "$name$_.AddEntriesFrom(ref input, _repeated_$name$_codec);\n" + : "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + GenerateSerializationCode(printer, true); +} + +void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) { printer->Print( variables_, - "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); + use_write_context + ? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n" + : "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h index c7a632a17d4f..9b9ebd48facd 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h @@ -59,7 +59,9 @@ class RepeatedEnumFieldGenerator : public FieldGeneratorBase { virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context); virtual void GenerateSerializationCode(io::Printer* printer); + virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context); virtual void GenerateSerializedSizeCode(io::Printer* printer); virtual void GenerateExtensionCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc index 4b4b37de1bb4..8a93cd13cfca 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -93,15 +93,27 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode(io::Printer* printer) { } void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) { + GenerateParsingCode(printer, true); +} + +void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) { printer->Print( variables_, - "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); + use_parse_context + ? "$name$_.AddEntriesFrom(ref input, _repeated_$name$_codec);\n" + : "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + GenerateSerializationCode(printer, true); +} + +void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) { printer->Print( variables_, - "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); + use_write_context + ? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n" + : "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h index 74f6874df263..90441b82ef32 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h @@ -59,7 +59,9 @@ class RepeatedMessageFieldGenerator : public FieldGeneratorBase { virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context); virtual void GenerateSerializationCode(io::Printer* printer); + virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context); virtual void GenerateSerializedSizeCode(io::Printer* printer); virtual void GenerateExtensionCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc index c1444ea124aa..0eacf91ce6ca 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -78,15 +78,27 @@ void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) } void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) { + GenerateParsingCode(printer, true); +} + +void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) { printer->Print( variables_, - "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); + use_parse_context + ? "$name$_.AddEntriesFrom(ref input, _repeated_$name$_codec);\n" + : "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + GenerateSerializationCode(printer, true); +} + +void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) { printer->Print( variables_, - "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); + use_write_context + ? "$name$_.WriteTo(ref output, _repeated_$name$_codec);\n" + : "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h index 2a3be4816809..23e77a9a2eaa 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h @@ -55,7 +55,9 @@ class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase { virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context); virtual void GenerateSerializationCode(io::Printer* printer); + virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context); virtual void GenerateSerializedSizeCode(io::Printer* printer); virtual void GenerateExtensionCode(io::Printer* printer); diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index add20ab9fe63..578f54ba697e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -81,7 +81,7 @@ void WrapperFieldGenerator::GenerateMembers(io::Printer* printer) { " $name$_ = value;\n" " }\n" "}\n\n"); - if (IsProto2(descriptor_->file())) { + if (SupportsPresenceApi(descriptor_)) { printer->Print( variables_, "/// Gets whether the $descriptor_name$ field is set\n"); @@ -114,20 +114,37 @@ void WrapperFieldGenerator::GenerateMergingCode(io::Printer* printer) { } void WrapperFieldGenerator::GenerateParsingCode(io::Printer* printer) { + GenerateParsingCode(printer, true); +} + +void WrapperFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) { printer->Print( variables_, - "$type_name$ value = _single_$name$_codec.Read(input);\n" - "if ($has_not_property_check$ || value != $default_value$) {\n" - " $property_name$ = value;\n" - "}\n"); + use_parse_context + ? "$type_name$ value = _single_$name$_codec.Read(ref input);\n" + "if ($has_not_property_check$ || value != $default_value$) {\n" + " $property_name$ = value;\n" + "}\n" + : "$type_name$ value = _single_$name$_codec.Read(input);\n" + "if ($has_not_property_check$ || value != $default_value$) {\n" + " $property_name$ = value;\n" + "}\n"); } void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + GenerateSerializationCode(printer, true); +} + +void WrapperFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) { printer->Print( variables_, - "if ($has_property_check$) {\n" - " _single_$name$_codec.WriteTagAndValue(output, $property_name$);\n" - "}\n"); + use_write_context + ? "if ($has_property_check$) {\n" + " _single_$name$_codec.WriteTagAndValue(ref output, $property_name$);\n" + "}\n" + : "if ($has_property_check$) {\n" + " _single_$name$_codec.WriteTagAndValue(output, $property_name$);\n" + "}\n"); } void WrapperFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { @@ -219,7 +236,7 @@ void WrapperOneofFieldGenerator::GenerateMembers(io::Printer* printer) { " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" " }\n" "}\n"); - if (IsProto2(descriptor_->file())) { + if (SupportsPresenceApi(descriptor_)) { printer->Print( variables_, "/// Gets whether the \"$descriptor_name$\" field is set\n"); @@ -248,18 +265,32 @@ void WrapperOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { } void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { + GenerateParsingCode(printer, true); +} + +void WrapperOneofFieldGenerator::GenerateParsingCode(io::Printer* printer, bool use_parse_context) { printer->Print( variables_, - "$property_name$ = _oneof_$name$_codec.Read(input);\n"); + use_parse_context + ? "$property_name$ = _oneof_$name$_codec.Read(ref input);\n" + : "$property_name$ = _oneof_$name$_codec.Read(input);\n"); } void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + GenerateSerializationCode(printer, true); +} + +void WrapperOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer, bool use_write_context) { // TODO: I suspect this is wrong... printer->Print( variables_, - "if ($has_property_check$) {\n" - " _oneof_$name$_codec.WriteTagAndValue(output, ($type_name$) $oneof_name$_);\n" - "}\n"); + use_write_context + ? "if ($has_property_check$) {\n" + " _oneof_$name$_codec.WriteTagAndValue(ref output, ($type_name$) $oneof_name$_);\n" + "}\n" + : "if ($has_property_check$) {\n" + " _oneof_$name$_codec.WriteTagAndValue(output, ($type_name$) $oneof_name$_);\n" + "}\n"); } void WrapperOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h index 394e27de595d..e9bd043f2276 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.h @@ -58,7 +58,9 @@ class WrapperFieldGenerator : public FieldGeneratorBase { virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context); virtual void GenerateSerializationCode(io::Printer* printer); + virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context); virtual void GenerateSerializedSizeCode(io::Printer* printer); virtual void GenerateExtensionCode(io::Printer* printer); @@ -83,7 +85,9 @@ class WrapperOneofFieldGenerator : public WrapperFieldGenerator { virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMergingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer, bool use_parse_context); virtual void GenerateSerializationCode(io::Printer* printer); + virtual void GenerateSerializationCode(io::Printer* printer, bool use_write_context); virtual void GenerateSerializedSizeCode(io::Printer* printer); }; diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index 400d5d07e849..23a4effe6372 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -231,8 +231,9 @@ const FileDescriptor* Importer::Import(const std::string& filename) { return pool_.FindFileByName(filename); } -void Importer::AddUnusedImportTrackFile(const std::string& file_name) { - pool_.AddUnusedImportTrackFile(file_name); +void Importer::AddUnusedImportTrackFile(const std::string& file_name, + bool is_error) { + pool_.AddUnusedImportTrackFile(file_name, is_error); } void Importer::ClearUnusedImportTrackFiles() { @@ -489,6 +490,22 @@ io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile( io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile( const std::string& filename) { + struct stat sb; + int ret = 0; + do { + ret = stat(filename.c_str(), &sb); + } while (ret != 0 && errno == EINTR); +#if defined(_WIN32) + if (ret == 0 && sb.st_mode & S_IFDIR) { + last_error_message_ = "Input file is a directory."; + return NULL; + } +#else + if (ret == 0 && S_ISDIR(sb.st_mode)) { + last_error_message_ = "Input file is a directory."; + return NULL; + } +#endif int file_descriptor; do { file_descriptor = open(filename.c_str(), O_RDONLY); diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h index fc4b47854536..db4a876c5bb6 100644 --- a/src/google/protobuf/compiler/importer.h +++ b/src/google/protobuf/compiler/importer.h @@ -178,7 +178,8 @@ class PROTOBUF_EXPORT Importer { // contents are stored. inline const DescriptorPool* pool() const { return &pool_; } - void AddUnusedImportTrackFile(const std::string& file_name); + void AddUnusedImportTrackFile(const std::string& file_name, + bool is_error = false); void ClearUnusedImportTrackFiles(); diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc index 111d66f8b207..daa197f46065 100644 --- a/src/google/protobuf/compiler/importer_unittest.cc +++ b/src/google/protobuf/compiler/importer_unittest.cc @@ -74,14 +74,14 @@ class MockErrorCollector : public MultiFileErrorCollector { // implements ErrorCollector --------------------------------------- void AddError(const std::string& filename, int line, int column, const std::string& message) { - strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, - column, message); + strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column, + message); } void AddWarning(const std::string& filename, int line, int column, const std::string& message) { - strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n", filename, - line, column, message); + strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n", filename, line, + column, message); } }; @@ -463,13 +463,14 @@ TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) { source_tree_.DiskFileToVirtualFile("../../baz", &virtual_file, &shadowing_disk_file)); - // "/foo" is not mapped (it should not be misintepreted as being under "."). + // "/foo" is not mapped (it should not be misinterpreted as being under "."). EXPECT_EQ(DiskSourceTree::NO_MAPPING, source_tree_.DiskFileToVirtualFile("/foo", &virtual_file, &shadowing_disk_file)); #ifdef WIN32 - // "C:\foo" is not mapped (it should not be misintepreted as being under "."). + // "C:\foo" is not mapped (it should not be misinterpreted as being under + // "."). EXPECT_EQ(DiskSourceTree::NO_MAPPING, source_tree_.DiskFileToVirtualFile("C:\\foo", &virtual_file, &shadowing_disk_file)); diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc index 9415eb5d21bc..51032c2742b3 100644 --- a/src/google/protobuf/compiler/java/java_enum.cc +++ b/src/google/protobuf/compiler/java/java_enum.cc @@ -77,9 +77,10 @@ void EnumGenerator::Generate(io::Printer* printer) { WriteEnumDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); printer->Print( - "public enum $classname$\n" + "$deprecation$public enum $classname$\n" " implements com.google.protobuf.ProtocolMessageEnum {\n", - "classname", descriptor_->name()); + "classname", descriptor_->name(), "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""); printer->Annotate("classname", descriptor_); printer->Indent(); @@ -142,9 +143,13 @@ void EnumGenerator::Generate(io::Printer* printer) { vars["number"] = StrCat(descriptor_->value(i)->number()); vars["{"] = ""; vars["}"] = ""; + vars["deprecation"] = descriptor_->value(i)->options().deprecated() + ? "@java.lang.Deprecated " + : ""; WriteEnumValueDocComment(printer, descriptor_->value(i)); printer->Print(vars, - "public static final int ${$$name$_VALUE$}$ = $number$;\n"); + "$deprecation$public static final int ${$$name$_VALUE$}$ = " + "$number$;\n"); printer->Annotate("{", "}", descriptor_->value(i)); } printer->Print("\n"); @@ -228,7 +233,25 @@ void EnumGenerator::Generate(io::Printer* printer) { if (HasDescriptorMethods(descriptor_, context_->EnforceLite())) { printer->Print( "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n" - " getValueDescriptor() {\n" + " getValueDescriptor() {\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + if (ordinal_is_index) { + printer->Print( + " if (this == UNRECOGNIZED) {\n" + " throw new java.lang.IllegalStateException(\n" + " \"Can't get the descriptor of an unrecognized enum " + "value.\");\n" + " }\n"); + } else { + printer->Print( + " if (index == -1) {\n" + " throw new java.lang.IllegalStateException(\n" + " \"Can't get the descriptor of an unrecognized enum " + "value.\");\n" + " }\n"); + } + } + printer->Print( " return getDescriptor().getValues().get($index_text$);\n" "}\n" "public final com.google.protobuf.Descriptors.EnumDescriptor\n" @@ -279,15 +302,22 @@ void EnumGenerator::Generate(io::Printer* printer) { // for every enum. printer->Print("values();\n"); } else { + printer->Print("getStaticValuesArray();\n"); + printer->Print("private static $classname$[] getStaticValuesArray() {\n", + "classname", descriptor_->name()); + printer->Indent(); printer->Print( - "{\n" - " "); + "return new $classname$[] {\n" + " ", + "classname", descriptor_->name()); for (int i = 0; i < descriptor_->value_count(); i++) { printer->Print("$name$, ", "name", descriptor_->value(i)->name()); } printer->Print( "\n" "};\n"); + printer->Outdent(); + printer->Print("}"); } printer->Print( diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 83acc49089b2..d96ac7d7724e 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -81,7 +81,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, // with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations. (*variables)["for_number"] = "valueOf"; - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -145,7 +145,7 @@ ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator( ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {} int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { @@ -154,7 +154,7 @@ int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); @@ -171,27 +171,28 @@ void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "private int $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); - printer->Print( - variables_, - "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $get_has_field_bit_message$;\n" - "}\n"); + printer->Print(variables_, + "@java.lang.Override $deprecation$public boolean " + "${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); - printer->Print( - variables_, - "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" - " return $name$_;\n" - "}\n"); + printer->Print(variables_, + "@java.lang.Override $deprecation$public int " + "${$get$capitalized_name$Value$}$() {\n" + " return $name$_;\n" + "}\n"); printer->Annotate("{", "}", descriptor_); } WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, - "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + "@java.lang.Override $deprecation$public $type$ " + "${$get$capitalized_name$$}$() {\n" " @SuppressWarnings(\"deprecation\")\n" " $type$ result = $type$.$for_number$($name$_);\n" " return result == null ? $unknown$ : result;\n" @@ -202,28 +203,29 @@ void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { void ImmutableEnumFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { printer->Print(variables_, "private int $name$_ = $default_number$;\n"); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); - printer->Print( - variables_, - "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $get_has_field_bit_builder$;\n" - "}\n"); + printer->Print(variables_, + "@java.lang.Override $deprecation$public boolean " + "${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); printer->Annotate("{", "}", descriptor_); } if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); - printer->Print( - variables_, - "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" - " return $name$_;\n" - "}\n"); + printer->Print(variables_, + "@java.lang.Override $deprecation$public int " + "${$get$capitalized_name$Value$}$() {\n" + " return $name$_;\n" + "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER, /* builder */ true); printer->Print(variables_, "$deprecation$public Builder " "${$set$capitalized_name$Value$}$(int value) {\n" + " $set_has_field_bit_builder$\n" " $name$_ = value;\n" " $on_changed$\n" " return this;\n" @@ -232,6 +234,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( } WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " @SuppressWarnings(\"deprecation\")\n" " $type$ result = $type$.$for_number$($name$_);\n" @@ -284,7 +287,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderClearCode( void ImmutableEnumFieldGenerator::GenerateMergingCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" " set$capitalized_name$(other.get$capitalized_name$());\n" @@ -302,7 +305,7 @@ void ImmutableEnumFieldGenerator::GenerateMergingCode( void ImmutableEnumFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" " $set_has_field_bit_to_local$;\n" @@ -386,7 +389,7 @@ ImmutableEnumOneofFieldGenerator::~ImmutableEnumOneofFieldGenerator() {} void ImmutableEnumOneofFieldGenerator::GenerateMembers( io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -423,10 +426,11 @@ void ImmutableEnumOneofFieldGenerator::GenerateMembers( void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); @@ -436,6 +440,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ((java.lang.Integer) $oneof_name$_).intValue();\n" @@ -457,6 +462,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( } WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " @SuppressWarnings(\"deprecation\")\n" @@ -650,6 +656,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$type$> " "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.ListAdapter<\n" @@ -659,6 +666,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); @@ -666,6 +674,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_converter_.convert($name$_.get(index));\n" "}\n"); @@ -673,6 +682,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( if (SupportUnknownEnumValue(descriptor_->file())) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List\n" "${$get$capitalized_name$ValueList$}$() {\n" " return $name$_;\n" @@ -681,6 +691,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public int " "${$get$capitalized_name$Value$}$(int index) {\n" " return $name$_.get(index);\n" @@ -701,7 +712,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( // list is immutable. If it's immutable, the invariant is that it must // either an instance of Collections.emptyList() or it's an ArrayList // wrapped in a Collections.unmodifiableList() wrapper and nobody else has - // a refererence to the underlying ArrayList. This invariant allows us to + // a reference to the underlying ArrayList. This invariant allows us to // share instances of lists between protocol buffers avoiding expensive // memory allocations. Note, immutable is a strong guarantee here -- not // just that the list cannot be modified via the reference but that the diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc index 5c137ca50c36..b0b3b78cc698 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -83,7 +83,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["required"] = descriptor->is_required() ? "true" : "false"; - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -103,9 +103,6 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, ".getNumber()"; } - // For repeated builders, the underlying list tracks mutability state. - (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; - (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); (*variables)["set_has_field_bit_to_local"] = @@ -140,12 +137,12 @@ ImmutableEnumFieldLiteGenerator::ImmutableEnumFieldLiteGenerator( ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {} int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); @@ -163,7 +160,7 @@ void ImmutableEnumFieldLiteGenerator::GenerateMembers( io::Printer* printer) const { printer->Print(variables_, "private int $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -217,7 +214,7 @@ void ImmutableEnumFieldLiteGenerator::GenerateMembers( void ImmutableEnumFieldLiteGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -288,11 +285,11 @@ void ImmutableEnumFieldLiteGenerator::GenerateFieldInfo( WriteIntToUtf16CharSequence(descriptor_->number(), output); WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), output); - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { WriteIntToUtf16CharSequence(messageBitIndex_, output); } printer->Print(variables_, "\"$name$_\",\n"); - if (SupportFieldPresence(descriptor_->file())) { + if (!SupportUnknownEnumValue((descriptor_))) { PrintEnumVerifierLogic(printer, descriptor_, variables_, /*var_name=*/"$type$", /*terminating_string=*/",\n", @@ -319,7 +316,7 @@ ImmutableEnumOneofFieldLiteGenerator::~ImmutableEnumOneofFieldLiteGenerator() {} void ImmutableEnumOneofFieldLiteGenerator::GenerateMembers( io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -386,7 +383,7 @@ void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo( WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), output); WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output); - if (SupportFieldPresence(descriptor_->file())) { + if (!SupportUnknownEnumValue(descriptor_)) { PrintEnumVerifierLogic(printer, descriptor_, variables_, /*var_name=*/"$type$", /*terminating_string=*/",\n", @@ -396,7 +393,7 @@ void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo( void ImmutableEnumOneofFieldLiteGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -572,9 +569,11 @@ void RepeatedImmutableEnumFieldLiteGenerator::GenerateMembers( printer->Print( variables_, "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$is_mutable$) {\n" + // Use a temporary to avoid a redundant iget-object. + " com.google.protobuf.Internal.IntList tmp = $name$_;\n" + " if (!tmp.isModifiable()) {\n" " $name$_ =\n" - " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" " }\n" "}\n"); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER); @@ -640,7 +639,7 @@ void RepeatedImmutableEnumFieldLiteGenerator::GenerateFieldInfo( WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), output); printer->Print(variables_, "\"$name$_\",\n"); - if (SupportFieldPresence(descriptor_->file())) { + if (!SupportUnknownEnumValue(descriptor_->file())) { PrintEnumVerifierLogic(printer, descriptor_, variables_, /*var_name=*/"$type$", /*terminating_string=*/",\n", diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index 69bd26c3f9ab..aa64c97127a5 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -78,9 +78,10 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { WriteEnumDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); printer->Print( - "public enum $classname$\n" + "$deprecation$public enum $classname$\n" " implements com.google.protobuf.Internal.EnumLite {\n", - "classname", descriptor_->name()); + "classname", descriptor_->name(), "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""); printer->Annotate("classname", descriptor_); printer->Indent(); @@ -124,9 +125,13 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { vars["number"] = StrCat(descriptor_->value(i)->number()); vars["{"] = ""; vars["}"] = ""; + vars["deprecation"] = descriptor_->value(i)->options().deprecated() + ? "@java.lang.Deprecated " + : ""; WriteEnumValueDocComment(printer, descriptor_->value(i)); printer->Print(vars, - "public static final int ${$$name$_VALUE$}$ = $number$;\n"); + "$deprecation$public static final int ${$$name$_VALUE$}$ = " + "$number$;\n"); printer->Annotate("{", "}", descriptor_->value(i)); } printer->Print("\n"); diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc index 96ed23401ab1..2f775a68a66e 100644 --- a/src/google/protobuf/compiler/java/java_field.cc +++ b/src/google/protobuf/compiler/java/java_field.cc @@ -87,7 +87,7 @@ ImmutableFieldGenerator* MakeImmutableGenerator(const FieldDescriptor* field, field, messageBitIndex, builderBitIndex, context); } } else { - if (field->containing_oneof()) { + if (IsRealOneof(field)) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: return new ImmutableMessageOneofFieldGenerator( @@ -144,7 +144,7 @@ ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( field, messageBitIndex, context); } } else { - if (field->containing_oneof()) { + if (IsRealOneof(field)) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: return new ImmutableMessageOneofFieldLiteGenerator( @@ -251,6 +251,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["disambiguated_reason"] = info->disambiguated_reason; (*variables)["constant_name"] = FieldConstantName(descriptor); (*variables)["number"] = StrCat(descriptor->number()); + (*variables)["kt_dsl_builder"] = "_builder"; // These variables are placeholders to pick out the beginning and ends of // identifiers for annotations (when doing so with existing variables would // be ambiguous or impossible). They should never be set to anything but the diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 4a96a365d46c..fb00110c4183 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -91,7 +91,9 @@ bool CollectExtensions(const Message& message, FieldDescriptorSet* extensions) { reflection->ListFields(message, &fields); for (int i = 0; i < fields.size(); i++) { - if (fields[i]->is_extension()) extensions->insert(fields[i]); + if (fields[i]->is_extension()) { + extensions->insert(fields[i]); + } if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { if (fields[i]->is_repeated()) { @@ -385,6 +387,7 @@ void FileGenerator::Generate(io::Printer* printer) { printer->Print("}\n"); } + void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( io::Printer* printer) { printer->Print( diff --git a/src/google/protobuf/compiler/java/java_file.h b/src/google/protobuf/compiler/java/java_file.h index bb3e4a576542..9f1f719237b0 100644 --- a/src/google/protobuf/compiler/java/java_file.h +++ b/src/google/protobuf/compiler/java/java_file.h @@ -78,6 +78,7 @@ class FileGenerator { void Generate(io::Printer* printer); + // If we aren't putting everything into one file, this will write all the // files other than the outer file (i.e. one for each message, enum, and // service type). diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc index 5045cfdc66d8..29ae2cf9f4c2 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -58,6 +58,10 @@ namespace java { JavaGenerator::JavaGenerator() {} JavaGenerator::~JavaGenerator() {} +uint64_t JavaGenerator::GetSupportedFeatures() const { + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; +} + bool JavaGenerator::Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* context, diff --git a/src/google/protobuf/compiler/java/java_generator.h b/src/google/protobuf/compiler/java/java_generator.h index be63ac49e2bf..6315e7c3fedc 100644 --- a/src/google/protobuf/compiler/java/java_generator.h +++ b/src/google/protobuf/compiler/java/java_generator.h @@ -58,7 +58,9 @@ class PROTOC_EXPORT JavaGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* context, std::string* error) const; + GeneratorContext* context, std::string* error) const override; + + uint64_t GetSupportedFeatures() const override; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator); diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index 41cd52402e23..e9bc6f76738d 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -75,8 +75,8 @@ const char* kForbiddenWordList[] = { "class", }; -const std::unordered_set* kReservedNames = - new std::unordered_set({ +const std::unordered_set* kReservedNames = + new std::unordered_set({ "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", @@ -89,6 +89,17 @@ const std::unordered_set* kReservedNames = "transient", "try", "void", "volatile", "while", }); +// Names that should be avoided as field names in Kotlin. +// All Kotlin hard keywords are in this list. +const std::unordered_set* kKotlinForbiddenNames = + new std::unordered_set({ + "as", "as?", "break", "class", "continue", "do", "else", + "false", "for", "fun", "if", "in", "!in", "interface", + "is", "!is", "null", "object", "package", "return", "super", + "this", "throw", "true", "try", "typealias", "typeof", "val", + "var", "when", "while", + }); + bool IsForbidden(const std::string& field_name) { for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { if (field_name == kForbiddenWordList[i]) { @@ -215,6 +226,7 @@ std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) { return name; } + std::string UniqueFileScopeIdentifier(const Descriptor* descriptor) { return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); } @@ -227,14 +239,6 @@ std::string CamelCaseFieldName(const FieldDescriptor* field) { return fieldName; } -std::string StripProto(const std::string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - std::string FileClassName(const FileDescriptor* file, bool immutable) { ClassNameResolver name_resolver; return name_resolver.GetFileClassName(file, immutable); @@ -308,7 +312,7 @@ std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) { std::string FieldConstantName(const FieldDescriptor* field) { std::string name = field->name() + "_FIELD_NUMBER"; - UpperString(&name); + ToUpper(&name); return name; } @@ -428,6 +432,7 @@ const char* BoxedPrimitiveTypeName(const FieldDescriptor* descriptor) { return BoxedPrimitiveTypeName(GetJavaType(descriptor)); } + std::string GetOneofStoredType(const FieldDescriptor* field) { const JavaType javaType = GetJavaType(field); switch (javaType) { @@ -963,6 +968,7 @@ int GetExperimentalJavaFieldType(const FieldDescriptor* field) { static const int kUtf8CheckBit = 0x200; static const int kCheckInitialized = 0x400; static const int kMapWithProto2EnumValue = 0x800; + static const int kHasHasBit = 0x1000; int extra_bits = field->is_required() ? kRequiredBit : 0; if (field->type() == FieldDescriptor::TYPE_STRING && CheckUtf8(field)) { extra_bits |= kUtf8CheckBit; @@ -971,9 +977,12 @@ int GetExperimentalJavaFieldType(const FieldDescriptor* field) { HasRequiredFields(field->message_type()))) { extra_bits |= kCheckInitialized; } + if (HasHasbit(field)) { + extra_bits |= kHasHasBit; + } if (field->is_map()) { - if (SupportFieldPresence(field->file())) { + if (!SupportUnknownEnumValue(field)) { const FieldDescriptor* value = field->message_type()->FindFieldByName("value"); if (GetJavaType(value) == JAVATYPE_ENUM) { @@ -985,7 +994,7 @@ int GetExperimentalJavaFieldType(const FieldDescriptor* field) { return GetExperimentalJavaFieldTypeForPacked(field); } else if (field->is_repeated()) { return GetExperimentalJavaFieldTypeForRepeated(field) | extra_bits; - } else if (field->containing_oneof() != NULL) { + } else if (IsRealOneof(field)) { return (GetExperimentalJavaFieldTypeForSingular(field) + kOneofFieldTypeOffset) | extra_bits; diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index 8655cae8e0b0..1ff4667a7a77 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -51,6 +51,7 @@ namespace java { extern const char kThickSeparator[]; extern const char kThinSeparator[]; + // If annotation_file is non-empty, prints a javax.annotation.Generated // annotation to the given Printer. annotation_file will be referenced in the // annotation's comments field. delimiter should be the Printer's delimiter @@ -95,9 +96,6 @@ std::string CamelCaseFieldName(const FieldDescriptor* field); // outermost file scope. std::string UniqueFileScopeIdentifier(const Descriptor* descriptor); -// Strips ".proto" or ".protodevel" from the end of a filename. -std::string StripProto(const std::string& filename); - // Gets the unqualified class name for the file. For each .proto file, there // will be one Java class containing all the immutable messages and another // Java class containing all the mutable messages. @@ -188,9 +186,11 @@ template void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer, Descriptor* descriptor, bool immutable, const std::string& suffix = "") { - if (context->options().annotate_code && IsOwnFile(descriptor, immutable)) { + if (IsOwnFile(descriptor, immutable)) { PrintGeneratedAnnotation(printer, '$', - AnnotationFileName(descriptor, suffix)); + context->options().annotate_code + ? AnnotationFileName(descriptor, suffix) + : ""); } } @@ -224,6 +224,7 @@ const char* PrimitiveTypeName(JavaType type); // types. const char* BoxedPrimitiveTypeName(JavaType type); + // Get the name of the java enum constant representing this type. E.g., // "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full // name is "com.google.protobuf.WireFormat.FieldType.INT32". @@ -352,9 +353,30 @@ inline bool HasPackedFields(const Descriptor* descriptor) { // them has a required field. Return true if a required field is found. bool HasRequiredFields(const Descriptor* descriptor); -// Whether a .proto file supports field presence test for non-message types. -inline bool SupportFieldPresence(const FileDescriptor* descriptor) { - return descriptor->syntax() != FileDescriptor::SYNTAX_PROTO3; +inline bool IsProto2(const FileDescriptor* descriptor) { + return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2; +} + +inline bool SupportFieldPresence(const FieldDescriptor* descriptor) { + // Note that while proto3 oneofs do conceptually support present, we return + // false for them because they do not offer a public hazzer. Therefore this + // method could be named HasHazzer(). + return !descriptor->is_repeated() && + (descriptor->message_type() || descriptor->has_optional_keyword() || + IsProto2(descriptor->file())); +} + +inline bool IsRealOneof(const FieldDescriptor* descriptor) { + return descriptor->containing_oneof() && + !descriptor->containing_oneof()->is_synthetic(); +} + +inline bool HasHasbit(const FieldDescriptor* descriptor) { + // Note that currently message fields inside oneofs have hasbits. This is + // surprising, as the oneof case should avoid any need for a hasbit. But if + // you change this method to remove hasbits for oneofs, a few tests fail. + return !descriptor->is_repeated() && + (descriptor->has_optional_keyword() || IsProto2(descriptor->file())); } // Whether generate classes expose public PARSER instances. @@ -370,6 +392,10 @@ inline bool SupportUnknownEnumValue(const FileDescriptor* descriptor) { return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3; } +inline bool SupportUnknownEnumValue(const FieldDescriptor* field) { + return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; +} + // Check whether a message has repeated fields. bool HasRepeatedFields(const Descriptor* descriptor); diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc index 53537458799c..5db199d38fa4 100644 --- a/src/google/protobuf/compiler/java/java_map_field.cc +++ b/src/google/protobuf/compiler/java/java_map_field.cc @@ -483,6 +483,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( printer->Print( variables_, "$deprecation$\n" + "@java.lang.Override\n" "public boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key) {\n" " $key_null_check$\n" @@ -494,6 +495,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( "/**\n" " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" + "@java.lang.Override\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" "${$get$capitalized_name$$}$() {\n" @@ -502,6 +504,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" "${$get$capitalized_name$Map$}$() {\n" @@ -512,6 +515,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" @@ -527,6 +531,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" @@ -545,6 +550,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( "/**\n" " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" " */\n" + "@java.lang.Override\n" "@java.lang.Deprecated\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "${$get$capitalized_name$Value$}$() {\n" @@ -554,6 +560,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" "${$get$capitalized_name$ValueMap$}$() {\n" @@ -563,6 +570,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" " $key_type$ key,\n" @@ -576,6 +584,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" " $key_type$ key) {\n" @@ -594,6 +603,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( "/**\n" " * Use {@link #get$capitalized_name$Map()} instead.\n" " */\n" + "@java.lang.Override\n" "@java.lang.Deprecated\n" "public java.util.Map<$type_parameters$> " "${$get$capitalized_name$$}$() {\n" @@ -602,6 +612,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$\n" "public java.util.Map<$type_parameters$> " "${$get$capitalized_name$Map$}$() {\n" @@ -611,6 +622,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" " $key_type$ key,\n" @@ -623,6 +635,7 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$\n" "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" " $key_type$ key) {\n" diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc index 8236f3a45c80..4fa939f3b8bf 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -508,7 +508,7 @@ void ImmutableMapFieldLiteGenerator::GenerateFieldInfo( printer->Print(variables_, "\"$name$_\",\n" "$default_entry$,\n"); - if (SupportFieldPresence(descriptor_->file()) && + if (!SupportUnknownEnumValue(descriptor_) && GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { PrintEnumVerifierLogic(printer, ValueField(descriptor_), variables_, /*var_name=*/"$value_enum_type$", diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index dbf62e58ff3d..6623595b1175 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -75,7 +75,13 @@ std::string MapValueImmutableClassdName(const Descriptor* descriptor, // =================================================================== MessageGenerator::MessageGenerator(const Descriptor* descriptor) - : descriptor_(descriptor) {} + : descriptor_(descriptor) { + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } +} MessageGenerator::~MessageGenerator() {} @@ -206,7 +212,7 @@ void ImmutableMessageGenerator::GenerateFieldAccessorTable( // 6 bytes per field and oneof *bytecode_estimate += - 10 + 6 * descriptor_->field_count() + 6 * descriptor_->oneof_decl_count(); + 10 + 6 * descriptor_->field_count() + 6 * oneofs_.size(); } int ImmutableMessageGenerator::GenerateFieldAccessorTableInitializer( @@ -225,6 +231,7 @@ int ImmutableMessageGenerator::GenerateFieldAccessorTableInitializer( bytecode_estimate += 6; printer->Print("\"$field_name$\", ", "field_name", info->capitalized_name); } + // We reproduce synthetic oneofs here since proto reflection needs these. for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { const OneofDescriptor* oneof = descriptor_->oneof_decl(i); const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof); @@ -269,15 +276,13 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { field_generators_.get(descriptor_->field(i)) .GenerateInterfaceMembers(printer); } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + for (auto oneof : oneofs_) { printer->Print( "\n" "public $classname$.$oneof_capitalized_name$Case " "get$oneof_capitalized_name$Case();\n", "oneof_capitalized_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->capitalized_name, - "classname", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname", context_->GetNameResolver()->GetImmutableClassName(descriptor_)); } printer->Outdent(); @@ -291,7 +296,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); std::map variables; - variables["static"] = is_own_file ? " " : " static "; + variables["static"] = is_own_file ? "" : "static "; variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); variables["ver"] = GeneratedCodeVersionSuffix(); @@ -330,7 +335,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { " $classname$OrBuilder {\n"); builder_type = strings::Substitute("com.google.protobuf.GeneratedMessage$0.Builder", - GeneratedCodeVersionSuffix()); + GeneratedCodeVersionSuffix()); } printer->Print("private static final long serialVersionUID = 0L;\n"); @@ -403,13 +408,11 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // oneof std::map vars; - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - vars["oneof_name"] = - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i))->name; + for (auto oneof : oneofs_) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; vars["oneof_capitalized_name"] = - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->capitalized_name; - vars["oneof_index"] = StrCat(descriptor_->oneof_decl(i)->index()); + context_->GetOneofGeneratorInfo(oneof)->capitalized_name; + vars["oneof_index"] = StrCat((oneof)->index()); // oneofCase_ and oneof_ printer->Print(vars, "private int $oneof_name$Case_ = 0;\n" @@ -423,8 +426,8 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { " implements com.google.protobuf.Internal.EnumLite,\n" " com.google.protobuf.AbstractMessage.InternalOneOfEnum {\n"); printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); printer->Print( "$deprecation$$field_name$($field_number$),\n", "deprecation", field->options().deprecated() ? "@java.lang.Deprecated " : "", @@ -452,8 +455,8 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { "\n" "public static $oneof_capitalized_name$Case forNumber(int value) {\n" " switch (value) {\n"); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); printer->Print(" case $field_number$: return $field_name$;\n", "field_number", StrCat(field->number()), "field_name", ToUpper(field->name())); @@ -912,19 +915,8 @@ void ImmutableMessageGenerator::GenerateIsInitialized(io::Printer* printer) { "name", info->capitalized_name); break; case FieldDescriptor::LABEL_OPTIONAL: - if (!SupportFieldPresence(descriptor_->file()) && - field->containing_oneof() != NULL) { - const OneofDescriptor* oneof = field->containing_oneof(); - const OneofGeneratorInfo* oneof_info = - context_->GetOneofGeneratorInfo(oneof); - printer->Print("if ($oneof_name$Case_ == $field_number$) {\n", - "oneof_name", oneof_info->name, "field_number", - StrCat(field->number())); - } else { - printer->Print("if (has$name$()) {\n", "name", - info->capitalized_name); - } printer->Print( + "if (has$name$()) {\n" " if (!get$name$().isInitialized()) {\n" " memoizedIsInitialized = 0;\n" " return false;\n" @@ -987,11 +979,10 @@ bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) { if (field->is_repeated()) { return false; } - if (SupportFieldPresence(field->file())) { + if (HasHasbit(field)) { return true; } - return GetJavaType(field) == JAVATYPE_MESSAGE && - field->containing_oneof() == NULL; + return GetJavaType(field) == JAVATYPE_MESSAGE && !IsRealOneof(field); } } // namespace @@ -1015,7 +1006,7 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->containing_oneof() == NULL) { + if (!IsRealOneof(field)) { const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field); if (check_has_bits) { @@ -1034,19 +1025,17 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( } // Compare oneofs. - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + for (auto oneof : oneofs_) { printer->Print( "if (!get$oneof_capitalized_name$Case().equals(" "other.get$oneof_capitalized_name$Case())) return false;\n", "oneof_capitalized_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->capitalized_name); - printer->Print( - "switch ($oneof_name$Case_) {\n", "oneof_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i))->name); + context_->GetOneofGeneratorInfo(oneof)->capitalized_name); + printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name", + context_->GetOneofGeneratorInfo(oneof)->name); printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); printer->Print("case $field_number$:\n", "field_number", StrCat(field->number())); printer->Indent(); @@ -1099,7 +1088,7 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( // hashCode non-oneofs. for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->containing_oneof() == NULL) { + if (!IsRealOneof(field)) { const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field); if (check_has_bits) { @@ -1115,13 +1104,12 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( } // hashCode oneofs. - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print( - "switch ($oneof_name$Case_) {\n", "oneof_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i))->name); + for (auto oneof : oneofs_) { + printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name", + context_->GetOneofGeneratorInfo(oneof)->name); printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); printer->Print("case $field_number$:\n", "field_number", StrCat(field->number())); printer->Indent(); @@ -1360,14 +1348,13 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { // =================================================================== void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) { for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { + if (!IsRealOneof(descriptor_->field(i))) { field_generators_.get(descriptor_->field(i)) .GenerateInitializationCode(printer); } } } - void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) { printer->Print( "private static String getTypeUrl(\n" diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h index de2f359a411b..87b9df5e598b 100644 --- a/src/google/protobuf/compiler/java/java_message.h +++ b/src/google/protobuf/compiler/java/java_message.h @@ -88,6 +88,7 @@ class MessageGenerator { protected: const Descriptor* descriptor_; + std::set oneofs_; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc index 16e63afc6cb5..320852b1be97 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.cc +++ b/src/google/protobuf/compiler/java/java_message_builder.cc @@ -76,6 +76,11 @@ MessageBuilderGenerator::MessageBuilderGenerator(const Descriptor* descriptor, GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite())) << "Generator factory error: A non-lite message generator is used to " "generate lite messages."; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } } MessageBuilderGenerator::~MessageBuilderGenerator() {} @@ -115,13 +120,11 @@ void MessageBuilderGenerator::Generate(io::Printer* printer) { // oneof std::map vars; - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - vars["oneof_name"] = - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i))->name; + for (auto oneof : oneofs_) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; vars["oneof_capitalized_name"] = - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->capitalized_name; - vars["oneof_index"] = StrCat(descriptor_->oneof_decl(i)->index()); + context_->GetOneofGeneratorInfo(oneof)->capitalized_name; + vars["oneof_index"] = StrCat(oneof->index()); // oneofCase_ and oneof_ printer->Print(vars, "private int $oneof_name$Case_ = 0;\n" @@ -308,7 +311,7 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( printer->Indent(); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { + if (!IsRealOneof(descriptor_->field(i))) { field_generators_.get(descriptor_->field(i)) .GenerateFieldBuilderInitializationCode(printer); } @@ -328,18 +331,17 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { + if (!IsRealOneof(descriptor_->field(i))) { field_generators_.get(descriptor_->field(i)) .GenerateBuilderClearCode(printer); } } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + for (auto oneof : oneofs_) { printer->Print( "$oneof_name$Case_ = 0;\n" "$oneof_name$_ = null;\n", - "oneof_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i))->name); + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); } printer->Outdent(); @@ -423,10 +425,9 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( "bit_field_name", GetBitFieldName(i)); } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print( - "result.$oneof_name$Case_ = $oneof_name$Case_;\n", "oneof_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i))->name); + for (auto oneof : oneofs_) { + printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n", + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); } printer->Outdent(); @@ -535,21 +536,20 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { + if (!IsRealOneof(descriptor_->field(i))) { field_generators_.get(descriptor_->field(i)) .GenerateMergingCode(printer); } } // Merge oneof fields. - for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { + for (auto oneof : oneofs_) { printer->Print("switch (other.get$oneof_capitalized_name$Case()) {\n", "oneof_capitalized_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->capitalized_name); + context_->GetOneofGeneratorInfo(oneof)->capitalized_name); printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + for (int j = 0; j < oneof->field_count(); j++) { + const FieldDescriptor* field = oneof->field(j); printer->Print("case $field_name$: {\n", "field_name", ToUpper(field->name())); printer->Indent(); @@ -563,9 +563,7 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( " break;\n" "}\n", "cap_oneof_name", - ToUpper( - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->name)); + ToUpper(context_->GetOneofGeneratorInfo(oneof)->name)); printer->Outdent(); printer->Print("}\n"); } @@ -655,19 +653,8 @@ void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) { "name", info->capitalized_name); break; case FieldDescriptor::LABEL_OPTIONAL: - if (!SupportFieldPresence(descriptor_->file()) && - field->containing_oneof() != NULL) { - const OneofDescriptor* oneof = field->containing_oneof(); - const OneofGeneratorInfo* oneof_info = - context_->GetOneofGeneratorInfo(oneof); - printer->Print("if ($oneof_name$Case_ == $field_number$) {\n", - "oneof_name", oneof_info->name, "field_number", - StrCat(field->number())); - } else { - printer->Print("if (has$name$()) {\n", "name", - info->capitalized_name); - } printer->Print( + "if (has$name$()) {\n" " if (!get$name$().isInitialized()) {\n" " return false;\n" " }\n" diff --git a/src/google/protobuf/compiler/java/java_message_builder.h b/src/google/protobuf/compiler/java/java_message_builder.h index a31d0badf967..fcd73b343626 100644 --- a/src/google/protobuf/compiler/java/java_message_builder.h +++ b/src/google/protobuf/compiler/java/java_message_builder.h @@ -76,6 +76,7 @@ class MessageBuilderGenerator { Context* context_; ClassNameResolver* name_resolver_; FieldGeneratorMap field_generators_; + std::set oneofs_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageBuilderGenerator); }; diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc index 6e78fb737149..7b69a9ab3894 100644 --- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc @@ -67,6 +67,11 @@ MessageBuilderLiteGenerator::MessageBuilderLiteGenerator( GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite())) << "Generator factory error: A lite message generator is used to " "generate non-lite messages."; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } } MessageBuilderLiteGenerator::~MessageBuilderLiteGenerator() {} @@ -88,13 +93,11 @@ void MessageBuilderLiteGenerator::Generate(io::Printer* printer) { // oneof std::map vars; - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - vars["oneof_name"] = - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i))->name; + for (auto oneof : oneofs_) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; vars["oneof_capitalized_name"] = - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->capitalized_name; - vars["oneof_index"] = StrCat(descriptor_->oneof_decl(i)->index()); + context_->GetOneofGeneratorInfo(oneof)->capitalized_name; + vars["oneof_index"] = StrCat(oneof->index()); // oneofCase() and clearOneof() printer->Print(vars, diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.h b/src/google/protobuf/compiler/java/java_message_builder_lite.h index e0a48dc1f797..3402adf3322b 100644 --- a/src/google/protobuf/compiler/java/java_message_builder_lite.h +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.h @@ -73,6 +73,7 @@ class MessageBuilderLiteGenerator { Context* context_; ClassNameResolver* name_resolver_; FieldGeneratorMap field_generators_; + std::set oneofs_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageBuilderLiteGenerator); }; diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index ad684a0d9acb..96c0c112762f 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -74,7 +74,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, ExposePublicParser(descriptor->message_type()->file()) ? "PARSER" : "parser()"; - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -131,7 +131,7 @@ ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator( ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {} int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { @@ -160,10 +160,11 @@ void ImmutableMessageFieldGenerator::GenerateMembers( printer->Print(variables_, "private $type$ $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); @@ -171,6 +172,7 @@ void ImmutableMessageFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); @@ -179,6 +181,7 @@ void ImmutableMessageFieldGenerator::GenerateMembers( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public $type$OrBuilder " "${$get$capitalized_name$OrBuilder$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" @@ -188,6 +191,7 @@ void ImmutableMessageFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $name$_ != null;\n" "}\n"); @@ -195,6 +199,7 @@ void ImmutableMessageFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); @@ -202,6 +207,7 @@ void ImmutableMessageFieldGenerator::GenerateMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$OrBuilder " "${$get$capitalized_name$OrBuilder$}$() {\n" " return get$capitalized_name$();\n" @@ -246,7 +252,7 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( // non-nested builder case. It only creates a nested builder lazily on // demand and then forever delegates to it after creation. - bool support_field_presence = SupportFieldPresence(descriptor_->file()); + bool has_hasbit = HasHasbit(descriptor_); printer->Print(variables_, "private $type$ $name$_;\n"); @@ -262,7 +268,7 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( // boolean hasField() WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); - if (support_field_presence) { + if (has_hasbit) { printer->Print( variables_, "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" @@ -323,7 +329,7 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( printer, "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", - support_field_presence + has_hasbit ? "if ($get_has_field_bit_builder$ &&\n" " $name$_ != null &&\n" " $name$_ != $type$.getDefaultInstance()) {\n" @@ -354,9 +360,9 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( "$name$_ = null;\n" "$on_changed$\n", - support_field_presence ? "$name$Builder_.clear();\n" - : "$name$_ = null;\n" - "$name$Builder_ = null;\n", + has_hasbit ? "$name$Builder_.clear();\n" + : "$name$_ = null;\n" + "$name$Builder_ = null;\n", "$clear_has_field_bit_builder$\n" "return this;\n"); @@ -402,7 +408,7 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n"); } } @@ -412,7 +418,7 @@ void ImmutableMessageFieldGenerator::GenerateInitializationCode( void ImmutableMessageFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { PrintNestedBuilderCondition(printer, "$name$_ = null;\n", "$name$Builder_.clear();\n"); @@ -435,7 +441,7 @@ void ImmutableMessageFieldGenerator::GenerateMergingCode( void ImmutableMessageFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n"); printer->Indent(); PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n", @@ -537,12 +543,14 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers( PrintExtraFieldInfo(variables_, printer); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" @@ -553,6 +561,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers( WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$OrBuilder " "${$get$capitalized_name$OrBuilder$}$() {\n" " if ($has_oneof_case_message$) {\n" @@ -581,6 +590,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( // boolean hasField() WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); @@ -589,7 +599,9 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( // Field getField() WriteFieldAccessorDocComment(printer, descriptor_, GETTER); PrintNestedBuilderFunction( - printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()", + printer, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$()", "if ($has_oneof_case_message$) {\n" " return ($type$) $oneof_name$_;\n" @@ -687,6 +699,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public $type$OrBuilder " "${$get$capitalized_name$OrBuilder$}$() {\n" " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n" @@ -846,6 +859,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$type$> " "${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list @@ -854,6 +868,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List \n" " ${$get$capitalized_name$OrBuilderList$}$() {\n" " return $name$_;\n" @@ -862,6 +877,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" " return $name$_.size();\n" "}\n"); @@ -869,12 +885,14 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" " return $name$_.get(index);\n" "}\n"); printer->Annotate("{", "}", descriptor_); WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$OrBuilder " "${$get$capitalized_name$OrBuilder$}$(\n" " int index) {\n" @@ -926,7 +944,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( // list is immutable. If it's immutable, the invariant is that it must // either an instance of Collections.emptyList() or it's an ArrayList // wrapped in a Collections.unmodifiableList() wrapper and nobody else has - // a refererence to the underlying ArrayList. This invariant allows us to + // a reference to the underlying ArrayList. This invariant allows us to // share instances of lists between protocol buffers avoiding expensive // memory allocations. Note, immutable is a strong guarantee here -- not // just that the list cannot be modified via the reference but that the diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc index cb5f3c0e0989..b17859d6b32c 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -70,7 +70,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["required"] = descriptor->is_required() ? "true" : "false"; - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -89,9 +89,6 @@ void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, (*variables)["name"] + "_ != null"; } - // For repeated builders, the underlying list tracks mutability state. - (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; - (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); (*variables)["set_has_field_bit_to_local"] = @@ -119,7 +116,11 @@ ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator( ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {} int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + // TODO(dweis): We don't need a has bit for messages as they have null + // sentinels and no user should be reflecting on this. We could save some + // bits by setting to 0 and updating the runtimes but this might come at a + // runtime performance cost since we can't memoize has-bit reads. + return HasHasbit(descriptor_) ? 1 : 0; } void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers( @@ -136,7 +137,7 @@ void ImmutableMessageFieldLiteGenerator::GenerateMembers( printer->Print(variables_, "private $type$ $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { WriteFieldDocComment(printer, descriptor_); printer->Print( variables_, @@ -279,7 +280,7 @@ void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo( WriteIntToUtf16CharSequence(descriptor_->number(), output); WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), output); - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { WriteIntToUtf16CharSequence(messageBitIndex_, output); } printer->Print(variables_, "\"$name$_\",\n"); @@ -528,9 +529,11 @@ void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers( printer->Print( variables_, "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$is_mutable$) {\n" + // Use a temporary to avoid a redundant iget-object. + " com.google.protobuf.Internal.ProtobufList<$type$> tmp = $name$_;\n" + " if (!tmp.isModifiable()) {\n" " $name$_ =\n" - " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" " }\n" "}\n" "\n"); diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index c2233110b504..4afffdc7a979 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -73,6 +73,11 @@ ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator( GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite())) << "Generator factory error: A lite message generator is used to " "generate non-lite messages."; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } } ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {} @@ -134,15 +139,13 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { field_generators_.get(descriptor_->field(i)) .GenerateInterfaceMembers(printer); } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + for (auto oneof : oneofs_) { printer->Print( "\n" "public $classname$.$oneof_capitalized_name$Case " "get$oneof_capitalized_name$Case();\n", "oneof_capitalized_name", - context_->GetOneofGeneratorInfo(descriptor_->oneof_decl(i)) - ->capitalized_name, - "classname", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname", context_->GetNameResolver()->GetImmutableClassName(descriptor_)); } printer->Outdent(); @@ -224,12 +227,11 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { // oneof std::map vars; - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + for (auto oneof : oneofs_) { vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(oneof)->capitalized_name; - vars["oneof_index"] = StrCat(oneof->index()); + vars["oneof_index"] = StrCat((oneof)->index()); // oneofCase_ and oneof_ printer->Print(vars, "private int $oneof_name$Case_ = 0;\n" @@ -237,8 +239,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { // OneofCase enum printer->Print(vars, "public enum $oneof_capitalized_name$Case {\n"); printer->Indent(); - for (int j = 0; j < oneof->field_count(); j++) { - const FieldDescriptor* field = oneof->field(j); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); printer->Print("$field_name$($field_number$),\n", "field_name", ToUpper(field->name()), "field_number", StrCat(field->number())); @@ -262,8 +264,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { "\n" "public static $oneof_capitalized_name$Case forNumber(int value) {\n" " switch (value) {\n"); - for (int j = 0; j < oneof->field_count(); j++) { - const FieldDescriptor* field = oneof->field(j); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); printer->Print(" case $field_number$: return $field_name$;\n", "field_number", StrCat(field->number()), "field_name", ToUpper(field->name())); @@ -472,7 +474,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo( std::vector chars; int flags = 0; - if (SupportFieldPresence(descriptor_->file())) { + if (IsProto2(descriptor_->file())) { flags |= 0x1; } if (descriptor_->options().message_set_wire_format()) { @@ -489,9 +491,8 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo( printer->Indent(); // Record the number of oneofs. - WriteIntToUtf16CharSequence(descriptor_->oneof_decl_count(), &chars); - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + WriteIntToUtf16CharSequence(oneofs_.size(), &chars); + for (auto oneof : oneofs_) { printer->Print( "\"$oneof_name$_\",\n" "\"$oneof_name$Case_\",\n", @@ -715,7 +716,7 @@ void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) { // =================================================================== void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) { for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { + if (!IsRealOneof(descriptor_->field(i))) { field_generators_.get(descriptor_->field(i)) .GenerateInitializationCode(printer); } diff --git a/src/google/protobuf/compiler/java/java_name_resolver.cc b/src/google/protobuf/compiler/java/java_name_resolver.cc index 361cfa98670e..f3c96c4d3d42 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.cc +++ b/src/google/protobuf/compiler/java/java_name_resolver.cc @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -67,6 +68,7 @@ std::string ClassNameWithoutPackage(const Descriptor* descriptor, return StripPackageName(descriptor->full_name(), descriptor->file()); } + // Get the name of an enum's Java class without package name prefix. std::string ClassNameWithoutPackage(const EnumDescriptor* descriptor, bool immutable) { @@ -91,7 +93,7 @@ std::string ClassNameWithoutPackage(const ServiceDescriptor* descriptor, } // Return true if a and b are equals (case insensitive). -NameEquality CheckNameEquality(const string& a, const string& b) { +NameEquality CheckNameEquality(const std::string& a, const std::string& b) { if (ToUpper(a) == ToUpper(b)) { if (a == b) { return NameEquality::EXACT_EQUAL; @@ -160,7 +162,14 @@ std::string ClassNameResolver::GetFileImmutableClassName( std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, bool immutable) { - if (immutable) { + return GetFileClassName(file, immutable, false); +} + +std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, + bool immutable, bool kotlin) { + if (kotlin) { + return GetFileImmutableClassName(file) + "Kt"; + } else if (immutable) { return GetFileImmutableClassName(file); } else { return "Mutable" + GetFileImmutableClassName(file); @@ -200,9 +209,14 @@ std::string ClassNameResolver::GetDescriptorClassName( std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, + bool immutable, bool kotlin) { std::string result = FileJavaPackage(descriptor, immutable); if (!result.empty()) result += '.'; - result += GetFileClassName(descriptor, immutable); + result += GetFileClassName(descriptor, immutable, kotlin); return result; } @@ -211,50 +225,79 @@ std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, std::string ClassNameResolver::GetClassFullName( const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file) { + return GetClassFullName(name_without_package, file, immutable, is_own_file, + false); +} + +std::string ClassNameResolver::GetClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool is_own_file, bool kotlin) { std::string result; if (is_own_file) { result = FileJavaPackage(file, immutable); } else { - result = GetClassName(file, immutable); + result = GetClassName(file, immutable, kotlin); } if (!result.empty()) { result += '.'; } result += name_without_package; + if (kotlin) result += "Kt"; return result; } std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, bool immutable) { - return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), - descriptor->file(), immutable, - MultipleJavaFiles(descriptor->file(), immutable)); + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); } std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, bool immutable) { - return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), - descriptor->file(), immutable, - MultipleJavaFiles(descriptor->file(), immutable)); + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); } std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, + bool immutable, bool kotlin) { return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), immutable, - IsOwnFile(descriptor, immutable)); + IsOwnFile(descriptor, immutable), kotlin); } // Get the Java Class style full name of a message. std::string ClassNameResolver::GetJavaClassFullName( const std::string& name_without_package, const FileDescriptor* file, bool immutable) { + return GetJavaClassFullName(name_without_package, file, immutable, false); +} + +std::string ClassNameResolver::GetJavaClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool kotlin) { std::string result; if (MultipleJavaFiles(file, immutable)) { result = FileJavaPackage(file, immutable); if (!result.empty()) result += '.'; } else { - result = GetClassName(file, immutable); + result = GetClassName(file, immutable, kotlin); if (!result.empty()) result += '$'; } result += StringReplace(name_without_package, ".", "$", true); @@ -263,7 +306,12 @@ std::string ClassNameResolver::GetJavaClassFullName( std::string ClassNameResolver::GetExtensionIdentifierName( const FieldDescriptor* descriptor, bool immutable) { - return GetClassName(descriptor->containing_type(), immutable) + "." + + return GetExtensionIdentifierName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetExtensionIdentifierName( + const FieldDescriptor* descriptor, bool immutable, bool kotlin) { + return GetClassName(descriptor->containing_type(), immutable, kotlin) + "." + descriptor->name(); } diff --git a/src/google/protobuf/compiler/java/java_name_resolver.h b/src/google/protobuf/compiler/java/java_name_resolver.h index b92570c60010..8461df900975 100644 --- a/src/google/protobuf/compiler/java/java_name_resolver.h +++ b/src/google/protobuf/compiler/java/java_name_resolver.h @@ -60,6 +60,8 @@ class ClassNameResolver { // Gets the unqualified outer class name for the file. std::string GetFileClassName(const FileDescriptor* file, bool immutable); + std::string GetFileClassName(const FileDescriptor* file, bool immutable, + bool kotlin); // Gets the unqualified immutable outer class name of a file. std::string GetFileImmutableClassName(const FileDescriptor* file); // Gets the unqualified default immutable outer class name of a file @@ -80,9 +82,17 @@ class ClassNameResolver { // Gets the fully-qualified class name corresponding to the given descriptor. std::string GetClassName(const Descriptor* descriptor, bool immutable); + std::string GetClassName(const Descriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const EnumDescriptor* descriptor, bool immutable); + std::string GetClassName(const EnumDescriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable); + std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable, + bool kotlin); std::string GetClassName(const FileDescriptor* descriptor, bool immutable); + std::string GetClassName(const FileDescriptor* descriptor, bool immutable, + bool kotlin); template std::string GetImmutableClassName(const DescriptorType* descriptor) { @@ -96,6 +106,8 @@ class ClassNameResolver { // Gets the fully qualified name of an extension identifier. std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, bool immutable); + std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, + bool immutable, bool kotlin); // Gets the fully qualified name for generated classes in Java convention. // Nested classes will be separated using '$' instead of '.' @@ -109,9 +121,15 @@ class ClassNameResolver { std::string GetClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable, bool is_own_file); + std::string GetClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool is_own_file, bool kotlin); // Get the Java Class style full name of a message. std::string GetJavaClassFullName(const std::string& name_without_package, const FileDescriptor* file, bool immutable); + std::string GetJavaClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool kotlin); // Caches the result to provide better performance. std::map file_immutable_outer_class_names_; diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index 186431aba4a4..f06e8fb203d4 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -133,7 +133,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } (*variables)["on_changed"] = "onChanged();"; - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -195,7 +195,7 @@ ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator( ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {} int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { @@ -204,7 +204,7 @@ int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); @@ -217,10 +217,11 @@ void ImmutablePrimitiveFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print(variables_, "private $field_type$ $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); @@ -229,6 +230,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); @@ -239,10 +241,11 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { printer->Print(variables_, "private $field_type$ $name$_ $default_init$;\n"); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_builder$;\n" "}\n"); @@ -251,6 +254,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " return $name$_;\n" "}\n"); @@ -292,6 +296,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( "}\n"); } + void ImmutablePrimitiveFieldGenerator::GenerateFieldBuilderInitializationCode( io::Printer* printer) const { // noop for primitives @@ -313,7 +318,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( void ImmutablePrimitiveFieldGenerator::GenerateMergingCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" " set$capitalized_name$(other.get$capitalized_name$());\n" @@ -328,7 +333,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateMergingCode( void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { if (IsDefaultValueJavaDefault(descriptor_)) { printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" @@ -492,10 +497,11 @@ ImmutablePrimitiveOneofFieldGenerator:: void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); @@ -504,6 +510,7 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" " if ($has_oneof_case_message$) {\n" " return ($boxed_type$) $oneof_name$_;\n" @@ -515,7 +522,7 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -663,6 +670,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers( PrintExtraFieldInfo(variables_, printer); WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public java.util.List<$boxed_type$>\n" " ${$get$capitalized_name$List$}$() {\n" " return $name$_;\n" // note: unmodifiable list @@ -695,7 +703,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( // list is immutable. If it's immutable, the invariant is that it must // either an instance of Collections.emptyList() or it's an ArrayList // wrapped in a Collections.unmodifiableList() wrapper and nobody else has - // a refererence to the underlying ArrayList. This invariant allows us to + // a reference to the underlying ArrayList. This invariant allows us to // share instances of lists between protocol buffers avoiding expensive // memory allocations. Note, immutable is a strong guarantee here -- not // just that the list cannot be modified via the reference but that the diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc index f038412bda1a..59dba76cc03f 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -32,6 +32,8 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include @@ -41,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -139,7 +140,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["fixed_size"] = StrCat(fixed_size); } - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -164,9 +165,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } } - // For repeated builders, the underlying list tracks mutability state. - (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; - (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); (*variables)["set_has_field_bit_to_local"] = @@ -190,12 +188,12 @@ ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator( ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {} int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); @@ -215,7 +213,7 @@ void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers( } printer->Print(variables_, "private $field_type$ $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -261,7 +259,7 @@ void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers( void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -303,12 +301,13 @@ void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers( printer->Annotate("{", "}", descriptor_); } + void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo( io::Printer* printer, std::vector* output) const { WriteIntToUtf16CharSequence(descriptor_->number(), output); WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), output); - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { WriteIntToUtf16CharSequence(messageBitIndex_, output); } printer->Print(variables_, "\"$name$_\",\n"); @@ -346,7 +345,7 @@ ImmutablePrimitiveOneofFieldLiteGenerator:: void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers( io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -396,7 +395,7 @@ void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo( void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -511,9 +510,11 @@ void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers( printer->Print( variables_, "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$is_mutable$) {\n" + // Use a temporary to avoid a redundant iget-object. + " $field_list_type$ tmp = $name$_;\n" + " if (!tmp.isModifiable()) {\n" " $name$_ =\n" - " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" " }\n" "}\n"); diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 0e483268d9dc..548f898e464f 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -90,7 +90,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["on_changed"] = "onChanged();"; - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -147,7 +147,7 @@ ImmutableStringFieldGenerator::ImmutableStringFieldGenerator( ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {} int ImmutableStringFieldGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { @@ -188,7 +188,7 @@ int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { // UnmodifiableLazyStringList. void ImmutableStringFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); @@ -207,10 +207,11 @@ void ImmutableStringFieldGenerator::GenerateMembers( printer->Print(variables_, "private volatile java.lang.Object $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $get_has_field_bit_message$;\n" "}\n"); @@ -220,6 +221,7 @@ void ImmutableStringFieldGenerator::GenerateMembers( WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref = $name$_;\n" " if (ref instanceof java.lang.String) {\n" @@ -243,6 +245,7 @@ void ImmutableStringFieldGenerator::GenerateMembers( "}\n"); WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref = $name$_;\n" @@ -263,7 +266,7 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { printer->Print(variables_, "private java.lang.Object $name$_ $default_init$;\n"); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -381,7 +384,7 @@ void ImmutableStringFieldGenerator::GenerateBuilderClearCode( void ImmutableStringFieldGenerator::GenerateMergingCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { // Allow a slight breach of abstraction here in order to avoid forcing // all string fields to Strings when copying fields from a Message. printer->Print(variables_, @@ -401,7 +404,7 @@ void ImmutableStringFieldGenerator::GenerateMergingCode( void ImmutableStringFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" " $set_has_field_bit_to_local$;\n" @@ -482,7 +485,7 @@ void ImmutableStringOneofFieldGenerator::GenerateMembers( io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -548,10 +551,11 @@ void ImmutableStringOneofFieldGenerator::GenerateMembers( void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" " return $has_oneof_case_message$;\n" "}\n"); @@ -561,6 +565,7 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( WriteFieldAccessorDocComment(printer, descriptor_, GETTER); printer->Print( variables_, + "@java.lang.Override\n" "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" " java.lang.Object ref $default_init$;\n" " if ($has_oneof_case_message$) {\n" @@ -590,6 +595,7 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); printer->Print(variables_, + "@java.lang.Override\n" "$deprecation$public com.google.protobuf.ByteString\n" " ${$get$capitalized_name$Bytes$}$() {\n" " java.lang.Object ref $default_init$;\n" @@ -795,7 +801,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( // list is immutable. If it's immutable, the invariant is that it must // either an instance of Collections.emptyList() or it's an ArrayList // wrapped in a Collections.unmodifiableList() wrapper and nobody else has - // a refererence to the underlying ArrayList. This invariant allows us to + // a reference to the underlying ArrayList. This invariant allows us to // share instances of lists between protocol buffers avoiding expensive // memory allocations. Note, immutable is a strong guarantee here -- not // just that the list cannot be modified via the reference but that the diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc index 90e158186044..06a3c25bd928 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -85,7 +85,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["required"] = descriptor->is_required() ? "true" : "false"; - if (SupportFieldPresence(descriptor->file())) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -104,9 +104,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, "!" + (*variables)["name"] + "_.isEmpty()"; } - // For repeated builders, the underlying list tracks mutability state. - (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; - (*variables)["get_has_field_bit_from_local"] = GenerateGetBitFromLocal(builderBitIndex); (*variables)["set_has_field_bit_to_local"] = @@ -130,7 +127,7 @@ ImmutableStringFieldLiteGenerator::ImmutableStringFieldLiteGenerator( ImmutableStringFieldLiteGenerator::~ImmutableStringFieldLiteGenerator() {} int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_->file()) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } // A note about how strings are handled. In the SPEED and CODE_SIZE runtimes, @@ -160,7 +157,7 @@ int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const { // shouldn't be necessary or used on devices. void ImmutableStringFieldLiteGenerator::GenerateInterfaceMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); @@ -179,7 +176,7 @@ void ImmutableStringFieldLiteGenerator::GenerateMembers( printer->Print(variables_, "private java.lang.String $name$_;\n"); PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -241,7 +238,7 @@ void ImmutableStringFieldLiteGenerator::GenerateMembers( void ImmutableStringFieldLiteGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -309,7 +306,7 @@ void ImmutableStringFieldLiteGenerator::GenerateFieldInfo( WriteIntToUtf16CharSequence(descriptor_->number(), output); WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), output); - if (SupportFieldPresence(descriptor_->file())) { + if (HasHasbit(descriptor_)) { WriteIntToUtf16CharSequence(messageBitIndex_, output); } printer->Print(variables_, "\"$name$_\",\n"); @@ -341,7 +338,7 @@ void ImmutableStringOneofFieldLiteGenerator::GenerateMembers( io::Printer* printer) const { PrintExtraFieldInfo(variables_, printer); - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -421,7 +418,7 @@ void ImmutableStringOneofFieldLiteGenerator::GenerateFieldInfo( void ImmutableStringOneofFieldLiteGenerator::GenerateBuilderMembers( io::Printer* printer) const { - if (SupportFieldPresence(descriptor_->file())) { + if (SupportFieldPresence(descriptor_)) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); printer->Print( variables_, @@ -567,9 +564,12 @@ void RepeatedImmutableStringFieldLiteGenerator::GenerateMembers( printer->Print( variables_, "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$is_mutable$) {\n" + // Use a temporary to avoid a redundant iget-object. + " com.google.protobuf.Internal.ProtobufList tmp =\n" + " $name$_;" + " if (!tmp.isModifiable()) {\n" " $name$_ =\n" - " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" " }\n" "}\n"); diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index c1216f8ce94f..746ecb2da739 100644 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -99,15 +99,6 @@ bool StrEndsWith(StringPiece sp, StringPiece x) { return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x; } -// Returns a copy of |filename| with any trailing ".protodevel" or ".proto -// suffix stripped. -// TODO(haberman): Unify with copy in compiler/cpp/internal/helpers.cc. -std::string StripProto(const std::string& filename) { - const char* suffix = - StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto"; - return StripSuffixString(filename, suffix); -} - std::string GetSnakeFilename(const std::string& filename) { std::string snake_name = filename; ReplaceCharacters(&snake_name, "/", '_'); @@ -467,6 +458,7 @@ bool IgnoreMessage(const Descriptor* d) { return d->options().map_entry(); } // Does JSPB ignore this entire oneof? True only if all fields are ignored. bool IgnoreOneof(const OneofDescriptor* oneof) { + if (oneof->is_synthetic()) return true; for (int i = 0; i < oneof->field_count(); i++) { if (!IgnoreField(oneof->field(i))) { return false; @@ -576,6 +568,7 @@ std::string JSOneofIndex(const OneofDescriptor* oneof) { int index = -1; for (int i = 0; i < oneof->containing_type()->oneof_decl_count(); i++) { const OneofDescriptor* o = oneof->containing_type()->oneof_decl(i); + if (o->is_synthetic()) continue; // If at least one field in this oneof is not JSPB-ignored, count the oneof. for (int j = 0; j < o->field_count(); j++) { const FieldDescriptor* f = o->field(j); @@ -794,6 +787,11 @@ std::string DoubleToString(double value) { return PostProcessFloat(result); } +bool InRealOneof(const FieldDescriptor* field) { + return field->containing_oneof() && + !field->containing_oneof()->is_synthetic(); +} + // Return true if this is an integral field that should be represented as string // in JS. bool IsIntegralFieldWithStringJSType(const FieldDescriptor* field) { @@ -1173,7 +1171,7 @@ std::string RepeatedFieldsArrayName(const GeneratorOptions& options, bool HasOneofFields(const Descriptor* desc) { for (int i = 0; i < desc->field_count(); i++) { - if (desc->field(i)->containing_oneof()) { + if (InRealOneof(desc->field(i))) { return true; } } @@ -1411,15 +1409,9 @@ std::string GetPivot(const Descriptor* desc) { // generate extra methods (clearFoo() and hasFoo()) for this field. bool HasFieldPresence(const GeneratorOptions& options, const FieldDescriptor* field) { - if (field->is_repeated() || field->is_map()) { - // We say repeated fields and maps don't have presence, but we still do - // generate clearFoo() methods for them through a special case elsewhere. - return false; - } - - return field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || - field->containing_oneof() != NULL || - field->file()->syntax() == FileDescriptor::SYNTAX_PROTO2; + // This returns false for repeated fields and maps, but we still do + // generate clearFoo() methods for these through a special case elsewhere. + return field->has_presence(); } // We use this to implement the semantics that same file can be generated @@ -1653,6 +1645,8 @@ void Generator::GenerateHeader(const GeneratorOptions& options, " * @public\n" " */\n" "// GENERATED CODE -- DO NOT EDIT!\n" + "/* eslint-disable */\n" + "// @ts-nocheck\n" "\n"); } @@ -2676,7 +2670,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, /* singular_if_not_packed = */ false), "class", GetMessagePath(options, field->containing_type()), "settername", "set" + JSGetterName(options, field), "oneoftag", - (field->containing_oneof() ? "Oneof" : ""), "repeatedtag", + (InRealOneof(field) ? "Oneof" : ""), "repeatedtag", (field->is_repeated() ? "Repeated" : "")); printer->Annotate("settername", field); @@ -2686,8 +2680,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "\n" "\n", "index", JSFieldIndex(field), "oneofgroup", - (field->containing_oneof() ? (", " + JSOneofArray(options, field)) - : "")); + (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : "")); if (field->is_repeated()) { GenerateRepeatedMessageHelperMethods(options, printer, field); @@ -2811,8 +2804,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, " return jspb.Message.set$oneoftag$Field(this, $index$", "class", GetMessagePath(options, field->containing_type()), "settername", "set" + JSGetterName(options, field), "oneoftag", - (field->containing_oneof() ? "Oneof" : ""), "index", - JSFieldIndex(field)); + (InRealOneof(field) ? "Oneof" : ""), "index", JSFieldIndex(field)); printer->Annotate("settername", field); printer->Print( "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);\n" @@ -2822,8 +2814,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "type", untyped ? "/** @type{string|number|boolean|Array|undefined} */(" : "", "typeclose", untyped ? ")" : "", "oneofgroup", - (field->containing_oneof() ? (", " + JSOneofArray(options, field)) - : ""), + (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "rptvalueinit", (field->is_repeated() ? " || []" : "")); } @@ -2899,8 +2890,8 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "$index$$maybeoneofgroup$, ", "class", GetMessagePath(options, field->containing_type()), "clearername", "clear" + JSGetterName(options, field), - "maybeoneof", (field->containing_oneof() ? "Oneof" : ""), - "maybeoneofgroup", (field->containing_oneof() + "maybeoneof", (InRealOneof(field) ? "Oneof" : ""), + "maybeoneofgroup", (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "index", JSFieldIndex(field)); @@ -2965,7 +2956,7 @@ void Generator::GenerateRepeatedPrimitiveHelperMethods( "\n", "type", untyped ? "/** @type{string|number|boolean|!Uint8Array} */(" : "", "typeclose", untyped ? ")" : "", "oneofgroup", - (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""), + (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "rptvalueinit", ""); // clang-format on } @@ -2994,8 +2985,8 @@ void Generator::GenerateRepeatedMessageHelperMethods( "\n" "\n", "index", JSFieldIndex(field), "oneofgroup", - (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""), - "ctor", GetMessagePath(options, field->message_type())); + (InRealOneof(field) ? (", " + JSOneofArray(options, field)) : ""), "ctor", + GetMessagePath(options, field->message_type())); } void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, @@ -3163,6 +3154,15 @@ void Generator::GenerateClassDeserializeBinaryField( (field->type() == FieldDescriptor::TYPE_GROUP) ? (StrCat(field->number()) + ", ") : ""); + } else if (field->is_packable()) { + printer->Print( + " var values = /** @type {$fieldtype$} */ " + "(reader.isDelimited() " + "? reader.readPacked$reader$() : [reader.read$reader$()]);\n", + "fieldtype", + JSFieldTypeAnnotation(options, field, false, true, + /* singular_if_not_packed */ false, BYTES_U8), + "reader", JSBinaryReaderMethodType(field)); } else { printer->Print( " var value = /** @type {$fieldtype$} */ " @@ -3174,7 +3174,14 @@ void Generator::GenerateClassDeserializeBinaryField( JSBinaryReadWriteMethodName(field, /* is_writer = */ false)); } - if (field->is_repeated() && !field->is_packed()) { + if (field->is_packable()) { + printer->Print( + " for (var i = 0; i < values.length; i++) {\n" + " msg.add$name$(values[i]);\n" + " }\n", + "name", + JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); + } else if (field->is_repeated()) { printer->Print( " msg.add$name$(value);\n", "name", JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true)); diff --git a/src/google/protobuf/compiler/js/js_generator.h b/src/google/protobuf/compiler/js/js_generator.h index 49f19f6eb61f..e452020a77c6 100644 --- a/src/google/protobuf/compiler/js/js_generator.h +++ b/src/google/protobuf/compiler/js/js_generator.h @@ -125,10 +125,10 @@ struct GeneratorOptions { std::string extension; // Create a separate output file for each input file? bool one_output_file_per_input_file; - // If true, we should append annotations as commen on the last line for + // If true, we should append annotations as comments on the last line for // generated .js file. Annotations used by tools like https://kythe.io // to provide cross-references between .js and .proto files. Annotations - // are enced as base64 proto of GeneratedCodeInfo message (see + // are encoded as base64 proto of GeneratedCodeInfo message (see // descriptor.proto). bool annotate_code; }; @@ -142,18 +142,21 @@ class PROTOC_EXPORT Generator : public CodeGenerator { Generator() {} virtual ~Generator() {} - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, GeneratorContext* context, - std::string* error) const { + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override { *error = "Unimplemented Generate() method. Call GenerateAll() instead."; return false; } - virtual bool HasGenerateAll() const { return true; } + bool HasGenerateAll() const override { return true; } - virtual bool GenerateAll(const std::vector& files, - const std::string& parameter, - GeneratorContext* context, std::string* error) const; + bool GenerateAll(const std::vector& files, + const std::string& parameter, GeneratorContext* context, + std::string* error) const override; + + uint64 GetSupportedFeatures() const override { + return FEATURE_PROTO3_OPTIONAL; + } private: void GenerateHeader(const GeneratorOptions& options, diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index 5239e09313fa..895b47dee65d 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -28,8 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Author: kenton@google.com (Kenton Varda) - #include #include #include @@ -67,6 +65,7 @@ int ProtobufMain(int argc, char* argv[]) { "Generate Java source file."); + // Proto2 Python python::Generator py_generator; cli.RegisterGenerator("--python_out", "--python_opt", &py_generator, @@ -87,10 +86,10 @@ int ProtobufMain(int argc, char* argv[]) { cli.RegisterGenerator("--csharp_out", "--csharp_opt", &csharp_generator, "Generate C# source file."); - // Objective C + // Objective-C objectivec::ObjectiveCGenerator objc_generator; cli.RegisterGenerator("--objc_out", "--objc_opt", &objc_generator, - "Generate Objective C header and source."); + "Generate Objective-C header and source."); // JavaScript js::Generator js_generator; diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index e88b18bea727..3abb5c0b1351 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -87,6 +87,15 @@ MockCodeGenerator::MockCodeGenerator(const std::string& name) : name_(name) {} MockCodeGenerator::~MockCodeGenerator() {} +uint64_t MockCodeGenerator::GetSupportedFeatures() const { + uint64 all_features = CodeGenerator::FEATURE_PROTO3_OPTIONAL; + return all_features & ~suppressed_features_; +} + +void MockCodeGenerator::SuppressFeatures(uint64 features) { + suppressed_features_ = features; +} + void MockCodeGenerator::ExpectGenerated( const std::string& name, const std::string& parameter, const std::string& insertions, const std::string& file, @@ -110,7 +119,7 @@ void MockCodeGenerator::ExpectGenerated( std::vector insertion_list; if (!insertions.empty()) { - SplitStringUsing(insertions, ",", &insertion_list); + insertion_list = Split(insertions, ",", true); } EXPECT_EQ(lines.size(), 3 + insertion_list.size() * 2); @@ -157,17 +166,36 @@ void MockCodeGenerator::CheckGeneratedAnnotations( &file_content, true)); std::string meta_content; GOOGLE_CHECK_OK(File::GetContents( - output_directory + "/" + GetOutputFileName(name, file) + ".meta", + output_directory + "/" + GetOutputFileName(name, file) + ".pb.meta", &meta_content, true)); GeneratedCodeInfo annotations; GOOGLE_CHECK(TextFormat::ParseFromString(meta_content, &annotations)); - ASSERT_EQ(3, annotations.annotation_size()); + ASSERT_EQ(7, annotations.annotation_size()); + CheckSingleAnnotation("first_annotation", "first", file_content, annotations.annotation(0)); + CheckSingleAnnotation("first_path", + "test_generator: first_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(1)); + CheckSingleAnnotation("first_path", + "test_plugin: first_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(2)); CheckSingleAnnotation("second_annotation", "second", file_content, - annotations.annotation(1)); + annotations.annotation(3)); + // This annotated text has changed because it was inserted at an indented + // insertion point. + CheckSingleAnnotation("second_path", + "test_generator: second_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(4)); + CheckSingleAnnotation("second_path", + "test_plugin: second_insert,\n foo.proto,\n " + "MockCodeGenerator_Annotate,\n foo.proto\n", + file_content, annotations.annotation(5)); CheckSingleAnnotation("third_annotation", "third", file_content, - annotations.annotation(2)); + annotations.annotation(6)); } bool MockCodeGenerator::Generate(const FileDescriptor* file, @@ -220,18 +248,33 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, } } - if (HasPrefixString(parameter, "insert=")) { - std::vector insert_into; - SplitStringUsing(StripPrefixString(parameter, "insert="), ",", - &insert_into); + bool insert_endlines = HasPrefixString(parameter, "insert_endlines="); + if (insert_endlines || HasPrefixString(parameter, "insert=")) { + std::vector insert_into = Split( + StripPrefixString( + parameter, insert_endlines ? "insert_endlines=" : "insert="), + ",", true); for (size_t i = 0; i < insert_into.size(); i++) { { - std::unique_ptr output(context->OpenForInsert( - GetOutputFileName(insert_into[i], file), kFirstInsertionPointName)); + google::protobuf::GeneratedCodeInfo info; + std::string content = + GetOutputFileContent(name_, "first_insert", file, context); + if (insert_endlines) { + GlobalReplaceSubstring(",", ",\n", &content); + } + if (annotate) { + auto* annotation = info.add_annotation(); + annotation->set_begin(0); + annotation->set_end(content.size()); + annotation->set_source_file("first_path"); + } + std::unique_ptr output( + context->OpenForInsertWithGeneratedCodeInfo( + GetOutputFileName(insert_into[i], file), + kFirstInsertionPointName, info)); io::Printer printer(output.get(), '$'); - printer.PrintRaw( - GetOutputFileContent(name_, "first_insert", file, context)); + printer.PrintRaw(content); if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; @@ -239,12 +282,24 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, } { + google::protobuf::GeneratedCodeInfo info; + std::string content = + GetOutputFileContent(name_, "second_insert", file, context); + if (insert_endlines) { + GlobalReplaceSubstring(",", ",\n", &content); + } + if (annotate) { + auto* annotation = info.add_annotation(); + annotation->set_begin(0); + annotation->set_end(content.size()); + annotation->set_source_file("second_path"); + } std::unique_ptr output( - context->OpenForInsert(GetOutputFileName(insert_into[i], file), - kSecondInsertionPointName)); + context->OpenForInsertWithGeneratedCodeInfo( + GetOutputFileName(insert_into[i], file), + kSecondInsertionPointName, info)); io::Printer printer(output.get(), '$'); - printer.PrintRaw( - GetOutputFileContent(name_, "second_insert", file, context)); + printer.PrintRaw(content); if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; @@ -263,17 +318,17 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, printer.PrintRaw(GetOutputFileContent(name_, parameter, file, context)); std::string annotate_suffix = "_annotation"; if (annotate) { - printer.Print("$p$", "p", "first"); + printer.Print("$p$\n", "p", "first"); printer.Annotate("p", "first" + annotate_suffix); } printer.PrintRaw(kFirstInsertionPoint); if (annotate) { - printer.Print("$p$", "p", "second"); + printer.Print("$p$\n", "p", "second"); printer.Annotate("p", "second" + annotate_suffix); } printer.PrintRaw(kSecondInsertionPoint); if (annotate) { - printer.Print("$p$", "p", "third"); + printer.Print("$p$\n", "p", "third"); printer.Annotate("p", "third" + annotate_suffix); } @@ -283,9 +338,9 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, } if (annotate) { std::unique_ptr meta_output( - context->Open(GetOutputFileName(name_, file) + ".meta")); + context->Open(GetOutputFileName(name_, file) + ".pb.meta")); if (!TextFormat::Print(annotations, meta_output.get())) { - *error = "MockCodeGenerator couldn't write .meta"; + *error = "MockCodeGenerator couldn't write .pb.meta"; return false; } } @@ -320,7 +375,7 @@ std::string MockCodeGenerator::GetOutputFileContent( const std::string& file, const std::string& parsed_file_list, const std::string& first_message_name) { return strings::Substitute("$0: $1, $2, $3, $4\n", generator_name, parameter, - file, first_message_name, parsed_file_list); + file, first_message_name, parsed_file_list); } } // namespace compiler diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index 082ba18d4d0d..9677d1904dc1 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -56,7 +56,9 @@ namespace compiler { // If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines // into the files generated by other MockCodeGenerators instead of creating // its own file. NAMES is a comma-separated list of the names of those other -// MockCodeGenerators. +// MockCodeGenerators. If the parameter is "insert_endlines=NAMES", the +// MockCodeGenerator will insert data guaranteed to contain more than one +// endline into the files generated by NAMES. // // MockCodeGenerator will also modify its behavior slightly if the input file // contains a message type with one of the following names: @@ -106,12 +108,15 @@ class MockCodeGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, GeneratorContext* context, - std::string* error) const; + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override; + + uint64_t GetSupportedFeatures() const override; + void SuppressFeatures(uint64 features); private: std::string name_; + uint64 suppressed_features_ = 0; static std::string GetOutputFileContent(const std::string& generator_name, const std::string& parameter, diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc index f2967683ee01..12c475ff5a5b 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc @@ -65,7 +65,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) base_values_.push_back(value); value_names.insert(EnumValueName(value)); } else { - string value_name(EnumValueName(value)); + std::string value_name(EnumValueName(value)); if (value_names.find(value_name) != value_names.end()) { alias_values_to_skip_.insert(value); } else { @@ -79,7 +79,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) EnumGenerator::~EnumGenerator() {} void EnumGenerator::GenerateHeader(io::Printer* printer) { - string enum_comments; + std::string enum_comments; SourceLocation location; if (descriptor_->GetSourceLocation(&location)) { enum_comments = BuildCommentsString(location, true); @@ -129,7 +129,7 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) { } SourceLocation location; if (all_values_[i]->GetSourceLocation(&location)) { - string comments = BuildCommentsString(location, true).c_str(); + std::string comments = BuildCommentsString(location, true).c_str(); if (comments.length() > 0) { if (i > 0) { printer->Print("\n"); @@ -172,11 +172,11 @@ void EnumGenerator::GenerateSource(io::Printer* printer) { // will be zero. TextFormatDecodeData text_format_decode_data; int enum_value_description_key = -1; - string text_blob; + std::string text_blob; for (int i = 0; i < all_values_.size(); i++) { ++enum_value_description_key; - string short_name(EnumValueShortName(all_values_[i])); + std::string short_name(EnumValueShortName(all_values_[i])); text_blob += short_name + '\0'; if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) { text_format_decode_data.AddString(enum_value_description_key, short_name, diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.h b/src/google/protobuf/compiler/objectivec/objectivec_enum.h index 50a656447979..1d5741a53ce2 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.h @@ -53,14 +53,14 @@ class EnumGenerator { void GenerateHeader(io::Printer* printer); void GenerateSource(io::Printer* printer); - const string& name() const { return name_; } + const std::string& name() const { return name_; } private: const EnumDescriptor* descriptor_; std::vector base_values_; std::vector all_values_; std::set alias_values_to_skip_; - const string name_; + const std::string name_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index 9890d0a140f6..ff69f39f484f 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -44,8 +44,8 @@ namespace objectivec { namespace { void SetEnumVariables(const FieldDescriptor* descriptor, - std::map* variables) { - string type = EnumName(descriptor->enum_type()); + std::map* variables) { + std::string type = EnumName(descriptor->enum_type()); (*variables)["storage_type"] = type; // For non repeated fields, if it was defined in a different file, the // property decls need to use "enum NAME" rather than just "NAME" to support @@ -104,26 +104,26 @@ void EnumFieldGenerator::GenerateCFunctionImplementations( "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n" " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n" - " return GPBGetMessageInt32Field(message, field);\n" + " return GPBGetMessageRawEnumField(message, field);\n" "}\n" "\n" "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n" " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n" - " GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);\n" + " GPBSetMessageRawEnumField(message, field, value);\n" "}\n" "\n"); } void EnumFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls); // If it is an enum defined in a different file, then we'll need a forward // declaration for it. When it is in our file, all the enums are output // before the message, so it will be declared before it is needed. if (descriptor_->file() != descriptor_->enum_type()->file()) { // Enum name is already in "storage_type". - const string& name = variable("storage_type"); + const std::string& name = variable("storage_type"); fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 5a69c9786710..f89a7bf22fb0 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -50,7 +50,8 @@ class EnumFieldGenerator : public SingleFieldGenerator { public: virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; virtual void GenerateCFunctionImplementations(io::Printer* printer) const; - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; protected: EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc index b514b8a72a6e..9cebcb22afa6 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc @@ -41,7 +41,7 @@ namespace protobuf { namespace compiler { namespace objectivec { -ExtensionGenerator::ExtensionGenerator(const string& root_class_name, +ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name, const FieldDescriptor* descriptor) : method_name_(ExtensionMethodName(descriptor)), root_class_and_method_name_(root_class_name + "_" + method_name_), @@ -59,7 +59,7 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name, ExtensionGenerator::~ExtensionGenerator() {} void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { - std::map vars; + std::map vars; vars["method_name"] = method_name_; if (IsRetainedName(method_name_)) { vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -82,13 +82,13 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { void ExtensionGenerator::GenerateStaticVariablesInitialization( io::Printer* printer) { - std::map vars; + std::map vars; vars["root_class_and_method_name"] = root_class_and_method_name_; - const string containing_type = ClassName(descriptor_->containing_type()); + const std::string containing_type = ClassName(descriptor_->containing_type()); vars["extended_type"] = ObjCClass(containing_type); vars["number"] = StrCat(descriptor_->number()); - std::vector options; + std::vector options; if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated"); if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked"); if (descriptor_->containing_type()->options().message_set_wire_format()) { @@ -110,8 +110,8 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( } else { vars["default"] = DefaultValue(descriptor_); } - string type = GetCapitalizedType(descriptor_); - vars["extension_type"] = string("GPBDataType") + type; + std::string type = GetCapitalizedType(descriptor_); + vars["extension_type"] = std::string("GPBDataType") + type; if (objc_type == OBJECTIVECTYPE_ENUM) { vars["enum_desc_func_name"] = @@ -134,12 +134,12 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization( } void ExtensionGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) { - string extended_type = ClassName(descriptor_->containing_type()); + std::set* fwd_decls) { + std::string extended_type = ClassName(descriptor_->containing_type()); fwd_decls->insert(ObjCClassDeclaration(extended_type)); ObjectiveCType objc_type = GetObjectiveCType(descriptor_); if (objc_type == OBJECTIVECTYPE_MESSAGE) { - string message_type = ClassName(descriptor_->message_type()); + std::string message_type = ClassName(descriptor_->message_type()); fwd_decls->insert(ObjCClassDeclaration(message_type)); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.h b/src/google/protobuf/compiler/objectivec/objectivec_extension.h index 1bc19d818770..d412f4a9f2a8 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_extension.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.h @@ -41,7 +41,7 @@ namespace objectivec { class ExtensionGenerator { public: - ExtensionGenerator(const string& root_class_name, + ExtensionGenerator(const std::string& root_class_name, const FieldDescriptor* descriptor); ~ExtensionGenerator(); @@ -51,11 +51,11 @@ class ExtensionGenerator { void GenerateMembersHeader(io::Printer* printer); void GenerateStaticVariablesInitialization(io::Printer* printer); void GenerateRegistrationSource(io::Printer* printer); - void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); + void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); private: - string method_name_; - string root_class_and_method_name_; + std::string method_name_; + std::string root_class_and_method_name_; const FieldDescriptor* descriptor_; }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc index 829f4258f980..9d5fa9933a61 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -48,16 +48,16 @@ namespace objectivec { namespace { void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map* variables) { - string camel_case_name = FieldName(descriptor); - string raw_field_name; + std::map* variables) { + std::string camel_case_name = FieldName(descriptor); + std::string raw_field_name; if (descriptor->type() == FieldDescriptor::TYPE_GROUP) { raw_field_name = descriptor->message_type()->name(); } else { raw_field_name = descriptor->name(); } // The logic here has to match -[GGPBFieldDescriptor textFormatName]. - const string un_camel_case_name( + const std::string un_camel_case_name( UnCamelCaseFieldName(camel_case_name, descriptor)); const bool needs_custom_name = (raw_field_name != un_camel_case_name); @@ -67,10 +67,10 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } else { (*variables)["comments"] = "\n"; } - const string& classname = ClassName(descriptor->containing_type()); + const std::string& classname = ClassName(descriptor->containing_type()); (*variables)["classname"] = classname; (*variables)["name"] = camel_case_name; - const string& capitalized_name = FieldNameCapitalized(descriptor); + const std::string& capitalized_name = FieldNameCapitalized(descriptor); (*variables)["capitalized_name"] = capitalized_name; (*variables)["raw_field_name"] = raw_field_name; (*variables)["field_number_name"] = @@ -78,7 +78,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["field_number"] = StrCat(descriptor->number()); (*variables)["field_type"] = GetCapitalizedType(descriptor); (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor); - std::vector field_flags; + std::vector field_flags; if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated"); if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired"); if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional"); @@ -91,6 +91,14 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, if (descriptor->type() == FieldDescriptor::TYPE_ENUM) { field_flags.push_back("GPBFieldHasEnumDescriptor"); } + // It will clear on a zero value if... + // - not repeated/map + // - doesn't have presence + bool clear_on_zero = + (!descriptor->is_repeated() && !descriptor->has_presence()); + if (clear_on_zero) { + field_flags.push_back("GPBFieldClearHasIvarOnZero"); + } (*variables)["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags); @@ -177,12 +185,12 @@ void FieldGenerator::GenerateCFunctionImplementations( } void FieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { // Nothing } void FieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { // Nothing } @@ -238,13 +246,18 @@ void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) { } void FieldGenerator::SetOneofIndexBase(int index_base) { - if (descriptor_->containing_oneof() != NULL) { - int index = descriptor_->containing_oneof()->index() + index_base; + const OneofDescriptor *oneof = descriptor_->real_containing_oneof(); + if (oneof != NULL) { + int index = oneof->index() + index_base; // Flip the sign to mark it as a oneof. variables_["has_index"] = StrCat(-index); } } +bool FieldGenerator::WantsHasProperty(void) const { + return descriptor_->has_presence() && !descriptor_->real_containing_oneof(); +} + void FieldGenerator::FinishInitialization(void) { // If "property_type" wasn't set, make it "storage_type". if ((variables_.find("property_type") == variables_.end()) && @@ -289,20 +302,8 @@ void SingleFieldGenerator::GeneratePropertyImplementation( } } -bool SingleFieldGenerator::WantsHasProperty(void) const { - if (descriptor_->containing_oneof() != NULL) { - // If in a oneof, it uses the oneofcase instead of a has bit. - return false; - } - if (HasFieldPresence(descriptor_->file())) { - // In proto1/proto2, every field has a has_$name$() method. - return true; - } - return false; -} - bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { - if (descriptor_->containing_oneof() != NULL) { + if (descriptor_->real_containing_oneof()) { // The oneof tracks what is set instead. return false; } @@ -402,13 +403,8 @@ void RepeatedFieldGenerator::GeneratePropertyDeclaration( printer->Print("\n"); } -bool RepeatedFieldGenerator::WantsHasProperty(void) const { - // Consumer check the array size/existence rather than a has bit. - return false; -} - bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { - return false; // The array having anything is what is used. + return false; // The array (or map/dict) having anything is what is used. } FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h index 68c470a50b43..0b0e3058f9c9 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -65,8 +65,10 @@ class FieldGenerator { virtual void GenerateCFunctionImplementations(io::Printer* printer) const; // Exposed for subclasses, should always call it on the parent class also. - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; // Used during generation, not intended to be extended by subclasses. void GenerateFieldDescription( @@ -81,25 +83,26 @@ class FieldGenerator { virtual void SetExtraRuntimeHasBitsBase(int index_base); void SetOneofIndexBase(int index_base); - string variable(const char* key) const { + std::string variable(const char* key) const { return variables_.find(key)->second; } bool needs_textformat_name_support() const { - const string& field_flags = variable("fieldflags"); - return field_flags.find("GPBFieldTextFormatNameCustom") != string::npos; + const std::string& field_flags = variable("fieldflags"); + return field_flags.find("GPBFieldTextFormatNameCustom") != + std::string::npos; } - string generated_objc_name() const { return variable("name"); } - string raw_field_name() const { return variable("raw_field_name"); } + std::string generated_objc_name() const { return variable("name"); } + std::string raw_field_name() const { return variable("raw_field_name"); } protected: FieldGenerator(const FieldDescriptor* descriptor, const Options& options); virtual void FinishInitialization(void); - virtual bool WantsHasProperty(void) const = 0; + bool WantsHasProperty(void) const; const FieldDescriptor* descriptor_; - std::map variables_; + std::map variables_; }; class SingleFieldGenerator : public FieldGenerator { @@ -119,7 +122,6 @@ class SingleFieldGenerator : public FieldGenerator { protected: SingleFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - virtual bool WantsHasProperty(void) const; }; // Subclass with common support for when the field ends up as an ObjC Object. @@ -156,7 +158,6 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator { RepeatedFieldGenerator(const FieldDescriptor* descriptor, const Options& options); virtual void FinishInitialization(void); - virtual bool WantsHasProperty(void) const; }; // Convenience class which constructs FieldGenerators for a Descriptor. diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index db58249ded10..417733ef4727 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -52,7 +52,7 @@ namespace objectivec { namespace { // This is also found in GPBBootstrap.h, and needs to be kept in sync. -const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30003; +const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004; const char* kHeaderExtension = ".pbobjc.h"; @@ -209,15 +209,15 @@ FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options) FileGenerator::~FileGenerator() {} void FileGenerator::GenerateHeader(io::Printer *printer) { - std::set headers; + std::vector headers; // Generated files bundled with the library get minimal imports, everything // else gets the wrapper so everything is usable. if (is_bundled_proto_) { - headers.insert("GPBRootObject.h"); - headers.insert("GPBMessage.h"); - headers.insert("GPBDescriptor.h"); + headers.push_back("GPBDescriptor.h"); + headers.push_back("GPBMessage.h"); + headers.push_back("GPBRootObject.h"); } else { - headers.insert("GPBProtocolBuffers.h"); + headers.push_back("GPBProtocolBuffers.h"); } PrintFileRuntimePreamble(printer, headers); @@ -242,8 +242,9 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { ImportWriter import_writer( options_.generate_for_named_framework, options_.named_framework_to_proto_path_mappings_path, + options_.runtime_import_prefix, is_bundled_proto_); - const string header_extension(kHeaderExtension); + const std::string header_extension(kHeaderExtension); for (int i = 0; i < file_->public_dependency_count(); i++) { import_writer.AddFile(file_->public_dependency(i), header_extension); } @@ -263,11 +264,11 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { "CF_EXTERN_C_BEGIN\n" "\n"); - std::set fwd_decls; + std::set fwd_decls; for (const auto& generator : message_generators_) { generator->DetermineForwardDeclarations(&fwd_decls); } - for (std::set::const_iterator i(fwd_decls.begin()); + for (std::set::const_iterator i(fwd_decls.begin()); i != fwd_decls.end(); ++i) { printer->Print("$value$;\n", "value", *i); } @@ -337,8 +338,8 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { void FileGenerator::GenerateSource(io::Printer *printer) { // #import the runtime support. - std::set headers; - headers.insert("GPBProtocolBuffers_RuntimeSupport.h"); + std::vector headers; + headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); PrintFileRuntimePreamble(printer, headers); // Enums use atomic in the generated code, so add the system import as needed. @@ -355,15 +356,16 @@ void FileGenerator::GenerateSource(io::Printer *printer) { ImportWriter import_writer( options_.generate_for_named_framework, options_.named_framework_to_proto_path_mappings_path, + options_.runtime_import_prefix, is_bundled_proto_); - const string header_extension(kHeaderExtension); + const std::string header_extension(kHeaderExtension); // #import the header for this proto file. import_writer.AddFile(file_, header_extension); // #import the headers for anything that a plain dependency of this proto // file (that means they were just an include, not a "public" include). - std::set public_import_names; + std::set public_import_names; for (int i = 0; i < file_->public_dependency_count(); i++) { public_import_names.insert(file_->public_dependency(i)->name()); } @@ -398,7 +400,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { } } - std::set fwd_decls; + std::set fwd_decls; for (const auto& generator : message_generators_) { generator->DetermineObjectiveCClassDefinitions(&fwd_decls); } @@ -419,7 +421,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"); if (includes_oneof) { // The generated code for oneof's uses direct ivar access, suppress the - // warning incase developer turn that on in the context they compile the + // warning in case developer turn that on in the context they compile the // generated code. printer->Print( "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n"); @@ -499,7 +501,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { for (std::vector::iterator iter = deps_with_extensions.begin(); iter != deps_with_extensions.end(); ++iter) { - const string root_class_name(FileClassName((*iter))); + const std::string root_class_name(FileClassName((*iter))); printer->Print( "[registry addExtensions:[$dependency$ extensionRegistry]];\n", "dependency", root_class_name); @@ -529,7 +531,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // File descriptor only needed if there are messages to use it. if (!message_generators_.empty()) { - std::map vars; + std::map vars; vars["root_class_name"] = root_class_name_; vars["package"] = file_->package(); vars["objc_prefix"] = FileClassPrefix(file_); @@ -590,48 +592,16 @@ void FileGenerator::GenerateSource(io::Printer *printer) { // files. This currently only supports the runtime coming from a framework // as defined by the official CocoaPod. void FileGenerator::PrintFileRuntimePreamble( - io::Printer* printer, const std::set& headers_to_import) const { + io::Printer* printer, + const std::vector& headers_to_import) const { printer->Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "// source: $filename$\n" "\n", "filename", file_->name()); - - const string framework_name(ProtobufLibraryFrameworkName); - const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); - - printer->Print( - "// This CPP symbol can be defined to use imports that match up to the framework\n" - "// imports needed when using CocoaPods.\n" - "#if !defined($cpp_symbol$)\n" - " #define $cpp_symbol$ 0\n" - "#endif\n" - "\n" - "#if $cpp_symbol$\n", - "cpp_symbol", cpp_symbol); - - - for (std::set::const_iterator iter = headers_to_import.begin(); - iter != headers_to_import.end(); ++iter) { - printer->Print( - " #import <$framework_name$/$header$>\n", - "header", *iter, - "framework_name", framework_name); - } - - printer->Print( - "#else\n"); - - for (std::set::const_iterator iter = headers_to_import.begin(); - iter != headers_to_import.end(); ++iter) { - printer->Print( - " #import \"$header$\"\n", - "header", *iter); - } - - printer->Print( - "#endif\n" - "\n"); + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, options_.runtime_import_prefix, true); + printer->Print("\n"); } } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h index fd57263484b3..cecbda2e336c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -58,11 +58,11 @@ class FileGenerator { void GenerateSource(io::Printer* printer); void GenerateHeader(io::Printer* printer); - const string& RootClassName() const { return root_class_name_; } + const std::string& RootClassName() const { return root_class_name_; } private: const FileDescriptor* file_; - string root_class_name_; + std::string root_class_name_; bool is_bundled_proto_; std::vector> enum_generators_; @@ -72,7 +72,8 @@ class FileGenerator { const Options options_; void PrintFileRuntimePreamble( - io::Printer* printer, const std::set& headers_to_import) const; + io::Printer* printer, + const std::vector& headers_to_import) const; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index 25338ad93962..c02e3775ece4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -29,12 +29,12 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include #include #include #include #include -#include namespace google { namespace protobuf { @@ -50,17 +50,17 @@ bool ObjectiveCGenerator::HasGenerateAll() const { } bool ObjectiveCGenerator::Generate(const FileDescriptor* file, - const string& parameter, + const std::string& parameter, GeneratorContext* context, - string* error) const { + std::string* error) const { *error = "Unimplemented Generate() method. Call GenerateAll() instead."; return false; } -bool ObjectiveCGenerator::GenerateAll(const std::vector& files, - const string& parameter, - GeneratorContext* context, - string* error) const { +bool ObjectiveCGenerator::GenerateAll( + const std::vector& files, + const std::string& parameter, GeneratorContext* context, + std::string* error) const { // ----------------------------------------------------------------- // Parse generator options. These options are passed to the compiler using the // --objc_opt flag. The options are passed as a comma separated list of @@ -71,7 +71,7 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& Options generation_options; - std::vector > options; + std::vector > options; ParseGeneratorParameter(parameter, &options); for (int i = 0; i < options.size(); i++) { if (options[i].first == "expected_prefixes_path") { @@ -93,8 +93,11 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& // A semicolon delimited string that lists the paths of .proto files to // exclude from the package prefix validations (expected_prefixes_path). // This is provided as an "out", to skip some files being checked. - SplitStringUsing(options[i].second, ";", - &generation_options.expected_prefixes_suppressions); + for (StringPiece split_piece : Split( + options[i].second, ";", true)) { + generation_options.expected_prefixes_suppressions.push_back( + std::string(split_piece)); + } } else if (options[i].first == "generate_for_named_framework") { // The name of the framework that protos are being generated for. This // will cause the #import statements to be framework based using this @@ -120,13 +123,20 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& // Any number of files can be listed for a framework, just separate them // with commas. // - // There can be multiple lines listing the same frameworkName incase it + // There can be multiple lines listing the same frameworkName in case it // has a lot of proto files included in it; having multiple lines makes // things easier to read. If a proto file is not configured in the // mappings file, it will use the default framework name if one was passed // with generate_for_named_framework, or the relative path to it's include // path otherwise. generation_options.named_framework_to_proto_path_mappings_path = options[i].second; + } else if (options[i].first == "runtime_import_prefix") { + // Path to use as a prefix on #imports of runtime provided headers in the + // generated files. When integrating ObjC protos into a build system, + // this can be used to avoid having to add the runtime directory to the + // header search path since the generate #import will be more complete. + generation_options.runtime_import_prefix = + StripSuffixString(options[i].second, "/"); } else { *error = "error: Unknown generator option: " + options[i].first; return false; @@ -144,7 +154,7 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& for (int i = 0; i < files.size(); i++) { const FileDescriptor* file = files[i]; FileGenerator file_generator(file, generation_options); - string filepath = FilePath(file); + std::string filepath = FilePath(file); // Generate header. { diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/src/google/protobuf/compiler/objectivec/objectivec_generator.h index d10efc20ef1b..1dbc666af16f 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.h @@ -57,15 +57,16 @@ class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete; // implements CodeGenerator ---------------------------------------- - bool HasGenerateAll() const; - bool Generate(const FileDescriptor* file, - const string& parameter, - GeneratorContext* context, - string* error) const; + bool HasGenerateAll() const override; + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override; bool GenerateAll(const std::vector& files, - const string& parameter, - GeneratorContext* context, - string* error) const; + const std::string& parameter, GeneratorContext* context, + std::string* error) const override; + + uint64_t GetSupportedFeatures() const override { + return FEATURE_PROTO3_OPTIONAL; + } }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index d38a2242e001..cce1695a844e 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -78,14 +79,16 @@ Options::Options() { } const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS"); if (suppressions) { - SplitStringUsing(suppressions, ";", &expected_prefixes_suppressions); + expected_prefixes_suppressions = + Split(suppressions, ";", true); } } namespace { -std::unordered_set MakeWordsMap(const char* const words[], size_t num_words) { - std::unordered_set result; +std::unordered_set MakeWordsMap(const char* const words[], + size_t num_words) { + std::unordered_set result; for (int i = 0; i < num_words; i++) { result.insert(words[i]); } @@ -94,7 +97,7 @@ std::unordered_set MakeWordsMap(const char* const words[], size_t num_wo const char* const kUpperSegmentsList[] = {"url", "http", "https"}; -std::unordered_set kUpperSegments = +std::unordered_set kUpperSegments = MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList)); bool ascii_isnewline(char c) { @@ -104,9 +107,10 @@ bool ascii_isnewline(char c) { // Internal helper for name handing. // Do not expose this outside of helpers, stick to having functions for specific // cases (ClassName(), FieldName()), so there is always consistent suffix rules. -string UnderscoresToCamelCase(const string& input, bool first_capitalized) { - std::vector values; - string current; +std::string UnderscoresToCamelCase(const std::string& input, + bool first_capitalized) { + std::vector values; + std::string current; bool last_char_was_number = false; bool last_char_was_lower = false; @@ -144,10 +148,11 @@ string UnderscoresToCamelCase(const string& input, bool first_capitalized) { } values.push_back(current); - string result; + std::string result; bool first_segment_forces_upper = false; - for (std::vector::iterator i = values.begin(); i != values.end(); ++i) { - string value = *i; + for (std::vector::iterator i = values.begin(); i != values.end(); + ++i) { + std::string value = *i; bool all_upper = (kUpperSegments.count(value) > 0); if (all_upper && (result.length() == 0)) { first_segment_forces_upper = true; @@ -233,7 +238,7 @@ const char* const kReservedWordList[] = { // but this verifies and allows for future expansion if we decide to redefine what a // reserved C identifier is (for example the GNU list // https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html ) -bool IsReservedCIdentifier(const string& input) { +bool IsReservedCIdentifier(const std::string& input) { if (input.length() > 2) { if (input.at(0) == '_') { if (isupper(input.at(1)) || input.at(1) == '_') { @@ -244,15 +249,15 @@ bool IsReservedCIdentifier(const string& input) { return false; } -string SanitizeNameForObjC(const string& prefix, - const string& input, - const string& extension, - string* out_suffix_added) { - static const std::unordered_set kReservedWords = +std::string SanitizeNameForObjC(const std::string& prefix, + const std::string& input, + const std::string& extension, + std::string* out_suffix_added) { + static const std::unordered_set kReservedWords = MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList)); - static const std::unordered_set kNSObjectMethods = + static const std::unordered_set kNSObjectMethods = MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList)); - string sanitized; + std::string sanitized; // We add the prefix in the cases where the string is missing a prefix. // We define "missing a prefix" as where 'input': // a) Doesn't start with the prefix or @@ -277,7 +282,7 @@ string SanitizeNameForObjC(const string& prefix, return sanitized; } -string NameFromFieldDescriptor(const FieldDescriptor* field) { +std::string NameFromFieldDescriptor(const FieldDescriptor* field) { if (field->type() == FieldDescriptor::TYPE_GROUP) { return field->message_type()->name(); } else { @@ -285,9 +290,10 @@ string NameFromFieldDescriptor(const FieldDescriptor* field) { } } -void PathSplit(const string& path, string* directory, string* basename) { - string::size_type last_slash = path.rfind('/'); - if (last_slash == string::npos) { +void PathSplit(const std::string& path, std::string* directory, + std::string* basename) { + std::string::size_type last_slash = path.rfind('/'); + if (last_slash == std::string::npos) { if (directory) { *directory = ""; } @@ -304,7 +310,7 @@ void PathSplit(const string& path, string* directory, string* basename) { } } -bool IsSpecialName(const string& name, const string* special_names, +bool IsSpecialName(const std::string& name, const std::string* special_names, size_t count) { for (size_t i = 0; i < count; ++i) { size_t length = special_names[i].length(); @@ -322,7 +328,7 @@ bool IsSpecialName(const string& name, const string* special_names, return false; } -string GetZeroEnumNameForFlagType(const FlagType flag_type) { +std::string GetZeroEnumNameForFlagType(const FlagType flag_type) { switch(flag_type) { case FLAGTYPE_DESCRIPTOR_INITIALIZATION: return "GPBDescriptorInitializationFlag_None"; @@ -336,7 +342,7 @@ string GetZeroEnumNameForFlagType(const FlagType flag_type) { } } -string GetEnumNameForFlagType(const FlagType flag_type) { +std::string GetEnumNameForFlagType(const FlagType flag_type) { switch(flag_type) { case FLAGTYPE_DESCRIPTOR_INITIALIZATION: return "GPBDescriptorInitializationFlags"; @@ -346,25 +352,17 @@ string GetEnumNameForFlagType(const FlagType flag_type) { return "GPBFieldFlags"; default: GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } } } // namespace // Escape C++ trigraphs by escaping question marks to \? -string EscapeTrigraphs(const string& to_escape) { +std::string EscapeTrigraphs(const std::string& to_escape) { return StringReplace(to_escape, "?", "\\?", true); } -string StripProto(const string& filename) { - if (HasSuffixString(filename, ".protodevel")) { - return StripSuffixString(filename, ".protodevel"); - } else { - return StripSuffixString(filename, ".proto"); - } -} - void TrimWhitespace(StringPiece* input) { while (!input->empty() && ascii_isspace(*input->data())) { input->remove_prefix(1); @@ -374,38 +372,37 @@ void TrimWhitespace(StringPiece* input) { } } - -bool IsRetainedName(const string& name) { +bool IsRetainedName(const std::string& name) { // List of prefixes from // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html - static const string retained_names[] = {"new", "alloc", "copy", - "mutableCopy"}; + static const std::string retained_names[] = {"new", "alloc", "copy", + "mutableCopy"}; return IsSpecialName(name, retained_names, sizeof(retained_names) / sizeof(retained_names[0])); } -bool IsInitName(const string& name) { - static const string init_names[] = {"init"}; +bool IsInitName(const std::string& name) { + static const std::string init_names[] = {"init"}; return IsSpecialName(name, init_names, sizeof(init_names) / sizeof(init_names[0])); } -string BaseFileName(const FileDescriptor* file) { - string basename; +std::string BaseFileName(const FileDescriptor* file) { + std::string basename; PathSplit(file->name(), NULL, &basename); return basename; } -string FileClassPrefix(const FileDescriptor* file) { +std::string FileClassPrefix(const FileDescriptor* file) { // Default is empty string, no need to check has_objc_class_prefix. - string result = file->options().objc_class_prefix(); + std::string result = file->options().objc_class_prefix(); return result; } -string FilePath(const FileDescriptor* file) { - string output; - string basename; - string directory; +std::string FilePath(const FileDescriptor* file) { + std::string output; + std::string basename; + std::string directory; PathSplit(file->name(), &directory, &basename); if (directory.length() > 0) { output = directory + "/"; @@ -419,10 +416,10 @@ string FilePath(const FileDescriptor* file) { return output; } -string FilePathBasename(const FileDescriptor* file) { - string output; - string basename; - string directory; +std::string FilePathBasename(const FileDescriptor* file) { + std::string output; + std::string basename; + std::string directory; PathSplit(file->name(), &directory, &basename); basename = StripProto(basename); @@ -432,16 +429,17 @@ string FilePathBasename(const FileDescriptor* file) { return output; } -string FileClassName(const FileDescriptor* file) { - const string prefix = FileClassPrefix(file); - const string name = UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; +std::string FileClassName(const FileDescriptor* file) { + const std::string prefix = FileClassPrefix(file); + const std::string name = + UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; // There aren't really any reserved words that end in "Root", but playing // it safe and checking. return SanitizeNameForObjC(prefix, name, "_RootClass", NULL); } -string ClassNameWorker(const Descriptor* descriptor) { - string name; +std::string ClassNameWorker(const Descriptor* descriptor) { + std::string name; if (descriptor->containing_type() != NULL) { name = ClassNameWorker(descriptor->containing_type()); name += "_"; @@ -449,8 +447,8 @@ string ClassNameWorker(const Descriptor* descriptor) { return name + descriptor->name(); } -string ClassNameWorker(const EnumDescriptor* descriptor) { - string name; +std::string ClassNameWorker(const EnumDescriptor* descriptor) { + std::string name; if (descriptor->containing_type() != NULL) { name = ClassNameWorker(descriptor->containing_type()); name += "_"; @@ -458,19 +456,20 @@ string ClassNameWorker(const EnumDescriptor* descriptor) { return name + descriptor->name(); } -string ClassName(const Descriptor* descriptor) { +std::string ClassName(const Descriptor* descriptor) { return ClassName(descriptor, NULL); } -string ClassName(const Descriptor* descriptor, string* out_suffix_added) { +std::string ClassName(const Descriptor* descriptor, + std::string* out_suffix_added) { // 1. Message names are used as is (style calls for CamelCase, trust it). // 2. Check for reserved word at the very end and then suffix things. - const string prefix = FileClassPrefix(descriptor->file()); - const string name = ClassNameWorker(descriptor); + const std::string prefix = FileClassPrefix(descriptor->file()); + const std::string name = ClassNameWorker(descriptor); return SanitizeNameForObjC(prefix, name, "_Class", out_suffix_added); } -string EnumName(const EnumDescriptor* descriptor) { +std::string EnumName(const EnumDescriptor* descriptor) { // 1. Enum names are used as is (style calls for CamelCase, trust it). // 2. Check for reserved word at the every end and then suffix things. // message Fixed { @@ -479,27 +478,28 @@ string EnumName(const EnumDescriptor* descriptor) { // ... // } // yields Fixed_Class, Fixed_Size. - const string prefix = FileClassPrefix(descriptor->file()); - const string name = ClassNameWorker(descriptor); + const std::string prefix = FileClassPrefix(descriptor->file()); + const std::string name = ClassNameWorker(descriptor); return SanitizeNameForObjC(prefix, name, "_Enum", NULL); } -string EnumValueName(const EnumValueDescriptor* descriptor) { +std::string EnumValueName(const EnumValueDescriptor* descriptor) { // Because of the Switch enum compatibility, the name on the enum has to have // the suffix handing, so it slightly diverges from how nested classes work. // enum Fixed { // FOO = 1 // } // yields Fixed_Enum and Fixed_Enum_Foo (not Fixed_Foo). - const string class_name = EnumName(descriptor->type()); - const string value_str = UnderscoresToCamelCase(descriptor->name(), true); - const string name = class_name + "_" + value_str; + const std::string class_name = EnumName(descriptor->type()); + const std::string value_str = + UnderscoresToCamelCase(descriptor->name(), true); + const std::string name = class_name + "_" + value_str; // There aren't really any reserved words with an underscore and a leading // capital letter, but playing it safe and checking. return SanitizeNameForObjC("", name, "_Value", NULL); } -string EnumValueShortName(const EnumValueDescriptor* descriptor) { +std::string EnumValueShortName(const EnumValueDescriptor* descriptor) { // Enum value names (EnumValueName above) are the enum name turned into // a class name and then the value name is CamelCased and concatenated; the // whole thing then gets sanitized for reserved words. @@ -512,14 +512,14 @@ string EnumValueShortName(const EnumValueDescriptor* descriptor) { // So the right way to get the short name is to take the full enum name // and then strip off the enum name (leaving the value name and anything // done by sanitize). - const string class_name = EnumName(descriptor->type()); - const string long_name_prefix = class_name + "_"; - const string long_name = EnumValueName(descriptor); + const std::string class_name = EnumName(descriptor->type()); + const std::string long_name_prefix = class_name + "_"; + const std::string long_name = EnumValueName(descriptor); return StripPrefixString(long_name, long_name_prefix); } -string UnCamelCaseEnumShortName(const string& name) { - string result; +std::string UnCamelCaseEnumShortName(const std::string& name) { + std::string result; for (int i = 0; i < name.size(); i++) { char c = name[i]; if (i > 0 && ascii_isupper(c)) { @@ -530,15 +530,15 @@ string UnCamelCaseEnumShortName(const string& name) { return result; } -string ExtensionMethodName(const FieldDescriptor* descriptor) { - const string name = NameFromFieldDescriptor(descriptor); - const string result = UnderscoresToCamelCase(name, false); +std::string ExtensionMethodName(const FieldDescriptor* descriptor) { + const std::string name = NameFromFieldDescriptor(descriptor); + const std::string result = UnderscoresToCamelCase(name, false); return SanitizeNameForObjC("", result, "_Extension", NULL); } -string FieldName(const FieldDescriptor* field) { - const string name = NameFromFieldDescriptor(field); - string result = UnderscoresToCamelCase(name, false); +std::string FieldName(const FieldDescriptor* field) { + const std::string name = NameFromFieldDescriptor(field); + std::string result = UnderscoresToCamelCase(name, false); if (field->is_repeated() && !field->is_map()) { // Add "Array" before do check for reserved worlds. result += "Array"; @@ -551,50 +551,50 @@ string FieldName(const FieldDescriptor* field) { return SanitizeNameForObjC("", result, "_p", NULL); } -string FieldNameCapitalized(const FieldDescriptor* field) { +std::string FieldNameCapitalized(const FieldDescriptor* field) { // Want the same suffix handling, so upcase the first letter of the other // name. - string result = FieldName(field); + std::string result = FieldName(field); if (result.length() > 0) { result[0] = ascii_toupper(result[0]); } return result; } -string OneofEnumName(const OneofDescriptor* descriptor) { +std::string OneofEnumName(const OneofDescriptor* descriptor) { const Descriptor* fieldDescriptor = descriptor->containing_type(); - string name = ClassName(fieldDescriptor); + std::string name = ClassName(fieldDescriptor); name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase"; // No sanitize needed because the OS never has names that end in _OneOfCase. return name; } -string OneofName(const OneofDescriptor* descriptor) { - string name = UnderscoresToCamelCase(descriptor->name(), false); +std::string OneofName(const OneofDescriptor* descriptor) { + std::string name = UnderscoresToCamelCase(descriptor->name(), false); // No sanitize needed because it gets OneOfCase added and that shouldn't // ever conflict. return name; } -string OneofNameCapitalized(const OneofDescriptor* descriptor) { +std::string OneofNameCapitalized(const OneofDescriptor* descriptor) { // Use the common handling and then up-case the first letter. - string result = OneofName(descriptor); + std::string result = OneofName(descriptor); if (result.length() > 0) { result[0] = ascii_toupper(result[0]); } return result; } -string ObjCClass(const string& class_name) { - return string("GPBObjCClass(") + class_name + ")"; +std::string ObjCClass(const std::string& class_name) { + return std::string("GPBObjCClass(") + class_name + ")"; } -string ObjCClassDeclaration(const string& class_name) { - return string("GPBObjCClassDeclaration(") + class_name + ");"; +std::string ObjCClassDeclaration(const std::string& class_name) { + return std::string("GPBObjCClassDeclaration(") + class_name + ");"; } -string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { - string worker(name); +std::string UnCamelCaseFieldName(const std::string& name, const FieldDescriptor* field) { + std::string worker(name); if (HasSuffixString(worker, "_p")) { worker = StripSuffixString(worker, "_p"); } @@ -609,7 +609,7 @@ string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { } return worker; } else { - string result; + std::string result; for (int i = 0; i < worker.size(); i++) { char c = worker[i]; if (ascii_isupper(c)) { @@ -625,7 +625,7 @@ string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { } } -string GetCapitalizedType(const FieldDescriptor* field) { +std::string GetCapitalizedType(const FieldDescriptor* field) { switch (field->type()) { case FieldDescriptor::TYPE_INT32: return "Int32"; @@ -668,7 +668,7 @@ string GetCapitalizedType(const FieldDescriptor* field) { // Some compilers report reaching end of function even though all cases of // the enum are handed in the switch. GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type) { @@ -742,7 +742,8 @@ bool IsReferenceType(const FieldDescriptor* field) { return !IsPrimitiveType(field); } -static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) { +static std::string HandleExtremeFloatingPoint(std::string val, + bool add_float_suffix) { if (val == "nan") { return "NAN"; } else if (val == "inf") { @@ -751,16 +752,16 @@ static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) { return "-INFINITY"; } else { // float strings with ., e or E need to have f appended - if (add_float_suffix && - (val.find(".") != string::npos || val.find("e") != string::npos || - val.find("E") != string::npos)) { + if (add_float_suffix && (val.find(".") != std::string::npos || + val.find("e") != std::string::npos || + val.find("E") != std::string::npos)) { val += "f"; } return val; } } -string GPBGenericValueFieldName(const FieldDescriptor* field) { +std::string GPBGenericValueFieldName(const FieldDescriptor* field) { // Returns the field within the GPBGenericValue union to use for the given // field. if (field->is_repeated()) { @@ -796,11 +797,11 @@ string GPBGenericValueFieldName(const FieldDescriptor* field) { // Some compilers report reaching end of function even though all cases of // the enum are handed in the switch. GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } -string DefaultValue(const FieldDescriptor* field) { +std::string DefaultValue(const FieldDescriptor* field) { // Repeated fields don't have defaults. if (field->is_repeated()) { return "nil"; @@ -835,7 +836,7 @@ string DefaultValue(const FieldDescriptor* field) { return field->default_value_bool() ? "YES" : "NO"; case FieldDescriptor::CPPTYPE_STRING: { const bool has_default_value = field->has_default_value(); - const string& default_string = field->default_value_string(); + const std::string& default_string = field->default_value_string(); if (!has_default_value || default_string.length() == 0) { // If the field is defined as being the empty string, // then we will just assign to nil, as the empty string is the @@ -852,7 +853,7 @@ string DefaultValue(const FieldDescriptor* field) { // Must convert to a standard byte order for packing length into // a cstring. uint32 length = ghtonl(default_string.length()); - string bytes((const char*)&length, sizeof(length)); + std::string bytes((const char*)&length, sizeof(length)); bytes.append(default_string); return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\""; } else { @@ -868,7 +869,7 @@ string DefaultValue(const FieldDescriptor* field) { // Some compilers report reaching end of function even though all cases of // the enum are handed in the switch. GOOGLE_LOG(FATAL) << "Can't get here."; - return string(); + return std::string(); } bool HasNonZeroDefaultValue(const FieldDescriptor* field) { @@ -901,7 +902,7 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) { case FieldDescriptor::CPPTYPE_BOOL: return field->default_value_bool(); case FieldDescriptor::CPPTYPE_STRING: { - const string& default_string = field->default_value_string(); + const std::string& default_string = field->default_value_string(); return default_string.length() != 0; } case FieldDescriptor::CPPTYPE_ENUM: @@ -916,14 +917,14 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) { return false; } -string BuildFlagsString(const FlagType flag_type, - const std::vector& strings) { +std::string BuildFlagsString(const FlagType flag_type, + const std::vector& strings) { if (strings.empty()) { return GetZeroEnumNameForFlagType(flag_type); } else if (strings.size() == 1) { return strings[0]; } - string string("(" + GetEnumNameForFlagType(flag_type) + ")("); + std::string string("(" + GetEnumNameForFlagType(flag_type) + ")("); for (size_t i = 0; i != strings.size(); ++i) { if (i > 0) { string.append(" | "); @@ -934,12 +935,12 @@ string BuildFlagsString(const FlagType flag_type, return string; } -string BuildCommentsString(const SourceLocation& location, +std::string BuildCommentsString(const SourceLocation& location, bool prefer_single_line) { - const string& comments = location.leading_comments.empty() + const std::string& comments = location.leading_comments.empty() ? location.trailing_comments : location.leading_comments; - std::vector lines; + std::vector lines; lines = Split(comments, "\n", false); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); @@ -949,10 +950,10 @@ string BuildCommentsString(const SourceLocation& location, return ""; } - string prefix; - string suffix; - string final_comments; - string epilogue; + std::string prefix; + std::string suffix; + std::string final_comments; + std::string epilogue; bool add_leading_space = false; @@ -968,7 +969,7 @@ string BuildCommentsString(const SourceLocation& location, } for (int i = 0; i < lines.size(); i++) { - string line = StripPrefixString(lines[i], " "); + std::string line = StripPrefixString(lines[i], " "); // HeaderDoc and appledoc use '\' and '@' for markers; escape them. line = StringReplace(line, "\\", "\\\\", true); line = StringReplace(line, "@", "\\@", true); @@ -990,11 +991,11 @@ string BuildCommentsString(const SourceLocation& location, // want to put the library in a framework is an interesting question. The // problem is it means changing sources shipped with the library to actually // use a different value; so it isn't as simple as a option. -const char* const ProtobufLibraryFrameworkName = "protobuf"; +const char* const ProtobufLibraryFrameworkName = "Protobuf"; -string ProtobufFrameworkImportSymbol(const string& framework_name) { +std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) { // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS - string result = string("GPB_USE_"); + std::string result = std::string("GPB_USE_"); result += ToUpper(framework_name); result += "_FRAMEWORK_IMPORTS"; return result; @@ -1004,7 +1005,7 @@ bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) { // We don't check the name prefix or proto package because some files // (descriptor.proto), aren't shipped generated by the library, so this // seems to be the safest way to only catch the ones shipped. - const string name = file->name(); + const std::string name = file->name(); if (name == "google/protobuf/any.proto" || name == "google/protobuf/api.proto" || name == "google/protobuf/duration.proto" || @@ -1043,21 +1044,21 @@ namespace { class ExpectedPrefixesCollector : public LineConsumer { public: - ExpectedPrefixesCollector(std::map* inout_package_to_prefix_map) + ExpectedPrefixesCollector(std::map* inout_package_to_prefix_map) : prefix_map_(inout_package_to_prefix_map) {} - virtual bool ConsumeLine(const StringPiece& line, string* out_error); + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error); private: - std::map* prefix_map_; + std::map* prefix_map_; }; bool ExpectedPrefixesCollector::ConsumeLine( - const StringPiece& line, string* out_error) { + const StringPiece& line, std::string* out_error) { int offset = line.find('='); if (offset == StringPiece::npos) { - *out_error = string("Expected prefixes file line without equal sign: '") + - string(line) + "'."; + *out_error = std::string("Expected prefixes file line without equal sign: '") + + std::string(line) + "'."; return false; } StringPiece package = line.substr(0, offset); @@ -1066,13 +1067,13 @@ bool ExpectedPrefixesCollector::ConsumeLine( TrimWhitespace(&prefix); // Don't really worry about error checking the package/prefix for // being valid. Assume the file is validated when it is created/edited. - (*prefix_map_)[string(package)] = string(prefix); + (*prefix_map_)[std::string(package)] = std::string(prefix); return true; } -bool LoadExpectedPackagePrefixes(const Options &generation_options, - std::map* prefix_map, - string* out_error) { +bool LoadExpectedPackagePrefixes(const Options& generation_options, + std::map* prefix_map, + std::string* out_error) { if (generation_options.expected_prefixes_path.empty()) { return true; } @@ -1083,19 +1084,18 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options, } bool ValidateObjCClassPrefix( - const FileDescriptor* file, - const string& expected_prefixes_path, - const std::map& expected_package_prefixes, - string* out_error) { - const string prefix = file->options().objc_class_prefix(); - const string package = file->package(); + const FileDescriptor* file, const std::string& expected_prefixes_path, + const std::map& expected_package_prefixes, + std::string* out_error) { + const std::string prefix = file->options().objc_class_prefix(); + const std::string package = file->package(); // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for warnings. // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). - std::map::const_iterator package_match = + std::map::const_iterator package_match = expected_package_prefixes.find(package); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... @@ -1125,7 +1125,7 @@ bool ValidateObjCClassPrefix( // to Apple's rules (the checks above implicitly whitelist anything that // doesn't meet these rules). if (!ascii_isupper(prefix[0])) { - std::cerr << std::endl + std::cerr << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" << prefix << "\";' in '" << file->name() << "';" << " it should start with a capital letter." << std::endl; @@ -1134,7 +1134,7 @@ bool ValidateObjCClassPrefix( if (prefix.length() < 3) { // Apple reserves 2 character prefixes for themselves. They do use some // 3 character prefixes, but they haven't updated the rules/docs. - std::cerr << std::endl + std::cerr << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" << prefix << "\";' in '" << file->name() << "';" << " Apple recommends they should be at least 3 characters long." @@ -1143,8 +1143,9 @@ bool ValidateObjCClassPrefix( } // Look for any other package that uses the same prefix. - string other_package_for_prefix; - for (std::map::const_iterator i = expected_package_prefixes.begin(); + std::string other_package_for_prefix; + for (std::map::const_iterator i = + expected_package_prefixes.begin(); i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; @@ -1158,7 +1159,7 @@ bool ValidateObjCClassPrefix( // The file does not have a package and ... if (other_package_for_prefix.empty()) { // ... no other package has declared that prefix. - std::cerr << std::endl + std::cerr << "protoc:0: warning: File '" << file->name() << "' has no " << "package. Consider adding a new package to the proto and adding '" << "new.package = " << prefix << "' to the expected prefixes file (" @@ -1166,7 +1167,7 @@ bool ValidateObjCClassPrefix( std::cerr.flush(); } else { // ... another package has declared the same prefix. - std::cerr << std::endl + std::cerr << "protoc:0: warning: File '" << file->name() << "' has no package " << "and package '" << other_package_for_prefix << "' already uses '" << prefix << "' as its prefix. Consider either adding a new package " @@ -1195,7 +1196,7 @@ bool ValidateObjCClassPrefix( // Check: Warning - If the given package/prefix pair wasn't expected, issue a // warning issue a warning suggesting it gets added to the file. if (!expected_package_prefixes.empty()) { - std::cerr << std::endl + std::cerr << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" << prefix << "\";' in '" << file->name() << "';" << " consider adding it to the expected prefixes file (" @@ -1210,9 +1211,9 @@ bool ValidateObjCClassPrefix( bool ValidateObjCClassPrefixes(const std::vector& files, const Options& generation_options, - string* out_error) { + std::string* out_error) { // Load the expected package prefixes, if available, to validate against. - std::map expected_package_prefixes; + std::map expected_package_prefixes; if (!LoadExpectedPackagePrefixes(generation_options, &expected_package_prefixes, out_error)) { @@ -1246,8 +1247,8 @@ TextFormatDecodeData::TextFormatDecodeData() { } TextFormatDecodeData::~TextFormatDecodeData() { } void TextFormatDecodeData::AddString(int32 key, - const string& input_for_decode, - const string& desired_output) { + const std::string& input_for_decode, + const std::string& desired_output) { for (std::vector::const_iterator i = entries_.begin(); i != entries_.end(); ++i) { if (i->first == key) { @@ -1259,12 +1260,12 @@ void TextFormatDecodeData::AddString(int32 key, } } - const string& data = TextFormatDecodeData::DecodeDataForString( + const std::string& data = TextFormatDecodeData::DecodeDataForString( input_for_decode, desired_output); entries_.push_back(DataEntry(key, data)); } -string TextFormatDecodeData::Data() const { +std::string TextFormatDecodeData::Data() const { std::ostringstream data_stringstream; if (num_entries() > 0) { @@ -1295,20 +1296,20 @@ class DecodeDataBuilder { Push(); need_underscore_ = true; } - string Finish() { + std::string Finish() { Push(); return decode_data_; } private: - static const uint8 kAddUnderscore = 0x80; + static constexpr uint8 kAddUnderscore = 0x80; - static const uint8 kOpAsIs = 0x00; - static const uint8 kOpFirstUpper = 0x40; - static const uint8 kOpFirstLower = 0x20; - static const uint8 kOpAllUpper = 0x60; + static constexpr uint8 kOpAsIs = 0x00; + static constexpr uint8 kOpFirstUpper = 0x40; + static constexpr uint8 kOpFirstLower = 0x20; + static constexpr uint8 kOpAllUpper = 0x60; - static const int kMaxSegmentLen = 0x1f; + static constexpr int kMaxSegmentLen = 0x1f; void AddChar(const char desired) { ++segment_len_; @@ -1351,7 +1352,7 @@ class DecodeDataBuilder { uint8 op_; int segment_len_; - string decode_data_; + std::string decode_data_; }; bool DecodeDataBuilder::AddCharacter(const char desired, const char input) { @@ -1392,8 +1393,8 @@ bool DecodeDataBuilder::AddCharacter(const char desired, const char input) { // If decode data can't be generated, a directive for the raw string // is used instead. -string DirectDecodeString(const string& str) { - string result; +std::string DirectDecodeString(const std::string& str) { + std::string result; result += (char)'\0'; // Marker for full string. result += str; result += (char)'\0'; // End of string. @@ -1403,8 +1404,8 @@ string DirectDecodeString(const string& str) { } // namespace // static -string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode, - const string& desired_output) { +std::string TextFormatDecodeData::DecodeDataForString( + const std::string& input_for_decode, const std::string& desired_output) { if (input_for_decode.empty() || desired_output.empty()) { std::cerr << "error: got empty string for making TextFormat data, input: \"" << input_for_decode << "\", desired: \"" << desired_output << "\"." @@ -1412,8 +1413,8 @@ string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode, std::cerr.flush(); abort(); } - if ((input_for_decode.find('\0') != string::npos) || - (desired_output.find('\0') != string::npos)) { + if ((input_for_decode.find('\0') != std::string::npos) || + (desired_output.find('\0') != std::string::npos)) { std::cerr << "error: got a null char in a string for making TextFormat data," << " input: \"" << CEscape(input_for_decode) << "\", desired: \"" << CEscape(desired_output) << "\"." << std::endl; @@ -1468,21 +1469,21 @@ class Parser { bool Finish(); int last_line() const { return line_; } - string error_str() const { return error_str_; } + std::string error_str() const { return error_str_; } private: bool ParseLoop(); LineConsumer* line_consumer_; int line_; - string error_str_; + std::string error_str_; StringPiece p_; - string leftover_; + std::string leftover_; }; bool Parser::ParseChunk(StringPiece chunk) { if (!leftover_.empty()) { - leftover_ += string(chunk); + leftover_ += std::string(chunk); p_ = StringPiece(leftover_); } else { p_ = chunk; @@ -1491,7 +1492,7 @@ bool Parser::ParseChunk(StringPiece chunk) { if (p_.empty()) { leftover_.clear(); } else { - leftover_ = string(p_); + leftover_ = std::string(p_); } return result; } @@ -1531,15 +1532,15 @@ LineConsumer::LineConsumer() {} LineConsumer::~LineConsumer() {} -bool ParseSimpleFile( - const string& path, LineConsumer* line_consumer, string* out_error) { +bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer, + std::string* out_error) { int fd; do { fd = posix::open(path.c_str(), O_RDONLY); } while (fd < 0 && errno == EINTR); if (fd < 0) { - *out_error = - string("error: Unable to open \"") + path + "\", " + strerror(errno); + *out_error = std::string("error: Unable to open \"") + path + "\", " + + strerror(errno); return false; } io::FileInputStream file_stream(fd); @@ -1555,7 +1556,7 @@ bool ParseSimpleFile( if (!parser.ParseChunk(StringPiece(static_cast(buf), buf_len))) { *out_error = - string("error: ") + path + + std::string("error: ") + path + " Line " + StrCat(parser.last_line()) + ", " + parser.error_str(); return false; } @@ -1564,30 +1565,28 @@ bool ParseSimpleFile( } ImportWriter::ImportWriter( - const string& generate_for_named_framework, - const string& named_framework_to_proto_path_mappings_path, - bool include_wkt_imports) + const std::string& generate_for_named_framework, + const std::string& named_framework_to_proto_path_mappings_path, + const std::string& runtime_import_prefix, bool include_wkt_imports) : generate_for_named_framework_(generate_for_named_framework), named_framework_to_proto_path_mappings_path_( named_framework_to_proto_path_mappings_path), + runtime_import_prefix_(runtime_import_prefix), include_wkt_imports_(include_wkt_imports), - need_to_parse_mapping_file_(true) { -} + need_to_parse_mapping_file_(true) {} ImportWriter::~ImportWriter() {} void ImportWriter::AddFile(const FileDescriptor* file, - const string& header_extension) { - const string file_path(FilePath(file)); - + const std::string& header_extension) { if (IsProtobufLibraryBundledProtoFile(file)) { // The imports of the WKTs are only needed within the library itself, // in other cases, they get skipped because the generated code already // import GPBProtocolBuffers.h and hence proves them. if (include_wkt_imports_) { - protobuf_framework_imports_.push_back( - FilePathBasename(file) + header_extension); - protobuf_non_framework_imports_.push_back(file_path + header_extension); + const std::string header_name = + "GPB" + FilePathBasename(file) + header_extension; + protobuf_imports_.push_back(header_name); } return; } @@ -1597,7 +1596,7 @@ void ImportWriter::AddFile(const FileDescriptor* file, ParseFrameworkMappings(); } - std::map::iterator proto_lookup = + std::map::iterator proto_lookup = proto_file_to_framework_name_.find(file->name()); if (proto_lookup != proto_file_to_framework_name_.end()) { other_framework_imports_.push_back( @@ -1613,40 +1612,14 @@ void ImportWriter::AddFile(const FileDescriptor* file, return; } - other_imports_.push_back(file_path + header_extension); + other_imports_.push_back(FilePath(file) + header_extension); } void ImportWriter::Print(io::Printer* printer) const { - assert(protobuf_non_framework_imports_.size() == - protobuf_framework_imports_.size()); - bool add_blank_line = false; - if (!protobuf_framework_imports_.empty()) { - const string framework_name(ProtobufLibraryFrameworkName); - const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); - - printer->Print( - "#if $cpp_symbol$\n", - "cpp_symbol", cpp_symbol); - for (std::vector::const_iterator iter = protobuf_framework_imports_.begin(); - iter != protobuf_framework_imports_.end(); ++iter) { - printer->Print( - " #import <$framework_name$/$header$>\n", - "framework_name", framework_name, - "header", *iter); - } - printer->Print( - "#else\n"); - for (std::vector::const_iterator iter = protobuf_non_framework_imports_.begin(); - iter != protobuf_non_framework_imports_.end(); ++iter) { - printer->Print( - " #import \"$header$\"\n", - "header", *iter); - } - printer->Print( - "#endif\n"); - + if (!protobuf_imports_.empty()) { + PrintRuntimeImports(printer, protobuf_imports_, runtime_import_prefix_); add_blank_line = true; } @@ -1655,7 +1628,8 @@ void ImportWriter::Print(io::Printer* printer) const { printer->Print("\n"); } - for (std::vector::const_iterator iter = other_framework_imports_.begin(); + for (std::vector::const_iterator iter = + other_framework_imports_.begin(); iter != other_framework_imports_.end(); ++iter) { printer->Print( "#import <$header$>\n", @@ -1670,7 +1644,7 @@ void ImportWriter::Print(io::Printer* printer) const { printer->Print("\n"); } - for (std::vector::const_iterator iter = other_imports_.begin(); + for (std::vector::const_iterator iter = other_imports_.begin(); iter != other_imports_.end(); ++iter) { printer->Print( "#import \"$header$\"\n", @@ -1679,6 +1653,54 @@ void ImportWriter::Print(io::Printer* printer) const { } } +void ImportWriter::PrintRuntimeImports( + io::Printer* printer, const std::vector& header_to_import, + const std::string& runtime_import_prefix, bool default_cpp_symbol) { + // Given an override, use that. + if (!runtime_import_prefix.empty()) { + for (const auto& header : header_to_import) { + printer->Print( + " #import \"$import_prefix$/$header$\"\n", + "import_prefix", runtime_import_prefix, + "header", header); + } + return; + } + + const std::string framework_name(ProtobufLibraryFrameworkName); + const std::string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); + + if (default_cpp_symbol) { + printer->Print( + "// This CPP symbol can be defined to use imports that match up to the framework\n" + "// imports needed when using CocoaPods.\n" + "#if !defined($cpp_symbol$)\n" + " #define $cpp_symbol$ 0\n" + "#endif\n" + "\n", + "cpp_symbol", cpp_symbol); + } + + printer->Print( + "#if $cpp_symbol$\n", + "cpp_symbol", cpp_symbol); + for (const auto& header : header_to_import) { + printer->Print( + " #import <$framework_name$/$header$>\n", + "framework_name", framework_name, + "header", header); + } + printer->Print( + "#else\n"); + for (const auto& header : header_to_import) { + printer->Print( + " #import \"$header$\"\n", + "header", header); + } + printer->Print( + "#endif\n"); +} + void ImportWriter::ParseFrameworkMappings() { need_to_parse_mapping_file_ = false; if (named_framework_to_proto_path_mappings_path_.empty()) { @@ -1686,7 +1708,7 @@ void ImportWriter::ParseFrameworkMappings() { } ProtoFrameworkCollector collector(&proto_file_to_framework_name_); - string parse_error; + std::string parse_error; if (!ParseSimpleFile(named_framework_to_proto_path_mappings_path_, &collector, &parse_error)) { std::cerr << "error parsing " << named_framework_to_proto_path_mappings_path_ @@ -1696,12 +1718,12 @@ void ImportWriter::ParseFrameworkMappings() { } bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( - const StringPiece& line, string* out_error) { + const StringPiece& line, std::string* out_error) { int offset = line.find(':'); if (offset == StringPiece::npos) { *out_error = - string("Framework/proto file mapping line without colon sign: '") + - string(line) + "'."; + std::string("Framework/proto file mapping line without colon sign: '") + + std::string(line) + "'."; return false; } StringPiece framework_name = line.substr(0, offset); @@ -1718,12 +1740,12 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( StringPiece proto_file = proto_file_list.substr(start, offset - start); TrimWhitespace(&proto_file); if (!proto_file.empty()) { - std::map::iterator existing_entry = + std::map::iterator existing_entry = map_->find(string(proto_file)); if (existing_entry != map_->end()) { std::cerr << "warning: duplicate proto file reference, replacing " "framework entry for '" - << string(proto_file) << "' with '" << string(framework_name) + << std::string(proto_file) << "' with '" << std::string(framework_name) << "' (was '" << existing_entry->second << "')." << std::endl; std::cerr.flush(); } @@ -1731,11 +1753,11 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( if (proto_file.find(' ') != StringPiece::npos) { std::cerr << "note: framework mapping file had a proto file with a " "space in, hopefully that isn't a missing comma: '" - << string(proto_file) << "'" << std::endl; + << std::string(proto_file) << "'" << std::endl; std::cerr.flush(); } - (*map_)[string(proto_file)] = string(framework_name); + (*map_)[std::string(proto_file)] = std::string(framework_name); } start = offset + 1; @@ -1744,7 +1766,6 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( return true; } - } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index c6a2c7733b7b..ce2d92cf3cf3 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -49,86 +49,80 @@ namespace objectivec { // Generator options (see objectivec_generator.cc for a description of each): struct Options { Options(); - string expected_prefixes_path; - std::vector expected_prefixes_suppressions; - string generate_for_named_framework; - string named_framework_to_proto_path_mappings_path; + std::string expected_prefixes_path; + std::vector expected_prefixes_suppressions; + std::string generate_for_named_framework; + std::string named_framework_to_proto_path_mappings_path; + std::string runtime_import_prefix; }; // Escape C++ trigraphs by escaping question marks to "\?". -string PROTOC_EXPORT EscapeTrigraphs(const string& to_escape); - -// Strips ".proto" or ".protodevel" from the end of a filename. -string PROTOC_EXPORT StripProto(const string& filename); +std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& to_escape); // Remove white space from either end of a StringPiece. void PROTOC_EXPORT TrimWhitespace(StringPiece* input); // Returns true if the name requires a ns_returns_not_retained attribute applied // to it. -bool PROTOC_EXPORT IsRetainedName(const string& name); +bool PROTOC_EXPORT IsRetainedName(const std::string& name); // Returns true if the name starts with "init" and will need to have special // handling under ARC. -bool PROTOC_EXPORT IsInitName(const string& name); +bool PROTOC_EXPORT IsInitName(const std::string& name); // Gets the objc_class_prefix. -string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file); +std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file); // Gets the path of the file we're going to generate (sans the .pb.h // extension). The path will be dependent on the objectivec package // declared in the proto package. -string PROTOC_EXPORT FilePath(const FileDescriptor* file); +std::string PROTOC_EXPORT FilePath(const FileDescriptor* file); // Just like FilePath(), but without the directory part. -string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file); +std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file); // Gets the name of the root class we'll generate in the file. This class // is not meant for external consumption, but instead contains helpers that // the rest of the classes need -string PROTOC_EXPORT FileClassName(const FileDescriptor* file); +std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file); // These return the fully-qualified class name corresponding to the given // descriptor. -string PROTOC_EXPORT ClassName(const Descriptor* descriptor); -string PROTOC_EXPORT ClassName(const Descriptor* descriptor, - string* out_suffix_added); -string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor); +std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor); +std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor, + std::string* out_suffix_added); +std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor); // Returns the fully-qualified name of the enum value corresponding to the // the descriptor. -string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor); +std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor); // Returns the name of the enum value corresponding to the descriptor. -string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor); +std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor); // Reverse what an enum does. -string PROTOC_EXPORT UnCamelCaseEnumShortName(const string& name); +std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name); // Returns the name to use for the extension (used as the method off the file's // Root class). -string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor); +std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor); // Returns the transformed field name. -string PROTOC_EXPORT FieldName(const FieldDescriptor* field); -string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field); +std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field); +std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field); // Returns the transformed oneof name. -string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor); -string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor); -string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor); +std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor); +std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor); +std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor); // Returns a symbol that can be used in C code to refer to an Objective C // class without initializing the class. -string PROTOC_EXPORT ObjCClass(const string& class_name); +std::string PROTOC_EXPORT ObjCClass(const std::string& class_name); // Declares an Objective C class without initializing the class so that it can // be refrerred to by ObjCClass. -string PROTOC_EXPORT ObjCClassDeclaration(const string& class_name); - -inline bool HasFieldPresence(const FileDescriptor* file) { - return file->syntax() != FileDescriptor::SYNTAX_PROTO3; -} +std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name); inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) { return file->syntax() == FileDescriptor::SYNTAX_PROTO3; @@ -139,8 +133,8 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) { } // Reverse of the above. -string PROTOC_EXPORT UnCamelCaseFieldName(const string& name, - const FieldDescriptor* field); +std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name, + const FieldDescriptor* field); enum ObjectiveCType { OBJECTIVECTYPE_INT32, @@ -162,11 +156,11 @@ enum FlagType { FLAGTYPE_FIELD }; -template -string GetOptionalDeprecatedAttribute( - const TDescriptor* descriptor, - const FileDescriptor* file = NULL, - bool preSpace = true, bool postNewline = false) { +template +std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, + const FileDescriptor* file = NULL, + bool preSpace = true, + bool postNewline = false) { bool isDeprecated = descriptor->options().deprecated(); // The file is only passed when checking Messages & Enums, so those types // get tagged. At the moment, it doesn't seem to make sense to tag every @@ -177,7 +171,7 @@ string GetOptionalDeprecatedAttribute( isDeprecated = isFileLevelDeprecation; } if (isDeprecated) { - string message; + std::string message; const FileDescriptor* sourceFile = descriptor->file(); if (isFileLevelDeprecation) { message = sourceFile->name() + " is deprecated."; @@ -186,7 +180,7 @@ string GetOptionalDeprecatedAttribute( sourceFile->name() + ")."; } - string result = string("GPB_DEPRECATED_MSG(\"") + message + "\")"; + std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")"; if (preSpace) { result.insert(0, " "); } @@ -199,7 +193,7 @@ string GetOptionalDeprecatedAttribute( } } -string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field); +std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field); ObjectiveCType PROTOC_EXPORT GetObjectiveCType(FieldDescriptor::Type field_type); @@ -211,25 +205,26 @@ inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) { bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field); bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field); -string PROTOC_EXPORT GPBGenericValueFieldName(const FieldDescriptor* field); -string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field); +std::string PROTOC_EXPORT +GPBGenericValueFieldName(const FieldDescriptor* field); +std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field); bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field); -string PROTOC_EXPORT BuildFlagsString(const FlagType type, - const std::vector& strings); +std::string PROTOC_EXPORT +BuildFlagsString(const FlagType type, const std::vector& strings); // Builds HeaderDoc/appledoc style comments out of the comments in the .proto // file. -string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location, - bool prefer_single_line); +std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location, + bool prefer_single_line); // The name the commonly used by the library when built as a framework. // This lines up to the name used in the CocoaPod. extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName; // Returns the CPP symbol name to use as the gate for framework style imports // for the given framework name to use. -string PROTOC_EXPORT -ProtobufFrameworkImportSymbol(const string& framework_name); +std::string PROTOC_EXPORT +ProtobufFrameworkImportSymbol(const std::string& framework_name); // Checks if the file is one of the proto's bundled with the library. bool PROTOC_EXPORT @@ -238,9 +233,9 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); // Checks the prefix for the given files and outputs any warnings as needed. If // there are flat out errors, then out_error is filled in with the first error // and the result is false. -bool PROTOC_EXPORT -ValidateObjCClassPrefixes(const std::vector& files, - const Options& generation_options, string* out_error); +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector& files, + const Options& generation_options, std::string* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. @@ -252,16 +247,16 @@ class PROTOC_EXPORT TextFormatDecodeData { TextFormatDecodeData(const TextFormatDecodeData&) = delete; TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete; - void AddString(int32 key, const string& input_for_decode, - const string& desired_output); + void AddString(int32 key, const std::string& input_for_decode, + const std::string& desired_output); size_t num_entries() const { return entries_.size(); } - string Data() const; + std::string Data() const; - static string DecodeDataForString(const string& input_for_decode, - const string& desired_output); + static std::string DecodeDataForString(const std::string& input_for_decode, + const std::string& desired_output); private: - typedef std::pair DataEntry; + typedef std::pair DataEntry; std::vector entries_; }; @@ -270,49 +265,55 @@ class PROTOC_EXPORT LineConsumer { public: LineConsumer(); virtual ~LineConsumer(); - virtual bool ConsumeLine(const StringPiece& line, string* out_error) = 0; + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) = 0; }; -bool PROTOC_EXPORT ParseSimpleFile(const string& path, +bool PROTOC_EXPORT ParseSimpleFile(const std::string& path, LineConsumer* line_consumer, - string* out_error); + std::string* out_error); // Helper class for parsing framework import mappings and generating // import statements. class PROTOC_EXPORT ImportWriter { public: - ImportWriter(const string& generate_for_named_framework, - const string& named_framework_to_proto_path_mappings_path, + ImportWriter(const std::string& generate_for_named_framework, + const std::string& named_framework_to_proto_path_mappings_path, + const std::string& runtime_import_prefix, bool include_wkt_imports); ~ImportWriter(); - void AddFile(const FileDescriptor* file, const string& header_extension); + void AddFile(const FileDescriptor* file, const std::string& header_extension); void Print(io::Printer *printer) const; + static void PrintRuntimeImports(io::Printer *printer, + const std::vector& header_to_import, + const std::string& runtime_import_prefix, + bool default_cpp_symbol = false); + private: class ProtoFrameworkCollector : public LineConsumer { public: - ProtoFrameworkCollector(std::map* inout_proto_file_to_framework_name) + ProtoFrameworkCollector(std::map* inout_proto_file_to_framework_name) : map_(inout_proto_file_to_framework_name) {} - virtual bool ConsumeLine(const StringPiece& line, string* out_error); + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error); private: - std::map* map_; + std::map* map_; }; void ParseFrameworkMappings(); - const string generate_for_named_framework_; - const string named_framework_to_proto_path_mappings_path_; + const std::string generate_for_named_framework_; + const std::string named_framework_to_proto_path_mappings_path_; + const std::string runtime_import_prefix_; const bool include_wkt_imports_; - std::map proto_file_to_framework_name_; + std::map proto_file_to_framework_name_; bool need_to_parse_mapping_file_; - std::vector protobuf_framework_imports_; - std::vector protobuf_non_framework_imports_; - std::vector other_framework_imports_; - std::vector other_imports_; + std::vector protobuf_imports_; + std::vector other_framework_imports_; + std::vector other_imports_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc index dc1cef556f35..0aef94fe3f82 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc @@ -39,21 +39,21 @@ namespace objectivec { namespace { TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { - string input_for_decode("abcdefghIJ"); - string desired_output_for_decode; - string expected; - string result; + std::string input_for_decode("abcdefghIJ"); + std::string desired_output_for_decode; + std::string expected; + std::string result; // Different data, can't transform. desired_output_for_decode = "zbcdefghIJ"; - expected = string("\0zbcdefghIJ\0", 12); + expected = std::string("\0zbcdefghIJ\0", 12); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); desired_output_for_decode = "abcdezghIJ"; - expected = string("\0abcdezghIJ\0", 12); + expected = std::string("\0abcdezghIJ\0", 12); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -61,7 +61,7 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { // Shortened data, can't transform. desired_output_for_decode = "abcdefghI"; - expected = string("\0abcdefghI\0", 11); + expected = std::string("\0abcdefghI\0", 11); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -69,32 +69,32 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { // Extra data, can't transform. desired_output_for_decode = "abcdefghIJz"; - expected = string("\0abcdefghIJz\0", 13); + expected = std::string("\0abcdefghIJz\0", 13); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); } TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) { - string input_for_decode("abcdefghIJ"); - string desired_output_for_decode; - string expected; - string result; + std::string input_for_decode("abcdefghIJ"); + std::string desired_output_for_decode; + std::string expected; + std::string result; desired_output_for_decode = "abcdefghIJ"; - expected = string("\x0A\x0", 2); + expected = std::string("\x0A\x0", 2); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); desired_output_for_decode = "_AbcdefghIJ"; - expected = string("\xCA\x0", 2); + expected = std::string("\xCA\x0", 2); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); desired_output_for_decode = "ABCD__EfghI_j"; - expected = string("\x64\x80\xC5\xA1\x0", 5); + expected = std::string("\x64\x80\xC5\xA1\x0", 5); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -105,7 +105,7 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) { "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000"; desired_output_for_decode = "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000"; - expected = string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9); + expected = std::string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9); result = TextFormatDecodeData::DecodeDataForString(input_for_decode, desired_output_for_decode); EXPECT_EQ(expected, result); @@ -128,7 +128,7 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) { // Null char in the string. - string str_with_null_char("ab\0c", 4); + std::string str_with_null_char("ab\0c", 4); EXPECT_EXIT( TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"), ::testing::KilledBySignal(SIGABRT), @@ -160,7 +160,7 @@ TEST(ObjCHelper, TextFormatDecodeData_RawStrings) { 0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0, 0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0, }; - string expected((const char*)expected_data, sizeof(expected_data)); + std::string expected((const char*)expected_data, sizeof(expected_data)); EXPECT_EQ(expected, decode_data.Data()); } @@ -196,7 +196,7 @@ TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) { // underscore, as is + 3 (00 op) 0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0, }; - string expected((const char*)expected_data, sizeof(expected_data)); + std::string expected((const char*)expected_data, sizeof(expected_data)); EXPECT_EQ(expected, decode_data.Data()); } @@ -221,7 +221,7 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) { // Null char in the string. - string str_with_null_char("ab\0c", 4); + std::string str_with_null_char("ab\0c", 4); EXPECT_EXIT( decode_data.AddString(1, str_with_null_char, "def"), ::testing::KilledBySignal(SIGABRT), diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index 3b8eaa040de8..746224ff86b2 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -85,9 +85,9 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options) : RepeatedFieldGenerator(descriptor, options) { const FieldDescriptor* key_descriptor = - descriptor->message_type()->FindFieldByName("key"); + descriptor->message_type()->map_key(); const FieldDescriptor* value_descriptor = - descriptor->message_type()->FindFieldByName("value"); + descriptor->message_type()->map_value(); value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options)); // Pull over some variables_ from the value. @@ -96,20 +96,21 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, variables_["default_name"] = value_field_generator_->variable("default_name"); // Build custom field flags. - std::vector field_flags; + std::vector field_flags; field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor)); // Pull over the current text format custom name values that was calculated. if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") != - string::npos) { + std::string::npos) { field_flags.push_back("GPBFieldTextFormatNameCustom"); } // Pull over some info from the value's flags. - const string& value_field_flags = + const std::string& value_field_flags = value_field_generator_->variable("fieldflags"); - if (value_field_flags.find("GPBFieldHasDefaultValue") != string::npos) { + if (value_field_flags.find("GPBFieldHasDefaultValue") != std::string::npos) { field_flags.push_back("GPBFieldHasDefaultValue"); } - if (value_field_flags.find("GPBFieldHasEnumDescriptor") != string::npos) { + if (value_field_flags.find("GPBFieldHasEnumDescriptor") != + std::string::npos) { field_flags.push_back("GPBFieldHasEnumDescriptor"); } @@ -127,7 +128,7 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, "NSMutableDictionaryvariable("storage_type") + "*>"; } else { - string class_name("GPB"); + std::string class_name("GPB"); class_name += MapEntryTypeName(key_descriptor, true); class_name += MapEntryTypeName(value_descriptor, false); class_name += "Dictionary"; @@ -160,19 +161,19 @@ void MapFieldGenerator::FinishInitialization(void) { } void MapFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); const FieldDescriptor* value_descriptor = descriptor_->message_type()->FindFieldByName("value"); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { - const string& value_storage_type = + const std::string& value_storage_type = value_field_generator_->variable("storage_type"); fwd_decls->insert("@class " + value_storage_type); } } void MapFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { // Class name is already in "storage_type". const FieldDescriptor* value_descriptor = descriptor_->message_type()->FindFieldByName("value"); @@ -182,7 +183,6 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions( } } - } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index da18d579f556..55fd56c125d2 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -54,8 +54,10 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); virtual ~MapFieldGenerator(); - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; private: std::unique_ptr value_field_generator_; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc index b5d8128a999c..917cc64861e8 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -170,22 +170,21 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { } } // namespace -MessageGenerator::MessageGenerator(const string& root_classname, +MessageGenerator::MessageGenerator(const std::string& root_classname, const Descriptor* descriptor, const Options& options) : root_classname_(root_classname), descriptor_(descriptor), field_generators_(descriptor, options), class_name_(ClassName(descriptor_)), - deprecated_attribute_( - GetOptionalDeprecatedAttribute(descriptor, descriptor->file(), false, true)) { - + deprecated_attribute_(GetOptionalDeprecatedAttribute( + descriptor, descriptor->file(), false, true)) { for (int i = 0; i < descriptor_->extension_count(); i++) { extension_generators_.emplace_back( new ExtensionGenerator(class_name_, descriptor_->extension(i))); } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i)); oneof_generators_.emplace_back(generator); } @@ -217,7 +216,8 @@ void MessageGenerator::GenerateStaticVariablesInitialization( } } -void MessageGenerator::DetermineForwardDeclarations(std::set* fwd_decls) { +void MessageGenerator::DetermineForwardDeclarations( + std::set* fwd_decls) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); @@ -231,7 +231,8 @@ void MessageGenerator::DetermineForwardDeclarations(std::set* fwd_decls) } } -void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set* fwd_decls) { +void MessageGenerator::DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); @@ -250,7 +251,7 @@ void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set* fwd const Descriptor* containing_descriptor = descriptor_->containing_type(); if (containing_descriptor != NULL) { - string containing_class = ClassName(containing_descriptor); + std::string containing_class = ClassName(containing_descriptor); fwd_decls->insert(ObjCClassDeclaration(containing_class)); } } @@ -325,7 +326,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { generator->GenerateCaseEnum(printer); } - string message_comments; + std::string message_comments; SourceLocation location; if (descriptor_->GetSourceLocation(&location)) { message_comments = BuildCommentsString(location, false); @@ -339,11 +340,12 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { "deprecated_attribute", deprecated_attribute_, "comments", message_comments); - std::vector seen_oneofs(descriptor_->oneof_decl_count(), 0); + std::vector seen_oneofs(oneof_generators_.size(), 0); for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->containing_oneof() != NULL) { - const int oneof_index = field->containing_oneof()->index(); + const OneofDescriptor *oneof = field->real_containing_oneof(); + if (oneof) { + const int oneof_index = oneof->index(); if (!seen_oneofs[oneof_index]) { seen_oneofs[oneof_index] = 1; oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration( @@ -443,7 +445,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { field_generators_.SetOneofIndexBase(sizeof_has_storage); // sizeof_has_storage needs enough bits for the single fields that aren't in // any oneof, and then one int32 for each oneof (to store the field number). - sizeof_has_storage += descriptor_->oneof_decl_count(); + sizeof_has_storage += oneof_generators_.size(); printer->Print( "\n" @@ -472,7 +474,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { TextFormatDecodeData text_format_decode_data; bool has_fields = descriptor_->field_count() > 0; bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault(); - string field_description_type; + std::string field_description_type; if (need_defaults) { field_description_type = "GPBMessageFieldDescriptionWithDefault"; } else { @@ -502,7 +504,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { printer->Outdent(); } - std::map vars; + std::map vars; vars["classname"] = class_name_; vars["rootclassname"] = root_classname_; vars["fields"] = has_fields ? "fields" : "NULL"; @@ -513,8 +515,9 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { vars["fields_count"] = "0"; } - std::vector init_flags; + std::vector init_flags; init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs"); + init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown"); if (need_defaults) { init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault"); } @@ -549,7 +552,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { "first_has_index", oneof_generators_[0]->HasIndexAsString()); } if (text_format_decode_data.num_entries() != 0) { - const string text_format_data_str(text_format_decode_data.Data()); + const std::string text_format_data_str(text_format_decode_data.Data()); printer->Print( "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n" " static const char *extraTextFormatInfo ="); @@ -579,13 +582,13 @@ void MessageGenerator::GenerateSource(io::Printer* printer) { " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n"); } if (descriptor_->containing_type() != NULL) { - string containing_class = ClassName(descriptor_->containing_type()); - string parent_class_ref = ObjCClass(containing_class); + std::string containing_class = ClassName(descriptor_->containing_type()); + std::string parent_class_ref = ObjCClass(containing_class); printer->Print( " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n", "parent_class_ref", parent_class_ref); } - string suffix_added; + std::string suffix_added; ClassName(descriptor_, &suffix_added); if (!suffix_added.empty()) { printer->Print( diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h index 138e62020638..01108d29e75a 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -50,9 +50,8 @@ class EnumGenerator; class MessageGenerator { public: - MessageGenerator(const string& root_classname, - const Descriptor* descriptor, - const Options& options); + MessageGenerator(const std::string& root_classname, + const Descriptor* descriptor, const Options& options); ~MessageGenerator(); MessageGenerator(const MessageGenerator&) = delete; @@ -63,8 +62,8 @@ class MessageGenerator { void GenerateMessageHeader(io::Printer* printer); void GenerateSource(io::Printer* printer); void GenerateExtensionRegistrationSource(io::Printer* printer); - void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); - void DetermineForwardDeclarations(std::set* fwd_decls); + void DetermineObjectiveCClassDefinitions(std::set* fwd_decls); + void DetermineForwardDeclarations(std::set* fwd_decls); // Checks if the message or a nested message includes a oneof definition. bool IncludesOneOfDefinition() const; @@ -81,11 +80,11 @@ class MessageGenerator { void GenerateDescriptionOneFieldSource(io::Printer* printer, const FieldDescriptor* field); - const string root_classname_; + const std::string root_classname_; const Descriptor* descriptor_; FieldGeneratorMap field_generators_; - const string class_name_; - const string deprecated_attribute_; + const std::string class_name_; + const std::string deprecated_attribute_; std::vector> extension_generators_; std::vector> enum_generators_; std::vector> nested_message_generators_; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index 2730e7591d9e..299a20b152ee 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -44,9 +44,10 @@ namespace objectivec { namespace { void SetMessageVariables(const FieldDescriptor* descriptor, - std::map* variables) { - const string& message_type = ClassName(descriptor->message_type()); - const string& containing_class = ClassName(descriptor->containing_type()); + std::map* variables) { + const std::string& message_type = ClassName(descriptor->message_type()); + const std::string& containing_class = + ClassName(descriptor->containing_type()); (*variables)["type"] = message_type; (*variables)["containing_class"] = containing_class; (*variables)["storage_type"] = message_type; @@ -66,27 +67,17 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls); // Class name is already in "storage_type". fwd_decls->insert("@class " + variable("storage_type")); } void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); } -bool MessageFieldGenerator::WantsHasProperty(void) const { - if (descriptor_->containing_oneof() != NULL) { - // If in a oneof, it uses the oneofcase instead of a has bit. - return false; - } - // In both proto2 & proto3, message fields have a has* property to tell - // when it is a non default value. - return true; -} - RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( const FieldDescriptor* descriptor, const Options& options) : RepeatedFieldGenerator(descriptor, options) { @@ -99,14 +90,14 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( - std::set* fwd_decls) const { + std::set* fwd_decls) const { RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); // Class name is already in "storage_type". fwd_decls->insert("@class " + variable("storage_type")); } void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set* fwd_decls) const { + std::set* fwd_decls) const { fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index 692f94c02614..01dd6ed21f0c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -52,11 +52,12 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; virtual ~MessageFieldGenerator(); - virtual bool WantsHasProperty(void) const; public: - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; }; class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { @@ -72,8 +73,10 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete; public: - virtual void DetermineForwardDeclarations(std::set* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions(std::set* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set* fwd_decls) const; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc index 5b37c4e945c7..1bef293e2885 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc @@ -50,7 +50,7 @@ OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor) const Descriptor* msg_descriptor = descriptor_->containing_type(); variables_["owning_message_class"] = ClassName(msg_descriptor); - string comments; + std::string comments; SourceLocation location; if (descriptor_->GetSourceLocation(&location)) { comments = BuildCommentsString(location, true); @@ -76,10 +76,10 @@ void OneofGenerator::GenerateCaseEnum(io::Printer* printer) { printer->Print( variables_, "$enum_name$_GPBUnsetOneOfCase = 0,\n"); - string enum_name = variables_["enum_name"]; + std::string enum_name = variables_["enum_name"]; for (int j = 0; j < descriptor_->field_count(); j++) { const FieldDescriptor* field = descriptor_->field(j); - string field_name = FieldNameCapitalized(field); + std::string field_name = FieldNameCapitalized(field); printer->Print( "$enum_name$_$field_name$ = $field_number$,\n", "enum_name", enum_name, @@ -120,17 +120,17 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) { printer->Print( variables_, "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n" - " GPBDescriptor *descriptor = [message descriptor];\n" + " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n" - " GPBMaybeClearOneof(message, oneof, $index$, 0);\n" + " GPBClearOneof(message, oneof);\n" "}\n"); } -string OneofGenerator::DescriptorName(void) const { +std::string OneofGenerator::DescriptorName(void) const { return variables_.find("name")->second; } -string OneofGenerator::HasIndexAsString(void) const { +std::string OneofGenerator::HasIndexAsString(void) const { return variables_.find("index")->second; } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h index 852ef02241cb..034f07fb3306 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h @@ -60,12 +60,12 @@ class OneofGenerator { void GeneratePropertyImplementation(io::Printer* printer); void GenerateClearFunctionImplementation(io::Printer* printer); - string DescriptorName(void) const; - string HasIndexAsString(void) const; + std::string DescriptorName(void) const; + std::string HasIndexAsString(void) const; private: const OneofDescriptor* descriptor_; - std::map variables_; + std::map variables_; }; } // namespace objectivec diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index 0511b37dd7eb..e198c5c182ca 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -116,7 +116,7 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) { } void SetPrimitiveVariables(const FieldDescriptor* descriptor, - std::map* variables) { + std::map* variables) { std::string primitive_name = PrimitiveTypeName(descriptor); (*variables)["type"] = primitive_name; (*variables)["storage_type"] = primitive_name; @@ -172,7 +172,7 @@ RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( : RepeatedFieldGenerator(descriptor, options) { SetPrimitiveVariables(descriptor, &variables_); - string base_name = PrimitiveArrayTypeName(descriptor); + std::string base_name = PrimitiveArrayTypeName(descriptor); if (base_name.length()) { variables_["array_storage_type"] = "GPB" + base_name + "Array"; } else { diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 41e2eb699f88..d92cd558735d 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -34,22 +34,24 @@ // // Recursive descent FTW. +#include + #include + #include #include - -#include +#include #include #include #include -#include #include #include #include #include #include #include +#include namespace google { namespace protobuf { @@ -765,6 +767,43 @@ bool Parser::ParseMessageDefinition( } } DO(ParseMessageBlock(message, message_location, containing_file)); + + if (syntax_identifier_ == "proto3") { + // Add synthetic one-field oneofs for optional fields, except messages which + // already have presence in proto3. + // + // We have to make sure the oneof names don't conflict with any other + // field or oneof. + std::unordered_set names; + for (const auto& field : message->field()) { + names.insert(field.name()); + } + for (const auto& oneof : message->oneof_decl()) { + names.insert(oneof.name()); + } + + for (auto& field : *message->mutable_field()) { + if (field.proto3_optional()) { + std::string oneof_name = field.name(); + + // Prepend 'XXXXX_' until we are no longer conflicting. + // Avoid prepending a double-underscore because such names are + // reserved in C++. + if (oneof_name.empty() || oneof_name[0] != '_') { + oneof_name = '_' + oneof_name; + } + while (names.count(oneof_name) > 0) { + oneof_name = 'X' + oneof_name; + } + + names.insert(oneof_name); + field.set_oneof_index(message->oneof_decl_size()); + OneofDescriptorProto* oneof = message->add_oneof_decl(); + oneof->set_name(oneof_name); + } + } + } + return true; } @@ -907,10 +946,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, field->set_label(label); if (label == FieldDescriptorProto::LABEL_OPTIONAL && syntax_identifier_ == "proto3") { - AddError( - "Explicit 'optional' labels are disallowed in the Proto3 syntax. " - "To define 'optional' fields in Proto3, simply remove the " - "'optional' label, as fields are 'optional' by default."); + field->set_proto3_optional(true); } } } diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 8994cc5a5e27..cbb24a50a58c 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -68,8 +69,7 @@ class MockErrorCollector : public io::ErrorCollector { // implements ErrorCollector --------------------------------------- void AddWarning(int line, int column, const std::string& message) override { - strings::SubstituteAndAppend(&warning_, "$0:$1: $2\n", line, column, - message); + strings::SubstituteAndAppend(&warning_, "$0:$1: $2\n", line, column, message); } void AddError(int line, int column, const std::string& message) override { @@ -1009,6 +1009,43 @@ TEST_F(ParseMessageTest, OptionalLabelProto3) { "}"); } +TEST_F(ParseMessageTest, ExplicitOptionalLabelProto3) { + ExpectParsesTo( + "syntax = 'proto3';\n" + "message TestMessage {\n" + " optional int32 foo = 1;\n" + "}\n", + + "syntax: \"proto3\" " + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 " + " proto3_optional: true oneof_index: 0 } " + " oneof_decl { name:\"_foo\" } " + "}"); + + // Handle collisions in the synthetic oneof name. + ExpectParsesTo( + "syntax = 'proto3';\n" + "message TestMessage {\n" + " optional int32 foo = 1;\n" + " oneof _foo {\n" + " int32 __foo = 2;\n" + " }\n" + "}\n", + + "syntax: \"proto3\" " + "message_type {" + " name: \"TestMessage\"" + " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 " + " proto3_optional: true oneof_index: 1 } " + " field { name:\"__foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:2 " + " oneof_index: 0 } " + " oneof_decl { name:\"_foo\" } " + " oneof_decl { name:\"X_foo\" } " + "}"); +} + // =================================================================== typedef ParserTest ParseEnumTest; @@ -1575,17 +1612,6 @@ TEST_F(ParseErrorTest, EofInAggregateValue) { "1:0: Unexpected end of stream while parsing aggregate value.\n"); } -TEST_F(ParseErrorTest, ExplicitOptionalLabelProto3) { - ExpectHasErrors( - "syntax = 'proto3';\n" - "message TestMessage {\n" - " optional int32 foo = 1;\n" - "}\n", - "2:11: Explicit 'optional' labels are disallowed in the Proto3 syntax. " - "To define 'optional' fields in Proto3, simply remove the 'optional' " - "label, as fields are 'optional' by default.\n"); -} - // ------------------------------------------------------------------- // Enum errors @@ -2251,6 +2277,11 @@ TEST_F(ParseDescriptorDebugTest, TestCustomOptions) { FileDescriptorProto import_proto; import->CopyTo(&import_proto); ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL); + + FileDescriptorProto any_import; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_import); + ASSERT_TRUE(pool_.BuildFile(any_import) != nullptr); + const FileDescriptor* actual = pool_.BuildFile(parsed); ASSERT_TRUE(actual != NULL); parsed.Clear(); diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index a90484ef6daa..d5cdee31d555 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -78,32 +78,41 @@ namespace protobuf { namespace compiler { namespace php { +struct Options { + bool is_descriptor = false; + bool aggregate_metadata = false; + bool gen_c_wkt = false; + std::set aggregate_metadata_prefixes; +}; + +namespace { + // Forward decls. -std::string PhpName(const std::string& full_name, bool is_descriptor); -std::string DefaultForField(FieldDescriptor* field); +std::string PhpName(const std::string& full_name, const Options& options); std::string IntToString(int32 value); -std::string FilenameToClassname(const string& filename); +std::string FilenameToClassname(const std::string& filename); std::string GeneratedMetadataFileName(const FileDescriptor* file, - bool is_descriptor); -std::string LabelForField(FieldDescriptor* field); -std::string TypeName(FieldDescriptor* field); -std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter); -std::string BinaryToHex(const string& binary); + const Options& options); +std::string UnderscoresToCamelCase(const std::string& name, + bool cap_first_letter); +std::string BinaryToHex(const std::string& binary); void Indent(io::Printer* printer); void Outdent(io::Printer* printer); +void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, + io::Printer* printer); void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, - int is_descriptor); + const Options& options); void GenerateMessageConstructorDocComment(io::Printer* printer, const Descriptor* message, - int is_descriptor); + const Options& options); void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, - int is_descriptor, int function_type); + const Options& options, int function_type); void GenerateWrapperFieldGetterDocComment(io::Printer* printer, const FieldDescriptor* field); void GenerateWrapperFieldSetterDocComment(io::Printer* printer, const FieldDescriptor* field); void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, - int is_descriptor); + const Options& options); void GenerateEnumValueDocComment(io::Printer* printer, const EnumValueDescriptor* value); void GenerateServiceDocComment(io::Printer* printer, @@ -111,13 +120,12 @@ void GenerateServiceDocComment(io::Printer* printer, void GenerateServiceMethodDocComment(io::Printer* printer, const MethodDescriptor* method); - -std::string ReservedNamePrefix(const string& classname, +std::string ReservedNamePrefix(const std::string& classname, const FileDescriptor* file) { bool is_reserved = false; - string lower = classname; - transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + std::string lower = classname; + std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (int i = 0; i < kReservedNamesSize; i++) { if (lower == kReservedNames[i]) { @@ -138,8 +146,8 @@ std::string ReservedNamePrefix(const string& classname, } template -std::string DescriptorFullName(const DescriptorType* desc, bool is_descriptor) { - if (is_descriptor) { +std::string DescriptorFullName(const DescriptorType* desc, bool is_internal) { + if (is_internal) { return StringReplace(desc->full_name(), "google.protobuf", "google.protobuf.internal", false); @@ -149,9 +157,9 @@ std::string DescriptorFullName(const DescriptorType* desc, bool is_descriptor) { } template -std::string ClassNamePrefix(const string& classname, +std::string ClassNamePrefix(const std::string& classname, const DescriptorType* desc) { - const string& prefix = (desc->file()->options()).php_class_prefix(); + const std::string& prefix = (desc->file()->options()).php_class_prefix(); if (!prefix.empty()) { return prefix; } @@ -176,18 +184,6 @@ std::string GeneratedClassNameImpl(const ServiceDescriptor* desc) { return ClassNamePrefix(classname, desc) + classname; } -std::string GeneratedClassName(const Descriptor* desc) { - return GeneratedClassNameImpl(desc); -} - -std::string GeneratedClassName(const EnumDescriptor* desc) { - return GeneratedClassNameImpl(desc); -} - -std::string GeneratedClassName(const ServiceDescriptor* desc) { - return GeneratedClassNameImpl(desc); -} - template std::string LegacyGeneratedClassName(const DescriptorType* desc) { std::string classname = desc->name(); @@ -199,9 +195,9 @@ std::string LegacyGeneratedClassName(const DescriptorType* desc) { return ClassNamePrefix(classname, desc) + classname; } -std::string ClassNamePrefix(const string& classname) { - string lower = classname; - transform(lower.begin(), lower.end(), lower.begin(), ::tolower); +std::string ClassNamePrefix(const std::string& classname) { + std::string lower = classname; + std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (int i = 0; i < kReservedNamesSize; i++) { if (lower == kReservedNames[i]) { @@ -212,11 +208,11 @@ std::string ClassNamePrefix(const string& classname) { return ""; } -std::string ConstantNamePrefix(const string& classname) { +std::string ConstantNamePrefix(const std::string& classname) { bool is_reserved = false; - string lower = classname; - transform(lower.begin(), lower.end(), lower.begin(), ::tolower); + std::string lower = classname; + std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); for (int i = 0; i < kReservedNamesSize; i++) { if (lower == kReservedNames[i]) { @@ -240,9 +236,10 @@ std::string ConstantNamePrefix(const string& classname) { } template -std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { +std::string RootPhpNamespace(const DescriptorType* desc, + const Options& options) { if (desc->file()->options().has_php_namespace()) { - const string& php_namespace = desc->file()->options().php_namespace(); + const std::string& php_namespace = desc->file()->options().php_namespace(); if (!php_namespace.empty()) { return php_namespace; } @@ -250,15 +247,15 @@ std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) { } if (!desc->file()->package().empty()) { - return PhpName(desc->file()->package(), is_descriptor); + return PhpName(desc->file()->package(), options); } return ""; } template -std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { - string classname = GeneratedClassNameImpl(desc); - string php_namespace = RootPhpNamespace(desc, is_descriptor); +std::string FullClassName(const DescriptorType* desc, const Options& options) { + std::string classname = GeneratedClassNameImpl(desc); + std::string php_namespace = RootPhpNamespace(desc, options); if (!php_namespace.empty()) { return php_namespace + "\\" + classname; } @@ -266,17 +263,25 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { } template -std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) { - string classname = LegacyGeneratedClassName(desc); - string php_namespace = RootPhpNamespace(desc, is_descriptor); +std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return FullClassName(desc, options); +} + +template +std::string LegacyFullClassName(const DescriptorType* desc, + const Options& options) { + std::string classname = LegacyGeneratedClassName(desc); + std::string php_namespace = RootPhpNamespace(desc, options); if (!php_namespace.empty()) { return php_namespace + "\\" + classname; } return classname; } -std::string PhpName(const std::string& full_name, bool is_descriptor) { - if (is_descriptor) { +std::string PhpName(const std::string& full_name, const Options& options) { + if (options.is_descriptor) { return kDescriptorPackageName; } @@ -325,8 +330,8 @@ std::string DefaultForField(const FieldDescriptor* field) { } std::string GeneratedMetadataFileName(const FileDescriptor* file, - bool is_descriptor) { - const string& proto_file = file->name(); + const Options& options) { + const std::string& proto_file = file->name(); int start_index = 0; int first_index = proto_file.find_first_of("/", start_index); std::string result = ""; @@ -335,7 +340,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, if (proto_file == kEmptyFile) { return kEmptyMetadataFile; } - if (is_descriptor) { + if (options.is_descriptor) { return kDescriptorMetadataFile; } @@ -349,7 +354,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, } if (file->options().has_php_metadata_namespace()) { - const string& php_metadata_namespace = + const std::string& php_metadata_namespace = file->options().php_metadata_namespace(); if (!php_metadata_namespace.empty() && php_metadata_namespace != "\\") { result += php_metadata_namespace; @@ -360,7 +365,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, } } else { result += "GPBMetadata/"; - while (first_index != string::npos) { + while (first_index != std::string::npos) { segment = UnderscoresToCamelCase( file_no_suffix.substr(start_index, first_index - start_index), true); result += ReservedNamePrefix(segment, file) + segment + "/"; @@ -371,7 +376,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, // Append file name. int file_name_start = file_no_suffix.find_last_of("/"); - if (file_name_start == string::npos) { + if (file_name_start == std::string::npos) { file_name_start = 0; } else { file_name_start += 1; @@ -382,10 +387,17 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file, return result + ReservedNamePrefix(segment, file) + segment + ".php"; } +std::string GeneratedMetadataFileName(const FileDescriptor* file, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return GeneratedMetadataFileName(file, options); +} + template std::string GeneratedClassFileName(const DescriptorType* desc, - bool is_descriptor) { - std::string result = FullClassName(desc, is_descriptor); + const Options& options) { + std::string result = FullClassName(desc, options); for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -396,8 +408,8 @@ std::string GeneratedClassFileName(const DescriptorType* desc, template std::string LegacyGeneratedClassFileName(const DescriptorType* desc, - bool is_descriptor) { - std::string result = LegacyFullClassName(desc, is_descriptor); + const Options& options) { + std::string result = LegacyFullClassName(desc, options); for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { @@ -408,8 +420,8 @@ std::string LegacyGeneratedClassFileName(const DescriptorType* desc, } std::string GeneratedServiceFileName(const ServiceDescriptor* service, - bool is_descriptor) { - std::string result = FullClassName(service, is_descriptor) + "Interface"; + const Options& options) { + std::string result = FullClassName(service, options) + "Interface"; for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -433,35 +445,12 @@ std::string LabelForField(const FieldDescriptor* field) { } } -std::string TypeName(const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_INT32: return "int32"; - case FieldDescriptor::TYPE_INT64: return "int64"; - case FieldDescriptor::TYPE_UINT32: return "uint32"; - case FieldDescriptor::TYPE_UINT64: return "uint64"; - case FieldDescriptor::TYPE_SINT32: return "sint32"; - case FieldDescriptor::TYPE_SINT64: return "sint64"; - case FieldDescriptor::TYPE_FIXED32: return "fixed32"; - case FieldDescriptor::TYPE_FIXED64: return "fixed64"; - case FieldDescriptor::TYPE_SFIXED32: return "sfixed32"; - case FieldDescriptor::TYPE_SFIXED64: return "sfixed64"; - case FieldDescriptor::TYPE_DOUBLE: return "double"; - case FieldDescriptor::TYPE_FLOAT: return "float"; - case FieldDescriptor::TYPE_BOOL: return "bool"; - case FieldDescriptor::TYPE_ENUM: return "enum"; - case FieldDescriptor::TYPE_STRING: return "string"; - case FieldDescriptor::TYPE_BYTES: return "bytes"; - case FieldDescriptor::TYPE_MESSAGE: return "message"; - case FieldDescriptor::TYPE_GROUP: return "group"; - default: assert(false); return ""; - } -} - -std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) { +std::string PhpSetterTypeName(const FieldDescriptor* field, + const Options& options) { if (field->is_map()) { return "array|\\Google\\Protobuf\\Internal\\MapField"; } - string type; + std::string type; switch (field->type()) { case FieldDescriptor::TYPE_INT32: case FieldDescriptor::TYPE_UINT32: @@ -490,7 +479,7 @@ std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) type = "string"; break; case FieldDescriptor::TYPE_MESSAGE: - type = "\\" + FullClassName(field->message_type(), is_descriptor); + type = "\\" + FullClassName(field->message_type(), options); break; case FieldDescriptor::TYPE_GROUP: return "null"; @@ -507,7 +496,15 @@ std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor) return type; } -std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor) { +std::string PhpSetterTypeName(const FieldDescriptor* field, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return PhpSetterTypeName(field, options); +} + +std::string PhpGetterTypeName(const FieldDescriptor* field, + const Options& options) { if (field->is_map()) { return "\\Google\\Protobuf\\Internal\\MapField"; } @@ -532,26 +529,44 @@ std::string PhpGetterTypeName(const FieldDescriptor* field, bool is_descriptor) case FieldDescriptor::TYPE_STRING: case FieldDescriptor::TYPE_BYTES: return "string"; case FieldDescriptor::TYPE_MESSAGE: - return "\\" + FullClassName(field->message_type(), is_descriptor); + return "\\" + FullClassName(field->message_type(), options); case FieldDescriptor::TYPE_GROUP: return "null"; default: assert(false); return ""; } } -std::string EnumOrMessageSuffix( - const FieldDescriptor* field, bool is_descriptor) { +std::string PhpGetterTypeName(const FieldDescriptor* field, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return PhpGetterTypeName(field, options); +} + +std::string EnumOrMessageSuffix(const FieldDescriptor* field, + const Options& options) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - return ", '" + DescriptorFullName(field->message_type(), is_descriptor) + "'"; + return ", '" + + DescriptorFullName(field->message_type(), options.is_descriptor) + + "'"; } if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - return ", '" + DescriptorFullName(field->enum_type(), is_descriptor) + "'"; + return ", '" + + DescriptorFullName(field->enum_type(), options.is_descriptor) + "'"; } return ""; } +std::string EnumOrMessageSuffix(const FieldDescriptor* field, + bool is_descriptor) { + Options options; + options.is_descriptor = is_descriptor; + return EnumOrMessageSuffix(field, options); +} + // Converts a name to camel-case. If cap_first_letter is true, capitalize the // first letter. -std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter) { +std::string UnderscoresToCamelCase(const std::string& name, + bool cap_first_letter) { std::string result; for (int i = 0; i < name.size(); i++) { if ('a' <= name[i] && name[i] <= 'z') { @@ -585,8 +600,8 @@ std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter) { return result; } -std::string BinaryToHex(const string& binary) { - string dest; +std::string BinaryToHex(const std::string& binary) { + std::string dest; size_t i; unsigned char symbol[16] = { '0', '1', '2', '3', @@ -616,27 +631,23 @@ void Outdent(io::Printer* printer) { } void GenerateField(const FieldDescriptor* field, io::Printer* printer, - bool is_descriptor) { + const Options& options) { if (field->is_repeated()) { - GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty); + GenerateFieldDocComment(printer, field, options, kFieldProperty); printer->Print( "private $^name^;\n", "name", field->name()); - } else if (field->containing_oneof()) { + } else if (field->real_containing_oneof()) { // Oneof fields are handled by GenerateOneofField. return; } else { - GenerateFieldDocComment(printer, field, is_descriptor, kFieldProperty); + std::string initial_value = + field->has_presence() ? "null" : DefaultForField(field); + GenerateFieldDocComment(printer, field, options, kFieldProperty); printer->Print( - "protected $^name^ = ^default^;\n", + "protected $^name^ = ^initial_value^;\n", "name", field->name(), - "default", DefaultForField(field)); - } - - if (is_descriptor) { - printer->Print( - "private $has_^name^ = false;\n", - "name", field->name()); + "initial_value", initial_value); } } @@ -648,22 +659,43 @@ void GenerateOneofField(const OneofDescriptor* oneof, io::Printer* printer) { "name", oneof->name()); } -void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, +void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options, io::Printer* printer) { - const OneofDescriptor* oneof = field->containing_oneof(); + const OneofDescriptor* oneof = field->real_containing_oneof(); // Generate getter. + GenerateFieldDocComment(printer, field, options, kFieldGetter); + if (oneof != NULL) { - GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); printer->Print( "public function get^camel_name^()\n" "{\n" " return $this->readOneof(^number^);\n" + "}\n\n" + "public function has^camel_name^()\n" + "{\n" + " return $this->hasOneof(^number^);\n" "}\n\n", "camel_name", UnderscoresToCamelCase(field->name(), true), "number", IntToString(field->number())); + } else if (field->has_presence()) { + printer->Print( + "public function get^camel_name^()\n" + "{\n" + " return isset($this->^name^) ? $this->^name^ : ^default_value^;\n" + "}\n\n" + "public function has^camel_name^()\n" + "{\n" + " return isset($this->^name^);\n" + "}\n\n" + "public function clear^camel_name^()\n" + "{\n" + " unset($this->^name^);\n" + "}\n\n", + "camel_name", UnderscoresToCamelCase(field->name(), true), + "name", field->name(), + "default_value", DefaultForField(field)); } else { - GenerateFieldDocComment(printer, field, is_descriptor, kFieldGetter); printer->Print( "public function get^camel_name^()\n" "{\n" @@ -689,7 +721,7 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, } // Generate setter. - GenerateFieldDocComment(printer, field, is_descriptor, kFieldSetter); + GenerateFieldDocComment(printer, field, options, kFieldSetter); printer->Print( "public function set^camel_name^($var)\n" "{\n", @@ -712,12 +744,12 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(value->message_type(), is_descriptor) + "::class"); + FullClassName(value->message_type(), options) + "::class"); } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(value->enum_type(), is_descriptor) + "::class"); + FullClassName(value->enum_type(), options) + "::class"); } else { printer->Print(");\n"); } @@ -730,23 +762,23 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(field->message_type(), is_descriptor) + "::class"); + FullClassName(field->message_type(), options) + "::class"); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( ", \\^class_name^);\n", "class_name", - FullClassName(field->enum_type(), is_descriptor) + "::class"); + FullClassName(field->enum_type(), options) + "::class"); } else { printer->Print(");\n"); } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { printer->Print( "GPBUtil::checkMessage($var, \\^class_name^::class);\n", - "class_name", LegacyFullClassName(field->message_type(), is_descriptor)); + "class_name", FullClassName(field->message_type(), options)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( "GPBUtil::checkEnum($var, \\^class_name^::class);\n", - "class_name", LegacyFullClassName(field->enum_type(), is_descriptor)); + "class_name", FullClassName(field->enum_type(), options)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { printer->Print( "GPBUtil::checkString($var, ^utf8^);\n", @@ -772,13 +804,6 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, "name", field->name()); } - // Set has bit for proto2 only. - if (is_descriptor) { - printer->Print( - "$this->has_^field_name^ = true;\n", - "field_name", field->name()); - } - printer->Print("\nreturn $this;\n"); Outdent(printer); @@ -801,17 +826,6 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, "camel_name", UnderscoresToCamelCase(field->name(), true), "field_name", field->name()); } - - // Generate has method for proto2 only. - if (is_descriptor) { - printer->Print( - "public function has^camel_name^()\n" - "{\n" - " return $this->has_^field_name^;\n" - "}\n\n", - "camel_name", UnderscoresToCamelCase(field->name(), true), - "field_name", field->name()); - } } void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) { @@ -843,15 +857,16 @@ void GenerateServiceMethod(const MethodDescriptor* method, ); } -void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, - io::Printer* printer) { +void GenerateMessageToPool(const std::string& name_prefix, + const Descriptor* message, io::Printer* printer) { // Don't generate MapEntry messages -- we use the PHP extension's native // support for map fields instead. if (message->options().map_entry()) { return; } - string class_name = (name_prefix.empty() ? "" : name_prefix + "\\") + - ReservedNamePrefix(message->name(), message->file()) + message->name(); + std::string class_name = + (name_prefix.empty() ? "" : name_prefix + "\\") + + ReservedNamePrefix(message->name(), message->file()) + message->name(); printer->Print( "$pool->addMessage('^message^', " @@ -876,7 +891,7 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, "value", ToUpper(val->type_name()), "number", StrCat(field->number()), "other", EnumOrMessageSuffix(val, true)); - } else if (!field->containing_oneof()) { + } else if (!field->real_containing_oneof()) { printer->Print( "->^label^('^field^', " "\\Google\\Protobuf\\Internal\\GPBType::^type^, ^number^^other^)\n", @@ -889,7 +904,7 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, } // oneofs. - for (int i = 0; i < message->oneof_decl_count(); i++) { + for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); printer->Print("->oneof(^name^)\n", "name", oneof->name()); @@ -924,13 +939,16 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message, } } -void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor, +void GenerateAddFileToPool(const FileDescriptor* file, const Options& options, io::Printer* printer) { - printer->Print( - "public static $is_initialized = false;\n\n" - "public static function initOnce() {\n"); - Indent(printer); + printer->Print( + "public static $is_initialized = false;\n\n" + "public static function initOnce() {\n"); + Indent(printer); + if (options.aggregate_metadata) { + GenerateAddFilesToPool(file, options, printer); + } else { printer->Print( "$pool = \\Google\\Protobuf\\Internal\\" "DescriptorPool::getGeneratedPool();\n\n" @@ -938,83 +956,236 @@ void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor, " return;\n" "}\n"); - if (is_descriptor) { - for (int i = 0; i < file->message_type_count(); i++) { - GenerateMessageToPool("", file->message_type(i), printer); - } - for (int i = 0; i < file->enum_type_count(); i++) { - GenerateEnumToPool(file->enum_type(i), printer); - } + if (options.is_descriptor) { + for (int i = 0; i < file->message_type_count(); i++) { + GenerateMessageToPool("", file->message_type(i), printer); + } + for (int i = 0; i < file->enum_type_count(); i++) { + GenerateEnumToPool(file->enum_type(i), printer); + } + + printer->Print( + "$pool->finish();\n"); + } else { + for (int i = 0; i < file->dependency_count(); i++) { + const std::string& name = file->dependency(i)->name(); + // Currently, descriptor.proto is not ready for external usage. Skip to + // import it for now, so that its dependencies can still work as long as + // they don't use protos defined in descriptor.proto. + if (name == kDescriptorFile) { + continue; + } + std::string dependency_filename = + GeneratedMetadataFileName(file->dependency(i), options); + printer->Print( + "\\^name^::initOnce();\n", + "name", FilenameToClassname(dependency_filename)); + } + + // Add messages and enums to descriptor pool. + FileDescriptorSet files; + FileDescriptorProto* file_proto = files.add_file(); + file->CopyTo(file_proto); + + // Filter out descriptor.proto as it cannot be depended on for now. + RepeatedPtrField* dependency = + file_proto->mutable_dependency(); + for (RepeatedPtrField::iterator it = dependency->begin(); + it != dependency->end(); ++it) { + if (*it != kDescriptorFile) { + dependency->erase(it); + break; + } + } + // Filter out all extensions, since we do not support extension yet. + file_proto->clear_extension(); + RepeatedPtrField* message_type = + file_proto->mutable_message_type(); + for (RepeatedPtrField::iterator it = message_type->begin(); + it != message_type->end(); ++it) { + it->clear_extension(); + } + + std::string files_data; + files.SerializeToString(&files_data); + + printer->Print("$pool->internalAddGeneratedFile(\n"); + Indent(printer); + printer->Print("'"); + + for (auto ch : files_data) { + switch (ch) { + case '\\': + printer->Print(R"(\\)"); + break; + case '\'': + printer->Print(R"(\')"); + break; + default: + printer->Print("^char^", "char", std::string(1, ch)); + break; + } + } + + printer->Print("'\n"); + Outdent(printer); + printer->Print( + ", true);\n\n"); + } printer->Print( - "$pool->finish();\n"); + "static::$is_initialized = true;\n"); + } + + Outdent(printer); + printer->Print("}\n"); +} + +static void AnalyzeDependencyForFile( + const FileDescriptor* file, + std::set* nodes_without_dependency, + std::map>* deps, + std::map* dependency_count) { + int count = file->dependency_count(); + for (int i = 0; i < file->dependency_count(); i++) { + const FileDescriptor* dependency = file->dependency(i); + if (dependency->name() == kDescriptorFile) { + count--; + break; + } + } + + if (count == 0) { + nodes_without_dependency->insert(file); } else { + (*dependency_count)[file] = count; for (int i = 0; i < file->dependency_count(); i++) { - const std::string& name = file->dependency(i)->name(); - // Currently, descriptor.proto is not ready for external usage. Skip to - // import it for now, so that its dependencies can still work as long as - // they don't use protos defined in descriptor.proto. - if (name == kDescriptorFile) { + const FileDescriptor* dependency = file->dependency(i); + if (dependency->name() == kDescriptorFile) { continue; } - std::string dependency_filename = - GeneratedMetadataFileName(file->dependency(i), is_descriptor); - printer->Print( - "\\^name^::initOnce();\n", - "name", FilenameToClassname(dependency_filename)); + if (deps->find(dependency) == deps->end()) { + (*deps)[dependency] = std::set(); + } + (*deps)[dependency].insert(file); + AnalyzeDependencyForFile( + dependency, nodes_without_dependency, deps, dependency_count); } + } +} - // Add messages and enums to descriptor pool. - FileDescriptorSet files; - FileDescriptorProto* file_proto = files.add_file(); - file->CopyTo(file_proto); - - // Filter out descriptor.proto as it cannot be depended on for now. - RepeatedPtrField* dependency = file_proto->mutable_dependency(); - for (RepeatedPtrField::iterator it = dependency->begin(); - it != dependency->end(); ++it) { - if (*it != kDescriptorFile) { - dependency->erase(it); +static bool NeedsUnwrapping(const FileDescriptor* file, + const Options& options) { + bool has_aggregate_metadata_prefix = false; + if (options.aggregate_metadata_prefixes.empty()) { + has_aggregate_metadata_prefix = true; + } else { + for (const auto& prefix : options.aggregate_metadata_prefixes) { + if (HasPrefixString(file->package(), prefix)) { + has_aggregate_metadata_prefix = true; break; } } + } - // Filter out all extensions, since we do not support extension yet. - file_proto->clear_extension(); - RepeatedPtrField* message_type = - file_proto->mutable_message_type(); - for (RepeatedPtrField::iterator it = message_type->begin(); - it != message_type->end(); ++it) { - it->clear_extension(); + return has_aggregate_metadata_prefix; +} + +void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, + io::Printer* printer) { + printer->Print( + "$pool = \\Google\\Protobuf\\Internal\\" + "DescriptorPool::getGeneratedPool();\n" + "if (static::$is_initialized == true) {\n" + " return;\n" + "}\n"); + + // Sort files according to dependency + std::map> deps; + std::map dependency_count; + std::set nodes_without_dependency; + FileDescriptorSet sorted_file_set; + + AnalyzeDependencyForFile( + file, &nodes_without_dependency, &deps, &dependency_count); + + while (!nodes_without_dependency.empty()) { + auto file = *nodes_without_dependency.begin(); + nodes_without_dependency.erase(file); + for (auto dependent : deps[file]) { + if (dependency_count[dependent] == 1) { + dependency_count.erase(dependent); + nodes_without_dependency.insert(dependent); + } else { + dependency_count[dependent] -= 1; + } } - string files_data; - files.SerializeToString(&files_data); + bool needs_aggregate = NeedsUnwrapping(file, options); - printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n"); - Indent(printer); + if (needs_aggregate) { + auto file_proto = sorted_file_set.add_file(); + file->CopyTo(file_proto); + + // Filter out descriptor.proto as it cannot be depended on for now. + RepeatedPtrField* dependency = + file_proto->mutable_dependency(); + for (RepeatedPtrField::iterator it = dependency->begin(); + it != dependency->end(); ++it) { + if (*it != kDescriptorFile) { + dependency->erase(it); + break; + } + } - // Only write 30 bytes per line. - static const int kBytesPerLine = 30; - for (int i = 0; i < files_data.size(); i += kBytesPerLine) { + // Filter out all extensions, since we do not support extension yet. + file_proto->clear_extension(); + RepeatedPtrField* message_type = + file_proto->mutable_message_type(); + for (RepeatedPtrField::iterator it = message_type->begin(); + it != message_type->end(); ++it) { + it->clear_extension(); + } + } else { + std::string dependency_filename = GeneratedMetadataFileName(file, false); printer->Print( - "\"^data^\"^dot^\n", - "data", BinaryToHex(files_data.substr(i, kBytesPerLine)), - "dot", i + kBytesPerLine < files_data.size() ? " ." : ""); + "\\^name^::initOnce();\n", + "name", FilenameToClassname(dependency_filename)); } + } - Outdent(printer); - printer->Print( - "), true);\n\n"); + std::string files_data; + sorted_file_set.SerializeToString(&files_data); + + printer->Print("$pool->internalAddGeneratedFile(\n"); + Indent(printer); + printer->Print("'"); + + for (auto ch : files_data) { + switch (ch) { + case '\\': + printer->Print(R"(\\)"); + break; + case '\'': + printer->Print(R"(\')"); + break; + default: + printer->Print("^char^", "char", std::string(1, ch)); + break; + } } + + printer->Print("'\n"); + Outdent(printer); + printer->Print( + ", true);\n"); + printer->Print( "static::$is_initialized = true;\n"); - Outdent(printer); - printer->Print("}\n"); } -void GenerateUseDeclaration(bool is_descriptor, io::Printer* printer) { - if (!is_descriptor) { +void GenerateUseDeclaration(const Options& options, io::Printer* printer) { + if (!options.is_descriptor) { printer->Print( "use Google\\Protobuf\\Internal\\GPBType;\n" "use Google\\Protobuf\\Internal\\RepeatedField;\n" @@ -1038,7 +1209,7 @@ void GenerateHead(const FileDescriptor* file, io::Printer* printer) { "filename", file->name()); } -std::string FilenameToClassname(const string& filename) { +std::string FilenameToClassname(const std::string& filename) { int lastindex = filename.find_last_of("."); std::string result = filename.substr(0, lastindex); for (int i = 0; i < result.size(); i++) { @@ -1049,10 +1220,9 @@ std::string FilenameToClassname(const string& filename) { return result; } -void GenerateMetadataFile(const FileDescriptor* file, - bool is_descriptor, +void GenerateMetadataFile(const FileDescriptor* file, const Options& options, GeneratorContext* generator_context) { - std::string filename = GeneratedMetadataFileName(file, is_descriptor); + std::string filename = GeneratedMetadataFileName(file, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1062,7 +1232,7 @@ void GenerateMetadataFile(const FileDescriptor* file, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1079,31 +1249,30 @@ void GenerateMetadataFile(const FileDescriptor* file, } Indent(&printer); - GenerateAddFileToPool(file, is_descriptor, &printer); + GenerateAddFileToPool(file, options, &printer); Outdent(&printer); printer.Print("}\n\n"); } template -void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* desc, - bool is_descriptor, - GeneratorContext* generator_context) { - - std::string filename = LegacyGeneratedClassFileName(desc, is_descriptor); +void LegacyGenerateClassFile(const FileDescriptor* file, + const DescriptorType* desc, const Options& options, + GeneratorContext* generator_context) { + std::string filename = LegacyGeneratedClassFileName(desc, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); GenerateHead(file, &printer); - std::string php_namespace = RootPhpNamespace(desc, is_descriptor); + std::string php_namespace = RootPhpNamespace(desc, options); if (!php_namespace.empty()) { printer.Print( "namespace ^name^;\n\n", "name", php_namespace); } - std::string newname = FullClassName(desc, is_descriptor); + std::string newname = FullClassName(desc, options); printer.Print("if (false) {\n"); Indent(&printer); printer.Print("/**\n"); @@ -1119,13 +1288,14 @@ void LegacyGenerateClassFile(const FileDescriptor* file, const DescriptorType* d "new", GeneratedClassNameImpl(desc)); printer.Print("@trigger_error('^old^ is deprecated and will be removed in " "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n", - "old", LegacyFullClassName(desc, is_descriptor), + "old", LegacyFullClassName(desc, options), "fullname", newname); } void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, - bool is_descriptor, GeneratorContext* generator_context) { - std::string filename = GeneratedClassFileName(en, is_descriptor); + const Options& options, + GeneratorContext* generator_context) { + std::string filename = GeneratedClassFileName(en, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1135,7 +1305,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1145,9 +1315,9 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, printer.Print("use UnexpectedValueException;\n\n"); } - GenerateEnumDocComment(&printer, en, is_descriptor); + GenerateEnumDocComment(&printer, en, options); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { fullname = fullname.substr(lastindex + 1); } @@ -1222,13 +1392,13 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, printer.Print( "class_alias(^new^::class, \\^old^::class);\n\n", "new", fullname, - "old", LegacyFullClassName(en, is_descriptor)); - LegacyGenerateClassFile(file, en, is_descriptor, generator_context); + "old", LegacyFullClassName(en, options)); + LegacyGenerateClassFile(file, en, options, generator_context); } } void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, - bool is_descriptor, + const Options& options, GeneratorContext* generator_context) { // Don't generate MapEntry messages -- we use the PHP extension's native // support for map fields instead. @@ -1236,7 +1406,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, return; } - std::string filename = GeneratedClassFileName(message, is_descriptor); + std::string filename = GeneratedClassFileName(message, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1246,58 +1416,74 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, std::string fullname = FilenameToClassname(filename); int lastindex = fullname.find_last_of("\\"); - if (lastindex != string::npos) { + if (lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); } - GenerateUseDeclaration(is_descriptor, &printer); + GenerateUseDeclaration(options, &printer); - GenerateMessageDocComment(&printer, message, is_descriptor); - if (lastindex != string::npos) { + GenerateMessageDocComment(&printer, message, options); + if (lastindex != std::string::npos) { fullname = fullname.substr(lastindex + 1); } + std::string base; + + switch (message->well_known_type()) { + case Descriptor::WELLKNOWNTYPE_ANY: + base = "\\Google\\Protobuf\\Internal\\AnyBase"; + break; + case Descriptor::WELLKNOWNTYPE_TIMESTAMP: + base = "\\Google\\Protobuf\\Internal\\TimestampBase"; + break; + default: + base = "\\Google\\Protobuf\\Internal\\Message"; + break; + } + printer.Print( - "class ^name^ extends \\Google\\Protobuf\\Internal\\Message\n" + "class ^name^ extends ^base^\n" "{\n", + "base", base, "name", fullname); Indent(&printer); // Field and oneof definitions. for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); - GenerateField(field, &printer, is_descriptor); + GenerateField(field, &printer, options); } - for (int i = 0; i < message->oneof_decl_count(); i++) { + for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); GenerateOneofField(oneof, &printer); } printer.Print("\n"); - GenerateMessageConstructorDocComment(&printer, message, is_descriptor); + GenerateMessageConstructorDocComment(&printer, message, options); printer.Print( "public function __construct($data = NULL) {\n"); Indent(&printer); - std::string metadata_filename = - GeneratedMetadataFileName(file, is_descriptor); + std::string metadata_filename = GeneratedMetadataFileName(file, options); std::string metadata_fullname = FilenameToClassname(metadata_filename); printer.Print( - "\\^fullname^::initOnce();\n" - "parent::__construct($data);\n", + "\\^fullname^::initOnce();\n", "fullname", metadata_fullname); + printer.Print( + "parent::__construct($data);\n"); + Outdent(&printer); printer.Print("}\n\n"); // Field and oneof accessors. for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); - GenerateFieldAccessor(field, is_descriptor, &printer); + GenerateFieldAccessor(field, options, &printer); } - for (int i = 0; i < message->oneof_decl_count(); i++) { + for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); printer.Print( "/**\n" @@ -1321,25 +1507,24 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, printer.Print( "class_alias(^new^::class, \\^old^::class);\n\n", "new", fullname, - "old", LegacyFullClassName(message, is_descriptor)); - LegacyGenerateClassFile(file, message, is_descriptor, generator_context); + "old", LegacyFullClassName(message, options)); + LegacyGenerateClassFile(file, message, options, generator_context); } // Nested messages and enums. for (int i = 0; i < message->nested_type_count(); i++) { - GenerateMessageFile(file, message->nested_type(i), is_descriptor, + GenerateMessageFile(file, message->nested_type(i), options, generator_context); } for (int i = 0; i < message->enum_type_count(); i++) { - GenerateEnumFile(file, message->enum_type(i), is_descriptor, - generator_context); + GenerateEnumFile(file, message->enum_type(i), options, generator_context); } } -void GenerateServiceFile(const FileDescriptor* file, - const ServiceDescriptor* service, bool is_descriptor, - GeneratorContext* generator_context) { - std::string filename = GeneratedServiceFileName(service, is_descriptor); +void GenerateServiceFile( + const FileDescriptor* file, const ServiceDescriptor* service, + const Options& options, GeneratorContext* generator_context) { + std::string filename = GeneratedServiceFileName(service, options); std::unique_ptr output( generator_context->Open(filename)); io::Printer printer(output.get(), '^'); @@ -1351,7 +1536,7 @@ void GenerateServiceFile(const FileDescriptor* file, if (!file->options().php_namespace().empty() || (!file->options().has_php_namespace() && !file->package().empty()) || - lastindex != string::npos) { + lastindex != std::string::npos) { printer.Print( "namespace ^name^;\n\n", "name", fullname.substr(0, lastindex)); @@ -1359,13 +1544,13 @@ void GenerateServiceFile(const FileDescriptor* file, GenerateServiceDocComment(&printer, service); - if (lastindex != string::npos) { - printer.Print( + if (lastindex != std::string::npos) { + printer.Print( "interface ^name^\n" "{\n", "name", fullname.substr(lastindex + 1)); } else { - printer.Print( + printer.Print( "interface ^name^\n" "{\n", "name", fullname); @@ -1383,32 +1568,31 @@ void GenerateServiceFile(const FileDescriptor* file, printer.Print("}\n\n"); } -void GenerateFile(const FileDescriptor* file, bool is_descriptor, +void GenerateFile(const FileDescriptor* file, const Options& options, GeneratorContext* generator_context) { - GenerateMetadataFile(file, is_descriptor, generator_context); + GenerateMetadataFile(file, options, generator_context); + for (int i = 0; i < file->message_type_count(); i++) { - GenerateMessageFile(file, file->message_type(i), is_descriptor, + GenerateMessageFile(file, file->message_type(i), options, generator_context); } for (int i = 0; i < file->enum_type_count(); i++) { - GenerateEnumFile(file, file->enum_type(i), is_descriptor, - generator_context); + GenerateEnumFile(file, file->enum_type(i), options, generator_context); } if (file->options().php_generic_services()) { for (int i = 0; i < file->service_count(); i++) { - GenerateServiceFile(file, file->service(i), is_descriptor, - generator_context); + GenerateServiceFile(file, file->service(i), options, generator_context); } } } -static string EscapePhpdoc(const string& input) { - string result; +static std::string EscapePhpdoc(const std::string& input) { + std::string result; result.reserve(input.size() * 2); char prev = '*'; - for (string::size_type i = 0; i < input.size(); i++) { + for (std::string::size_type i = 0; i < input.size(); i++) { char c = input[i]; switch (c) { case '*': @@ -1447,8 +1631,9 @@ static string EscapePhpdoc(const string& input) { static void GenerateDocCommentBodyForLocation( io::Printer* printer, const SourceLocation& location, bool trailingNewline, int indentCount) { - string comments = location.leading_comments.empty() ? - location.trailing_comments : location.leading_comments; + std::string comments = location.leading_comments.empty() + ? location.trailing_comments + : location.leading_comments; if (!comments.empty()) { // TODO(teboring): Ideally we should parse the comment text as Markdown and // write it back as HTML, but this requires a Markdown parser. For now @@ -1458,7 +1643,7 @@ static void GenerateDocCommentBodyForLocation( // HTML-escape them so that they don't accidentally close the doc comment. comments = EscapePhpdoc(comments); - std::vector lines = Split(comments, "\n", true); + std::vector lines = Split(comments, "\n", true); while (!lines.empty() && lines.back().empty()) { lines.pop_back(); } @@ -1489,31 +1674,31 @@ static void GenerateDocCommentBody( } } -static string FirstLineOf(const string& value) { - string result = value; +static std::string FirstLineOf(const std::string& value) { + std::string result = value; - string::size_type pos = result.find_first_of('\n'); - if (pos != string::npos) { + std::string::size_type pos = result.find_first_of('\n'); + if (pos != std::string::npos) { result.erase(pos); } return result; } -void GenerateMessageDocComment(io::Printer* printer, - const Descriptor* message, int is_descriptor) { +void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message, + const Options& options) { printer->Print("/**\n"); GenerateDocCommentBody(printer, message); printer->Print( " * Generated from protobuf message ^messagename^\n" " */\n", - "fullname", EscapePhpdoc(FullClassName(message, is_descriptor)), + "fullname", EscapePhpdoc(FullClassName(message, options)), "messagename", EscapePhpdoc(message->full_name())); } void GenerateMessageConstructorDocComment(io::Printer* printer, const Descriptor* message, - int is_descriptor) { + const Options& options) { // In theory we should have slightly different comments for setters, getters, // etc., but in practice everyone already knows the difference between these // so it's redundant information. @@ -1531,7 +1716,7 @@ void GenerateMessageConstructorDocComment(io::Printer* printer, for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); printer->Print(" * @type ^php_type^ $^var^\n", - "php_type", PhpSetterTypeName(field, is_descriptor), + "php_type", PhpSetterTypeName(field, options), "var", field->name()); SourceLocation location; if (field->GetSourceLocation(&location)) { @@ -1553,7 +1738,7 @@ void GenerateServiceDocComment(io::Printer* printer, } void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, - int is_descriptor, int function_type) { + const Options& options, int function_type) { // In theory we should have slightly different comments for setters, getters, // etc., but in practice everyone already knows the difference between these // so it's redundant information. @@ -1569,11 +1754,11 @@ void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field, "def", EscapePhpdoc(FirstLineOf(field->DebugString()))); if (function_type == kFieldSetter) { printer->Print(" * @param ^php_type^ $var\n", - "php_type", PhpSetterTypeName(field, is_descriptor)); + "php_type", PhpSetterTypeName(field, options)); printer->Print(" * @return $this\n"); } else if (function_type == kFieldGetter) { printer->Print(" * @return ^php_type^\n", - "php_type", PhpGetterTypeName(field, is_descriptor)); + "php_type", PhpGetterTypeName(field, options)); } printer->Print(" */\n"); } @@ -1602,7 +1787,7 @@ void GenerateWrapperFieldSetterDocComment(io::Printer* printer, const FieldDescr printer->Print("/**\n"); printer->Print( " * Sets the field by wrapping a primitive type in a ^message_name^ object.\n\n", - "message_name", LegacyFullClassName(field->message_type(), false)); + "message_name", FullClassName(field->message_type(), false)); GenerateDocCommentBody(printer, field); printer->Print( " * Generated from protobuf field ^def^\n", @@ -1614,7 +1799,7 @@ void GenerateWrapperFieldSetterDocComment(io::Printer* printer, const FieldDescr } void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_, - int is_descriptor) { + const Options& options) { printer->Print("/**\n"); GenerateDocCommentBody(printer, enum_); printer->Print( @@ -1634,7 +1819,7 @@ void GenerateEnumValueDocComment(io::Printer* printer, } void GenerateServiceMethodDocComment(io::Printer* printer, - const MethodDescriptor* method) { + const MethodDescriptor* method) { printer->Print("/**\n"); GenerateDocCommentBody(printer, method); printer->Print( @@ -1650,25 +1835,443 @@ void GenerateServiceMethodDocComment(io::Printer* printer, "return_type", EscapePhpdoc(FullClassName(method->output_type(), false))); } -bool Generator::Generate(const FileDescriptor* file, const string& parameter, +std::string FilenameCName(const FileDescriptor* file) { + std::string c_name = file->name(); + c_name = StringReplace(c_name, ".", "_", true); + c_name = StringReplace(c_name, "/", "_", true); + return c_name; +} + +void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) { + std::string c_name = desc->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + std::string php_name = FullClassName(desc, Options()); + php_name = StringReplace(php_name, "\\", "\\\\", true); + printer->Print( + "/* $c_name$ */\n" + "\n" + "zend_class_entry* $c_name$_ce;\n" + "\n" + "PHP_METHOD($c_name$, name) {\n" + " $file_c_name$_AddDescriptor();\n" + " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" + " const char *name;\n" + " zend_long value;\n" + " if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"l\", &value) ==\n" + " FAILURE) {\n" + " return;\n" + " }\n" + " name = upb_enumdef_iton(e, value);\n" + " if (!name) {\n" + " zend_throw_exception_ex(NULL, 0,\n" + " \"$php_name$ has no name \"\n" + " \"defined for value \" ZEND_LONG_FMT \".\",\n" + " value);\n" + " return;\n" + " }\n" + " RETURN_STRING(name);\n" + "}\n" + "\n" + "PHP_METHOD($c_name$, value) {\n" + " $file_c_name$_AddDescriptor();\n" + " const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n" + " const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n" + " char *name = NULL;\n" + " size_t name_len;\n" + " int32_t num;\n" + " if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \"s\", &name,\n" + " &name_len) == FAILURE) {\n" + " return;\n" + " }\n" + " if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n" + " zend_throw_exception_ex(NULL, 0,\n" + " \"$php_name$ has no value \"\n" + " \"defined for name %s.\",\n" + " name);\n" + " return;\n" + " }\n" + " RETURN_LONG(num);\n" + "}\n" + "\n" + "static zend_function_entry $c_name$_phpmethods[] = {\n" + " PHP_ME($c_name$, name, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n" + " PHP_ME($c_name$, value, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n" + " ZEND_FE_END\n" + "};\n" + "\n" + "static void $c_name$_ModuleInit() {\n" + " zend_class_entry tmp_ce;\n" + "\n" + " INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n" + " $c_name$_phpmethods);\n" + "\n" + " $c_name$_ce = zend_register_internal_class(&tmp_ce);\n", + "name", desc->full_name(), + "file_c_name", FilenameCName(desc->file()), + "c_name", c_name, + "php_name", php_name); + + for (int i = 0; i < desc->value_count(); i++) { + const EnumValueDescriptor* value = desc->value(i); + printer->Print( + " zend_declare_class_constant_long($c_name$_ce, \"$name$\",\n" + " strlen(\"$name$\"), $num$);\n", + "c_name", c_name, + "name", value->name(), + "num", std::to_string(value->number())); + } + + printer->Print( + "}\n" + "\n"); +} + +void GenerateCMessage(const Descriptor* message, io::Printer* printer) { + std::string c_name = message->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + std::string php_name = FullClassName(message, Options()); + php_name = StringReplace(php_name, "\\", "\\\\", true); + printer->Print( + "/* $c_name$ */\n" + "\n" + "zend_class_entry* $c_name$_ce;\n" + "\n" + "static PHP_METHOD($c_name$, __construct) {\n" + " $file_c_name$_AddDescriptor();\n" + " zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n" + "}\n" + "\n", + "file_c_name", FilenameCName(message->file()), + "c_name", c_name); + + for (int i = 0; i < message->field_count(); i++) { + auto field = message->field(i); + printer->Print( + "static PHP_METHOD($c_name$, get$camel_name$) {\n" + " Message* intern = (Message*)Z_OBJ_P(getThis());\n" + " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" + " \"$name$\");\n" + " zval ret;\n" + " Message_get(intern, f, &ret);\n" + " RETURN_ZVAL(&ret, 1, 0);\n" + "}\n" + "\n" + "static PHP_METHOD($c_name$, set$camel_name$) {\n" + " Message* intern = (Message*)Z_OBJ_P(getThis());\n" + " const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n" + " \"$name$\");\n" + " zval *val;\n" + " if (zend_parse_parameters(ZEND_NUM_ARGS(), \"z\", &val)\n" + " == FAILURE) {\n" + " return;\n" + " }\n" + " Message_set(intern, f, val);\n" + " RETURN_ZVAL(getThis(), 1, 0);\n" + "}\n" + "\n", + "c_name", c_name, + "name", field->name(), + "camel_name", UnderscoresToCamelCase(field->name(), true)); + } + + for (int i = 0; i < message->real_oneof_decl_count(); i++) { + auto oneof = message->oneof_decl(i); + printer->Print( + "static PHP_METHOD($c_name$, get$camel_name$) {\n" + " Message* intern = (Message*)Z_OBJ_P(getThis());\n" + " const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n" + " \"$name$\");\n" + " const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n" + " RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n" + "}\n", + "c_name", c_name, + "name", oneof->name(), + "camel_name", UnderscoresToCamelCase(oneof->name(), true)); + } + + printer->Print( + "static zend_function_entry $c_name$_phpmethods[] = {\n" + " PHP_ME($c_name$, __construct, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name); + + for (int i = 0; i < message->field_count(); i++) { + auto field = message->field(i); + printer->Print( + " PHP_ME($c_name$, get$camel_name$, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, set$camel_name$, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name, + "camel_name", UnderscoresToCamelCase(field->name(), true)); + } + + for (int i = 0; i < message->real_oneof_decl_count(); i++) { + auto oneof = message->oneof_decl(i); + printer->Print( + " PHP_ME($c_name$, get$camel_name$, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name, + "camel_name", UnderscoresToCamelCase(oneof->name(), true)); + } + + // Extra hand-written functions added to the well-known types. + switch (message->well_known_type()) { + case Descriptor::WELLKNOWNTYPE_ANY: + printer->Print( + " PHP_ME($c_name$, is, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, pack, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, unpack, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name); + break; + case Descriptor::WELLKNOWNTYPE_TIMESTAMP: + printer->Print( + " PHP_ME($c_name$, fromDateTime, NULL, ZEND_ACC_PUBLIC)\n" + " PHP_ME($c_name$, toDateTime, NULL, ZEND_ACC_PUBLIC)\n", + "c_name", c_name); + break; + default: + break; + } + + printer->Print( + " ZEND_FE_END\n" + "};\n" + "\n" + "static void $c_name$_ModuleInit() {\n" + " zend_class_entry tmp_ce;\n" + "\n" + " INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n" + " $c_name$_phpmethods);\n" + "\n" + " $c_name$_ce = zend_register_internal_class(&tmp_ce);\n" + " $c_name$_ce->ce_flags |= ZEND_ACC_FINAL;\n" + " $c_name$_ce->create_object = Message_create;\n" + " zend_do_inheritance($c_name$_ce, message_ce);\n" + "}\n" + "\n", + "c_name", c_name, + "php_name", php_name); + + for (int i = 0; i < message->nested_type_count(); i++) { + GenerateCMessage(message->nested_type(i), printer); + } + for (int i = 0; i < message->enum_type_count(); i++) { + GenerateCEnum(message->enum_type(i), printer); + } +} + +void GenerateEnumCInit(const EnumDescriptor* desc, io::Printer* printer) { + std::string c_name = desc->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + + printer->Print( + " $c_name$_ModuleInit();\n", + "c_name", c_name); +} + +void GenerateCInit(const Descriptor* message, io::Printer* printer) { + std::string c_name = message->full_name(); + c_name = StringReplace(c_name, ".", "_", true); + + printer->Print( + " $c_name$_ModuleInit();\n", + "c_name", c_name); + + for (int i = 0; i < message->nested_type_count(); i++) { + GenerateCInit(message->nested_type(i), printer); + } + for (int i = 0; i < message->enum_type_count(); i++) { + GenerateEnumCInit(message->enum_type(i), printer); + } +} + +void GenerateCWellKnownTypes(const std::vector& files, + GeneratorContext* context) { + std::unique_ptr output( + context->Open("../ext/google/protobuf/wkt.inc")); + io::Printer printer(output.get(), '$'); + + printer.Print( + "// This file is generated from the .proto files for the well-known\n" + "// types. Do not edit!\n"); + + for (auto file : files) { + printer.Print( + "static void $c_name$_AddDescriptor();\n", + "c_name", FilenameCName(file)); + } + + for (auto file : files) { + std::string c_name = FilenameCName(file); + std::string metadata_filename = GeneratedMetadataFileName(file, Options()); + std::string metadata_classname = FilenameToClassname(metadata_filename); + std::string metadata_c_name = + StringReplace(metadata_classname, "\\", "_", true); + metadata_classname = StringReplace(metadata_classname, "\\", "\\\\", true); + FileDescriptorProto file_proto; + file->CopyTo(&file_proto); + std::string serialized; + file_proto.SerializeToString(&serialized); + printer.Print( + "/* $filename$ */\n" + "\n" + "zend_class_entry* $metadata_c_name$_ce;\n" + "\n" + "const char $c_name$_descriptor [$size$] = {\n", + "filename", file->name(), + "c_name", c_name, + "metadata_c_name", metadata_c_name, + "size", std::to_string(serialized.size())); + + for (size_t i = 0; i < serialized.size();) { + for (size_t j = 0; j < 25 && i < serialized.size(); ++i, ++j) { + printer.Print("'$ch$', ", "ch", CEscape(serialized.substr(i, 1))); + } + printer.Print("\n"); + } + + printer.Print( + "};\n" + "\n" + "static void $c_name$_AddDescriptor() {\n" + " if (DescriptorPool_HasFile(\"$filename$\")) return;\n", + "filename", file->name(), + "c_name", c_name, + "metadata_c_name", metadata_c_name); + + for (int i = 0; i < file->dependency_count(); i++) { + std::string dep_c_name = FilenameCName(file->dependency(i)); + printer.Print( + " $dep_c_name$_AddDescriptor();\n", + "dep_c_name", dep_c_name); + } + + printer.Print( + " DescriptorPool_AddDescriptor(\"$filename$\", $c_name$_descriptor,\n" + " sizeof($c_name$_descriptor));\n" + "}\n" + "\n" + "static PHP_METHOD($metadata_c_name$, initOnce) {\n" + " $c_name$_AddDescriptor();\n" + "}\n" + "\n" + "static zend_function_entry $metadata_c_name$_methods[] = {\n" + " PHP_ME($metadata_c_name$, initOnce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n" + " ZEND_FE_END\n" + "};\n" + "\n" + "static void $metadata_c_name$_ModuleInit() {\n" + " zend_class_entry tmp_ce;\n" + "\n" + " INIT_CLASS_ENTRY(tmp_ce, \"$metadata_classname$\",\n" + " $metadata_c_name$_methods);\n" + "\n" + " $metadata_c_name$_ce = zend_register_internal_class(&tmp_ce);\n" + "}\n" + "\n", + "filename", file->name(), + "c_name", c_name, + "metadata_c_name", metadata_c_name, + "metadata_classname", metadata_classname); + for (int i = 0; i < file->message_type_count(); i++) { + GenerateCMessage(file->message_type(i), &printer); + } + for (int i = 0; i < file->enum_type_count(); i++) { + GenerateCEnum(file->enum_type(i), &printer); + } + } + + printer.Print( + "static void WellKnownTypes_ModuleInit() {\n"); + + for (auto file : files) { + std::string metadata_filename = GeneratedMetadataFileName(file, Options()); + std::string metadata_classname = FilenameToClassname(metadata_filename); + std::string metadata_c_name = + StringReplace(metadata_classname, "\\", "_", true); + printer.Print( + " $metadata_c_name$_ModuleInit();\n", + "metadata_c_name", metadata_c_name); + for (int i = 0; i < file->message_type_count(); i++) { + GenerateCInit(file->message_type(i), &printer); + } + for (int i = 0; i < file->enum_type_count(); i++) { + GenerateEnumCInit(file->enum_type(i), &printer); + } + } + + printer.Print( + "}\n"); +} + +} // namespace + +std::string GeneratedClassName(const Descriptor* desc) { + return GeneratedClassNameImpl(desc); +} + +std::string GeneratedClassName(const EnumDescriptor* desc) { + return GeneratedClassNameImpl(desc); +} + +std::string GeneratedClassName(const ServiceDescriptor* desc) { + return GeneratedClassNameImpl(desc); +} + +bool Generator::Generate(const FileDescriptor* file, + const std::string& parameter, GeneratorContext* generator_context, - string* error) const { - bool is_descriptor = parameter == "internal"; + std::string* error) const { + return Generate(file, Options(), generator_context, error); +} - if (is_descriptor && file->name() != kDescriptorFile) { +bool Generator::Generate(const FileDescriptor* file, const Options& options, + GeneratorContext* generator_context, + std::string* error) const { + if (options.is_descriptor && file->name() != kDescriptorFile) { *error = "Can only generate PHP code for google/protobuf/descriptor.proto.\n"; return false; } - if (!is_descriptor && file->syntax() != FileDescriptor::SYNTAX_PROTO3) { + if (!options.is_descriptor && file->syntax() != FileDescriptor::SYNTAX_PROTO3) { *error = "Can only generate PHP code for proto3 .proto files.\n" "Please add 'syntax = \"proto3\";' to the top of your .proto file.\n"; return false; } - GenerateFile(file, is_descriptor, generator_context); + GenerateFile(file, options, generator_context); + + return true; +} + +bool Generator::GenerateAll(const std::vector& files, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const { + Options options; + + for (const auto& option : Split(parameter, ",", true)) { + const std::vector option_pair = Split(option, "=", true); + if (HasPrefixString(option_pair[0], "aggregate_metadata")) { + options.aggregate_metadata = true; + for (const auto& prefix : Split(option_pair[1], "#", false)) { + options.aggregate_metadata_prefixes.insert(prefix); + GOOGLE_LOG(INFO) << prefix; + } + } else if (option_pair[0] == "internal") { + options.is_descriptor = true; + } else if (option_pair[0] == "internal_generate_c_wkt") { + GenerateCWellKnownTypes(files, generator_context); + } else { + GOOGLE_LOG(FATAL) << "Unknown codegen option: " << option_pair[0]; + } + } + + for (auto file : files) { + if (!Generate(file, options, generator_context, error)) { + return false; + } + } return true; } diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index ef708ab56d5b..17cb59c08b6a 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -43,12 +43,31 @@ namespace protobuf { namespace compiler { namespace php { +struct Options; + class PROTOC_EXPORT Generator : public CodeGenerator { + public: virtual bool Generate( const FileDescriptor* file, - const string& parameter, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + + bool GenerateAll(const std::vector& files, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + + uint64_t GetSupportedFeatures() const override { + return FEATURE_PROTO3_OPTIONAL; + } + + private: + bool Generate( + const FileDescriptor* file, + const Options& options, GeneratorContext* generator_context, - string* error) const; + std::string* error) const; }; // To skip reserved keywords in php, some generated classname are prefixed. diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 7de3985c530f..cb7801d53c96 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -86,6 +86,16 @@ class GeneratorResponseContext : public GeneratorContext { return new io::StringOutputStream(file->mutable_content()); } + virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo( + const std::string& filename, const std::string& insertion_point, + const google::protobuf::GeneratedCodeInfo& info) { + CodeGeneratorResponse::File* file = response_->add_file(); + file->set_name(filename); + file->set_insertion_point(insertion_point); + *file->mutable_generated_code_info() = info; + return new io::StringOutputStream(file->mutable_content()); + } + void ListParsedFiles(std::vector* output) { *output = parsed_files_; } @@ -132,6 +142,8 @@ bool GenerateCode(const CodeGeneratorRequest& request, bool succeeded = generator.GenerateAll(parsed_files, request.parameter(), &context, &error); + response->set_supported_features(generator.GetSupportedFeatures()); + if (!succeeded && error.empty()) { error = "Code generator returned false but provided no error " diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 8e590e91794e..58283cd742bd 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -14,8 +14,11 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto; -extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto; +extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto; PROTOBUF_NAMESPACE_OPEN namespace compiler { @@ -45,7 +48,6 @@ static void InitDefaultsscc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompil new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest::InitAsDefaultInstance(); } PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_CodeGeneratorRequest_google_2fprotobuf_2fcompiler_2fplugin_2eproto = @@ -61,7 +63,6 @@ static void InitDefaultsscc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompi new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse::InitAsDefaultInstance(); } PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto = @@ -76,11 +77,11 @@ static void InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2f new (ptr) PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File::InitAsDefaultInstance(); } -PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto = - {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {}}; +PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto = + {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 1, 0, InitDefaultsscc_info_CodeGeneratorResponse_File_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, { + &scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto.base,}}; static void InitDefaultsscc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto() { GOOGLE_PROTOBUF_VERIFY_VERSION; @@ -90,14 +91,13 @@ static void InitDefaultsscc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2 new (ptr) PROTOBUF_NAMESPACE_ID::compiler::Version(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::compiler::Version::InitAsDefaultInstance(); } PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {{ATOMIC_VAR_INIT(::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase::kUninitialized), 0, 0, InitDefaultsscc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto}, {}}; static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[4]; -static constexpr ::PROTOBUF_NAMESPACE_ID::EnumDescriptor const** file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; +static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]; static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr; const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { @@ -135,24 +135,28 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fcompiler_2 PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, insertion_point_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, content_), + PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File, generated_code_info_), 0, 1, 2, + 3, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, error_), + PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, supported_features_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse, file_), 0, + 1, ~0u, }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { { 0, 9, sizeof(PROTOBUF_NAMESPACE_ID::compiler::Version)}, { 13, 22, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest)}, - { 26, 34, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, - { 37, 44, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, + { 26, 35, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File)}, + { 39, 47, sizeof(PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -172,13 +176,17 @@ const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2epro "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf." "FileDescriptorProto\022;\n\020compiler_version\030" "\003 \001(\0132!.google.protobuf.compiler.Version" - "\"\252\001\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001(" - "\t\022B\n\004file\030\017 \003(\01324.google.protobuf.compil" - "er.CodeGeneratorResponse.File\032>\n\004File\022\014\n" - "\004name\030\001 \001(\t\022\027\n\017insertion_point\030\002 \001(\t\022\017\n\007" - "content\030\017 \001(\tBg\n\034com.google.protobuf.com" - "pilerB\014PluginProtosZ9github.com/golang/p" - "rotobuf/protoc-gen-go/plugin;plugin_go" + "\"\301\002\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001(" + "\t\022\032\n\022supported_features\030\002 \001(\004\022B\n\004file\030\017 " + "\003(\01324.google.protobuf.compiler.CodeGener" + "atorResponse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t\022" + "\027\n\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(" + "\t\022\?\n\023generated_code_info\030\020 \001(\0132\".google." + "protobuf.GeneratedCodeInfo\"8\n\007Feature\022\020\n" + "\014FEATURE_NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTION" + "AL\020\001BW\n\034com.google.protobuf.compilerB\014Pl" + "uginProtosZ)google.golang.org/protobuf/t" + "ypes/pluginpb" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, @@ -190,23 +198,41 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", 638, + false, false, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", 773, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_sccs, descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps, 4, 1, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); PROTOBUF_NAMESPACE_OPEN namespace compiler { +const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor() { + ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); + return file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]; +} +bool CodeGeneratorResponse_Feature_IsValid(int value) { + switch (value) { + case 0: + case 1: + return true; + default: + return false; + } +} + +#if (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_NONE; +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL; +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MIN; +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MAX; +constexpr int CodeGeneratorResponse::Feature_ARRAYSIZE; +#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || _MSC_VER >= 1900) // =================================================================== -void Version::InitAsDefaultInstance() { -} class Version::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -224,19 +250,20 @@ class Version::_Internal { } }; -Version::Version() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +Version::Version(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.compiler.Version) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version) } Version::Version(const Version& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_suffix()) { - suffix_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.suffix_); + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_suffix(), + GetArena()); } ::memcpy(&major_, &from.major_, static_cast(reinterpret_cast(&patch_) - @@ -247,20 +274,29 @@ Version::Version(const Version& from) void Version::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Version_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base); suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&major_, 0, static_cast( - reinterpret_cast(&patch_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&major_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&patch_) - reinterpret_cast(&major_)) + sizeof(patch_)); } Version::~Version() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Version::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); suffix_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } +void Version::ArenaDtor(void* object) { + Version* _this = reinterpret_cast< Version* >(object); + (void)_this; +} +void Version::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void Version::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -278,7 +314,7 @@ void Version::Clear() { cached_has_bits = _has_bits_[0]; if (cached_has_bits & 0x00000001u) { - suffix_.ClearNonDefaultToEmptyNoArena(); + suffix_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x0000000eu) { ::memset(&major_, 0, static_cast( @@ -286,7 +322,7 @@ void Version::Clear() { reinterpret_cast(&major_)) + sizeof(patch_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -338,7 +374,9 @@ const char* Version::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::in ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -390,7 +428,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Version::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version) return target; @@ -462,15 +500,14 @@ void Version::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Version::MergeFrom(const Version& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; cached_has_bits = from._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - suffix_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.suffix_); + _internal_set_suffix(from._internal_suffix()); } if (cached_has_bits & 0x00000002u) { major_ = from.major_; @@ -505,13 +542,15 @@ bool Version::IsInitialized() const { void Version::InternalSwap(Version* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - suffix_.Swap(&other->suffix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(major_, other->major_); - swap(minor_, other->minor_); - swap(patch_, other->patch_); + suffix_.Swap(&other->suffix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Version, patch_) + + sizeof(Version::patch_) + - PROTOBUF_FIELD_OFFSET(Version, major_)>( + reinterpret_cast(&major_), + reinterpret_cast(&other->major_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Version::GetMetadata() const { @@ -521,10 +560,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Version::GetMetadata() const { // =================================================================== -void CodeGeneratorRequest::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorRequest_default_instance_._instance.get_mutable()->compiler_version_ = const_cast< PROTOBUF_NAMESPACE_ID::compiler::Version*>( - PROTOBUF_NAMESPACE_ID::compiler::Version::internal_default_instance()); -} class CodeGeneratorRequest::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -544,21 +579,24 @@ CodeGeneratorRequest::_Internal::compiler_version(const CodeGeneratorRequest* ms void CodeGeneratorRequest::clear_proto_file() { proto_file_.Clear(); } -CodeGeneratorRequest::CodeGeneratorRequest() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +CodeGeneratorRequest::CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena), + file_to_generate_(arena), + proto_file_(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest) } CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), file_to_generate_(from.file_to_generate_), proto_file_(from.proto_file_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_parameter()) { - parameter_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.parameter_); + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_parameter(), + GetArena()); } if (from._internal_has_compiler_version()) { compiler_version_ = new PROTOBUF_NAMESPACE_ID::compiler::Version(*from.compiler_version_); @@ -577,13 +615,21 @@ void CodeGeneratorRequest::SharedCtor() { CodeGeneratorRequest::~CodeGeneratorRequest() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void CodeGeneratorRequest::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); parameter_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete compiler_version_; } +void CodeGeneratorRequest::ArenaDtor(void* object) { + CodeGeneratorRequest* _this = reinterpret_cast< CodeGeneratorRequest* >(object); + (void)_this; +} +void CodeGeneratorRequest::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void CodeGeneratorRequest::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -604,7 +650,7 @@ void CodeGeneratorRequest::Clear() { cached_has_bits = _has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - parameter_.ClearNonDefaultToEmptyNoArena(); + parameter_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x00000002u) { GOOGLE_DCHECK(compiler_version_ != nullptr); @@ -612,7 +658,7 @@ void CodeGeneratorRequest::Clear() { } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -675,7 +721,9 @@ const char* CodeGeneratorRequest::_InternalParse(const char* ptr, ::PROTOBUF_NAM ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -735,7 +783,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorRequest::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest) return target; @@ -808,7 +856,7 @@ void CodeGeneratorRequest::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& fro void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -817,8 +865,7 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) { cached_has_bits = from._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - parameter_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.parameter_); + _internal_set_parameter(from._internal_parameter()); } if (cached_has_bits & 0x00000002u) { _internal_mutable_compiler_version()->PROTOBUF_NAMESPACE_ID::compiler::Version::MergeFrom(from._internal_compiler_version()); @@ -847,12 +894,11 @@ bool CodeGeneratorRequest::IsInitialized() const { void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); file_to_generate_.InternalSwap(&other->file_to_generate_); proto_file_.InternalSwap(&other->proto_file_); - parameter_.Swap(&other->parameter_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + parameter_.Swap(&other->parameter_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(compiler_version_, other->compiler_version_); } @@ -863,8 +909,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorRequest::GetMetadata() const { // =================================================================== -void CodeGeneratorResponse_File::InitAsDefaultInstance() { -} class CodeGeneratorResponse_File::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -877,29 +921,49 @@ class CodeGeneratorResponse_File::_Internal { static void set_has_content(HasBits* has_bits) { (*has_bits)[0] |= 4u; } + static const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info(const CodeGeneratorResponse_File* msg); + static void set_has_generated_code_info(HasBits* has_bits) { + (*has_bits)[0] |= 8u; + } }; -CodeGeneratorResponse_File::CodeGeneratorResponse_File() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& +CodeGeneratorResponse_File::_Internal::generated_code_info(const CodeGeneratorResponse_File* msg) { + return *msg->generated_code_info_; +} +void CodeGeneratorResponse_File::clear_generated_code_info() { + if (generated_code_info_ != nullptr) generated_code_info_->Clear(); + _has_bits_[0] &= ~0x00000008u; +} +CodeGeneratorResponse_File::CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_insertion_point()) { - insertion_point_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.insertion_point_); + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_insertion_point(), + GetArena()); } content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_content()) { - content_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.content_); + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_content(), + GetArena()); + } + if (from._internal_has_generated_code_info()) { + generated_code_info_ = new PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(*from.generated_code_info_); + } else { + generated_code_info_ = nullptr; } // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } @@ -909,19 +973,29 @@ void CodeGeneratorResponse_File::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + generated_code_info_ = nullptr; } CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void CodeGeneratorResponse_File::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); insertion_point_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); content_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + if (this != internal_default_instance()) delete generated_code_info_; } +void CodeGeneratorResponse_File::ArenaDtor(void* object) { + CodeGeneratorResponse_File* _this = reinterpret_cast< CodeGeneratorResponse_File* >(object); + (void)_this; +} +void CodeGeneratorResponse_File::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void CodeGeneratorResponse_File::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -938,19 +1012,23 @@ void CodeGeneratorResponse_File::Clear() { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - name_.ClearNonDefaultToEmptyNoArena(); + name_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x00000002u) { - insertion_point_.ClearNonDefaultToEmptyNoArena(); + insertion_point_.ClearNonDefaultToEmpty(); } if (cached_has_bits & 0x00000004u) { - content_.ClearNonDefaultToEmptyNoArena(); + content_.ClearNonDefaultToEmpty(); + } + if (cached_has_bits & 0x00000008u) { + GOOGLE_DCHECK(generated_code_info_ != nullptr); + generated_code_info_->Clear(); } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -994,13 +1072,22 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* ptr, ::PROTOB CHK_(ptr); } else goto handle_unusual; continue; + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + case 16: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 130)) { + ptr = ctx->ParseMessage(_internal_mutable_generated_code_info(), ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; default: { handle_unusual: if ((tag & 7) == 4 || tag == 0) { ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1052,9 +1139,17 @@ ::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorResponse_File::_InternalSerialize( 15, this->_internal_content(), target); } + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + if (cached_has_bits & 0x00000008u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite:: + InternalWriteMessage( + 16, _Internal::generated_code_info(this), target, stream); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File) return target; @@ -1069,7 +1164,7 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { (void) cached_has_bits; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x0000000fu) { // optional string name = 1; if (cached_has_bits & 0x00000001u) { total_size += 1 + @@ -1091,6 +1186,13 @@ size_t CodeGeneratorResponse_File::ByteSizeLong() const { this->_internal_content()); } + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + if (cached_has_bits & 0x00000008u) { + total_size += 2 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize( + *generated_code_info_); + } + } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( @@ -1119,23 +1221,23 @@ void CodeGeneratorResponse_File::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Messag void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; cached_has_bits = from._has_bits_[0]; - if (cached_has_bits & 0x00000007u) { + if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - _has_bits_[0] |= 0x00000001u; - name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_); + _internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _has_bits_[0] |= 0x00000002u; - insertion_point_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.insertion_point_); + _internal_set_insertion_point(from._internal_insertion_point()); } if (cached_has_bits & 0x00000004u) { - _has_bits_[0] |= 0x00000004u; - content_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.content_); + _internal_set_content(from._internal_content()); + } + if (cached_has_bits & 0x00000008u) { + _internal_mutable_generated_code_info()->PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::MergeFrom(from._internal_generated_code_info()); } } } @@ -1160,14 +1262,12 @@ bool CodeGeneratorResponse_File::IsInitialized() const { void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - insertion_point_.Swap(&other->insertion_point_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - content_.Swap(&other->content_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + insertion_point_.Swap(&other->insertion_point_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + content_.Swap(&other->content_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + swap(generated_code_info_, other->generated_code_info_); } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() const { @@ -1177,48 +1277,61 @@ ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse_File::GetMetadata() cons // =================================================================== -void CodeGeneratorResponse::InitAsDefaultInstance() { -} class CodeGeneratorResponse::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); static void set_has_error(HasBits* has_bits) { (*has_bits)[0] |= 1u; } + static void set_has_supported_features(HasBits* has_bits) { + (*has_bits)[0] |= 2u; + } }; -CodeGeneratorResponse::CodeGeneratorResponse() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +CodeGeneratorResponse::CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena), + file_(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse) } CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), file_(from.file_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_error()) { - error_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.error_); + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_error(), + GetArena()); } + supported_features_ = from.supported_features_; // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse) } void CodeGeneratorResponse::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_CodeGeneratorResponse_google_2fprotobuf_2fcompiler_2fplugin_2eproto.base); error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + supported_features_ = PROTOBUF_ULONGLONG(0); } CodeGeneratorResponse::~CodeGeneratorResponse() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void CodeGeneratorResponse::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); error_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } +void CodeGeneratorResponse::ArenaDtor(void* object) { + CodeGeneratorResponse* _this = reinterpret_cast< CodeGeneratorResponse* >(object); + (void)_this; +} +void CodeGeneratorResponse::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void CodeGeneratorResponse::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -1237,10 +1350,11 @@ void CodeGeneratorResponse::Clear() { file_.Clear(); cached_has_bits = _has_bits_[0]; if (cached_has_bits & 0x00000001u) { - error_.ClearNonDefaultToEmptyNoArena(); + error_.ClearNonDefaultToEmpty(); } + supported_features_ = PROTOBUF_ULONGLONG(0); _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -1262,6 +1376,14 @@ const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NA CHK_(ptr); } else goto handle_unusual; continue; + // optional uint64 supported_features = 2; + case 2: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 16)) { + _Internal::set_has_supported_features(&has_bits); + supported_features_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; case 15: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 122)) { @@ -1280,7 +1402,9 @@ const char* CodeGeneratorResponse::_InternalParse(const char* ptr, ::PROTOBUF_NA ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1312,6 +1436,12 @@ ::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorResponse::_InternalSerialize( 1, this->_internal_error(), target); } + // optional uint64 supported_features = 2; + if (cached_has_bits & 0x00000002u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteUInt64ToArray(2, this->_internal_supported_features(), target); + } + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; for (unsigned int i = 0, n = static_cast(this->_internal_file_size()); i < n; i++) { @@ -1322,7 +1452,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* CodeGeneratorResponse::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse) return target; @@ -1343,14 +1473,23 @@ size_t CodeGeneratorResponse::ByteSizeLong() const { ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(msg); } - // optional string error = 1; cached_has_bits = _has_bits_[0]; - if (cached_has_bits & 0x00000001u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( - this->_internal_error()); - } + if (cached_has_bits & 0x00000003u) { + // optional string error = 1; + if (cached_has_bits & 0x00000001u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize( + this->_internal_error()); + } + + // optional uint64 supported_features = 2; + if (cached_has_bits & 0x00000002u) { + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::UInt64Size( + this->_internal_supported_features()); + } + } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { return ::PROTOBUF_NAMESPACE_ID::internal::ComputeUnknownFieldsSize( _internal_metadata_, total_size, &_cached_size_); @@ -1378,14 +1517,20 @@ void CodeGeneratorResponse::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& fr void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; file_.MergeFrom(from.file_); - if (from._internal_has_error()) { - _has_bits_[0] |= 0x00000001u; - error_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.error_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x00000001u) { + _internal_set_error(from._internal_error()); + } + if (cached_has_bits & 0x00000002u) { + supported_features_ = from.supported_features_; + } + _has_bits_[0] |= cached_has_bits; } } @@ -1409,11 +1554,11 @@ bool CodeGeneratorResponse::IsInitialized() const { void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); file_.InternalSwap(&other->file_); - error_.Swap(&other->error_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + error_.Swap(&other->error_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + swap(supported_features_, other->supported_features_); } ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse::GetMetadata() const { @@ -1426,16 +1571,16 @@ ::PROTOBUF_NAMESPACE_ID::Metadata CodeGeneratorResponse::GetMetadata() const { PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::compiler::Version* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::compiler::Version >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::compiler::Version >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::compiler::Version >(arena); } template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest >(arena); } template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >(arena); } template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 0fdf8c6ec9f0..6f48efa66289 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,12 +25,12 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export #include // IWYU pragma: export +#include #include #include // @@protoc_insertion_point(includes) @@ -52,7 +52,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -86,12 +86,35 @@ PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN namespace compiler { +enum CodeGeneratorResponse_Feature : int { + CodeGeneratorResponse_Feature_FEATURE_NONE = 0, + CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL = 1 +}; +PROTOC_EXPORT bool CodeGeneratorResponse_Feature_IsValid(int value); +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MIN = CodeGeneratorResponse_Feature_FEATURE_NONE; +constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MAX = CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL; +constexpr int CodeGeneratorResponse_Feature_Feature_ARRAYSIZE = CodeGeneratorResponse_Feature_Feature_MAX + 1; + +PROTOC_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor(); +template +inline const std::string& CodeGeneratorResponse_Feature_Name(T enum_t_value) { + static_assert(::std::is_same::value || + ::std::is_integral::value, + "Incorrect type passed to function CodeGeneratorResponse_Feature_Name."); + return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum( + CodeGeneratorResponse_Feature_descriptor(), enum_t_value); +} +inline bool CodeGeneratorResponse_Feature_Parse( + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, CodeGeneratorResponse_Feature* value) { + return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( + CodeGeneratorResponse_Feature_descriptor(), name, value); +} // =================================================================== -class PROTOC_EXPORT Version : +class PROTOC_EXPORT Version PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ { public: - Version(); + inline Version() : Version(nullptr) {} virtual ~Version(); Version(const Version& from); @@ -105,7 +128,7 @@ class PROTOC_EXPORT Version : return *this; } inline Version& operator=(Version&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -114,10 +137,10 @@ class PROTOC_EXPORT Version : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { @@ -131,7 +154,6 @@ class PROTOC_EXPORT Version : } static const Version& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Version* internal_default_instance() { return reinterpret_cast( &_Version_default_instance_); @@ -144,6 +166,15 @@ class PROTOC_EXPORT Version : } inline void Swap(Version* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(Version* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -178,13 +209,11 @@ class PROTOC_EXPORT Version : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.compiler.Version"; } + protected: + explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -269,7 +298,9 @@ class PROTOC_EXPORT Version : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr suffix_; @@ -280,10 +311,10 @@ class PROTOC_EXPORT Version : }; // ------------------------------------------------------------------- -class PROTOC_EXPORT CodeGeneratorRequest : +class PROTOC_EXPORT CodeGeneratorRequest PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ { public: - CodeGeneratorRequest(); + inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {} virtual ~CodeGeneratorRequest(); CodeGeneratorRequest(const CodeGeneratorRequest& from); @@ -297,7 +328,7 @@ class PROTOC_EXPORT CodeGeneratorRequest : return *this; } inline CodeGeneratorRequest& operator=(CodeGeneratorRequest&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -306,10 +337,10 @@ class PROTOC_EXPORT CodeGeneratorRequest : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { @@ -323,7 +354,6 @@ class PROTOC_EXPORT CodeGeneratorRequest : } static const CodeGeneratorRequest& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorRequest* internal_default_instance() { return reinterpret_cast( &_CodeGeneratorRequest_default_instance_); @@ -336,6 +366,15 @@ class PROTOC_EXPORT CodeGeneratorRequest : } inline void Swap(CodeGeneratorRequest* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(CodeGeneratorRequest* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -370,13 +409,11 @@ class PROTOC_EXPORT CodeGeneratorRequest : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.compiler.CodeGeneratorRequest"; } + protected: + explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -474,12 +511,17 @@ class PROTOC_EXPORT CodeGeneratorRequest : const PROTOBUF_NAMESPACE_ID::compiler::Version& _internal_compiler_version() const; PROTOBUF_NAMESPACE_ID::compiler::Version* _internal_mutable_compiler_version(); public: + void unsafe_arena_set_allocated_compiler_version( + PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version); + PROTOBUF_NAMESPACE_ID::compiler::Version* unsafe_arena_release_compiler_version(); // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField file_to_generate_; @@ -490,10 +532,10 @@ class PROTOC_EXPORT CodeGeneratorRequest : }; // ------------------------------------------------------------------- -class PROTOC_EXPORT CodeGeneratorResponse_File : +class PROTOC_EXPORT CodeGeneratorResponse_File PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ { public: - CodeGeneratorResponse_File(); + inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {} virtual ~CodeGeneratorResponse_File(); CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); @@ -507,7 +549,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File : return *this; } inline CodeGeneratorResponse_File& operator=(CodeGeneratorResponse_File&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -516,10 +558,10 @@ class PROTOC_EXPORT CodeGeneratorResponse_File : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { @@ -533,7 +575,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File : } static const CodeGeneratorResponse_File& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorResponse_File* internal_default_instance() { return reinterpret_cast( &_CodeGeneratorResponse_File_default_instance_); @@ -546,6 +587,15 @@ class PROTOC_EXPORT CodeGeneratorResponse_File : } inline void Swap(CodeGeneratorResponse_File* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(CodeGeneratorResponse_File* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -580,13 +630,11 @@ class PROTOC_EXPORT CodeGeneratorResponse_File : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse.File"; } + protected: + explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -606,6 +654,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File : kNameFieldNumber = 1, kInsertionPointFieldNumber = 2, kContentFieldNumber = 15, + kGeneratedCodeInfoFieldNumber = 16, }; // optional string name = 1; bool has_name() const; @@ -667,24 +716,45 @@ class PROTOC_EXPORT CodeGeneratorResponse_File : std::string* _internal_mutable_content(); public: + // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; + bool has_generated_code_info() const; + private: + bool _internal_has_generated_code_info() const; + public: + void clear_generated_code_info(); + const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info() const; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info(); + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* mutable_generated_code_info(); + void set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info); + private: + const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& _internal_generated_code_info() const; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _internal_mutable_generated_code_info(); + public: + void unsafe_arena_set_allocated_generated_code_info( + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info); + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* unsafe_arena_release_generated_code_info(); + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr insertion_point_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr content_; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info_; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; }; // ------------------------------------------------------------------- -class PROTOC_EXPORT CodeGeneratorResponse : +class PROTOC_EXPORT CodeGeneratorResponse PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ { public: - CodeGeneratorResponse(); + inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {} virtual ~CodeGeneratorResponse(); CodeGeneratorResponse(const CodeGeneratorResponse& from); @@ -698,7 +768,7 @@ class PROTOC_EXPORT CodeGeneratorResponse : return *this; } inline CodeGeneratorResponse& operator=(CodeGeneratorResponse&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -707,10 +777,10 @@ class PROTOC_EXPORT CodeGeneratorResponse : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { @@ -724,7 +794,6 @@ class PROTOC_EXPORT CodeGeneratorResponse : } static const CodeGeneratorResponse& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const CodeGeneratorResponse* internal_default_instance() { return reinterpret_cast( &_CodeGeneratorResponse_default_instance_); @@ -737,6 +806,15 @@ class PROTOC_EXPORT CodeGeneratorResponse : } inline void Swap(CodeGeneratorResponse* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(CodeGeneratorResponse* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -771,13 +849,11 @@ class PROTOC_EXPORT CodeGeneratorResponse : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse"; } + protected: + explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -793,11 +869,42 @@ class PROTOC_EXPORT CodeGeneratorResponse : typedef CodeGeneratorResponse_File File; + typedef CodeGeneratorResponse_Feature Feature; + static constexpr Feature FEATURE_NONE = + CodeGeneratorResponse_Feature_FEATURE_NONE; + static constexpr Feature FEATURE_PROTO3_OPTIONAL = + CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL; + static inline bool Feature_IsValid(int value) { + return CodeGeneratorResponse_Feature_IsValid(value); + } + static constexpr Feature Feature_MIN = + CodeGeneratorResponse_Feature_Feature_MIN; + static constexpr Feature Feature_MAX = + CodeGeneratorResponse_Feature_Feature_MAX; + static constexpr int Feature_ARRAYSIZE = + CodeGeneratorResponse_Feature_Feature_ARRAYSIZE; + static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* + Feature_descriptor() { + return CodeGeneratorResponse_Feature_descriptor(); + } + template + static inline const std::string& Feature_Name(T enum_t_value) { + static_assert(::std::is_same::value || + ::std::is_integral::value, + "Incorrect type passed to function Feature_Name."); + return CodeGeneratorResponse_Feature_Name(enum_t_value); + } + static inline bool Feature_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, + Feature* value) { + return CodeGeneratorResponse_Feature_Parse(name, value); + } + // accessors ------------------------------------------------------- enum : int { kFileFieldNumber = 15, kErrorFieldNumber = 1, + kSupportedFeaturesFieldNumber = 2, }; // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; int file_size() const; @@ -837,15 +944,31 @@ class PROTOC_EXPORT CodeGeneratorResponse : std::string* _internal_mutable_error(); public: + // optional uint64 supported_features = 2; + bool has_supported_features() const; + private: + bool _internal_has_supported_features() const; + public: + void clear_supported_features(); + ::PROTOBUF_NAMESPACE_ID::uint64 supported_features() const; + void set_supported_features(::PROTOBUF_NAMESPACE_ID::uint64 value); + private: + ::PROTOBUF_NAMESPACE_ID::uint64 _internal_supported_features() const; + void _internal_set_supported_features(::PROTOBUF_NAMESPACE_ID::uint64 value); + public: + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File > file_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_; + ::PROTOBUF_NAMESPACE_ID::uint64 supported_features_; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; }; // =================================================================== @@ -952,7 +1075,7 @@ inline bool Version::has_suffix() const { return _internal_has_suffix(); } inline void Version::clear_suffix() { - suffix_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + suffix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& Version::suffix() const { @@ -968,33 +1091,34 @@ inline std::string* Version::mutable_suffix() { return _internal_mutable_suffix(); } inline const std::string& Version::_internal_suffix() const { - return suffix_.GetNoArena(); + return suffix_.Get(); } inline void Version::_internal_set_suffix(const std::string& value) { _has_bits_[0] |= 0x00000001u; - suffix_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Version::set_suffix(std::string&& value) { _has_bits_[0] |= 0x00000001u; - suffix_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + suffix_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.Version.suffix) } inline void Version::set_suffix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - suffix_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix) } -inline void Version::set_suffix(const char* value, size_t size) { +inline void Version::set_suffix(const char* value, + size_t size) { _has_bits_[0] |= 0x00000001u; - suffix_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.Version.suffix) } inline std::string* Version::_internal_mutable_suffix() { _has_bits_[0] |= 0x00000001u; - return suffix_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return suffix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Version::release_suffix() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix) @@ -1002,7 +1126,7 @@ inline std::string* Version::release_suffix() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return suffix_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return suffix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Version::set_allocated_suffix(std::string* suffix) { if (suffix != nullptr) { @@ -1010,7 +1134,8 @@ inline void Version::set_allocated_suffix(std::string* suffix) { } else { _has_bits_[0] &= ~0x00000001u; } - suffix_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), suffix); + suffix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), suffix, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix) } @@ -1101,7 +1226,7 @@ inline bool CodeGeneratorRequest::has_parameter() const { return _internal_has_parameter(); } inline void CodeGeneratorRequest::clear_parameter() { - parameter_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + parameter_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorRequest::parameter() const { @@ -1117,33 +1242,34 @@ inline std::string* CodeGeneratorRequest::mutable_parameter() { return _internal_mutable_parameter(); } inline const std::string& CodeGeneratorRequest::_internal_parameter() const { - return parameter_.GetNoArena(); + return parameter_.Get(); } inline void CodeGeneratorRequest::_internal_set_parameter(const std::string& value) { _has_bits_[0] |= 0x00000001u; - parameter_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorRequest::set_parameter(std::string&& value) { _has_bits_[0] |= 0x00000001u; - parameter_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + parameter_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline void CodeGeneratorRequest::set_parameter(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - parameter_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter) } -inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) { +inline void CodeGeneratorRequest::set_parameter(const char* value, + size_t size) { _has_bits_[0] |= 0x00000001u; - parameter_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() { _has_bits_[0] |= 0x00000001u; - return parameter_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return parameter_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorRequest::release_parameter() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1151,7 +1277,7 @@ inline std::string* CodeGeneratorRequest::release_parameter() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return parameter_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return parameter_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter) { if (parameter != nullptr) { @@ -1159,7 +1285,8 @@ inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter } else { _has_bits_[0] &= ~0x00000001u; } - parameter_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), parameter); + parameter_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), parameter, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter) } @@ -1214,14 +1341,36 @@ inline void CodeGeneratorRequest::clear_compiler_version() { } inline const PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const { const PROTOBUF_NAMESPACE_ID::compiler::Version* p = compiler_version_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::compiler_version() const { // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) return _internal_compiler_version(); } +inline void CodeGeneratorRequest::unsafe_arena_set_allocated_compiler_version( + PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(compiler_version_); + } + compiler_version_ = compiler_version; + if (compiler_version) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) +} inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::release_compiler_version() { + _has_bits_[0] &= ~0x00000002u; + PROTOBUF_NAMESPACE_ID::compiler::Version* temp = compiler_version_; + compiler_version_ = nullptr; + if (GetArena() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + return temp; +} +inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::unsafe_arena_release_compiler_version() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) _has_bits_[0] &= ~0x00000002u; PROTOBUF_NAMESPACE_ID::compiler::Version* temp = compiler_version_; @@ -1231,7 +1380,7 @@ inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::release_c inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::_internal_mutable_compiler_version() { _has_bits_[0] |= 0x00000002u; if (compiler_version_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); compiler_version_ = p; } return compiler_version_; @@ -1241,12 +1390,13 @@ inline PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::mutable_c return _internal_mutable_compiler_version(); } inline void CodeGeneratorRequest::set_allocated_compiler_version(PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete compiler_version_; } if (compiler_version) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(compiler_version); if (message_arena != submessage_arena) { compiler_version = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, compiler_version, submessage_arena); @@ -1272,7 +1422,7 @@ inline bool CodeGeneratorResponse_File::has_name() const { return _internal_has_name(); } inline void CodeGeneratorResponse_File::clear_name() { - name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorResponse_File::name() const { @@ -1288,33 +1438,34 @@ inline std::string* CodeGeneratorResponse_File::mutable_name() { return _internal_mutable_name(); } inline const std::string& CodeGeneratorResponse_File::_internal_name() const { - return name_.GetNoArena(); + return name_.Get(); } inline void CodeGeneratorResponse_File::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse_File::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; - name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + name_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline void CodeGeneratorResponse_File::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name) } -inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) { +inline void CodeGeneratorResponse_File::set_name(const char* value, + size_t size) { _has_bits_[0] |= 0x00000001u; - name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse_File::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1322,7 +1473,7 @@ inline std::string* CodeGeneratorResponse_File::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1330,7 +1481,8 @@ inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) { } else { _has_bits_[0] &= ~0x00000001u; } - name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name); + name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name) } @@ -1343,7 +1495,7 @@ inline bool CodeGeneratorResponse_File::has_insertion_point() const { return _internal_has_insertion_point(); } inline void CodeGeneratorResponse_File::clear_insertion_point() { - insertion_point_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + insertion_point_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& CodeGeneratorResponse_File::insertion_point() const { @@ -1359,33 +1511,34 @@ inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() { return _internal_mutable_insertion_point(); } inline const std::string& CodeGeneratorResponse_File::_internal_insertion_point() const { - return insertion_point_.GetNoArena(); + return insertion_point_.Get(); } inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const std::string& value) { _has_bits_[0] |= 0x00000002u; - insertion_point_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse_File::set_insertion_point(std::string&& value) { _has_bits_[0] |= 0x00000002u; - insertion_point_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + insertion_point_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - insertion_point_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } -inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) { +inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, + size_t size) { _has_bits_[0] |= 0x00000002u; - insertion_point_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_point() { _has_bits_[0] |= 0x00000002u; - return insertion_point_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return insertion_point_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse_File::release_insertion_point() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1393,7 +1546,7 @@ inline std::string* CodeGeneratorResponse_File::release_insertion_point() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - return insertion_point_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return insertion_point_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::string* insertion_point) { if (insertion_point != nullptr) { @@ -1401,7 +1554,8 @@ inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::strin } else { _has_bits_[0] &= ~0x00000002u; } - insertion_point_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), insertion_point); + insertion_point_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), insertion_point, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } @@ -1414,7 +1568,7 @@ inline bool CodeGeneratorResponse_File::has_content() const { return _internal_has_content(); } inline void CodeGeneratorResponse_File::clear_content() { - content_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + content_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& CodeGeneratorResponse_File::content() const { @@ -1430,33 +1584,34 @@ inline std::string* CodeGeneratorResponse_File::mutable_content() { return _internal_mutable_content(); } inline const std::string& CodeGeneratorResponse_File::_internal_content() const { - return content_.GetNoArena(); + return content_.Get(); } inline void CodeGeneratorResponse_File::_internal_set_content(const std::string& value) { _has_bits_[0] |= 0x00000004u; - content_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse_File::set_content(std::string&& value) { _has_bits_[0] |= 0x00000004u; - content_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + content_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline void CodeGeneratorResponse_File::set_content(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - content_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content) } -inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) { +inline void CodeGeneratorResponse_File::set_content(const char* value, + size_t size) { _has_bits_[0] |= 0x00000004u; - content_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() { _has_bits_[0] |= 0x00000004u; - return content_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return content_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse_File::release_content() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1464,7 +1619,7 @@ inline std::string* CodeGeneratorResponse_File::release_content() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - return content_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return content_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void CodeGeneratorResponse_File::set_allocated_content(std::string* content) { if (content != nullptr) { @@ -1472,10 +1627,90 @@ inline void CodeGeneratorResponse_File::set_allocated_content(std::string* conte } else { _has_bits_[0] &= ~0x00000004u; } - content_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), content); + content_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), content, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content) } +// optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; +inline bool CodeGeneratorResponse_File::_internal_has_generated_code_info() const { + bool value = (_has_bits_[0] & 0x00000008u) != 0; + PROTOBUF_ASSUME(!value || generated_code_info_ != nullptr); + return value; +} +inline bool CodeGeneratorResponse_File::has_generated_code_info() const { + return _internal_has_generated_code_info(); +} +inline const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::_internal_generated_code_info() const { + const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* p = generated_code_info_; + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_); +} +inline const PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::generated_code_info() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) + return _internal_generated_code_info(); +} +inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_generated_code_info( + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_); + } + generated_code_info_ = generated_code_info; + if (generated_code_info) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::release_generated_code_info() { + _has_bits_[0] &= ~0x00000008u; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_; + generated_code_info_ = nullptr; + if (GetArena() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + return temp; +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) + _has_bits_[0] &= ~0x00000008u; + PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = generated_code_info_; + generated_code_info_ = nullptr; + return temp; +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() { + _has_bits_[0] |= 0x00000008u; + if (generated_code_info_ == nullptr) { + auto* p = CreateMaybeMessage(GetArena()); + generated_code_info_ = p; + } + return generated_code_info_; +} +inline PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) + return _internal_mutable_generated_code_info(); +} +inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) { + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); + if (message_arena == nullptr) { + delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info_); + } + if (generated_code_info) { + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info)->GetArena(); + if (message_arena != submessage_arena) { + generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( + message_arena, generated_code_info, submessage_arena); + } + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + generated_code_info_ = generated_code_info; + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) +} + // ------------------------------------------------------------------- // CodeGeneratorResponse @@ -1489,7 +1724,7 @@ inline bool CodeGeneratorResponse::has_error() const { return _internal_has_error(); } inline void CodeGeneratorResponse::clear_error() { - error_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + error_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorResponse::error() const { @@ -1505,33 +1740,34 @@ inline std::string* CodeGeneratorResponse::mutable_error() { return _internal_mutable_error(); } inline const std::string& CodeGeneratorResponse::_internal_error() const { - return error_.GetNoArena(); + return error_.Get(); } inline void CodeGeneratorResponse::_internal_set_error(const std::string& value) { _has_bits_[0] |= 0x00000001u; - error_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse::set_error(std::string&& value) { _has_bits_[0] |= 0x00000001u; - error_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + error_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.error) } inline void CodeGeneratorResponse::set_error(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - error_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error) } -inline void CodeGeneratorResponse::set_error(const char* value, size_t size) { +inline void CodeGeneratorResponse::set_error(const char* value, + size_t size) { _has_bits_[0] |= 0x00000001u; - error_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error) } inline std::string* CodeGeneratorResponse::_internal_mutable_error() { _has_bits_[0] |= 0x00000001u; - return error_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return error_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse::release_error() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error) @@ -1539,7 +1775,7 @@ inline std::string* CodeGeneratorResponse::release_error() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return error_.ReleaseNonDefaultNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return error_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void CodeGeneratorResponse::set_allocated_error(std::string* error) { if (error != nullptr) { @@ -1547,10 +1783,39 @@ inline void CodeGeneratorResponse::set_allocated_error(std::string* error) { } else { _has_bits_[0] &= ~0x00000001u; } - error_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error); + error_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), error, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error) } +// optional uint64 supported_features = 2; +inline bool CodeGeneratorResponse::_internal_has_supported_features() const { + bool value = (_has_bits_[0] & 0x00000002u) != 0; + return value; +} +inline bool CodeGeneratorResponse::has_supported_features() const { + return _internal_has_supported_features(); +} +inline void CodeGeneratorResponse::clear_supported_features() { + supported_features_ = PROTOBUF_ULONGLONG(0); + _has_bits_[0] &= ~0x00000002u; +} +inline ::PROTOBUF_NAMESPACE_ID::uint64 CodeGeneratorResponse::_internal_supported_features() const { + return supported_features_; +} +inline ::PROTOBUF_NAMESPACE_ID::uint64 CodeGeneratorResponse::supported_features() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.supported_features) + return _internal_supported_features(); +} +inline void CodeGeneratorResponse::_internal_set_supported_features(::PROTOBUF_NAMESPACE_ID::uint64 value) { + _has_bits_[0] |= 0x00000002u; + supported_features_ = value; +} +inline void CodeGeneratorResponse::set_supported_features(::PROTOBUF_NAMESPACE_ID::uint64 value) { + _internal_set_supported_features(value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.supported_features) +} + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; inline int CodeGeneratorResponse::_internal_file_size() const { return file_.size(); @@ -1605,6 +1870,16 @@ CodeGeneratorResponse::file() const { } // namespace compiler PROTOBUF_NAMESPACE_CLOSE +PROTOBUF_NAMESPACE_OPEN + +template <> struct is_proto_enum< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature> : ::std::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature>() { + return PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature_descriptor(); +} + +PROTOBUF_NAMESPACE_CLOSE + // @@protoc_insertion_point(global_scope) #include diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index 665e5a725d8c..9242aacc5bd9 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -50,7 +50,7 @@ package google.protobuf.compiler; option java_package = "com.google.protobuf.compiler"; option java_outer_classname = "PluginProtos"; -option go_package = "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go"; +option go_package = "google.golang.org/protobuf/types/pluginpb"; import "google/protobuf/descriptor.proto"; @@ -107,6 +107,16 @@ message CodeGeneratorResponse { // exiting with a non-zero status code. optional string error = 1; + // A bitmask of supported features that the code generator supports. + // This is a bitwise "or" of values from the Feature enum. + optional uint64 supported_features = 2; + + // Sync with code_generator.h. + enum Feature { + FEATURE_NONE = 0; + FEATURE_PROTO3_OPTIONAL = 1; + } + // Represents a single generated file. message File { // The file name, relative to the output directory. The name must not @@ -163,6 +173,11 @@ message CodeGeneratorResponse { // The file contents. optional string content = 15; + + // Information describing the file content being inserted. If an insertion + // point is used, this information will be appropriately offset and inserted + // into the code generation metadata for the generated files. + optional GeneratedCodeInfo generated_code_info = 16; } repeated File file = 15; } diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index b20f3fb27dae..d849fa6eee6f 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -69,19 +69,6 @@ namespace python { namespace { -bool StrEndsWith(StringPiece sp, StringPiece x) { - return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x; -} - -// Returns a copy of |filename| with any trailing ".protodevel" or ".proto -// suffix stripped. -// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc. -std::string StripProto(const std::string& filename) { - const char* suffix = - StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto"; - return StripSuffixString(filename, suffix); -} - // Returns the Python module name expected for a given .proto filename. std::string ModuleName(const std::string& filename) { std::string basename = StripProto(filename); @@ -106,11 +93,12 @@ std::string ModuleAlias(const std::string& filename) { // Keywords reserved by the Python language. const char* const kKeywords[] = { - "False", "None", "True", "and", "as", "assert", "break", - "class", "continue", "def", "del", "elif", "else", "except", - "finally", "for", "from", "global", "if", "import", "in", - "is", "lambda", "nonlocal", "not", "or", "pass", "raise", - "return", "try", "while", "with", "yield", "print", + "False", "None", "True", "and", "as", "assert", + "async", "await", "break", "class", "continue", "def", + "del", "elif", "else", "except", "finally", "for", + "from", "global", "if", "import", "in", "is", + "lambda", "nonlocal", "not", "or", "pass", "raise", + "return", "try", "while", "with", "yield", "print", }; const char* const* kKeywordsEnd = kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0])); @@ -125,7 +113,7 @@ bool ContainsPythonKeyword(const std::string& module_name) { return false; } -inline bool IsPythonKeyword(const string& name) { +inline bool IsPythonKeyword(const std::string& name) { return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd); } @@ -183,7 +171,7 @@ void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file, "# -*- coding: utf-8 -*-\n" "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" "# source: $filename$\n" - "\n", + "\"\"\"Generated protocol buffer code.\"\"\"\n", "filename", file->name()); if (HasTopLevelEnums(file)) { printer->Print( @@ -301,6 +289,10 @@ Generator::Generator() : file_(nullptr) {} Generator::~Generator() {} +uint64_t Generator::GetSupportedFeatures() const { + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; +} + bool Generator::Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* context, std::string* error) const { @@ -441,7 +433,8 @@ void Generator::PrintFileDescriptor() const { " name='$name$',\n" " package='$package$',\n" " syntax='$syntax$',\n" - " serialized_options=$options$,\n"; + " serialized_options=$options$,\n" + " create_key=_descriptor._internal_create_key,\n"; printer_->Print(m, file_descriptor_template); printer_->Indent(); if (pure_python_workable_) { @@ -531,6 +524,7 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { " full_name='$full_name$',\n" " filename=None,\n" " file=$file$,\n" + " create_key=_descriptor._internal_create_key,\n" " values=[\n"; std::string options_string; enum_descriptor.options().SerializeToString(&options_string); @@ -578,7 +572,7 @@ void Generator::PrintTopLevelExtensions() const { for (int i = 0; i < file_->extension_count(); ++i) { const FieldDescriptor& extension_field = *file_->extension(i); std::string constant_name = extension_field.name() + "_FIELD_NUMBER"; - UpperString(&constant_name); + ToUpper(&constant_name); printer_->Print("$constant_name$ = $number$\n", "constant_name", constant_name, "number", StrCat(extension_field.number())); @@ -635,7 +629,8 @@ void Generator::PrintServiceDescriptor( "full_name='$full_name$',\n" "file=$file$,\n" "index=$index$,\n" - "serialized_options=$options_value$,\n"; + "serialized_options=$options_value$,\n" + "create_key=_descriptor._internal_create_key,\n"; printer_->Print(m, required_function_arguments); ServiceDescriptorProto sdp; @@ -663,7 +658,8 @@ void Generator::PrintServiceDescriptor( "containing_service=None,\n" "input_type=$input_type$,\n" "output_type=$output_type$,\n" - "serialized_options=$options_value$,\n"); + "serialized_options=$options_value$,\n" + "create_key=_descriptor._internal_create_key,\n"); printer_->Outdent(); printer_->Print("),\n"); } @@ -733,7 +729,8 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { "full_name='$full_name$',\n" "filename=None,\n" "file=$file$,\n" - "containing_type=None,\n"; + "containing_type=None,\n" + "create_key=_descriptor._internal_create_key,\n"; printer_->Print(m, required_function_arguments); PrintFieldsInDescriptor(message_descriptor); PrintExtensionsInDescriptor(message_descriptor); @@ -796,7 +793,8 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { printer_->Print(m, "_descriptor.OneofDescriptor(\n" " name='$name$', full_name='$full_name$',\n" - " index=$index$, containing_type=None, " + " index=$index$, containing_type=None,\n" + " create_key=_descriptor._internal_create_key,\n" "fields=[]$serialized_options$),\n"); } printer_->Outdent(); @@ -1037,8 +1035,8 @@ std::string Generator::FieldReferencingExpression( return ResolveKeyword(field.name()); } return strings::Substitute("$0.$1['$2']", - ModuleLevelDescriptorName(*containing_type), - python_dict_name, field.name()); + ModuleLevelDescriptorName(*containing_type), + python_dict_name, field.name()); } // Prints containing_type for nested descriptors or enum descriptors. @@ -1056,7 +1054,7 @@ void Generator::FixContainingTypeInDescriptor( } // Prints statements setting the message_type and enum_type fields in the -// Python descriptor objects we've already output in ths file. We must +// Python descriptor objects we've already output in the file. We must // do this in a separate step due to circular references (otherwise, we'd // just set everything in the initial assignment statements). void Generator::FixForeignFieldsInDescriptors() const { @@ -1144,7 +1142,8 @@ void Generator::PrintEnumValueDescriptor( "_descriptor.EnumValueDescriptor(\n" " name='$name$', index=$index$, number=$number$,\n" " serialized_options=$options$,\n" - " type=None)"); + " type=None,\n" + " create_key=_descriptor._internal_create_key)"); } // Returns a CEscaped string of serialized_options. @@ -1187,7 +1186,8 @@ void Generator::PrintFieldDescriptor(const FieldDescriptor& field, "default_value=$default_value$,\n" " message_type=None, enum_type=None, containing_type=None,\n" " is_extension=$is_extension$, extension_scope=None,\n" - " serialized_options=$serialized_options$$json_name$, file=DESCRIPTOR)"; + " serialized_options=$serialized_options$$json_name$, file=DESCRIPTOR," + " create_key=_descriptor._internal_create_key)"; printer_->Print(m, field_descriptor_decl); } @@ -1250,7 +1250,7 @@ std::string Generator::ModuleLevelDescriptorName( // The C++ implementation doesn't guard against this either. Leaving // it for now... std::string name = NamePrefixedWithNestedTypes(descriptor, "_"); - UpperString(&name); + ToUpper(&name); // Module-private for now. Easy to make public later; almost impossible // to make private later. name = "_" + name; @@ -1280,7 +1280,7 @@ std::string Generator::ModuleLevelMessageName( std::string Generator::ModuleLevelServiceDescriptorName( const ServiceDescriptor& descriptor) const { std::string name = descriptor.name(); - UpperString(&name); + ToUpper(&name); name = "_" + name; if (descriptor.file() != file_) { name = ModuleAlias(descriptor.file()->name()) + "." + name; diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h index 6f299e850738..ed1c99504ca6 100644 --- a/src/google/protobuf/compiler/python/python_generator.h +++ b/src/google/protobuf/compiler/python/python_generator.h @@ -69,10 +69,11 @@ class PROTOC_EXPORT Generator : public CodeGenerator { virtual ~Generator(); // CodeGenerator methods. - virtual bool Generate(const FileDescriptor* file, - const std::string& parameter, - GeneratorContext* generator_context, - std::string* error) const; + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + + uint64_t GetSupportedFeatures() const override; private: void PrintImports() const; diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index 8c0aed1c71b1..ebc972c14856 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -77,6 +77,10 @@ std::string GetOutputFilename(const std::string& proto_file) { } std::string LabelForField(const FieldDescriptor* field) { + if (field->has_optional_keyword() && + field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { + return "proto3_optional"; + } switch (field->label()) { case FieldDescriptor::LABEL_OPTIONAL: return "optional"; case FieldDescriptor::LABEL_REQUIRED: return "required"; @@ -109,7 +113,7 @@ std::string TypeName(const FieldDescriptor* field) { } } -string StringifySyntax(FileDescriptor::Syntax syntax) { +std::string StringifySyntax(FileDescriptor::Syntax syntax) { switch (syntax) { case FileDescriptor::SYNTAX_PROTO2: return "proto2"; @@ -143,7 +147,7 @@ std::string DefaultValueForField(const FieldDescriptor* field) { return NumberToString(field->default_value_enum()->number()); case FieldDescriptor::CPPTYPE_STRING: { std::ostringstream os; - string default_str = field->default_value_string(); + std::string default_str = field->default_value_string(); if (field->type() == FieldDescriptor::TYPE_STRING) { os << "\"" << default_str << "\""; @@ -255,12 +259,12 @@ bool GenerateMessage(const Descriptor* message, io::Printer* printer, for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); - if (!field->containing_oneof()) { + if (!field->real_containing_oneof()) { GenerateField(field, printer); } } - for (int i = 0; i < message->oneof_decl_count(); i++) { + for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); GenerateOneof(oneof, printer); } @@ -409,7 +413,7 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { // If :: is in the package use the Ruby formatted name as-is // -> A::B::C - // otherwise, use the dot seperator + // otherwise, use the dot separator // -> A.B.C if (package_name.find("::") != std::string::npos) { need_change_to_module = false; @@ -422,14 +426,14 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { } // Use the appropriate delimiter - string delimiter = need_change_to_module ? "." : "::"; + std::string delimiter = need_change_to_module ? "." : "::"; int delimiter_size = need_change_to_module ? 1 : 2; // Extract each module name and indent while (!package_name.empty()) { size_t dot_index = package_name.find(delimiter); - string component; - if (dot_index == string::npos) { + std::string component; + if (dot_index == std::string::npos) { component = package_name; package_name = ""; } else { @@ -458,7 +462,7 @@ void EndPackageModules(int levels, io::Printer* printer) { } bool UsesTypeFromFile(const Descriptor* message, const FileDescriptor* file, - string* error) { + std::string* error) { for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && @@ -495,7 +499,7 @@ bool UsesTypeFromFile(const Descriptor* message, const FileDescriptor* file, bool MaybeEmitDependency(const FileDescriptor* import, const FileDescriptor* from, io::Printer* printer, - string* error) { + std::string* error) { if (from->syntax() == FileDescriptor::SYNTAX_PROTO3 && import->syntax() == FileDescriptor::SYNTAX_PROTO2) { for (int i = 0; i < from->message_type_count(); i++) { @@ -520,7 +524,7 @@ bool MaybeEmitDependency(const FileDescriptor* import, } bool GenerateFile(const FileDescriptor* file, io::Printer* printer, - string* error) { + std::string* error) { printer->Print( "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" "# source: $filename$\n" @@ -576,9 +580,9 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, bool Generator::Generate( const FileDescriptor* file, - const string& parameter, + const std::string& parameter, GeneratorContext* generator_context, - string* error) const { + std::string* error) const { if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 && file->syntax() != FileDescriptor::SYNTAX_PROTO2) { diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.h b/src/google/protobuf/compiler/ruby/ruby_generator.h index 731a81a52d7a..647bb836065a 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.h +++ b/src/google/protobuf/compiler/ruby/ruby_generator.h @@ -49,11 +49,12 @@ namespace ruby { // Ruby output, you can do so by registering an instance of this // CodeGenerator with the CommandLineInterface in your main() function. class PROTOC_EXPORT Generator : public CodeGenerator { - virtual bool Generate( - const FileDescriptor* file, - const string& parameter, - GeneratorContext* generator_context, - string* error) const; + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const override; + uint64_t GetSupportedFeatures() const override { + return FEATURE_PROTO3_OPTIONAL; + } }; } // namespace ruby @@ -64,4 +65,3 @@ class PROTOC_EXPORT Generator : public CodeGenerator { #include #endif // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__ - diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index d93a68d9afd1..27439a737bba 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -46,7 +46,7 @@ namespace compiler { namespace ruby { namespace { -string FindRubyTestDir() { +std::string FindRubyTestDir() { return TestSourceDir() + "/google/protobuf/compiler/ruby"; } @@ -58,7 +58,7 @@ string FindRubyTestDir() { // extensions to the point where we can do this test in a more automated way. void RubyTest(string proto_file) { - string ruby_tests = FindRubyTestDir(); + std::string ruby_tests = FindRubyTestDir(); google::protobuf::compiler::CommandLineInterface cli; cli.SetInputsAreProtoPathRelative(true); @@ -67,7 +67,7 @@ void RubyTest(string proto_file) { cli.RegisterGenerator("--ruby_out", &ruby_generator, ""); // Copy generated_code.proto to the temporary test directory. - string test_input; + std::string test_input; GOOGLE_CHECK_OK(File::GetContents( ruby_tests + proto_file + ".proto", &test_input, @@ -78,9 +78,9 @@ void RubyTest(string proto_file) { true)); // Invoke the proto compiler (we will be inside TestTempDir() at this point). - string ruby_out = "--ruby_out=" + TestTempDir(); - string proto_path = "--proto_path=" + TestTempDir(); - string proto_target = TestTempDir() + proto_file + ".proto"; + std::string ruby_out = "--ruby_out=" + TestTempDir(); + std::string proto_path = "--proto_path=" + TestTempDir(); + std::string proto_target = TestTempDir() + proto_file + ".proto"; const char* argv[] = { "protoc", ruby_out.c_str(), @@ -91,12 +91,12 @@ void RubyTest(string proto_file) { EXPECT_EQ(0, cli.Run(4, argv)); // Load the generated output and compare to the expected result. - string output; + std::string output; GOOGLE_CHECK_OK(File::GetContentsAsText( TestTempDir() + proto_file + "_pb.rb", &output, true)); - string expected_output; + std::string expected_output; GOOGLE_CHECK_OK(File::GetContentsAsText( ruby_tests + proto_file + "_pb.rb", &expected_output, diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc index bd6be2b09bb0..7e59cd7d8d26 100644 --- a/src/google/protobuf/compiler/subprocess.cc +++ b/src/google/protobuf/compiler/subprocess.cc @@ -255,8 +255,7 @@ bool Subprocess::Communicate(const Message& input, Message* output, child_handle_ = NULL; if (exit_code != 0) { - *error = - strings::Substitute("Plugin failed with status code $0.", exit_code); + *error = strings::Substitute("Plugin failed with status code $0.", exit_code); return false; } @@ -274,7 +273,7 @@ std::string Subprocess::Win32ErrorMessage(DWORD error_code) { // WTF? FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error_code, 0, + NULL, error_code, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPSTR)&message, // NOT A BUG! 0, NULL); diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc index 872dd9edd6fd..5ae026154b20 100644 --- a/src/google/protobuf/compiler/zip_writer.cc +++ b/src/google/protobuf/compiler/zip_writer.cc @@ -28,36 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. - // Author: ambrose@google.com (Ambrose Feinstein), // kenton@google.com (Kenton Varda) // diff --git a/src/google/protobuf/compiler/zip_writer.h b/src/google/protobuf/compiler/zip_writer.h index a99bb78ce7c7..3a8903a3f34c 100644 --- a/src/google/protobuf/compiler/zip_writer.h +++ b/src/google/protobuf/compiler/zip_writer.h @@ -28,36 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. - // Author: kenton@google.com (Kenton Varda) #include diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 80a12fc85418..7af37c57f309 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -254,14 +255,14 @@ std::string ToCamelCase(const std::string& input, bool lower_first) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { capitalize_next = true; } else if (capitalize_next) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); capitalize_next = false; } else { - result.push_back(input[i]); + result.push_back(character); } } @@ -278,14 +279,14 @@ std::string ToJsonName(const std::string& input) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { capitalize_next = true; } else if (capitalize_next) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); capitalize_next = false; } else { - result.push_back(input[i]); + result.push_back(character); } } @@ -297,14 +298,14 @@ std::string EnumValueToPascalCase(const std::string& input) { std::string result; result.reserve(input.size()); - for (int i = 0; i < input.size(); i++) { - if (input[i] == '_') { + for (char character : input) { + if (character == '_') { next_upper = true; } else { if (next_upper) { - result.push_back(ToUpper(input[i])); + result.push_back(ToUpper(character)); } else { - result.push_back(ToLower(input[i])); + result.push_back(ToLower(character)); } next_upper = false; } @@ -318,9 +319,9 @@ class PrefixRemover { public: PrefixRemover(StringPiece prefix) { // Strip underscores and lower-case the prefix. - for (int i = 0; i < prefix.size(); i++) { - if (prefix[i] != '_') { - prefix_ += ascii_tolower(prefix[i]); + for (char character : prefix) { + if (character != '_') { + prefix_ += ascii_tolower(character); } } } @@ -383,19 +384,8 @@ class PrefixRemover { // hash-maps for each object. // // The keys to these hash-maps are (parent, name) or (parent, number) pairs. -// -// TODO(kenton): Use StringPiece rather than const char* in keys? It would -// be a lot cleaner but we'd just have to convert it back to const char* -// for the open source release. - -typedef std::pair PointerStringPair; -struct PointerStringPairEqual { - inline bool operator()(const PointerStringPair& a, - const PointerStringPair& b) const { - return a.first == b.first && strcmp(a.second, b.second) == 0; - } -}; +typedef std::pair PointerStringPair; typedef std::pair DescriptorIntPair; typedef std::pair EnumIntPair; @@ -419,16 +409,16 @@ struct PointerIntegerPairHash { static const size_t min_buckets = 8; #endif inline bool operator()(const PairType& a, const PairType& b) const { - return a.first < b.first || (a.first == b.first && a.second < b.second); + return a < b; } }; struct PointerStringPairHash { size_t operator()(const PointerStringPair& p) const { static const size_t prime = 16777619; - hash cstring_hash; + hash string_hash; return reinterpret_cast(p.first) * prime ^ - static_cast(cstring_hash(p.second)); + static_cast(string_hash(p.second)); } #ifdef _MSC_VER @@ -438,28 +428,25 @@ struct PointerStringPairHash { #endif inline bool operator()(const PointerStringPair& a, const PointerStringPair& b) const { - if (a.first < b.first) return true; - if (a.first > b.first) return false; - return strcmp(a.second, b.second) < 0; + return a < b; } }; const Symbol kNullSymbol; -typedef HASH_MAP, streq> +typedef HASH_MAP> SymbolsByNameMap; -typedef HASH_MAP +typedef HASH_MAP SymbolsByParentMap; -typedef HASH_MAP, - streq> +typedef HASH_MAP> FilesByNameMap; typedef HASH_MAP + PointerStringPairHash> FieldsByNameMap; typedef HASH_MAP* NewAllowedProto3Extendee() { const char* kOptionNames[] = { "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions", "EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"}; - for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) { + for (const char* option_name : kOptionNames) { // descriptor.proto has a different package name in opensource. We allow // both so the opensource protocol compiler can also compile internal // proto3 files with custom options. See: b/27567912 allowed_proto3_extendees->insert(std::string("google.protobuf.") + - kOptionNames[i]); + option_name); // Split the word to trick the opensource processing scripts so they // will keep the original package name. - allowed_proto3_extendees->insert(std::string("proto") + "2." + - kOptionNames[i]); + allowed_proto3_extendees->insert(std::string("proto") + "2." + option_name); } return allowed_proto3_extendees; } @@ -579,21 +565,27 @@ class DescriptorPool::Tables { // set of extensions numbers from fallback_database_. HASH_SET extensions_loaded_from_db_; + // Maps type name to Descriptor::WellKnownType. This is logically global + // and const, but we make it a member here to simplify its construction and + // destruction. This only has 20-ish entries and is one per DescriptorPool, + // so the overhead is small. + HASH_MAP well_known_types_; + // ----------------------------------------------------------------- // Finding items. // Find symbols. This returns a null Symbol (symbol.IsNull() is true) // if not found. - inline Symbol FindSymbol(const std::string& key) const; + inline Symbol FindSymbol(StringPiece key) const; // This implements the body of DescriptorPool::Find*ByName(). It should // really be a private method of DescriptorPool, but that would require // declaring Symbol in descriptor.h, which would drag all kinds of other // stuff into the header. Yay C++. - Symbol FindByNameHelper(const DescriptorPool* pool, const std::string& name); + Symbol FindByNameHelper(const DescriptorPool* pool, StringPiece name); // These return nullptr if not found. - inline const FileDescriptor* FindFile(const std::string& key) const; + inline const FileDescriptor* FindFile(StringPiece key) const; inline const FieldDescriptor* FindExtension(const Descriptor* extendee, int number) const; inline void FindAllExtensions(const Descriptor* extendee, @@ -627,7 +619,7 @@ class DescriptorPool::Tables { // Allocate a string which will be destroyed when the pool is destroyed. // The string is initialized to the given value for convenience. - std::string* AllocateString(const std::string& value); + std::string* AllocateString(StringPiece value); // Allocate empty string which will be destroyed when the pool is destroyed. std::string* AllocateEmptyString(); @@ -649,7 +641,7 @@ class DescriptorPool::Tables { private: // All other memory allocated in the pool. Must be first as other objects can // point into these. - std::vector> allocations_; + std::vector> allocations_; std::vector> strings_; std::vector> messages_; std::vector> once_dynamics_; @@ -714,18 +706,18 @@ class FileDescriptorTables { // Find symbols. These return a null Symbol (symbol.IsNull() is true) // if not found. inline Symbol FindNestedSymbol(const void* parent, - const std::string& name) const; + StringPiece name) const; inline Symbol FindNestedSymbolOfType(const void* parent, - const std::string& name, + StringPiece name, const Symbol::Type type) const; // These return nullptr if not found. inline const FieldDescriptor* FindFieldByNumber(const Descriptor* parent, int number) const; inline const FieldDescriptor* FindFieldByLowercaseName( - const void* parent, const std::string& lowercase_name) const; + const void* parent, StringPiece lowercase_name) const; inline const FieldDescriptor* FindFieldByCamelcaseName( - const void* parent, const std::string& camelcase_name) const; + const void* parent, StringPiece camelcase_name) const; inline const EnumValueDescriptor* FindEnumValueByNumber( const EnumDescriptor* parent, int number) const; // This creates a new EnumValueDescriptor if not found, in a thread-safe way. @@ -800,7 +792,26 @@ DescriptorPool::Tables::Tables() known_bad_symbols_(3), extensions_loaded_from_db_(3), symbols_by_name_(3), - files_by_name_(3) {} + files_by_name_(3) { + well_known_types_.insert({ + {"google.protobuf.DoubleValue", Descriptor::WELLKNOWNTYPE_DOUBLEVALUE}, + {"google.protobuf.FloatValue", Descriptor::WELLKNOWNTYPE_FLOATVALUE}, + {"google.protobuf.Int64Value", Descriptor::WELLKNOWNTYPE_INT64VALUE}, + {"google.protobuf.UInt64Value", Descriptor::WELLKNOWNTYPE_UINT64VALUE}, + {"google.protobuf.Int32Value", Descriptor::WELLKNOWNTYPE_INT32VALUE}, + {"google.protobuf.UInt32Value", Descriptor::WELLKNOWNTYPE_UINT32VALUE}, + {"google.protobuf.StringValue", Descriptor::WELLKNOWNTYPE_STRINGVALUE}, + {"google.protobuf.BytesValue", Descriptor::WELLKNOWNTYPE_BYTESVALUE}, + {"google.protobuf.BoolValue", Descriptor::WELLKNOWNTYPE_BOOLVALUE}, + {"google.protobuf.Any", Descriptor::WELLKNOWNTYPE_ANY}, + {"google.protobuf.FieldMask", Descriptor::WELLKNOWNTYPE_FIELDMASK}, + {"google.protobuf.Duration", Descriptor::WELLKNOWNTYPE_DURATION}, + {"google.protobuf.Timestamp", Descriptor::WELLKNOWNTYPE_TIMESTAMP}, + {"google.protobuf.Value", Descriptor::WELLKNOWNTYPE_VALUE}, + {"google.protobuf.ListValue", Descriptor::WELLKNOWNTYPE_LISTVALUE}, + {"google.protobuf.Struct", Descriptor::WELLKNOWNTYPE_STRUCT}, + }); +} DescriptorPool::Tables::~Tables() { GOOGLE_DCHECK(checkpoints_.empty()); } @@ -844,15 +855,15 @@ void DescriptorPool::Tables::RollbackToLastCheckpoint() { GOOGLE_DCHECK(!checkpoints_.empty()); const CheckPoint& checkpoint = checkpoints_.back(); - for (int i = checkpoint.pending_symbols_before_checkpoint; + for (size_t i = checkpoint.pending_symbols_before_checkpoint; i < symbols_after_checkpoint_.size(); i++) { symbols_by_name_.erase(symbols_after_checkpoint_[i]); } - for (int i = checkpoint.pending_files_before_checkpoint; + for (size_t i = checkpoint.pending_files_before_checkpoint; i < files_after_checkpoint_.size(); i++) { files_by_name_.erase(files_after_checkpoint_[i]); } - for (int i = checkpoint.pending_extensions_before_checkpoint; + for (size_t i = checkpoint.pending_extensions_before_checkpoint; i < extensions_after_checkpoint_.size(); i++) { extensions_.erase(extensions_after_checkpoint_[i]); } @@ -873,8 +884,8 @@ void DescriptorPool::Tables::RollbackToLastCheckpoint() { // ------------------------------------------------------------------- -inline Symbol DescriptorPool::Tables::FindSymbol(const std::string& key) const { - const Symbol* result = FindOrNull(symbols_by_name_, key.c_str()); +inline Symbol DescriptorPool::Tables::FindSymbol(StringPiece key) const { + const Symbol* result = FindOrNull(symbols_by_name_, key); if (result == nullptr) { return kNullSymbol; } else { @@ -883,9 +894,9 @@ inline Symbol DescriptorPool::Tables::FindSymbol(const std::string& key) const { } inline Symbol FileDescriptorTables::FindNestedSymbol( - const void* parent, const std::string& name) const { - const Symbol* result = FindOrNull( - symbols_by_parent_, PointerStringPair(parent, name.c_str())); + const void* parent, StringPiece name) const { + const Symbol* result = + FindOrNull(symbols_by_parent_, PointerStringPair(parent, name)); if (result == nullptr) { return kNullSymbol; } else { @@ -894,15 +905,14 @@ inline Symbol FileDescriptorTables::FindNestedSymbol( } inline Symbol FileDescriptorTables::FindNestedSymbolOfType( - const void* parent, const std::string& name, - const Symbol::Type type) const { + const void* parent, StringPiece name, const Symbol::Type type) const { Symbol result = FindNestedSymbol(parent, name); if (result.type != type) return kNullSymbol; return result; } Symbol DescriptorPool::Tables::FindByNameHelper(const DescriptorPool* pool, - const std::string& name) { + StringPiece name) { if (pool->mutex_ != nullptr) { // Fast path: the Symbol is already cached. This is just a hash lookup. ReaderMutexLock lock(pool->mutex_); @@ -934,8 +944,8 @@ Symbol DescriptorPool::Tables::FindByNameHelper(const DescriptorPool* pool, } inline const FileDescriptor* DescriptorPool::Tables::FindFile( - const std::string& key) const { - return FindPtrOrNull(files_by_name_, key.c_str()); + StringPiece key) const { + return FindPtrOrNull(files_by_name_, key); } inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber( @@ -972,12 +982,12 @@ void FileDescriptorTables::FieldsByLowercaseNamesLazyInitInternal() const { } inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName( - const void* parent, const std::string& lowercase_name) const { + const void* parent, StringPiece lowercase_name) const { internal::call_once( fields_by_lowercase_name_once_, &FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic, this); return FindPtrOrNull(fields_by_lowercase_name_, - PointerStringPair(parent, lowercase_name.c_str())); + PointerStringPair(parent, lowercase_name)); } void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic( @@ -996,12 +1006,12 @@ void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal() const { } inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName( - const void* parent, const std::string& camelcase_name) const { + const void* parent, StringPiece camelcase_name) const { internal::call_once( fields_by_camelcase_name_once_, FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic, this); return FindPtrOrNull(fields_by_camelcase_name_, - PointerStringPair(parent, camelcase_name.c_str())); + PointerStringPair(parent, camelcase_name)); } inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber( @@ -1171,7 +1181,7 @@ Type* DescriptorPool::Tables::AllocateArray(int count) { return reinterpret_cast(AllocateBytes(sizeof(Type) * count)); } -std::string* DescriptorPool::Tables::AllocateString(const std::string& value) { +std::string* DescriptorPool::Tables::AllocateString(StringPiece value) { std::string* result = new std::string(value); strings_.emplace_back(result); return result; @@ -1209,8 +1219,8 @@ void* DescriptorPool::Tables::AllocateBytes(int size) { // allocators... if (size == 0) return nullptr; - allocations_.emplace_back(new char[size]); - return allocations_.back().get(); + allocations_.emplace_back(size); + return allocations_.back().data(); } void FileDescriptorTables::BuildLocationsByPath( @@ -1283,15 +1293,16 @@ void DescriptorPool::InternalDontEnforceDependencies() { enforce_dependencies_ = false; } -void DescriptorPool::AddUnusedImportTrackFile(const std::string& file_name) { - unused_import_track_files_.insert(file_name); +void DescriptorPool::AddUnusedImportTrackFile(ConstStringParam file_name, + bool is_error) { + unused_import_track_files_[std::string(file_name)] = is_error; } void DescriptorPool::ClearUnusedImportTrackFiles() { unused_import_track_files_.clear(); } -bool DescriptorPool::InternalIsFileLoaded(const std::string& filename) const { +bool DescriptorPool::InternalIsFileLoaded(ConstStringParam filename) const { MutexLockMaybe lock(mutex_); return tables_->FindFile(filename) != nullptr; } @@ -1315,6 +1326,10 @@ DescriptorPool* NewGeneratedPool() { } // anonymous namespace +DescriptorDatabase* DescriptorPool::internal_generated_database() { + return GeneratedDatabase(); +} + DescriptorPool* DescriptorPool::internal_generated_pool() { static DescriptorPool* generated_pool = internal::OnShutdownDelete(NewGeneratedPool()); @@ -1364,7 +1379,7 @@ void DescriptorPool::InternalAddGeneratedFile( // there's nothing more important to do (read: never). const FileDescriptor* DescriptorPool::FindFileByName( - const std::string& name) const { + ConstStringParam name) const { MutexLockMaybe lock(mutex_); if (fallback_database_ != nullptr) { tables_->known_bad_symbols_.clear(); @@ -1384,7 +1399,7 @@ const FileDescriptor* DescriptorPool::FindFileByName( } const FileDescriptor* DescriptorPool::FindFileContainingSymbol( - const std::string& symbol_name) const { + ConstStringParam symbol_name) const { MutexLockMaybe lock(mutex_); if (fallback_database_ != nullptr) { tables_->known_bad_symbols_.clear(); @@ -1405,13 +1420,13 @@ const FileDescriptor* DescriptorPool::FindFileContainingSymbol( } const Descriptor* DescriptorPool::FindMessageTypeByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); return (result.type == Symbol::MESSAGE) ? result.descriptor : nullptr; } const FieldDescriptor* DescriptorPool::FindFieldByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); if (result.type == Symbol::FIELD && !result.field_descriptor->is_extension()) { @@ -1422,7 +1437,7 @@ const FieldDescriptor* DescriptorPool::FindFieldByName( } const FieldDescriptor* DescriptorPool::FindExtensionByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); if (result.type == Symbol::FIELD && result.field_descriptor->is_extension()) { return result.field_descriptor; @@ -1432,32 +1447,32 @@ const FieldDescriptor* DescriptorPool::FindExtensionByName( } const OneofDescriptor* DescriptorPool::FindOneofByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : nullptr; } const EnumDescriptor* DescriptorPool::FindEnumTypeByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); return (result.type == Symbol::ENUM) ? result.enum_descriptor : nullptr; } const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); return (result.type == Symbol::ENUM_VALUE) ? result.enum_value_descriptor : nullptr; } const ServiceDescriptor* DescriptorPool::FindServiceByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); return (result.type == Symbol::SERVICE) ? result.service_descriptor : nullptr; } const MethodDescriptor* DescriptorPool::FindMethodByName( - const std::string& name) const { + ConstStringParam name) const { Symbol result = tables_->FindByNameHelper(this, name); return (result.type == Symbol::METHOD) ? result.method_descriptor : nullptr; } @@ -1514,7 +1529,7 @@ const FieldDescriptor* DescriptorPool::InternalFindExtensionByNumberNoLock( } const FieldDescriptor* DescriptorPool::FindExtensionByPrintableName( - const Descriptor* extendee, const std::string& printable_name) const { + const Descriptor* extendee, ConstStringParam printable_name) const { if (extendee->extension_range_count() == 0) return nullptr; const FieldDescriptor* result = FindExtensionByName(printable_name); if (result != nullptr && result->containing_type() == extendee) { @@ -1556,8 +1571,7 @@ void DescriptorPool::FindAllExtensions( std::vector numbers; if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), &numbers)) { - for (int i = 0; i < numbers.size(); ++i) { - int number = numbers[i]; + for (int number : numbers) { if (tables_->FindExtension(extendee, number) == nullptr) { TryFindExtensionInFallbackDatabase(extendee, number); } @@ -1585,7 +1599,7 @@ const FieldDescriptor* Descriptor::FindFieldByNumber(int key) const { } const FieldDescriptor* Descriptor::FindFieldByLowercaseName( - const std::string& key) const { + ConstStringParam key) const { const FieldDescriptor* result = file()->tables_->FindFieldByLowercaseName(this, key); if (result == nullptr || result->is_extension()) { @@ -1596,7 +1610,7 @@ const FieldDescriptor* Descriptor::FindFieldByLowercaseName( } const FieldDescriptor* Descriptor::FindFieldByCamelcaseName( - const std::string& key) const { + ConstStringParam key) const { const FieldDescriptor* result = file()->tables_->FindFieldByCamelcaseName(this, key); if (result == nullptr || result->is_extension()) { @@ -1606,8 +1620,7 @@ const FieldDescriptor* Descriptor::FindFieldByCamelcaseName( } } -const FieldDescriptor* Descriptor::FindFieldByName( - const std::string& key) const { +const FieldDescriptor* Descriptor::FindFieldByName(ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); if (!result.IsNull() && !result.field_descriptor->is_extension()) { @@ -1617,8 +1630,7 @@ const FieldDescriptor* Descriptor::FindFieldByName( } } -const OneofDescriptor* Descriptor::FindOneofByName( - const std::string& key) const { +const OneofDescriptor* Descriptor::FindOneofByName(ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF); if (!result.IsNull()) { @@ -1629,7 +1641,7 @@ const OneofDescriptor* Descriptor::FindOneofByName( } const FieldDescriptor* Descriptor::FindExtensionByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); if (!result.IsNull() && result.field_descriptor->is_extension()) { @@ -1640,7 +1652,7 @@ const FieldDescriptor* Descriptor::FindExtensionByName( } const FieldDescriptor* Descriptor::FindExtensionByLowercaseName( - const std::string& key) const { + ConstStringParam key) const { const FieldDescriptor* result = file()->tables_->FindFieldByLowercaseName(this, key); if (result == nullptr || !result->is_extension()) { @@ -1651,7 +1663,7 @@ const FieldDescriptor* Descriptor::FindExtensionByLowercaseName( } const FieldDescriptor* Descriptor::FindExtensionByCamelcaseName( - const std::string& key) const { + ConstStringParam key) const { const FieldDescriptor* result = file()->tables_->FindFieldByCamelcaseName(this, key); if (result == nullptr || !result->is_extension()) { @@ -1661,8 +1673,7 @@ const FieldDescriptor* Descriptor::FindExtensionByCamelcaseName( } } -const Descriptor* Descriptor::FindNestedTypeByName( - const std::string& key) const { +const Descriptor* Descriptor::FindNestedTypeByName(ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); if (!result.IsNull()) { @@ -1673,7 +1684,7 @@ const Descriptor* Descriptor::FindNestedTypeByName( } const EnumDescriptor* Descriptor::FindEnumTypeByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); if (!result.IsNull()) { @@ -1684,7 +1695,7 @@ const EnumDescriptor* Descriptor::FindEnumTypeByName( } const EnumValueDescriptor* Descriptor::FindEnumValueByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); if (!result.IsNull()) { @@ -1694,8 +1705,20 @@ const EnumValueDescriptor* Descriptor::FindEnumValueByName( } } +const FieldDescriptor* Descriptor::map_key() const { + if (!options().map_entry()) return nullptr; + GOOGLE_DCHECK_EQ(field_count(), 2); + return field(0); +} + +const FieldDescriptor* Descriptor::map_value() const { + if (!options().map_entry()) return nullptr; + GOOGLE_DCHECK_EQ(field_count(), 2); + return field(1); +} + const EnumValueDescriptor* EnumDescriptor::FindValueByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); if (!result.IsNull()) { @@ -1715,7 +1738,7 @@ const EnumValueDescriptor* EnumDescriptor::FindValueByNumberCreatingIfUnknown( } const MethodDescriptor* ServiceDescriptor::FindMethodByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); if (!result.IsNull()) { @@ -1726,7 +1749,7 @@ const MethodDescriptor* ServiceDescriptor::FindMethodByName( } const Descriptor* FileDescriptor::FindMessageTypeByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); if (!result.IsNull()) { return result.descriptor; @@ -1736,7 +1759,7 @@ const Descriptor* FileDescriptor::FindMessageTypeByName( } const EnumDescriptor* FileDescriptor::FindEnumTypeByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); if (!result.IsNull()) { return result.enum_descriptor; @@ -1746,7 +1769,7 @@ const EnumDescriptor* FileDescriptor::FindEnumTypeByName( } const EnumValueDescriptor* FileDescriptor::FindEnumValueByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); if (!result.IsNull()) { @@ -1757,7 +1780,7 @@ const EnumValueDescriptor* FileDescriptor::FindEnumValueByName( } const ServiceDescriptor* FileDescriptor::FindServiceByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); if (!result.IsNull()) { return result.service_descriptor; @@ -1767,7 +1790,7 @@ const ServiceDescriptor* FileDescriptor::FindServiceByName( } const FieldDescriptor* FileDescriptor::FindExtensionByName( - const std::string& key) const { + ConstStringParam key) const { Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); if (!result.IsNull() && result.field_descriptor->is_extension()) { return result.field_descriptor; @@ -1777,7 +1800,7 @@ const FieldDescriptor* FileDescriptor::FindExtensionByName( } const FieldDescriptor* FileDescriptor::FindExtensionByLowercaseName( - const std::string& key) const { + ConstStringParam key) const { const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key); if (result == nullptr || !result->is_extension()) { return nullptr; @@ -1787,7 +1810,7 @@ const FieldDescriptor* FileDescriptor::FindExtensionByLowercaseName( } const FieldDescriptor* FileDescriptor::FindExtensionByCamelcaseName( - const std::string& key) const { + ConstStringParam key) const { const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key); if (result == nullptr || !result->is_extension()) { return nullptr; @@ -1844,22 +1867,23 @@ EnumDescriptor::FindReservedRangeContainingNumber(int number) const { // ------------------------------------------------------------------- bool DescriptorPool::TryFindFileInFallbackDatabase( - const std::string& name) const { + StringPiece name) const { if (fallback_database_ == nullptr) return false; - if (tables_->known_bad_files_.count(name) > 0) return false; + auto name_string = std::string(name); + if (tables_->known_bad_files_.count(name_string) > 0) return false; FileDescriptorProto file_proto; - if (!fallback_database_->FindFileByName(name, &file_proto) || + if (!fallback_database_->FindFileByName(name_string, &file_proto) || BuildFileFromDatabase(file_proto) == nullptr) { - tables_->known_bad_files_.insert(name); + tables_->known_bad_files_.insert(std::move(name_string)); return false; } return true; } -bool DescriptorPool::IsSubSymbolOfBuiltType(const std::string& name) const { - std::string prefix = name; +bool DescriptorPool::IsSubSymbolOfBuiltType(StringPiece name) const { + auto prefix = std::string(name); for (;;) { std::string::size_type dot_pos = prefix.find_last_of('.'); if (dot_pos == std::string::npos) { @@ -1881,10 +1905,11 @@ bool DescriptorPool::IsSubSymbolOfBuiltType(const std::string& name) const { } bool DescriptorPool::TryFindSymbolInFallbackDatabase( - const std::string& name) const { + StringPiece name) const { if (fallback_database_ == nullptr) return false; - if (tables_->known_bad_symbols_.count(name) > 0) return false; + auto name_string = std::string(name); + if (tables_->known_bad_symbols_.count(name_string) > 0) return false; FileDescriptorProto file_proto; if ( // We skip looking in the fallback database if the name is a sub-symbol @@ -1906,7 +1931,7 @@ bool DescriptorPool::TryFindSymbolInFallbackDatabase( IsSubSymbolOfBuiltType(name) // Look up file containing this symbol in fallback database. - || !fallback_database_->FindFileContainingSymbol(name, &file_proto) + || !fallback_database_->FindFileContainingSymbol(name_string, &file_proto) // Check if we've already built this file. If so, it apparently doesn't // contain the symbol we're looking for. Some DescriptorDatabases @@ -1915,7 +1940,7 @@ bool DescriptorPool::TryFindSymbolInFallbackDatabase( // Build the file. || BuildFileFromDatabase(file_proto) == nullptr) { - tables_->known_bad_symbols_.insert(name); + tables_->known_bad_symbols_.insert(std::move(name_string)); return false; } @@ -2117,7 +2142,9 @@ void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { if (has_json_name_) { proto->set_json_name(json_name()); } - + if (proto3_optional_) { + proto->set_proto3_optional(true); + } // Some compilers do not allow static_cast directly between two enum types, // so we must cast to int first. proto->set_label(static_cast( @@ -2251,34 +2278,34 @@ bool RetrieveOptionsAssumingRightPool( const Reflection* reflection = options.GetReflection(); std::vector fields; reflection->ListFields(options, &fields); - for (int i = 0; i < fields.size(); i++) { + for (const FieldDescriptor* field : fields) { int count = 1; bool repeated = false; - if (fields[i]->is_repeated()) { - count = reflection->FieldSize(options, fields[i]); + if (field->is_repeated()) { + count = reflection->FieldSize(options, field); repeated = true; } for (int j = 0; j < count; j++) { std::string fieldval; - if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { std::string tmp; TextFormat::Printer printer; printer.SetInitialIndentLevel(depth + 1); - printer.PrintFieldValueToString(options, fields[i], repeated ? j : -1, + printer.PrintFieldValueToString(options, field, repeated ? j : -1, &tmp); fieldval.append("{\n"); fieldval.append(tmp); fieldval.append(depth * 2, ' '); fieldval.append("}"); } else { - TextFormat::PrintFieldValueToString(options, fields[i], - repeated ? j : -1, &fieldval); + TextFormat::PrintFieldValueToString(options, field, repeated ? j : -1, + &fieldval); } std::string name; - if (fields[i]->is_extension()) { - name = "(." + fields[i]->full_name() + ")"; + if (field->is_extension()) { + name = "(." + field->full_name() + ")"; } else { - name = fields[i]->name(); + name = field->name(); } option_entries->push_back(name + " = " + fieldval); } @@ -2335,9 +2362,8 @@ bool FormatLineOptions(int depth, const Message& options, std::string prefix(depth * 2, ' '); std::vector all_options; if (RetrieveOptions(depth, options, pool, &all_options)) { - for (int i = 0; i < all_options.size(); i++) { - strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, - all_options[i]); + for (const std::string& option : all_options) { + strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, option); } } return !all_options.empty(); @@ -2367,8 +2393,9 @@ class SourceLocationCommentPrinter { void AddPreComment(std::string* output) { if (have_source_loc_) { // Detached leading comments. - for (int i = 0; i < source_loc_.leading_detached_comments.size(); ++i) { - *output += FormatComment(source_loc_.leading_detached_comments[i]); + for (const std::string& leading_detached_comment : + source_loc_.leading_detached_comments) { + *output += FormatComment(leading_detached_comment); *output += "\n"; } // Attached leading comments. @@ -2390,8 +2417,7 @@ class SourceLocationCommentPrinter { StripWhitespace(&stripped_comment); std::vector lines = Split(stripped_comment, "\n"); std::string output; - for (int i = 0; i < lines.size(); ++i) { - const std::string& line = lines[i]; + for (const std::string& line : lines) { strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line); } return output; @@ -2422,7 +2448,7 @@ std::string FileDescriptor::DebugStringWithOptions( debug_string_options); syntax_comment.AddPreComment(&contents); strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n", - SyntaxName(syntax())); + SyntaxName(syntax())); syntax_comment.AddPostComment(&contents); } @@ -2439,13 +2465,13 @@ std::string FileDescriptor::DebugStringWithOptions( for (int i = 0; i < dependency_count(); i++) { if (public_dependencies.count(i) > 0) { strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", - dependency(i)->name()); + dependency(i)->name()); } else if (weak_dependencies.count(i) > 0) { strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", - dependency(i)->name()); + dependency(i)->name()); } else { strings::SubstituteAndAppend(&contents, "import \"$0\";\n", - dependency(i)->name()); + dependency(i)->name()); } } @@ -2496,10 +2522,9 @@ std::string FileDescriptor::DebugStringWithOptions( if (i > 0) contents.append("}\n\n"); containing_type = extension(i)->containing_type(); strings::SubstituteAndAppend(&contents, "extend .$0 {\n", - containing_type->full_name()); + containing_type->full_name()); } - extension(i)->DebugString(1, FieldDescriptor::PRINT_LABEL, &contents, - debug_string_options); + extension(i)->DebugString(1, &contents, debug_string_options); } if (extension_count() > 0) contents.append("}\n\n"); @@ -2567,8 +2592,7 @@ void Descriptor::DebugString(int depth, std::string* contents, } for (int i = 0; i < field_count(); i++) { if (field(i)->containing_oneof() == nullptr) { - field(i)->DebugString(depth, FieldDescriptor::PRINT_LABEL, contents, - debug_string_options); + field(i)->DebugString(depth, contents, debug_string_options); } else if (field(i)->containing_oneof()->field(0) == field(i)) { // This is the first field in this oneof, so print the whole oneof. field(i)->containing_oneof()->DebugString(depth, contents, @@ -2578,8 +2602,8 @@ void Descriptor::DebugString(int depth, std::string* contents, for (int i = 0; i < extension_range_count(); i++) { strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", prefix, - extension_range(i)->start, - extension_range(i)->end - 1); + extension_range(i)->start, + extension_range(i)->end - 1); } // Group extensions by what they extend, so they can be printed out together. @@ -2589,10 +2613,9 @@ void Descriptor::DebugString(int depth, std::string* contents, if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); containing_type = extension(i)->containing_type(); strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", prefix, - containing_type->full_name()); + containing_type->full_name()); } - extension(i)->DebugString(depth + 1, FieldDescriptor::PRINT_LABEL, contents, - debug_string_options); + extension(i)->DebugString(depth + 1, contents, debug_string_options); } if (extension_count() > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); @@ -2605,7 +2628,7 @@ void Descriptor::DebugString(int depth, std::string* contents, strings::SubstituteAndAppend(contents, "$0, ", range->start); } else { strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start, - range->end - 1); + range->end - 1); } } contents->replace(contents->size() - 2, 2, ";\n"); @@ -2615,7 +2638,7 @@ void Descriptor::DebugString(int depth, std::string* contents, strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); for (int i = 0; i < reserved_name_count(); i++) { strings::SubstituteAndAppend(contents, "\"$0\", ", - CEscape(reserved_name(i))); + CEscape(reserved_name(i))); } contents->replace(contents->size() - 2, 2, ";\n"); } @@ -2635,10 +2658,10 @@ std::string FieldDescriptor::DebugStringWithOptions( int depth = 0; if (is_extension()) { strings::SubstituteAndAppend(&contents, "extend .$0 {\n", - containing_type()->full_name()); + containing_type()->full_name()); depth = 1; } - DebugString(depth, PRINT_LABEL, &contents, debug_string_options); + DebugString(depth, &contents, debug_string_options); if (is_extension()) { contents.append("}\n"); } @@ -2658,7 +2681,7 @@ std::string FieldDescriptor::FieldTypeNameDebugString() const { } void FieldDescriptor::DebugString( - int depth, PrintLabelFlag print_label_flag, std::string* contents, + int depth, std::string* contents, const DebugStringOptions& debug_string_options) const { std::string prefix(depth * 2, ' '); std::string field_type; @@ -2673,20 +2696,12 @@ void FieldDescriptor::DebugString( field_type = FieldTypeNameDebugString(); } - bool print_label = true; - // Determine whether to omit label: - // 1. For an optional field, omit label if it's in oneof or in proto3. - // 2. For a repeated field, omit label if it's a map. - if (is_optional() && (print_label_flag == OMIT_LABEL || - file()->syntax() == FileDescriptor::SYNTAX_PROTO3)) { - print_label = false; - } else if (is_map()) { - print_label = false; - } - std::string label; - if (print_label) { - label = kLabelToName[this->label()]; - label.push_back(' '); + std::string label = StrCat(kLabelToName[this->label()], " "); + + // Label is omitted for maps, oneof, and plain proto3 fields. + if (is_map() || containing_oneof() || + (is_optional() && !has_optional_keyword())) { + label.clear(); } SourceLocationCommentPrinter comment_printer(this, prefix, @@ -2701,12 +2716,12 @@ void FieldDescriptor::DebugString( if (has_default_value()) { bracketed = true; strings::SubstituteAndAppend(contents, " [default = $0", - DefaultValueAsString(true)); + DefaultValueAsString(true)); } if (has_json_name_) { if (!bracketed) { bracketed = true; - contents->append("["); + contents->append(" ["); } else { contents->append(", "); } @@ -2771,8 +2786,7 @@ void OneofDescriptor::DebugString( } else { contents->append("\n"); for (int i = 0; i < field_count(); i++) { - field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents, - debug_string_options); + field(i)->DebugString(depth, contents, debug_string_options); } strings::SubstituteAndAppend(contents, "$0}\n", prefix); } @@ -2817,7 +2831,7 @@ void EnumDescriptor::DebugString( strings::SubstituteAndAppend(contents, "$0, ", range->start); } else { strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start, - range->end); + range->end); } } contents->replace(contents->size() - 2, 2, ";\n"); @@ -2827,7 +2841,7 @@ void EnumDescriptor::DebugString( strings::SubstituteAndAppend(contents, "$0 reserved ", prefix); for (int i = 0; i < reserved_name_count(); i++) { strings::SubstituteAndAppend(contents, "\"$0\", ", - CEscape(reserved_name(i))); + CEscape(reserved_name(i))); } contents->replace(contents->size() - 2, 2, ";\n"); } @@ -2933,7 +2947,7 @@ void MethodDescriptor::DebugString( if (FormatLineOptions(depth, options(), service()->file()->pool(), &formatted_options)) { strings::SubstituteAndAppend(contents, " {\n$0$1}\n", formatted_options, - prefix); + prefix); } else { contents->append(";\n"); } @@ -3294,14 +3308,14 @@ class DescriptorBuilder { void BuildMessage(const DescriptorProto& proto, const Descriptor* parent, Descriptor* result); void BuildFieldOrExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, FieldDescriptor* result, + Descriptor* parent, FieldDescriptor* result, bool is_extension); - void BuildField(const FieldDescriptorProto& proto, const Descriptor* parent, + void BuildField(const FieldDescriptorProto& proto, Descriptor* parent, FieldDescriptor* result) { BuildFieldOrExtension(proto, parent, result, false); } - void BuildExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, FieldDescriptor* result) { + void BuildExtension(const FieldDescriptorProto& proto, Descriptor* parent, + FieldDescriptor* result) { BuildFieldOrExtension(proto, parent, result, true); } void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, @@ -3493,7 +3507,7 @@ class DescriptorBuilder { return pool->enforce_weak_; } static inline bool get_is_placeholder(const Descriptor* descriptor) { - return descriptor->is_placeholder_; + return descriptor != nullptr && descriptor->is_placeholder_; } static inline void assert_mutex_held(const DescriptorPool* pool) { if (pool->mutex_ != nullptr) { @@ -3517,6 +3531,9 @@ class DescriptorBuilder { const EnumDescriptorProto& proto); void ValidateEnumValueOptions(EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto); + void ValidateExtensionRangeOptions( + const std::string& full_name, Descriptor::ExtensionRange* extension_range, + const DescriptorProto_ExtensionRange& proto); void ValidateServiceOptions(ServiceDescriptor* service, const ServiceDescriptorProto& proto); void ValidateMethodOptions(MethodDescriptor* method, @@ -3843,16 +3860,16 @@ Symbol DescriptorBuilder::LookupSymbol( return result; } -static bool ValidateQualifiedName(const std::string& name) { +static bool ValidateQualifiedName(StringPiece name) { bool last_was_period = false; - for (int i = 0; i < name.size(); i++) { + for (char character : name) { // I don't trust isalnum() due to locales. :( - if (('a' <= name[i] && name[i] <= 'z') || - ('A' <= name[i] && name[i] <= 'Z') || - ('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) { + if (('a' <= character && character <= 'z') || + ('A' <= character && character <= 'Z') || + ('0' <= character && character <= '9') || (character == '_')) { last_was_period = false; - } else if (name[i] == '.') { + } else if (character == '.') { if (last_was_period) return false; last_was_period = true; } else { @@ -3863,14 +3880,14 @@ static bool ValidateQualifiedName(const std::string& name) { return !name.empty() && !last_was_period; } -Symbol DescriptorPool::NewPlaceholder(const std::string& name, +Symbol DescriptorPool::NewPlaceholder(StringPiece name, PlaceholderType placeholder_type) const { MutexLockMaybe lock(mutex_); return NewPlaceholderWithMutexHeld(name, placeholder_type); } Symbol DescriptorPool::NewPlaceholderWithMutexHeld( - const std::string& name, PlaceholderType placeholder_type) const { + StringPiece name, PlaceholderType placeholder_type) const { if (mutex_) { mutex_->AssertHeld(); } @@ -3968,13 +3985,13 @@ Symbol DescriptorPool::NewPlaceholderWithMutexHeld( } FileDescriptor* DescriptorPool::NewPlaceholderFile( - const std::string& name) const { + StringPiece name) const { MutexLockMaybe lock(mutex_); return NewPlaceholderFileWithMutexHeld(name); } FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld( - const std::string& name) const { + StringPiece name) const { if (mutex_) { mutex_->AssertHeld(); } @@ -3988,7 +4005,7 @@ FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld( placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance(); placeholder->source_code_info_ = &SourceCodeInfo::default_instance(); placeholder->is_placeholder_ = true; - placeholder->syntax_ = FileDescriptor::SYNTAX_PROTO2; + placeholder->syntax_ = FileDescriptor::SYNTAX_UNKNOWN; placeholder->finished_building_ = true; // All other fields are zero or nullptr. @@ -4032,7 +4049,8 @@ bool DescriptorBuilder::AddSymbol(const std::string& full_name, // Symbol seems to have been defined in a different file. AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "\"" + full_name + "\" is already defined in file \"" + - other_file->name() + "\"."); + (other_file == nullptr ? "null" : other_file->name()) + + "\"."); } return false; } @@ -4075,11 +4093,11 @@ void DescriptorBuilder::ValidateSymbolName(const std::string& name, AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "Missing name."); } else { - for (int i = 0; i < name.size(); i++) { + for (char character : name) { // I don't trust isalnum() due to locales. :( - if ((name[i] < 'a' || 'z' < name[i]) && - (name[i] < 'A' || 'Z' < name[i]) && - (name[i] < '0' || '9' < name[i]) && (name[i] != '_')) { + if ((character < 'a' || 'z' < character) && + (character < 'A' || 'Z' < character) && + (character < '0' || '9' < character) && (character != '_')) { AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "\"" + name + "\" is not a valid identifier."); } @@ -4185,13 +4203,13 @@ void DescriptorBuilder::AllocateOptionsImpl( void DescriptorBuilder::AddRecursiveImportError( const FileDescriptorProto& proto, int from_here) { std::string error_message("File recursively imports itself: "); - for (int i = from_here; i < tables_->pending_files_.size(); i++) { + for (size_t i = from_here; i < tables_->pending_files_.size(); i++) { error_message.append(tables_->pending_files_[i]); error_message.append(" -> "); } error_message.append(proto.name()); - if (from_here < tables_->pending_files_.size() - 1) { + if (static_cast(from_here) < tables_->pending_files_.size() - 1) { AddError(tables_->pending_files_[from_here + 1], proto, DescriptorPool::ErrorCollector::IMPORT, error_message); } else { @@ -4264,7 +4282,7 @@ const FileDescriptor* DescriptorBuilder::BuildFile( // mid-file, but that's pretty ugly, and I'm pretty sure there are // some languages out there that do not allow recursive dependencies // at all. - for (int i = 0; i < tables_->pending_files_.size(); i++) { + for (size_t i = 0; i < tables_->pending_files_.size(); i++) { if (tables_->pending_files_[i] == proto.name()) { AddRecursiveImportError(proto, i); return nullptr; @@ -4489,9 +4507,8 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl( BUILD_ARRAY(proto, result, extension, BuildExtension, nullptr); // Copy options. - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { AllocateOptions(proto.options(), result); } @@ -4532,8 +4549,10 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl( // Again, see comments at InternalSetLazilyBuildDependencies about error - // checking. - if (!unused_dependency_.empty() && !pool_->lazily_build_dependencies_) { + // checking. Also, don't log unused dependencies if there were previous + // errors, since the results might be inaccurate. + if (!had_errors_ && !unused_dependency_.empty() && + !pool_->lazily_build_dependencies_) { LogUnusedDependency(proto, result); } @@ -4571,6 +4590,12 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, result->containing_type_ = parent; result->is_placeholder_ = false; result->is_unqualified_placeholder_ = false; + result->well_known_type_ = Descriptor::WELLKNOWNTYPE_UNSPECIFIED; + + auto it = pool_->tables_->well_known_types_.find(*full_name); + if (it != pool_->tables_->well_known_types_.end()) { + result->well_known_type_ = it->second; + } // Build oneofs first so that fields and extension ranges can refer to them. BUILD_ARRAY(proto, result, oneof_decl, BuildOneof, result); @@ -4592,9 +4617,8 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, } // Copy options. - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { AllocateOptions(proto.options(), result, DescriptorProto::kOptionsFieldNumber, "google.protobuf.MessageOptions"); @@ -4610,9 +4634,9 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, AddError(result->full_name(), proto.reserved_range(i), DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Reserved range $0 to $1 overlaps with " - "already-defined range $2 to $3.", - range2.start(), range2.end() - 1, - range1.start(), range1.end() - 1)); + "already-defined range $2 to $3.", + range2.start(), range2.end() - 1, + range1.start(), range1.end() - 1)); } } } @@ -4624,11 +4648,12 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, reserved_name_set.insert(name); } else { AddError(name, proto, DescriptorPool::ErrorCollector::NAME, - strings::Substitute( - "Field name \"$0\" is reserved multiple times.", name)); + strings::Substitute("Field name \"$0\" is reserved multiple times.", + name)); } } + for (int i = 0; i < result->field_count(); i++) { const FieldDescriptor* field = result->field(i); for (int j = 0; j < result->extension_range_count(); j++) { @@ -4648,7 +4673,7 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, AddError(field->full_name(), proto.reserved_range(j), DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Field \"$0\" uses reserved number $1.", - field->name(), field->number())); + field->name(), field->number())); } } if (reserved_name_set.find(field->name()) != reserved_name_set.end()) { @@ -4657,10 +4682,11 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, DescriptorPool::ErrorCollector::NAME, strings::Substitute("Field name \"$0\" is reserved.", field->name())); } + } // Check that extension ranges don't overlap and don't include - // reserved field numbers. + // reserved field numbers or names. for (int i = 0; i < result->extension_range_count(); i++) { const Descriptor::ExtensionRange* range1 = result->extension_range(i); for (int j = 0; j < result->reserved_range_count(); j++) { @@ -4669,9 +4695,9 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, AddError(result->full_name(), proto.extension_range(i), DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Extension range $0 to $1 overlaps with " - "reserved range $2 to $3.", - range1->start, range1->end - 1, - range2->start, range2->end - 1)); + "reserved range $2 to $3.", + range1->start, range1->end - 1, range2->start, + range2->end - 1)); } } for (int j = i + 1; j < result->extension_range_count(); j++) { @@ -4680,16 +4706,16 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, AddError(result->full_name(), proto.extension_range(i), DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Extension range $0 to $1 overlaps with " - "already-defined range $2 to $3.", - range2->start, range2->end - 1, - range1->start, range1->end - 1)); + "already-defined range $2 to $3.", + range2->start, range2->end - 1, range1->start, + range1->end - 1)); } } } } void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, - const Descriptor* parent, + Descriptor* parent, FieldDescriptor* result, bool is_extension) { const std::string& scope = @@ -4702,6 +4728,15 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, result->file_ = file_; result->number_ = proto.number(); result->is_extension_ = is_extension; + result->proto3_optional_ = proto.proto3_optional(); + + if (proto.proto3_optional() && + file_->syntax() != FileDescriptor::SYNTAX_PROTO3) { + AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, + "The [proto3_optional=true] option may only be set on proto3" + "fields, not " + + result->full_name()); + } // If .proto files follow the style guide then the name should already be // lower-cased. If that's the case we can just reuse the string we @@ -4736,17 +4771,18 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, result->label_ = static_cast( implicit_cast(proto.label())); - // An extension cannot have a required field (b/13365836). - if (result->is_extension_ && - result->label_ == FieldDescriptor::LABEL_REQUIRED) { - AddError(result->full_name(), proto, - // Error location `TYPE`: we would really like to indicate - // `LABEL`, but the `ErrorLocation` enum has no entry for this, and - // we don't necessarily know about all implementations of the - // `ErrorCollector` interface to extend them to handle the new - // error location type properly. - DescriptorPool::ErrorCollector::TYPE, - "The extension " + result->full_name() + " cannot be required."); + if (result->label_ == FieldDescriptor::LABEL_REQUIRED) { + // An extension cannot have a required field (b/13365836). + if (result->is_extension_) { + AddError(result->full_name(), proto, + // Error location `TYPE`: we would really like to indicate + // `LABEL`, but the `ErrorLocation` enum has no entry for this, + // and we don't necessarily know about all implementations of the + // `ErrorCollector` interface to extend them to handle the new + // error location type properly. + DescriptorPool::ErrorCollector::TYPE, + "The extension " + result->full_name() + " cannot be required."); + } } // Some of these may be filled in when cross-linking. @@ -4845,6 +4881,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, DescriptorPool::ErrorCollector::DEFAULT_VALUE, "Messages can't have default values."); result->has_default_value_ = false; + result->default_generated_instance_ = nullptr; break; } @@ -4891,6 +4928,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, result->default_value_string_ = &internal::GetEmptyString(); break; case FieldDescriptor::CPPTYPE_MESSAGE: + result->default_generated_instance_ = nullptr; break; } } @@ -4910,7 +4948,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, // on extension numbers. AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Field numbers cannot be greater than $0.", - FieldDescriptor::kMaxNumber)); + FieldDescriptor::kMaxNumber)); } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && result->number() <= FieldDescriptor::kLastReservedNumber) { AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, @@ -4953,8 +4991,8 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, strings::Substitute("FieldDescriptorProto.oneof_index $0 is " - "out of range for type \"$1\".", - proto.oneof_index(), parent->name())); + "out of range for type \"$1\".", + proto.oneof_index(), parent->name())); result->containing_oneof_ = nullptr; } else { result->containing_oneof_ = parent->oneof_decl(proto.oneof_index()); @@ -4965,9 +5003,8 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, } // Copy options. - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { AllocateOptions(proto.options(), result, FieldDescriptorProto::kOptionsFieldNumber, "google.protobuf.FieldOptions"); @@ -4997,9 +5034,8 @@ void DescriptorBuilder::BuildExtensionRange( "Extension range end number must be greater than start number."); } - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { std::vector options_path; parent->GetLocationPath(&options_path); options_path.push_back(DescriptorProto::kExtensionRangeFieldNumber); @@ -5169,9 +5205,8 @@ void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, CheckEnumValueUniqueness(proto, result); // Copy options. - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { AllocateOptions(proto.options(), result, EnumDescriptorProto::kOptionsFieldNumber, "google.protobuf.EnumOptions"); @@ -5189,9 +5224,9 @@ void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, AddError(result->full_name(), proto.reserved_range(i), DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Reserved range $0 to $1 overlaps with " - "already-defined range $2 to $3.", - range2.start(), range2.end(), - range1.start(), range1.end())); + "already-defined range $2 to $3.", + range2.start(), range2.end(), range1.start(), + range1.end())); } } } @@ -5203,8 +5238,8 @@ void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, reserved_name_set.insert(name); } else { AddError(name, proto, DescriptorPool::ErrorCollector::NAME, - strings::Substitute( - "Enum value \"$0\" is reserved multiple times.", name)); + strings::Substitute("Enum value \"$0\" is reserved multiple times.", + name)); } } @@ -5213,11 +5248,10 @@ void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, for (int j = 0; j < result->reserved_range_count(); j++) { const EnumDescriptor::ReservedRange* range = result->reserved_range(j); if (range->start <= value->number() && value->number() <= range->end) { - AddError( - value->full_name(), proto.reserved_range(j), - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Enum value \"$0\" uses reserved number $1.", - value->name(), value->number())); + AddError(value->full_name(), proto.reserved_range(j), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Enum value \"$0\" uses reserved number $1.", + value->name(), value->number())); } } if (reserved_name_set.find(value->name()) != reserved_name_set.end()) { @@ -5248,9 +5282,8 @@ void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, ValidateSymbolName(proto.name(), *full_name, proto); // Copy options. - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { AllocateOptions(proto.options(), result, EnumValueDescriptorProto::kOptionsFieldNumber, "google.protobuf.EnumValueOptions"); @@ -5314,9 +5347,8 @@ void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, BUILD_ARRAY(proto, result, method, BuildMethod, result); // Copy options. - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { AllocateOptions(proto.options(), result, ServiceDescriptorProto::kOptionsFieldNumber, "google.protobuf.ServiceOptions"); @@ -5343,9 +5375,8 @@ void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, result->output_type_.Init(); // Copy options. - if (!proto.has_options()) { - result->options_ = nullptr; // Will set to default_instance later. - } else { + result->options_ = nullptr; // Set to default_instance later if necessary. + if (proto.has_options()) { AllocateOptions(proto.options(), result, MethodDescriptorProto::kOptionsFieldNumber, "google.protobuf.MethodOptions"); @@ -5469,6 +5500,42 @@ void DescriptorBuilder::CrossLinkMessage(Descriptor* message, message->field(i); } } + + for (int i = 0; i < message->field_count(); i++) { + const FieldDescriptor* field = message->field(i); + if (field->proto3_optional_) { + if (!field->containing_oneof() || + !field->containing_oneof()->is_synthetic()) { + AddError(message->full_name(), proto.field(i), + DescriptorPool::ErrorCollector::OTHER, + "Fields with proto3_optional set must be " + "a member of a one-field oneof"); + } + } + } + + // Synthetic oneofs must be last. + int first_synthetic = -1; + for (int i = 0; i < message->oneof_decl_count(); i++) { + const OneofDescriptor* oneof = message->oneof_decl(i); + if (oneof->is_synthetic()) { + if (first_synthetic == -1) { + first_synthetic = i; + } + } else { + if (first_synthetic != -1) { + AddError(message->full_name(), proto.oneof_decl(i), + DescriptorPool::ErrorCollector::OTHER, + "Synthetic oneofs must be after all other oneofs"); + } + } + } + + if (first_synthetic == -1) { + message->real_oneof_decl_count_ = message->oneof_decl_count_; + } else { + message->real_oneof_decl_count_ = first_synthetic; + } } void DescriptorBuilder::CrossLinkExtensionRange( @@ -5519,9 +5586,9 @@ void DescriptorBuilder::CrossLinkField(FieldDescriptor* field, AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("\"$0\" does not declare $1 as an " - "extension number.", - field->containing_type()->full_name(), - field->number())); + "extension number.", + field->containing_type()->full_name(), + field->number())); } } } @@ -5702,16 +5769,16 @@ void DescriptorBuilder::CrossLinkField(FieldDescriptor* field, AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Extension number $0 has already been used " - "in \"$1\" by extension \"$2\".", - field->number(), containing_type_name, - conflicting_field->full_name())); + "in \"$1\" by extension \"$2\".", + field->number(), containing_type_name, + conflicting_field->full_name())); } else { AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, strings::Substitute("Field number $0 has already been used in " - "\"$1\" by field \"$2\".", - field->number(), containing_type_name, - conflicting_field->name())); + "\"$1\" by field \"$2\".", + field->number(), containing_type_name, + conflicting_field->name())); } } else { if (field->is_extension()) { @@ -5875,12 +5942,12 @@ void DescriptorBuilder::ValidateProto3(FileDescriptor* file, static std::string ToLowercaseWithoutUnderscores(const std::string& name) { std::string result; - for (int i = 0; i < name.size(); ++i) { - if (name[i] != '_') { - if (name[i] >= 'A' && name[i] <= 'Z') { - result.push_back(name[i] - 'A' + 'a'); + for (char character : name) { + if (character != '_') { + if (character >= 'A' && character <= 'Z') { + result.push_back(character - 'A' + 'a'); } else { - result.push_back(name[i]); + result.push_back(character); } } } @@ -5951,7 +6018,8 @@ void DescriptorBuilder::ValidateProto3Field(FieldDescriptor* field, } if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM && field->enum_type() && - field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3) { + field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 && + field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_UNKNOWN) { // Proto3 messages can only use Proto3 enum types; otherwise we can't // guarantee that the default value is zero. AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, @@ -5988,12 +6056,15 @@ void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, : FieldDescriptor::kMaxNumber); for (int i = 0; i < message->extension_range_count(); ++i) { if (message->extension_range(i)->end > max_extension_range + 1) { - AddError( - message->full_name(), proto.extension_range(i), - DescriptorPool::ErrorCollector::NUMBER, - strings::Substitute("Extension numbers cannot be greater than $0.", - max_extension_range)); + AddError(message->full_name(), proto.extension_range(i), + DescriptorPool::ErrorCollector::NUMBER, + strings::Substitute("Extension numbers cannot be greater than $0.", + max_extension_range)); } + + ValidateExtensionRangeOptions(message->full_name(), + message->extension_ranges_ + i, + proto.extension_range(i)); } } @@ -6060,7 +6131,7 @@ void DescriptorBuilder::ValidateFieldOptions( // json_name option is not allowed on extension fields. Note that the // json_name field in FieldDescriptorProto is always populated by protoc - // when it sends descriptor data to plugins (caculated from field name if + // when it sends descriptor data to plugins (calculated from field name if // the option is not explicitly set) so we can't rely on its presence to // determine whether the json_name option is set on the field. Here we // compare it against the default calculated json_name value and consider @@ -6108,6 +6179,12 @@ void DescriptorBuilder::ValidateEnumValueOptions( const EnumValueDescriptorProto& /* proto */) { // Nothing to do so far. } + +void DescriptorBuilder::ValidateExtensionRangeOptions( + const std::string& full_name, Descriptor::ExtensionRange* extension_range, + const DescriptorProto_ExtensionRange& proto) { +} + void DescriptorBuilder::ValidateServiceOptions( ServiceDescriptor* service, const ServiceDescriptorProto& proto) { if (IsLite(service->file()) && @@ -6145,8 +6222,8 @@ bool DescriptorBuilder::ValidateMapEntry(FieldDescriptor* field, return false; } - const FieldDescriptor* key = message->field(0); - const FieldDescriptor* value = message->field(1); + const FieldDescriptor* key = message->map_key(); + const FieldDescriptor* value = message->map_value(); if (key->label() != FieldDescriptor::LABEL_OPTIONAL || key->number() != 1 || key->name() != "key") { return false; @@ -6382,6 +6459,7 @@ bool DescriptorBuilder::OptionInterpreter::InterpretOptions( options->GetReflection()->Swap(unparsed_options.get(), options); } } + return !failed; } @@ -6624,10 +6702,10 @@ void DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo( if (matched) { // see if this location is in the range to remove bool loc_matches = true; - if (loc->path_size() < pathv.size()) { + if (loc->path_size() < static_cast(pathv.size())) { loc_matches = false; } else { - for (int j = 0; j < pathv.size(); j++) { + for (size_t j = 0; j < pathv.size(); j++) { if (loc->path(j) != pathv[j]) { loc_matches = false; break; @@ -6984,6 +7062,18 @@ class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder public: DescriptorBuilder* builder_; + const Descriptor* FindAnyType(const Message& message, + const std::string& prefix, + const std::string& name) const override { + if (prefix != internal::kTypeGoogleApisComPrefix && + prefix != internal::kTypeGoogleProdComPrefix) { + return nullptr; + } + assert_mutex_held(builder_->pool_); + Symbol result = builder_->FindSymbol(name); + return result.type == Symbol::MESSAGE ? result.descriptor : nullptr; + } + const FieldDescriptor* FindExtension(Message* message, const std::string& name) const override { assert_mutex_held(builder_->pool_); @@ -7170,20 +7260,27 @@ void DescriptorBuilder::LogUnusedDependency(const FileDescriptorProto& proto, const FileDescriptor* result) { if (!unused_dependency_.empty()) { + auto itr = pool_->unused_import_track_files_.find(proto.name()); + bool is_error = + itr != pool_->unused_import_track_files_.end() && itr->second; for (std::set::const_iterator it = unused_dependency_.begin(); it != unused_dependency_.end(); ++it) { - // Log warnings for unused imported files. std::string error_message = "Import " + (*it)->name() + " is unused."; - AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT, + if (is_error) { + AddError((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT, error_message); + } else { + AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT, + error_message); + } } } } -Symbol DescriptorPool::CrossLinkOnDemandHelper(const std::string& name, +Symbol DescriptorPool::CrossLinkOnDemandHelper(StringPiece name, bool expecting_enum) const { - std::string lookup_name = name; + auto lookup_name = std::string(name); if (!lookup_name.empty() && lookup_name[0] == '.') { lookup_name = lookup_name.substr(1); } @@ -7311,7 +7408,7 @@ void LazyDescriptor::Set(const Descriptor* descriptor) { descriptor_ = descriptor; } -void LazyDescriptor::SetLazy(const std::string& name, +void LazyDescriptor::SetLazy(StringPiece name, const FileDescriptor* file) { // verify Init() has been called and Set hasn't been called yet. GOOGLE_CHECK(!descriptor_); @@ -7347,3 +7444,5 @@ void LazyDescriptor::OnceInternal() { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 8a75142debcc..0625b5022156 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -54,14 +54,17 @@ #ifndef GOOGLE_PROTOBUF_DESCRIPTOR_H__ #define GOOGLE_PROTOBUF_DESCRIPTOR_H__ +#include +#include #include #include #include #include + #include #include #include - +#include #include // TYPE_BOOL is defined in the MacOS's ConditionalMacros.h. @@ -201,7 +204,7 @@ class PROTOBUF_EXPORT LazyDescriptor { // build time if the symbol wasn't found and building of the file containing // that type is delayed because lazily_build_dependencies_ is set on the pool. // Should not be called after Set() has been called. - void SetLazy(const std::string& name, const FileDescriptor* file); + void SetLazy(StringPiece name, const FileDescriptor* file); // Returns the current value of the descriptor, thread-safe. If SetLazy(...) // has been called, will do a one-time cross link of the type specified, @@ -277,6 +280,36 @@ class PROTOBUF_EXPORT Descriptor { // with AllowUnknownDependencies() set. bool is_placeholder() const; + enum WellKnownType { + WELLKNOWNTYPE_UNSPECIFIED, // Not a well-known type. + + // Wrapper types. + WELLKNOWNTYPE_DOUBLEVALUE, // google.protobuf.DoubleValue + WELLKNOWNTYPE_FLOATVALUE, // google.protobuf.FloatValue + WELLKNOWNTYPE_INT64VALUE, // google.protobuf.Int64Value + WELLKNOWNTYPE_UINT64VALUE, // google.protobuf.UInt64Value + WELLKNOWNTYPE_INT32VALUE, // google.protobuf.Int32Value + WELLKNOWNTYPE_UINT32VALUE, // google.protobuf.UInt32Value + WELLKNOWNTYPE_STRINGVALUE, // google.protobuf.StringValue + WELLKNOWNTYPE_BYTESVALUE, // google.protobuf.BytesValue + WELLKNOWNTYPE_BOOLVALUE, // google.protobuf.BoolValue + + // Other well known types. + WELLKNOWNTYPE_ANY, // google.protobuf.Any + WELLKNOWNTYPE_FIELDMASK, // google.protobuf.FieldMask + WELLKNOWNTYPE_DURATION, // google.protobuf.Duration + WELLKNOWNTYPE_TIMESTAMP, // google.protobuf.Timestamp + WELLKNOWNTYPE_VALUE, // google.protobuf.Value + WELLKNOWNTYPE_LISTVALUE, // google.protobuf.ListValue + WELLKNOWNTYPE_STRUCT, // google.protobuf.Struct + + // New well-known types may be added in the future. + // Please make sure any switch() statements have a 'default' case. + __WELLKNOWNTYPE__DO_NOT_USE__ADD_DEFAULT_INSTEAD__, + }; + + WellKnownType well_known_type() const; + // Field stuff ----------------------------------------------------- // The number of fields in this message type. @@ -289,29 +322,33 @@ class PROTOBUF_EXPORT Descriptor { // exists. const FieldDescriptor* FindFieldByNumber(int number) const; // Looks up a field by name. Returns nullptr if no such field exists. - const FieldDescriptor* FindFieldByName(const std::string& name) const; + const FieldDescriptor* FindFieldByName(ConstStringParam name) const; // Looks up a field by lowercased name (as returned by lowercase_name()). // This lookup may be ambiguous if multiple field names differ only by case, // in which case the field returned is chosen arbitrarily from the matches. const FieldDescriptor* FindFieldByLowercaseName( - const std::string& lowercase_name) const; + ConstStringParam lowercase_name) const; // Looks up a field by camel-case name (as returned by camelcase_name()). // This lookup may be ambiguous if multiple field names differ in a way that // leads them to have identical camel-case names, in which case the field // returned is chosen arbitrarily from the matches. const FieldDescriptor* FindFieldByCamelcaseName( - const std::string& camelcase_name) const; + ConstStringParam camelcase_name) const; // The number of oneofs in this message type. int oneof_decl_count() const; + // The number of oneofs in this message type, excluding synthetic oneofs. + // Real oneofs always come first, so iterating up to real_oneof_decl_cout() + // will yield all real oneofs. + int real_oneof_decl_count() const; // Get a oneof by index, where 0 <= index < oneof_decl_count(). // These are returned in the order they were defined in the .proto file. const OneofDescriptor* oneof_decl(int index) const; // Looks up a oneof by name. Returns nullptr if no such oneof exists. - const OneofDescriptor* FindOneofByName(const std::string& name) const; + const OneofDescriptor* FindOneofByName(ConstStringParam name) const; // Nested type stuff ----------------------------------------------- @@ -323,7 +360,7 @@ class PROTOBUF_EXPORT Descriptor { // Looks up a nested type by name. Returns nullptr if no such nested type // exists. - const Descriptor* FindNestedTypeByName(const std::string& name) const; + const Descriptor* FindNestedTypeByName(ConstStringParam name) const; // Enum stuff ------------------------------------------------------ @@ -335,11 +372,11 @@ class PROTOBUF_EXPORT Descriptor { // Looks up an enum type by name. Returns nullptr if no such enum type // exists. - const EnumDescriptor* FindEnumTypeByName(const std::string& name) const; + const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const; // Looks up an enum value by name, among all enum types in this message. // Returns nullptr if no such value exists. - const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const; + const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const; // Extensions ------------------------------------------------------ @@ -372,8 +409,30 @@ class PROTOBUF_EXPORT Descriptor { // Returns nullptr if no extension range contains the given number. const ExtensionRange* FindExtensionRangeContainingNumber(int number) const; - // The number of extensions -- extending *other* messages -- that were - // defined nested within this message type's scope. + // The number of extensions defined nested within this message type's scope. + // See doc: + // https://developers.google.com/protocol-buffers/docs/proto#nested-extensions + // + // Note that the extensions may be extending *other* messages. + // + // For example: + // message M1 { + // extensions 1 to max; + // } + // + // message M2 { + // extend M1 { + // optional int32 foo = 1; + // } + // } + // + // In this case, + // DescriptorPool::generated_pool() + // ->FindMessageTypeByName("M2") + // ->extension(0) + // will return "foo", even though "foo" is an extension of M1. + // To find all known extensions of a given message, instead use + // DescriptorPool::FindAllExtensions. int extension_count() const; // Get an extension by index, where 0 <= index < extension_count(). // These are returned in the order they were defined in the .proto file. @@ -381,17 +440,17 @@ class PROTOBUF_EXPORT Descriptor { // Looks up a named extension (which extends some *other* message type) // defined within this message type's scope. - const FieldDescriptor* FindExtensionByName(const std::string& name) const; + const FieldDescriptor* FindExtensionByName(ConstStringParam name) const; // Similar to FindFieldByLowercaseName(), but finds extensions defined within // this message type's scope. const FieldDescriptor* FindExtensionByLowercaseName( - const std::string& name) const; + ConstStringParam name) const; // Similar to FindFieldByCamelcaseName(), but finds extensions defined within // this message type's scope. const FieldDescriptor* FindExtensionByCamelcaseName( - const std::string& name) const; + ConstStringParam name) const; // Reserved fields ------------------------------------------------- @@ -421,7 +480,7 @@ class PROTOBUF_EXPORT Descriptor { const std::string& reserved_name(int index) const; // Returns true if the field name is reserved. - bool IsReservedName(const std::string& name) const; + bool IsReservedName(ConstStringParam name) const; // Source Location --------------------------------------------------- @@ -430,6 +489,16 @@ class PROTOBUF_EXPORT Descriptor { // |*out_location| unchanged iff location information was not available. bool GetSourceLocation(SourceLocation* out_location) const; + // Maps -------------------------------------------------------------- + + // Returns the FieldDescriptor for the "key" field. If this isn't a map entry + // field, returns nullptr. + const FieldDescriptor* map_key() const; + + // Returns the FieldDescriptor for the "value" field. If this isn't a map + // entry field, returns nullptr. + const FieldDescriptor* map_value() const; + private: typedef MessageOptions OptionsType; @@ -473,6 +542,7 @@ class PROTOBUF_EXPORT Descriptor { int field_count_; int oneof_decl_count_; + int real_oneof_decl_count_; int nested_type_count_; int enum_type_count_; int extension_range_count_; @@ -484,6 +554,8 @@ class PROTOBUF_EXPORT Descriptor { bool is_placeholder_; // True if this is a placeholder and the type name wasn't fully-qualified. bool is_unqualified_placeholder_; + // Well known type. Stored as char to conserve space. + char well_known_type_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in descriptor.cc @@ -629,6 +701,19 @@ class PROTOBUF_EXPORT FieldDescriptor { bool is_map() const; // shorthand for type() == TYPE_MESSAGE && // message_type()->options().map_entry() + // Returns true if this field was syntactically written with "optional" in the + // .proto file. Excludes singular proto3 fields that do not have a label. + bool has_optional_keyword() const; + + // Returns true if this field tracks presence, ie. does the field + // distinguish between "unset" and "present with default value." + // This includes required, optional, and oneof fields. It excludes maps, + // repeated fields, and singular proto3 fields without "optional". + // + // For fields where has_presence() == true, the return value of + // Reflection::HasField() is semantically meaningful. + bool has_presence() const; + // Index of this field within the message's field array, or the file or // extension scope's extensions array. int index() const; @@ -678,6 +763,10 @@ class PROTOBUF_EXPORT FieldDescriptor { // nullptr. const OneofDescriptor* containing_oneof() const; + // If the field is a member of a non-synthetic oneof, returns the descriptor + // for the oneof, otherwise returns nullptr. + const OneofDescriptor* real_containing_oneof() const; + // If the field is a member of a oneof, returns the index in that oneof. int index_in_oneof() const; @@ -751,14 +840,13 @@ class PROTOBUF_EXPORT FieldDescriptor { // Allows access to GetLocationPath for annotations. friend class io::Printer; friend class compiler::cpp::Formatter; + friend class Reflection; // Fill the json_name field of FieldDescriptorProto. void CopyJsonNameTo(FieldDescriptorProto* proto) const; // See Descriptor::DebugString(). - enum PrintLabelFlag { PRINT_LABEL, OMIT_LABEL }; - void DebugString(int depth, PrintLabelFlag print_label_flag, - std::string* contents, + void DebugString(int depth, std::string* contents, const DebugStringOptions& options) const; // formats the default value appropriately and returns it as a string. @@ -790,6 +878,7 @@ class PROTOBUF_EXPORT FieldDescriptor { mutable Type type_; Label label_; bool has_default_value_; + bool proto3_optional_; // Whether the user has specified the json_name field option in the .proto // file. bool has_json_name_; @@ -819,6 +908,7 @@ class PROTOBUF_EXPORT FieldDescriptor { mutable const EnumValueDescriptor* default_value_enum_; const std::string* default_value_string_; + mutable std::atomic default_generated_instance_; }; static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; @@ -850,6 +940,10 @@ class PROTOBUF_EXPORT OneofDescriptor { // Index of this oneof within the message's oneof array. int index() const; + // Returns whether this oneof was inserted by the compiler to wrap a proto3 + // optional field. If this returns true, code generators should *not* emit it. + bool is_synthetic() const; + // The .proto file in which this oneof was defined. Never nullptr. const FileDescriptor* file() const; // The Descriptor for the message containing this oneof. @@ -939,7 +1033,7 @@ class PROTOBUF_EXPORT EnumDescriptor { const EnumValueDescriptor* value(int index) const; // Looks up a value by name. Returns nullptr if no such value exists. - const EnumValueDescriptor* FindValueByName(const std::string& name) const; + const EnumValueDescriptor* FindValueByName(ConstStringParam name) const; // Looks up a value by number. Returns nullptr if no such value exists. If // multiple values have this number, the first one defined is returned. const EnumValueDescriptor* FindValueByNumber(int number) const; @@ -997,7 +1091,7 @@ class PROTOBUF_EXPORT EnumDescriptor { const std::string& reserved_name(int index) const; // Returns true if the field name is reserved. - bool IsReservedName(const std::string& name) const; + bool IsReservedName(ConstStringParam name) const; // Source Location --------------------------------------------------- @@ -1144,6 +1238,7 @@ class PROTOBUF_EXPORT EnumValueDescriptor { friend class EnumDescriptor; friend class DescriptorPool; friend class FileDescriptorTables; + friend class Reflection; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); }; @@ -1176,7 +1271,7 @@ class PROTOBUF_EXPORT ServiceDescriptor { const MethodDescriptor* method(int index) const; // Look up a MethodDescriptor by name. - const MethodDescriptor* FindMethodByName(const std::string& name) const; + const MethodDescriptor* FindMethodByName(ConstStringParam name) const; // See Descriptor::CopyTo(). void CopyTo(ServiceDescriptorProto* proto) const; @@ -1396,26 +1491,27 @@ class PROTOBUF_EXPORT FileDescriptor { Syntax syntax() const; static const char* SyntaxName(Syntax syntax); - // Find a top-level message type by name. Returns nullptr if not found. - const Descriptor* FindMessageTypeByName(const std::string& name) const; + // Find a top-level message type by name (not full_name). Returns nullptr if + // not found. + const Descriptor* FindMessageTypeByName(ConstStringParam name) const; // Find a top-level enum type by name. Returns nullptr if not found. - const EnumDescriptor* FindEnumTypeByName(const std::string& name) const; + const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const; // Find an enum value defined in any top-level enum by name. Returns nullptr // if not found. - const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const; + const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const; // Find a service definition by name. Returns nullptr if not found. - const ServiceDescriptor* FindServiceByName(const std::string& name) const; + const ServiceDescriptor* FindServiceByName(ConstStringParam name) const; // Find a top-level extension definition by name. Returns nullptr if not // found. - const FieldDescriptor* FindExtensionByName(const std::string& name) const; + const FieldDescriptor* FindExtensionByName(ConstStringParam name) const; // Similar to FindExtensionByName(), but searches by lowercased-name. See // Descriptor::FindFieldByLowercaseName(). const FieldDescriptor* FindExtensionByLowercaseName( - const std::string& name) const; + ConstStringParam name) const; // Similar to FindExtensionByName(), but searches by camelcased-name. See // Descriptor::FindFieldByCamelcaseName(). const FieldDescriptor* FindExtensionByCamelcaseName( - const std::string& name) const; + ConstStringParam name) const; // See Descriptor::CopyTo(). // Notes: @@ -1578,28 +1674,28 @@ class PROTOBUF_EXPORT DescriptorPool { // Find a FileDescriptor in the pool by file name. Returns nullptr if not // found. - const FileDescriptor* FindFileByName(const std::string& name) const; + const FileDescriptor* FindFileByName(ConstStringParam name) const; // Find the FileDescriptor in the pool which defines the given symbol. // If any of the Find*ByName() methods below would succeed, then this is // equivalent to calling that method and calling the result's file() method. // Otherwise this returns nullptr. const FileDescriptor* FindFileContainingSymbol( - const std::string& symbol_name) const; + ConstStringParam symbol_name) const; // Looking up descriptors ------------------------------------------ // These find descriptors by fully-qualified name. These will find both // top-level descriptors and nested descriptors. They return nullptr if not // found. - const Descriptor* FindMessageTypeByName(const std::string& name) const; - const FieldDescriptor* FindFieldByName(const std::string& name) const; - const FieldDescriptor* FindExtensionByName(const std::string& name) const; - const OneofDescriptor* FindOneofByName(const std::string& name) const; - const EnumDescriptor* FindEnumTypeByName(const std::string& name) const; - const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const; - const ServiceDescriptor* FindServiceByName(const std::string& name) const; - const MethodDescriptor* FindMethodByName(const std::string& name) const; + const Descriptor* FindMessageTypeByName(ConstStringParam name) const; + const FieldDescriptor* FindFieldByName(ConstStringParam name) const; + const FieldDescriptor* FindExtensionByName(ConstStringParam name) const; + const OneofDescriptor* FindOneofByName(ConstStringParam name) const; + const EnumDescriptor* FindEnumTypeByName(ConstStringParam name) const; + const EnumValueDescriptor* FindEnumValueByName(ConstStringParam name) const; + const ServiceDescriptor* FindServiceByName(ConstStringParam name) const; + const MethodDescriptor* FindMethodByName(ConstStringParam name) const; // Finds an extension of the given type by number. The extendee must be // a member of this DescriptorPool or one of its underlays. @@ -1612,7 +1708,7 @@ class PROTOBUF_EXPORT DescriptorPool { // or one of its underlays. Returns nullptr if there is no known message // extension with the given printable name. const FieldDescriptor* FindExtensionByPrintableName( - const Descriptor* extendee, const std::string& printable_name) const; + const Descriptor* extendee, ConstStringParam printable_name) const; // Finds extensions of extendee. The extensions will be appended to // out in an undefined order. Only extensions defined directly in @@ -1752,6 +1848,11 @@ class PROTOBUF_EXPORT DescriptorPool { // the underlay takes precedence. static DescriptorPool* internal_generated_pool(); + // For internal use only: Gets a non-const pointer to the generated + // descriptor database. + // Only used for testing. + static DescriptorDatabase* internal_generated_database(); + // For internal use only: Changes the behavior of BuildFile() such that it // allows the file to make reference to message types declared in other files // which it did not officially declare as dependencies. @@ -1761,7 +1862,7 @@ class PROTOBUF_EXPORT DescriptorPool { // Delay the building of dependencies of a file descriptor until absolutely // necessary, like when message_type() is called on a field that is defined // in that dependency's file. This will cause functional issues if a proto - // or one of it's dependencies has errors. Should only be enabled for the + // or one of its dependencies has errors. Should only be enabled for the // generated_pool_ (because no descriptor build errors are guaranteed by // the compilation generation process), testing, or if a lack of descriptor // build errors can be guaranteed for a pool. @@ -1780,11 +1881,12 @@ class PROTOBUF_EXPORT DescriptorPool { // For internal (unit test) use only: Returns true if a FileDescriptor has // been constructed for the given file, false otherwise. Useful for testing // lazy descriptor initialization behavior. - bool InternalIsFileLoaded(const std::string& filename) const; + bool InternalIsFileLoaded(ConstStringParam filename) const; // Add a file to unused_import_track_files_. DescriptorBuilder will log - // warnings for those files if there is any unused import. - void AddUnusedImportTrackFile(const std::string& file_name); + // warnings or errors for those files if there is any unused import. + void AddUnusedImportTrackFile(ConstStringParam file_name, + bool is_error = false); void ClearUnusedImportTrackFiles(); private: @@ -1802,14 +1904,14 @@ class PROTOBUF_EXPORT DescriptorPool { // Return true if the given name is a sub-symbol of any non-package // descriptor that already exists in the descriptor pool. (The full // definition of such types is already known.) - bool IsSubSymbolOfBuiltType(const std::string& name) const; + bool IsSubSymbolOfBuiltType(StringPiece name) const; // Tries to find something in the fallback database and link in the // corresponding proto file. Returns true if successful, in which case // the caller should search for the thing again. These are declared // const because they are called by (semantically) const methods. - bool TryFindFileInFallbackDatabase(const std::string& name) const; - bool TryFindSymbolInFallbackDatabase(const std::string& name) const; + bool TryFindFileInFallbackDatabase(StringPiece name) const; + bool TryFindSymbolInFallbackDatabase(StringPiece name) const; bool TryFindExtensionInFallbackDatabase(const Descriptor* containing_type, int field_number) const; @@ -1830,13 +1932,12 @@ class PROTOBUF_EXPORT DescriptorPool { // symbol is defined if necessary. Will create a placeholder if the type // doesn't exist in the fallback database, or the file doesn't build // successfully. - Symbol CrossLinkOnDemandHelper(const std::string& name, + Symbol CrossLinkOnDemandHelper(StringPiece name, bool expecting_enum) const; // Create a placeholder FileDescriptor of the specified name - FileDescriptor* NewPlaceholderFile(const std::string& name) const; - FileDescriptor* NewPlaceholderFileWithMutexHeld( - const std::string& name) const; + FileDescriptor* NewPlaceholderFile(StringPiece name) const; + FileDescriptor* NewPlaceholderFileWithMutexHeld(StringPiece name) const; enum PlaceholderType { PLACEHOLDER_MESSAGE, @@ -1844,9 +1945,9 @@ class PROTOBUF_EXPORT DescriptorPool { PLACEHOLDER_EXTENDABLE_MESSAGE }; // Create a placeholder Descriptor of the specified name - Symbol NewPlaceholder(const std::string& name, + Symbol NewPlaceholder(StringPiece name, PlaceholderType placeholder_type) const; - Symbol NewPlaceholderWithMutexHeld(const std::string& name, + Symbol NewPlaceholderWithMutexHeld(StringPiece name, PlaceholderType placeholder_type) const; // If fallback_database_ is nullptr, this is nullptr. Otherwise, this is a @@ -1868,7 +1969,10 @@ class PROTOBUF_EXPORT DescriptorPool { bool allow_unknown_; bool enforce_weak_; bool disallow_enforce_utf8_; - std::set unused_import_track_files_; + + // Set of files to track for unused imports. The bool value when true means + // unused imports are treated as errors (and as warnings when false). + std::map unused_import_track_files_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); }; @@ -1898,6 +2002,7 @@ PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(Descriptor, field_count, int) PROTOBUF_DEFINE_ACCESSOR(Descriptor, oneof_decl_count, int) +PROTOBUF_DEFINE_ACCESSOR(Descriptor, real_oneof_decl_count, int) PROTOBUF_DEFINE_ACCESSOR(Descriptor, nested_type_count, int) PROTOBUF_DEFINE_ACCESSOR(Descriptor, enum_type_count, int) @@ -2013,6 +2118,10 @@ PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension, // A few accessors differ from the macros... +inline Descriptor::WellKnownType Descriptor::well_known_type() const { + return static_cast(well_known_type_); +} + inline bool Descriptor::IsExtensionNumber(int number) const { return FindExtensionRangeContainingNumber(number) != nullptr; } @@ -2021,9 +2130,9 @@ inline bool Descriptor::IsReservedNumber(int number) const { return FindReservedRangeContainingNumber(number) != nullptr; } -inline bool Descriptor::IsReservedName(const std::string& name) const { +inline bool Descriptor::IsReservedName(ConstStringParam name) const { for (int i = 0; i < reserved_name_count(); i++) { - if (name == reserved_name(i)) { + if (name == static_cast(reserved_name(i))) { return true; } } @@ -2040,9 +2149,9 @@ inline bool EnumDescriptor::IsReservedNumber(int number) const { return FindReservedRangeContainingNumber(number) != nullptr; } -inline bool EnumDescriptor::IsReservedName(const std::string& name) const { +inline bool EnumDescriptor::IsReservedName(ConstStringParam name) const { for (int i = 0; i < reserved_name_count(); i++) { - if (name == reserved_name(i)) { + if (name == static_cast(reserved_name(i))) { return true; } } @@ -2082,6 +2191,24 @@ inline bool FieldDescriptor::is_map() const { return type() == TYPE_MESSAGE && is_map_message_type(); } +inline bool FieldDescriptor::has_optional_keyword() const { + return proto3_optional_ || + (file()->syntax() == FileDescriptor::SYNTAX_PROTO2 && is_optional() && + !containing_oneof()); +} + +inline const OneofDescriptor* FieldDescriptor::real_containing_oneof() const { + return containing_oneof_ && !containing_oneof_->is_synthetic() + ? containing_oneof_ + : nullptr; +} + +inline bool FieldDescriptor::has_presence() const { + if (is_repeated()) return false; + return cpp_type() == CPPTYPE_MESSAGE || containing_oneof() || + file()->syntax() == FileDescriptor::SYNTAX_PROTO2; +} + // To save space, index() is computed by looking at the descriptor's position // in the parent's array of children. inline int FieldDescriptor::index() const { @@ -2110,6 +2237,10 @@ inline int OneofDescriptor::index() const { return static_cast(this - containing_type_->oneof_decls_); } +inline bool OneofDescriptor::is_synthetic() const { + return field_count() == 1 && field(0)->proto3_optional_; +} + inline int EnumDescriptor::index() const { if (containing_type_ == nullptr) { return static_cast(this - file_->enum_types_); diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index c15d76c8a60b..d9590f8b8e8b 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fdescriptor_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto; @@ -157,7 +159,6 @@ static void InitDefaultsscc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_ new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_DescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -177,7 +178,6 @@ static void InitDefaultsscc_info_DescriptorProto_ExtensionRange_google_2fprotobu new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto = @@ -192,7 +192,6 @@ static void InitDefaultsscc_info_DescriptorProto_ReservedRange_google_2fprotobuf new (ptr) PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DescriptorProto_ReservedRange_google_2fprotobuf_2fdescriptor_2eproto = @@ -206,7 +205,6 @@ static void InitDefaultsscc_info_EnumDescriptorProto_google_2fprotobuf_2fdescrip new (ptr) PROTOBUF_NAMESPACE_ID::EnumDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_EnumDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -223,7 +221,6 @@ static void InitDefaultsscc_info_EnumDescriptorProto_EnumReservedRange_google_2f new (ptr) PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_EnumDescriptorProto_EnumReservedRange_google_2fprotobuf_2fdescriptor_2eproto = @@ -237,7 +234,6 @@ static void InitDefaultsscc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2epr new (ptr) PROTOBUF_NAMESPACE_ID::EnumOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -252,7 +248,6 @@ static void InitDefaultsscc_info_EnumValueDescriptorProto_google_2fprotobuf_2fde new (ptr) PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -267,7 +262,6 @@ static void InitDefaultsscc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor new (ptr) PROTOBUF_NAMESPACE_ID::EnumValueOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumValueOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValueOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -282,7 +276,6 @@ static void InitDefaultsscc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescr new (ptr) PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ExtensionRangeOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -297,7 +290,6 @@ static void InitDefaultsscc_info_FieldDescriptorProto_google_2fprotobuf_2fdescri new (ptr) PROTOBUF_NAMESPACE_ID::FieldDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FieldDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FieldDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -312,7 +304,6 @@ static void InitDefaultsscc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2ep new (ptr) PROTOBUF_NAMESPACE_ID::FieldOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FieldOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -327,7 +318,6 @@ static void InitDefaultsscc_info_FileDescriptorProto_google_2fprotobuf_2fdescrip new (ptr) PROTOBUF_NAMESPACE_ID::FileDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FileDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<6> scc_info_FileDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -347,7 +337,6 @@ static void InitDefaultsscc_info_FileDescriptorSet_google_2fprotobuf_2fdescripto new (ptr) PROTOBUF_NAMESPACE_ID::FileDescriptorSet(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FileDescriptorSet::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FileDescriptorSet_google_2fprotobuf_2fdescriptor_2eproto = @@ -362,7 +351,6 @@ static void InitDefaultsscc_info_FileOptions_google_2fprotobuf_2fdescriptor_2epr new (ptr) PROTOBUF_NAMESPACE_ID::FileOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FileOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_FileOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -377,7 +365,6 @@ static void InitDefaultsscc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescripto new (ptr) PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_GeneratedCodeInfo_google_2fprotobuf_2fdescriptor_2eproto = @@ -392,7 +379,6 @@ static void InitDefaultsscc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_ new (ptr) PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto = @@ -406,7 +392,6 @@ static void InitDefaultsscc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2 new (ptr) PROTOBUF_NAMESPACE_ID::MessageOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::MessageOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -421,7 +406,6 @@ static void InitDefaultsscc_info_MethodDescriptorProto_google_2fprotobuf_2fdescr new (ptr) PROTOBUF_NAMESPACE_ID::MethodDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::MethodDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MethodDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -436,7 +420,6 @@ static void InitDefaultsscc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2e new (ptr) PROTOBUF_NAMESPACE_ID::MethodOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::MethodOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -451,7 +434,6 @@ static void InitDefaultsscc_info_OneofDescriptorProto_google_2fprotobuf_2fdescri new (ptr) PROTOBUF_NAMESPACE_ID::OneofDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::OneofDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_OneofDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -466,7 +448,6 @@ static void InitDefaultsscc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2ep new (ptr) PROTOBUF_NAMESPACE_ID::OneofOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::OneofOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_OneofOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -481,7 +462,6 @@ static void InitDefaultsscc_info_ServiceDescriptorProto_google_2fprotobuf_2fdesc new (ptr) PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<2> scc_info_ServiceDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto = @@ -497,7 +477,6 @@ static void InitDefaultsscc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2 new (ptr) PROTOBUF_NAMESPACE_ID::ServiceOptions(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::ServiceOptions::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_ServiceOptions_google_2fprotobuf_2fdescriptor_2eproto = @@ -512,7 +491,6 @@ static void InitDefaultsscc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2 new (ptr) PROTOBUF_NAMESPACE_ID::SourceCodeInfo(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::SourceCodeInfo::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_SourceCodeInfo_google_2fprotobuf_2fdescriptor_2eproto = @@ -527,7 +505,6 @@ static void InitDefaultsscc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdes new (ptr) PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_SourceCodeInfo_Location_google_2fprotobuf_2fdescriptor_2eproto = @@ -541,7 +518,6 @@ static void InitDefaultsscc_info_UninterpretedOption_google_2fprotobuf_2fdescrip new (ptr) PROTOBUF_NAMESPACE_ID::UninterpretedOption(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UninterpretedOption::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_UninterpretedOption_google_2fprotobuf_2fdescriptor_2eproto = @@ -556,7 +532,6 @@ static void InitDefaultsscc_info_UninterpretedOption_NamePart_google_2fprotobuf_ new (ptr) PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto = @@ -567,13 +542,12 @@ static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptor static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto = nullptr; const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorSet, _has_bits_), + ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorSet, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorSet, file_), - ~0u, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FileDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ @@ -648,13 +622,12 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fdescriptor 1, ~0u, ~0u, - PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _has_bits_), + ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _internal_metadata_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions, uninterpreted_option_), - ~0u, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ @@ -670,16 +643,18 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fdescriptor PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, oneof_index_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, json_name_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, options_), + PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto, proto3_optional_), 0, 6, - 8, 9, + 10, 2, 1, 3, 7, 4, 5, + 8, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ @@ -783,14 +758,14 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fdescriptor 10, 11, 12, - 19, + 18, 2, 13, 14, 15, 16, 17, - 18, + 19, 3, 4, 5, @@ -833,13 +808,12 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fdescriptor 3, 4, ~0u, - PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofOptions, _has_bits_), + ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofOptions, _internal_metadata_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofOptions, _extensions_), ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::OneofOptions, uninterpreted_option_), - ~0u, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, _internal_metadata_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::EnumOptions, _extensions_), @@ -923,13 +897,12 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fdescriptor 0, 1, ~0u, - PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceCodeInfo, _has_bits_), + ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceCodeInfo, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::SourceCodeInfo, location_), - ~0u, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _has_bits_), PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation, _internal_metadata_), ~0u, // no _extensions_ @@ -943,22 +916,21 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fdescriptor 0, 1, 2, - PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, _has_bits_), + ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ ~0u, // no _weak_field_map_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo, annotation_), - ~0u, }; static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = { - { 0, 6, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorSet)}, - { 7, 24, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorProto)}, - { 36, 44, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange)}, - { 47, 54, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange)}, - { 56, 71, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto)}, - { 81, 87, sizeof(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions)}, - { 88, 103, sizeof(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto)}, + { 0, -1, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorSet)}, + { 6, 23, sizeof(PROTOBUF_NAMESPACE_ID::FileDescriptorProto)}, + { 35, 43, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange)}, + { 46, 53, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange)}, + { 55, 70, sizeof(PROTOBUF_NAMESPACE_ID::DescriptorProto)}, + { 80, -1, sizeof(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions)}, + { 86, 102, sizeof(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto)}, { 113, 120, sizeof(PROTOBUF_NAMESPACE_ID::OneofDescriptorProto)}, { 122, 129, sizeof(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange)}, { 131, 141, sizeof(PROTOBUF_NAMESPACE_ID::EnumDescriptorProto)}, @@ -968,17 +940,17 @@ static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOB { 185, 211, sizeof(PROTOBUF_NAMESPACE_ID::FileOptions)}, { 232, 242, sizeof(PROTOBUF_NAMESPACE_ID::MessageOptions)}, { 247, 259, sizeof(PROTOBUF_NAMESPACE_ID::FieldOptions)}, - { 266, 272, sizeof(PROTOBUF_NAMESPACE_ID::OneofOptions)}, - { 273, 281, sizeof(PROTOBUF_NAMESPACE_ID::EnumOptions)}, - { 284, 291, sizeof(PROTOBUF_NAMESPACE_ID::EnumValueOptions)}, - { 293, 300, sizeof(PROTOBUF_NAMESPACE_ID::ServiceOptions)}, - { 302, 310, sizeof(PROTOBUF_NAMESPACE_ID::MethodOptions)}, - { 313, 320, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)}, - { 322, 334, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption)}, - { 341, 351, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)}, - { 356, 362, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo)}, - { 363, 372, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)}, - { 376, 382, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)}, + { 266, -1, sizeof(PROTOBUF_NAMESPACE_ID::OneofOptions)}, + { 272, 280, sizeof(PROTOBUF_NAMESPACE_ID::EnumOptions)}, + { 283, 290, sizeof(PROTOBUF_NAMESPACE_ID::EnumValueOptions)}, + { 292, 299, sizeof(PROTOBUF_NAMESPACE_ID::ServiceOptions)}, + { 301, 309, sizeof(PROTOBUF_NAMESPACE_ID::MethodOptions)}, + { 312, 319, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption_NamePart)}, + { 321, 333, sizeof(PROTOBUF_NAMESPACE_ID::UninterpretedOption)}, + { 340, 350, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location)}, + { 355, -1, sizeof(PROTOBUF_NAMESPACE_ID::SourceCodeInfo)}, + { 361, 370, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation)}, + { 374, -1, sizeof(PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo)}, }; static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = { @@ -1046,7 +1018,7 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PR "s\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end" "\030\002 \001(\005\"g\n\025ExtensionRangeOptions\022C\n\024unint" "erpreted_option\030\347\007 \003(\0132$.google.protobuf" - ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\274\005\n\024Fiel" + ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\325\005\n\024Fiel" "dDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number" "\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobuf." "FieldDescriptorProto.Label\0228\n\004type\030\005 \001(\016" @@ -1054,115 +1026,115 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PR "Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(" "\t\022\025\n\rdefault_value\030\007 \001(\t\022\023\n\013oneof_index\030" "\t \001(\005\022\021\n\tjson_name\030\n \001(\t\022.\n\007options\030\010 \001(" - "\0132\035.google.protobuf.FieldOptions\"\266\002\n\004Typ" - "e\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTY" - "PE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT3" - "2\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022" - "\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_" - "GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020" - "\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYP" - "E_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_" - "SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LA" - "BEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LA" - "BEL_REPEATED\020\003\"T\n\024OneofDescriptorProto\022\014" - "\n\004name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.google.p" - "rotobuf.OneofOptions\"\244\002\n\023EnumDescriptorP" - "roto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).goog" - "le.protobuf.EnumValueDescriptorProto\022-\n\007" - "options\030\003 \001(\0132\034.google.protobuf.EnumOpti" - "ons\022N\n\016reserved_range\030\004 \003(\01326.google.pro" - "tobuf.EnumDescriptorProto.EnumReservedRa" - "nge\022\025\n\rreserved_name\030\005 \003(\t\032/\n\021EnumReserv" - "edRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030E" - "numValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n" - "\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google." - "protobuf.EnumValueOptions\"\220\001\n\026ServiceDes" - "criptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003" - "(\0132&.google.protobuf.MethodDescriptorPro" - "to\0220\n\007options\030\003 \001(\0132\037.google.protobuf.Se" - "rviceOptions\"\301\001\n\025MethodDescriptorProto\022\014" - "\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013outp" - "ut_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google." - "protobuf.MethodOptions\022\037\n\020client_streami" - "ng\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(" - "\010:\005false\"\246\006\n\013FileOptions\022\024\n\014java_package" - "\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023" - "java_multiple_files\030\n \001(\010:\005false\022)\n\035java" - "_generate_equals_and_hash\030\024 \001(\010B\002\030\001\022%\n\026j" - "ava_string_check_utf8\030\033 \001(\010:\005false\022F\n\014op" - "timize_for\030\t \001(\0162).google.protobuf.FileO" - "ptions.OptimizeMode:\005SPEED\022\022\n\ngo_package" - "\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fal" - "se\022$\n\025java_generic_services\030\021 \001(\010:\005false" - "\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022#\n\024" - "php_generic_services\030* \001(\010:\005false\022\031\n\ndep" - "recated\030\027 \001(\010:\005false\022\037\n\020cc_enable_arenas" - "\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030$ \001(\t" - "\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014swift_pref" - "ix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001(\t\022\025\n\rph" - "p_namespace\030) \001(\t\022\036\n\026php_metadata_namesp" - "ace\030, \001(\t\022\024\n\014ruby_package\030- \001(\t\022C\n\024unint" - "erpreted_option\030\347\007 \003(\0132$.google.protobuf" - ".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005" - "SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003" - "*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016MessageOptions\022&\n\027" - "message_set_wire_format\030\001 \001(\010:\005false\022.\n\037" - "no_standard_descriptor_accessor\030\002 \001(\010:\005f" - "alse\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_e" - "ntry\030\007 \001(\010\022C\n\024uninterpreted_option\030\347\007 \003(" - "\0132$.google.protobuf.UninterpretedOption*" - "\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014FieldOptions\022" - ":\n\005ctype\030\001 \001(\0162#.google.protobuf.FieldOp" - "tions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\?\n\006j" - "stype\030\006 \001(\0162$.google.protobuf.FieldOptio" - "ns.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010:\005fals" - "e\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001" - "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013" - "2$.google.protobuf.UninterpretedOption\"/" - "\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_" - "PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_S" - "TRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\"" - "^\n\014OneofOptions\022C\n\024uninterpreted_option\030" + "\0132\035.google.protobuf.FieldOptions\022\027\n\017prot" + "o3_optional\030\021 \001(\010\"\266\002\n\004Type\022\017\n\013TYPE_DOUBL" + "E\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013T" + "YPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIX" + "ED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022" + "\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE" + "_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT3" + "2\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n" + "\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYP" + "E_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022" + "\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"" + "T\n\024OneofDescriptorProto\022\014\n\004name\030\001 \001(\t\022.\n" + "\007options\030\002 \001(\0132\035.google.protobuf.OneofOp" + "tions\"\244\002\n\023EnumDescriptorProto\022\014\n\004name\030\001 " + "\001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.Enu" + "mValueDescriptorProto\022-\n\007options\030\003 \001(\0132\034" + ".google.protobuf.EnumOptions\022N\n\016reserved" + "_range\030\004 \003(\01326.google.protobuf.EnumDescr" + "iptorProto.EnumReservedRange\022\025\n\rreserved" + "_name\030\005 \003(\t\032/\n\021EnumReservedRange\022\r\n\005star" + "t\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"l\n\030EnumValueDescrip" + "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222" + "\n\007options\030\003 \001(\0132!.google.protobuf.EnumVa" + "lueOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n" + "\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.pro" + "tobuf.MethodDescriptorProto\0220\n\007options\030\003" + " \001(\0132\037.google.protobuf.ServiceOptions\"\301\001" + "\n\025MethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n" + "\ninput_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/" + "\n\007options\030\004 \001(\0132\036.google.protobuf.Method" + "Options\022\037\n\020client_streaming\030\005 \001(\010:\005false" + "\022\037\n\020server_streaming\030\006 \001(\010:\005false\"\245\006\n\013Fi" + "leOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java_" + "outer_classname\030\010 \001(\t\022\"\n\023java_multiple_f" + "iles\030\n \001(\010:\005false\022)\n\035java_generate_equal" + "s_and_hash\030\024 \001(\010B\002\030\001\022%\n\026java_string_chec" + "k_utf8\030\033 \001(\010:\005false\022F\n\014optimize_for\030\t \001(" + "\0162).google.protobuf.FileOptions.Optimize" + "Mode:\005SPEED\022\022\n\ngo_package\030\013 \001(\t\022\"\n\023cc_ge" + "neric_services\030\020 \001(\010:\005false\022$\n\025java_gene" + "ric_services\030\021 \001(\010:\005false\022\"\n\023py_generic_" + "services\030\022 \001(\010:\005false\022#\n\024php_generic_ser" + "vices\030* \001(\010:\005false\022\031\n\ndeprecated\030\027 \001(\010:\005" + "false\022\036\n\020cc_enable_arenas\030\037 \001(\010:\004true\022\031\n" + "\021objc_class_prefix\030$ \001(\t\022\030\n\020csharp_names" + "pace\030% \001(\t\022\024\n\014swift_prefix\030\' \001(\t\022\030\n\020php_" + "class_prefix\030( \001(\t\022\025\n\rphp_namespace\030) \001(" + "\t\022\036\n\026php_metadata_namespace\030, \001(\t\022\024\n\014rub" + "y_package\030- \001(\t\022C\n\024uninterpreted_option\030" "\347\007 \003(\0132$.google.protobuf.UninterpretedOp" - "tion*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOptions\022\023\n\013allow" - "_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022" + "tion\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_" + "SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020" + "\'\"\362\001\n\016MessageOptions\022&\n\027message_set_wire" + "_format\030\001 \001(\010:\005false\022.\n\037no_standard_desc" + "riptor_accessor\030\002 \001(\010:\005false\022\031\n\ndeprecat" + "ed\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024un" + "interpreted_option\030\347\007 \003(\0132$.google.proto" + "buf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\t" + "J\004\010\t\020\n\"\236\003\n\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#" + ".google.protobuf.FieldOptions.CType:\006STR" + "ING\022\016\n\006packed\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$.go" + "ogle.protobuf.FieldOptions.JSType:\tJS_NO" + "RMAL\022\023\n\004lazy\030\005 \001(\010:\005false\022\031\n\ndeprecated\030" + "\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:\005false\022C\n\024uni" + "nterpreted_option\030\347\007 \003(\0132$.google.protob" + "uf.UninterpretedOption\"/\n\005CType\022\n\n\006STRIN" + "G\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002\"5\n\006JSTyp" + "e\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRING\020\001\022\r\n\tJS_NU" + "MBER\020\002*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005\"^\n\014OneofOptions\022" "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google." - "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J" - "\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030" - "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 " - "\003(\0132$.google.protobuf.UninterpretedOptio" - "n*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprec" - "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio" - "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted" - "Option*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\nd" - "eprecated\030! \001(\010:\005false\022_\n\021idempotency_le" - "vel\030\" \001(\0162/.google.protobuf.MethodOption" - "s.IdempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022" - "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google." - "protobuf.UninterpretedOption\"P\n\020Idempote" - "ncyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_" - "SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200" - "\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132" - "-.google.protobuf.UninterpretedOption.Na" - "mePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posi" - "tive_int_value\030\004 \001(\004\022\032\n\022negative_int_val" - "ue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string" - "_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n" - "\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exten" - "sion\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locatio" - "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo" - ".Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001" - "\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003" - " \001(\t\022\031\n\021trailing_comments\030\004 \001(\t\022!\n\031leadi" - "ng_detached_comments\030\006 \003(\t\"\247\001\n\021Generated" - "CodeInfo\022A\n\nannotation\030\001 \003(\0132-.google.pr" - "otobuf.GeneratedCodeInfo.Annotation\032O\n\nA" - "nnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_fi" - "le\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\217\001\n" - "\023com.google.protobufB\020DescriptorProtosH\001" - "Z>github.com/golang/protobuf/protoc-gen-" - "go/descriptor;descriptor\370\001\001\242\002\003GPB\252\002\032Goog" - "le.Protobuf.Reflection" + "protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"" + "\223\001\n\013EnumOptions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\n" + "deprecated\030\003 \001(\010:\005false\022C\n\024uninterpreted" + "_option\030\347\007 \003(\0132$.google.protobuf.Uninter" + "pretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\"}\n\020EnumVal" + "ueOptions\022\031\n\ndeprecated\030\001 \001(\010:\005false\022C\n\024" + "uninterpreted_option\030\347\007 \003(\0132$.google.pro" + "tobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016" + "ServiceOptions\022\031\n\ndeprecated\030! \001(\010:\005fals" + "e\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl" + "e.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200" + "\002\"\255\002\n\rMethodOptions\022\031\n\ndeprecated\030! \001(\010:" + "\005false\022_\n\021idempotency_level\030\" \001(\0162/.goog" + "le.protobuf.MethodOptions.IdempotencyLev" + "el:\023IDEMPOTENCY_UNKNOWN\022C\n\024uninterpreted" + "_option\030\347\007 \003(\0132$.google.protobuf.Uninter" + "pretedOption\"P\n\020IdempotencyLevel\022\027\n\023IDEM" + "POTENCY_UNKNOWN\020\000\022\023\n\017NO_SIDE_EFFECTS\020\001\022\016" + "\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninterpre" + "tedOption\022;\n\004name\030\002 \003(\0132-.google.protobu" + "f.UninterpretedOption.NamePart\022\030\n\020identi" + "fier_value\030\003 \001(\t\022\032\n\022positive_int_value\030\004" + " \001(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014doub" + "le_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017" + "aggregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tnam" + "e_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016S" + "ourceCodeInfo\022:\n\010location\030\001 \003(\0132(.google" + ".protobuf.SourceCodeInfo.Location\032\206\001\n\010Lo" + "cation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002" + "\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trailing" + "_comments\030\004 \001(\t\022!\n\031leading_detached_comm" + "ents\030\006 \003(\t\"\247\001\n\021GeneratedCodeInfo\022A\n\nanno" + "tation\030\001 \003(\0132-.google.protobuf.Generated" + "CodeInfo.Annotation\032O\n\nAnnotation\022\020\n\004pat" + "h\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001(\t\022\r\n\005begi" + "n\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B~\n\023com.google.proto" + "bufB\020DescriptorProtosH\001Z-google.golang.o" + "rg/protobuf/types/descriptorpb\370\001\001\242\002\003GPB\252" + "\002\032Google.Protobuf.Reflection" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_deps[1] = { }; @@ -1196,16 +1168,15 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_UninterpretedOption_NamePart_google_2fprotobuf_2fdescriptor_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = { - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", 6022, + false, false, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", 6028, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_sccs, descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_deps, 27, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fdescriptor_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto, 27, file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto, file_level_service_descriptors_google_2fprotobuf_2fdescriptor_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); PROTOBUF_NAMESPACE_OPEN const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* FieldDescriptorProto_Type_descriptor() { ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); @@ -1378,21 +1349,12 @@ constexpr int MethodOptions::IdempotencyLevel_ARRAYSIZE; // =================================================================== -void FileDescriptorSet::InitAsDefaultInstance() { -} class FileDescriptorSet::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); }; -FileDescriptorSet::FileDescriptorSet() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorSet) -} FileDescriptorSet::FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), file_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -1400,10 +1362,8 @@ FileDescriptorSet::FileDescriptorSet(::PROTOBUF_NAMESPACE_ID::Arena* arena) } FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), file_(from.file_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet) } @@ -1414,10 +1374,11 @@ void FileDescriptorSet::SharedCtor() { FileDescriptorSet::~FileDescriptorSet() { // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void FileDescriptorSet::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void FileDescriptorSet::ArenaDtor(void* object) { @@ -1442,13 +1403,11 @@ void FileDescriptorSet::Clear() { (void) cached_has_bits; file_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* FileDescriptorSet::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1472,7 +1431,9 @@ const char* FileDescriptorSet::_InternalParse(const char* ptr, ::PROTOBUF_NAMESP ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1502,7 +1463,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FileDescriptorSet::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet) return target; @@ -1550,7 +1511,7 @@ void FileDescriptorSet::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1578,8 +1539,7 @@ bool FileDescriptorSet::IsInitialized() const { void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); file_.InternalSwap(&other->file_); } @@ -1590,12 +1550,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorSet::GetMetadata() const { // =================================================================== -void FileDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::FileOptions*>( - PROTOBUF_NAMESPACE_ID::FileOptions::internal_default_instance()); - PROTOBUF_NAMESPACE_ID::_FileDescriptorProto_default_instance_._instance.get_mutable()->source_code_info_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceCodeInfo*>( - PROTOBUF_NAMESPACE_ID::SourceCodeInfo::internal_default_instance()); -} class FileDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -1626,40 +1580,8 @@ const PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_Internal::source_code_info(const FileDescriptorProto* msg) { return *msg->source_code_info_; } -void FileDescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::FileOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options) -} -void FileDescriptorProto::unsafe_arena_set_allocated_source_code_info( - PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) { - if (GetArenaNoVirtual() == nullptr) { - delete source_code_info_; - } - source_code_info_ = source_code_info; - if (source_code_info) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info) -} -FileDescriptorProto::FileDescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorProto) -} FileDescriptorProto::FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), dependency_(arena), message_type_(arena), enum_type_(arena), @@ -1673,7 +1595,6 @@ FileDescriptorProto::FileDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) } FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), dependency_(from.dependency_), message_type_(from.message_type_), @@ -1682,21 +1603,21 @@ FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) extension_(from.extension_), public_dependency_(from.public_dependency_), weak_dependency_(from.weak_dependency_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_package()) { - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_package(), - GetArenaNoVirtual()); + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_package(), + GetArena()); } syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_syntax()) { - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_syntax(), - GetArenaNoVirtual()); + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_syntax(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::FileOptions(*from.options_); @@ -1716,18 +1637,20 @@ void FileDescriptorProto::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&source_code_info_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&source_code_info_) - reinterpret_cast(&options_)) + sizeof(source_code_info_)); } FileDescriptorProto::~FileDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void FileDescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); syntax_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); @@ -1784,13 +1707,12 @@ void FileDescriptorProto::Clear() { } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* FileDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1943,7 +1865,9 @@ const char* FileDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAME ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -2067,7 +1991,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FileDescriptorProto::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto) return target; @@ -2200,7 +2124,7 @@ void FileDescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -2258,7 +2182,7 @@ bool FileDescriptorProto::IsInitialized() const { void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); dependency_.InternalSwap(&other->dependency_); message_type_.InternalSwap(&other->message_type_); @@ -2267,14 +2191,15 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { extension_.InternalSwap(&other->extension_); public_dependency_.InternalSwap(&other->public_dependency_); weak_dependency_.InternalSwap(&other->weak_dependency_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - package_.Swap(&other->package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - syntax_.Swap(&other->syntax_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(options_, other->options_); - swap(source_code_info_, other->source_code_info_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + package_.Swap(&other->package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + syntax_.Swap(&other->syntax_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FileDescriptorProto, source_code_info_) + + sizeof(FileDescriptorProto::source_code_info_) + - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, options_)>( + reinterpret_cast(&options_), + reinterpret_cast(&other->options_)); } ::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorProto::GetMetadata() const { @@ -2284,10 +2209,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata FileDescriptorProto::GetMetadata() const { // =================================================================== -void DescriptorProto_ExtensionRange::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_DescriptorProto_ExtensionRange_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions*>( - PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions::internal_default_instance()); -} class DescriptorProto_ExtensionRange::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -2307,36 +2228,16 @@ const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_Internal::options(const DescriptorProto_ExtensionRange* msg) { return *msg->options_; } -void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options) -} -DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ExtensionRange) -} DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange) } DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions(*from.options_); } else { @@ -2350,18 +2251,20 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorP void DescriptorProto_ExtensionRange::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_DescriptorProto_ExtensionRange_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&options_)) + sizeof(end_)); } DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void DescriptorProto_ExtensionRange::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); if (this != internal_default_instance()) delete options_; } @@ -2397,13 +2300,12 @@ void DescriptorProto_ExtensionRange::Clear() { reinterpret_cast(&start_)) + sizeof(end_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -2438,7 +2340,9 @@ const char* DescriptorProto_ExtensionRange::_InternalParse(const char* ptr, ::PR ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -2482,7 +2386,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* DescriptorProto_ExtensionRange::_InternalSeriali if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange) return target; @@ -2547,7 +2451,7 @@ void DescriptorProto_ExtensionRange::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Me void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -2589,11 +2493,14 @@ bool DescriptorProto_ExtensionRange::IsInitialized() const { void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - swap(options_, other->options_); - swap(start_, other->start_); - swap(end_, other->end_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_) + + sizeof(DescriptorProto_ExtensionRange::end_) + - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, options_)>( + reinterpret_cast(&options_), + reinterpret_cast(&other->options_)); } ::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { @@ -2603,8 +2510,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ExtensionRange::GetMetadata() // =================================================================== -void DescriptorProto_ReservedRange::InitAsDefaultInstance() { -} class DescriptorProto_ReservedRange::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -2616,23 +2521,16 @@ class DescriptorProto_ReservedRange::_Internal { } }; -DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ReservedRange) -} DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange) } DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::memcpy(&start_, &from.start_, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&start_)) + sizeof(end_)); @@ -2640,18 +2538,20 @@ DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorPro } void DescriptorProto_ReservedRange::SharedCtor() { - ::memset(&start_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&start_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&start_)) + sizeof(end_)); } DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() { // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void DescriptorProto_ReservedRange::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void DescriptorProto_ReservedRange::ArenaDtor(void* object) { @@ -2682,13 +2582,12 @@ void DescriptorProto_ReservedRange::Clear() { reinterpret_cast(&start_)) + sizeof(end_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -2716,7 +2615,9 @@ const char* DescriptorProto_ReservedRange::_InternalParse(const char* ptr, ::PRO ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -2752,7 +2653,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* DescriptorProto_ReservedRange::_InternalSerializ if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ReservedRange) return target; @@ -2810,7 +2711,7 @@ void DescriptorProto_ReservedRange::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Mes void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRange& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -2846,10 +2747,14 @@ bool DescriptorProto_ReservedRange::IsInitialized() const { void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - swap(start_, other->start_); - swap(end_, other->end_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, end_) + + sizeof(DescriptorProto_ReservedRange::end_) + - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, start_)>( + reinterpret_cast(&start_), + reinterpret_cast(&other->start_)); } ::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ReservedRange::GetMetadata() const { @@ -2859,10 +2764,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto_ReservedRange::GetMetadata() c // =================================================================== -void DescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_DescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::MessageOptions*>( - PROTOBUF_NAMESPACE_ID::MessageOptions::internal_default_instance()); -} class DescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -2879,27 +2780,8 @@ const PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_Internal::options(const DescriptorProto* msg) { return *msg->options_; } -void DescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::MessageOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options) -} -DescriptorProto::DescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto) -} DescriptorProto::DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), field_(arena), nested_type_(arena), enum_type_(arena), @@ -2914,7 +2796,6 @@ DescriptorProto::DescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) } DescriptorProto::DescriptorProto(const DescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), field_(from.field_), nested_type_(from.nested_type_), @@ -2924,11 +2805,11 @@ DescriptorProto::DescriptorProto(const DescriptorProto& from) oneof_decl_(from.oneof_decl_), reserved_range_(from.reserved_range_), reserved_name_(from.reserved_name_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::MessageOptions(*from.options_); @@ -2947,10 +2828,11 @@ void DescriptorProto::SharedCtor() { DescriptorProto::~DescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void DescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete options_; } @@ -2995,13 +2877,12 @@ void DescriptorProto::Clear() { } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* DescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -3131,7 +3012,9 @@ const char* DescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPAC ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -3239,7 +3122,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* DescriptorProto::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto) return target; @@ -3354,7 +3237,7 @@ void DescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void DescriptorProto::MergeFrom(const DescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -3406,7 +3289,7 @@ bool DescriptorProto::IsInitialized() const { void DescriptorProto::InternalSwap(DescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); field_.InternalSwap(&other->field_); nested_type_.InternalSwap(&other->nested_type_); @@ -3416,8 +3299,7 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { oneof_decl_.InternalSwap(&other->oneof_decl_); reserved_range_.InternalSwap(&other->reserved_range_); reserved_name_.InternalSwap(&other->reserved_name_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(options_, other->options_); } @@ -3428,22 +3310,13 @@ ::PROTOBUF_NAMESPACE_ID::Metadata DescriptorProto::GetMetadata() const { // =================================================================== -void ExtensionRangeOptions::InitAsDefaultInstance() { -} class ExtensionRangeOptions::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); }; -ExtensionRangeOptions::ExtensionRangeOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.ExtensionRangeOptions) -} ExtensionRangeOptions::ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -3451,10 +3324,8 @@ ExtensionRangeOptions::ExtensionRangeOptions(::PROTOBUF_NAMESPACE_ID::Arena* are } ExtensionRangeOptions::ExtensionRangeOptions(const ExtensionRangeOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions) } @@ -3466,10 +3337,11 @@ void ExtensionRangeOptions::SharedCtor() { ExtensionRangeOptions::~ExtensionRangeOptions() { // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void ExtensionRangeOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void ExtensionRangeOptions::ArenaDtor(void* object) { @@ -3495,13 +3367,11 @@ void ExtensionRangeOptions::Clear() { _extensions_.Clear(); uninterpreted_option_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -3531,7 +3401,9 @@ const char* ExtensionRangeOptions::_InternalParse(const char* ptr, ::PROTOBUF_NA CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -3565,7 +3437,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* ExtensionRangeOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ExtensionRangeOptions) return target; @@ -3616,7 +3488,7 @@ void ExtensionRangeOptions::MergeFrom(const ExtensionRangeOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -3649,8 +3521,7 @@ bool ExtensionRangeOptions::IsInitialized() const { void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); } @@ -3661,10 +3532,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata ExtensionRangeOptions::GetMetadata() const { // =================================================================== -void FieldDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_FieldDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::FieldOptions*>( - PROTOBUF_NAMESPACE_ID::FieldOptions::internal_default_instance()); -} class FieldDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -3675,10 +3542,10 @@ class FieldDescriptorProto::_Internal { (*has_bits)[0] |= 64u; } static void set_has_label(HasBits* has_bits) { - (*has_bits)[0] |= 256u; + (*has_bits)[0] |= 512u; } static void set_has_type(HasBits* has_bits) { - (*has_bits)[0] |= 512u; + (*has_bits)[0] |= 1024u; } static void set_has_type_name(HasBits* has_bits) { (*has_bits)[0] |= 4u; @@ -3699,66 +3566,49 @@ class FieldDescriptorProto::_Internal { static void set_has_options(HasBits* has_bits) { (*has_bits)[0] |= 32u; } + static void set_has_proto3_optional(HasBits* has_bits) { + (*has_bits)[0] |= 256u; + } }; const PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_Internal::options(const FieldDescriptorProto* msg) { return *msg->options_; } -void FieldDescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::FieldOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000020u; - } else { - _has_bits_[0] &= ~0x00000020u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options) -} -FieldDescriptorProto::FieldDescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.FieldDescriptorProto) -} FieldDescriptorProto::FieldDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto) } FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } extendee_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_extendee()) { - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_extendee(), - GetArenaNoVirtual()); + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_extendee(), + GetArena()); } type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_type_name()) { - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_type_name(), - GetArenaNoVirtual()); + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_name(), + GetArena()); } default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_default_value()) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_default_value(), - GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(), + GetArena()); } json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_json_name()) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_json_name(), - GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::FieldOptions(*from.options_); @@ -3778,9 +3628,10 @@ void FieldDescriptorProto::SharedCtor() { type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&oneof_index_) - - reinterpret_cast(&options_)) + sizeof(oneof_index_)); + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&proto3_optional_) - + reinterpret_cast(&options_)) + sizeof(proto3_optional_)); label_ = 1; type_ = 1; } @@ -3788,10 +3639,11 @@ void FieldDescriptorProto::SharedCtor() { FieldDescriptorProto::~FieldDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void FieldDescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); extendee_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); type_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); @@ -3848,18 +3700,18 @@ void FieldDescriptorProto::Clear() { reinterpret_cast(&oneof_index_) - reinterpret_cast(&number_)) + sizeof(oneof_index_)); } - if (cached_has_bits & 0x00000300u) { + if (cached_has_bits & 0x00000700u) { + proto3_optional_ = false; label_ = 1; type_ = 1; } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -3967,13 +3819,23 @@ const char* FieldDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAM CHK_(ptr); } else goto handle_unusual; continue; + // optional bool proto3_optional = 17; + case 17: + if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 136)) { + _Internal::set_has_proto3_optional(&has_bits); + proto3_optional_ = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr); + CHK_(ptr); + } else goto handle_unusual; + continue; default: { handle_unusual: if ((tag & 7) == 4 || tag == 0) { ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -4022,14 +3884,14 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FieldDescriptorProto::_InternalSerialize( } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (cached_has_bits & 0x00000100u) { + if (cached_has_bits & 0x00000200u) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 4, this->_internal_label(), target); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (cached_has_bits & 0x00000200u) { + if (cached_has_bits & 0x00000400u) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 5, this->_internal_type(), target); @@ -4079,9 +3941,15 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FieldDescriptorProto::_InternalSerialize( 10, this->_internal_json_name(), target); } + // optional bool proto3_optional = 17; + if (cached_has_bits & 0x00000100u) { + target = stream->EnsureSpace(target); + target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(17, this->_internal_proto3_optional(), target); + } + if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto) return target; @@ -4154,15 +4022,20 @@ size_t FieldDescriptorProto::ByteSizeLong() const { } } - if (cached_has_bits & 0x00000300u) { - // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + if (cached_has_bits & 0x00000700u) { + // optional bool proto3_optional = 17; if (cached_has_bits & 0x00000100u) { + total_size += 2 + 1; + } + + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; + if (cached_has_bits & 0x00000200u) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_label()); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (cached_has_bits & 0x00000200u) { + if (cached_has_bits & 0x00000400u) { total_size += 1 + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_type()); } @@ -4195,7 +4068,7 @@ void FieldDescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& fro void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -4227,11 +4100,14 @@ void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) { } _has_bits_[0] |= cached_has_bits; } - if (cached_has_bits & 0x00000300u) { + if (cached_has_bits & 0x00000700u) { if (cached_has_bits & 0x00000100u) { - label_ = from.label_; + proto3_optional_ = from.proto3_optional_; } if (cached_has_bits & 0x00000200u) { + label_ = from.label_; + } + if (cached_has_bits & 0x00000400u) { type_ = from.type_; } _has_bits_[0] |= cached_has_bits; @@ -4261,21 +4137,19 @@ bool FieldDescriptorProto::IsInitialized() const { void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - extendee_.Swap(&other->extendee_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - type_name_.Swap(&other->type_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - default_value_.Swap(&other->default_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - json_name_.Swap(&other->json_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(options_, other->options_); - swap(number_, other->number_); - swap(oneof_index_, other->oneof_index_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + extendee_.Swap(&other->extendee_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + type_name_.Swap(&other->type_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + default_value_.Swap(&other->default_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + json_name_.Swap(&other->json_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, proto3_optional_) + + sizeof(FieldDescriptorProto::proto3_optional_) + - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, options_)>( + reinterpret_cast(&options_), + reinterpret_cast(&other->options_)); swap(label_, other->label_); swap(type_, other->type_); } @@ -4287,10 +4161,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata FieldDescriptorProto::GetMetadata() const { // =================================================================== -void OneofDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_OneofDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::OneofOptions*>( - PROTOBUF_NAMESPACE_ID::OneofOptions::internal_default_instance()); -} class OneofDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -4307,40 +4177,20 @@ const PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_Internal::options(const OneofDescriptorProto* msg) { return *msg->options_; } -void OneofDescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::OneofOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options) -} -OneofDescriptorProto::OneofDescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.OneofDescriptorProto) -} OneofDescriptorProto::OneofDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto) } OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::OneofOptions(*from.options_); @@ -4359,10 +4209,11 @@ void OneofDescriptorProto::SharedCtor() { OneofDescriptorProto::~OneofDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void OneofDescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete options_; } @@ -4399,13 +4250,12 @@ void OneofDescriptorProto::Clear() { } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -4435,7 +4285,9 @@ const char* OneofDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAM ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -4477,7 +4329,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* OneofDescriptorProto::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto) return target; @@ -4535,7 +4387,7 @@ void OneofDescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& fro void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -4573,10 +4425,9 @@ bool OneofDescriptorProto::IsInitialized() const { void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(options_, other->options_); } @@ -4587,8 +4438,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata OneofDescriptorProto::GetMetadata() const { // =================================================================== -void EnumDescriptorProto_EnumReservedRange::InitAsDefaultInstance() { -} class EnumDescriptorProto_EnumReservedRange::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -4600,23 +4449,16 @@ class EnumDescriptorProto_EnumReservedRange::_Internal { } }; -EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) -} EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) } EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::memcpy(&start_, &from.start_, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&start_)) + sizeof(end_)); @@ -4624,18 +4466,20 @@ EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(con } void EnumDescriptorProto_EnumReservedRange::SharedCtor() { - ::memset(&start_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&start_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&start_)) + sizeof(end_)); } EnumDescriptorProto_EnumReservedRange::~EnumDescriptorProto_EnumReservedRange() { // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void EnumDescriptorProto_EnumReservedRange::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void EnumDescriptorProto_EnumReservedRange::ArenaDtor(void* object) { @@ -4666,13 +4510,12 @@ void EnumDescriptorProto_EnumReservedRange::Clear() { reinterpret_cast(&start_)) + sizeof(end_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -4700,7 +4543,9 @@ const char* EnumDescriptorProto_EnumReservedRange::_InternalParse(const char* pt ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -4736,7 +4581,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumDescriptorProto_EnumReservedRange::_Internal if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto.EnumReservedRange) return target; @@ -4794,7 +4639,7 @@ void EnumDescriptorProto_EnumReservedRange::MergeFrom(const ::PROTOBUF_NAMESPACE void EnumDescriptorProto_EnumReservedRange::MergeFrom(const EnumDescriptorProto_EnumReservedRange& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -4830,10 +4675,14 @@ bool EnumDescriptorProto_EnumReservedRange::IsInitialized() const { void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - swap(start_, other->start_); - swap(end_, other->end_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, end_) + + sizeof(EnumDescriptorProto_EnumReservedRange::end_) + - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, start_)>( + reinterpret_cast(&start_), + reinterpret_cast(&other->start_)); } ::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const { @@ -4843,10 +4692,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto_EnumReservedRange::GetMeta // =================================================================== -void EnumDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_EnumDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::EnumOptions*>( - PROTOBUF_NAMESPACE_ID::EnumOptions::internal_default_instance()); -} class EnumDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -4863,27 +4708,8 @@ const PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_Internal::options(const EnumDescriptorProto* msg) { return *msg->options_; } -void EnumDescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::EnumOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options) -} -EnumDescriptorProto::EnumDescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto) -} EnumDescriptorProto::EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), value_(arena), reserved_range_(arena), reserved_name_(arena) { @@ -4893,16 +4719,15 @@ EnumDescriptorProto::EnumDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) } EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), value_(from.value_), reserved_range_(from.reserved_range_), reserved_name_(from.reserved_name_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::EnumOptions(*from.options_); @@ -4921,10 +4746,11 @@ void EnumDescriptorProto::SharedCtor() { EnumDescriptorProto::~EnumDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void EnumDescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete options_; } @@ -4964,13 +4790,12 @@ void EnumDescriptorProto::Clear() { } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -5040,7 +4865,9 @@ const char* EnumDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAME ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -5108,7 +4935,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumDescriptorProto::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto) return target; @@ -5188,7 +5015,7 @@ void EnumDescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -5230,13 +5057,12 @@ bool EnumDescriptorProto::IsInitialized() const { void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); value_.InternalSwap(&other->value_); reserved_range_.InternalSwap(&other->reserved_range_); reserved_name_.InternalSwap(&other->reserved_name_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(options_, other->options_); } @@ -5247,10 +5073,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata EnumDescriptorProto::GetMetadata() const { // =================================================================== -void EnumValueDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_EnumValueDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::EnumValueOptions*>( - PROTOBUF_NAMESPACE_ID::EnumValueOptions::internal_default_instance()); -} class EnumValueDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -5270,40 +5092,20 @@ const PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_Internal::options(const EnumValueDescriptorProto* msg) { return *msg->options_; } -void EnumValueDescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options) -} -EnumValueDescriptorProto::EnumValueDescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.EnumValueDescriptorProto) -} EnumValueDescriptorProto::EnumValueDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto) } EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::EnumValueOptions(*from.options_); @@ -5317,18 +5119,20 @@ EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProt void EnumValueDescriptorProto::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_EnumValueDescriptorProto_google_2fprotobuf_2fdescriptor_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&number_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&number_) - reinterpret_cast(&options_)) + sizeof(number_)); } EnumValueDescriptorProto::~EnumValueDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void EnumValueDescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete options_; } @@ -5366,13 +5170,12 @@ void EnumValueDescriptorProto::Clear() { } number_ = 0; _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -5410,7 +5213,9 @@ const char* EnumValueDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -5458,7 +5263,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumValueDescriptorProto::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto) return target; @@ -5523,7 +5328,7 @@ void EnumValueDescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -5565,12 +5370,15 @@ bool EnumValueDescriptorProto::IsInitialized() const { void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(options_, other->options_); - swap(number_, other->number_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, number_) + + sizeof(EnumValueDescriptorProto::number_) + - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, options_)>( + reinterpret_cast(&options_), + reinterpret_cast(&other->options_)); } ::PROTOBUF_NAMESPACE_ID::Metadata EnumValueDescriptorProto::GetMetadata() const { @@ -5580,10 +5388,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata EnumValueDescriptorProto::GetMetadata() const // =================================================================== -void ServiceDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_ServiceDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::ServiceOptions*>( - PROTOBUF_NAMESPACE_ID::ServiceOptions::internal_default_instance()); -} class ServiceDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -5600,27 +5404,8 @@ const PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_Internal::options(const ServiceDescriptorProto* msg) { return *msg->options_; } -void ServiceDescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::ServiceOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options) -} -ServiceDescriptorProto::ServiceDescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.ServiceDescriptorProto) -} ServiceDescriptorProto::ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), method_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -5628,14 +5413,13 @@ ServiceDescriptorProto::ServiceDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* a } ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), method_(from.method_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::ServiceOptions(*from.options_); @@ -5654,10 +5438,11 @@ void ServiceDescriptorProto::SharedCtor() { ServiceDescriptorProto::~ServiceDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void ServiceDescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete options_; } @@ -5695,13 +5480,12 @@ void ServiceDescriptorProto::Clear() { } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -5743,7 +5527,9 @@ const char* ServiceDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_N ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -5793,7 +5579,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* ServiceDescriptorProto::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto) return target; @@ -5858,7 +5644,7 @@ void ServiceDescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& f void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -5898,11 +5684,10 @@ bool ServiceDescriptorProto::IsInitialized() const { void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); method_.InternalSwap(&other->method_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(options_, other->options_); } @@ -5913,10 +5698,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata ServiceDescriptorProto::GetMetadata() const { // =================================================================== -void MethodDescriptorProto::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_MethodDescriptorProto_default_instance_._instance.get_mutable()->options_ = const_cast< PROTOBUF_NAMESPACE_ID::MethodOptions*>( - PROTOBUF_NAMESPACE_ID::MethodOptions::internal_default_instance()); -} class MethodDescriptorProto::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -5945,50 +5726,30 @@ const PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_Internal::options(const MethodDescriptorProto* msg) { return *msg->options_; } -void MethodDescriptorProto::unsafe_arena_set_allocated_options( - PROTOBUF_NAMESPACE_ID::MethodOptions* options) { - if (GetArenaNoVirtual() == nullptr) { - delete options_; - } - options_ = options; - if (options) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options) -} -MethodDescriptorProto::MethodDescriptorProto() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.MethodDescriptorProto) -} MethodDescriptorProto::MethodDescriptorProto(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto) } MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_input_type()) { - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_input_type(), - GetArenaNoVirtual()); + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_input_type(), + GetArena()); } output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_output_type()) { - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_output_type(), - GetArenaNoVirtual()); + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_output_type(), + GetArena()); } if (from._internal_has_options()) { options_ = new PROTOBUF_NAMESPACE_ID::MethodOptions(*from.options_); @@ -6006,18 +5767,20 @@ void MethodDescriptorProto::SharedCtor() { name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&options_, 0, static_cast( - reinterpret_cast(&server_streaming_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&options_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&server_streaming_) - reinterpret_cast(&options_)) + sizeof(server_streaming_)); } MethodDescriptorProto::~MethodDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void MethodDescriptorProto::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); input_type_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); output_type_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); @@ -6065,13 +5828,12 @@ void MethodDescriptorProto::Clear() { reinterpret_cast(&server_streaming_) - reinterpret_cast(&client_streaming_)) + sizeof(server_streaming_)); _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -6139,7 +5901,9 @@ const char* MethodDescriptorProto::_InternalParse(const char* ptr, ::PROTOBUF_NA ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -6213,7 +5977,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* MethodDescriptorProto::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto) return target; @@ -6295,7 +6059,7 @@ void MethodDescriptorProto::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& fr void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -6346,17 +6110,17 @@ bool MethodDescriptorProto::IsInitialized() const { void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - input_type_.Swap(&other->input_type_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - output_type_.Swap(&other->output_type_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(options_, other->options_); - swap(client_streaming_, other->client_streaming_); - swap(server_streaming_, other->server_streaming_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + input_type_.Swap(&other->input_type_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + output_type_.Swap(&other->output_type_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, server_streaming_) + + sizeof(MethodDescriptorProto::server_streaming_) + - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, options_)>( + reinterpret_cast(&options_), + reinterpret_cast(&other->options_)); } ::PROTOBUF_NAMESPACE_ID::Metadata MethodDescriptorProto::GetMetadata() const { @@ -6366,8 +6130,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata MethodDescriptorProto::GetMetadata() const { // =================================================================== -void FileOptions::InitAsDefaultInstance() { -} class FileOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -6387,7 +6149,7 @@ class FileOptions::_Internal { (*has_bits)[0] |= 4096u; } static void set_has_optimize_for(HasBits* has_bits) { - (*has_bits)[0] |= 524288u; + (*has_bits)[0] |= 262144u; } static void set_has_go_package(HasBits* has_bits) { (*has_bits)[0] |= 4u; @@ -6408,7 +6170,7 @@ class FileOptions::_Internal { (*has_bits)[0] |= 131072u; } static void set_has_cc_enable_arenas(HasBits* has_bits) { - (*has_bits)[0] |= 262144u; + (*has_bits)[0] |= 524288u; } static void set_has_objc_class_prefix(HasBits* has_bits) { (*has_bits)[0] |= 8u; @@ -6433,15 +6195,9 @@ class FileOptions::_Internal { } }; -FileOptions::FileOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.FileOptions) -} FileOptions::FileOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -6449,64 +6205,63 @@ FileOptions::FileOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } FileOptions::FileOptions(const FileOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_java_package()) { - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_java_package(), - GetArenaNoVirtual()); + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_package(), + GetArena()); } java_outer_classname_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_java_outer_classname()) { - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_java_outer_classname(), - GetArenaNoVirtual()); + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_outer_classname(), + GetArena()); } go_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_go_package()) { - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_go_package(), - GetArenaNoVirtual()); + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_go_package(), + GetArena()); } objc_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_objc_class_prefix()) { - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_objc_class_prefix(), - GetArenaNoVirtual()); + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_objc_class_prefix(), + GetArena()); } csharp_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_csharp_namespace()) { - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_csharp_namespace(), - GetArenaNoVirtual()); + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_csharp_namespace(), + GetArena()); } swift_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_swift_prefix()) { - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_swift_prefix(), - GetArenaNoVirtual()); + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_swift_prefix(), + GetArena()); } php_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_php_class_prefix()) { - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_php_class_prefix(), - GetArenaNoVirtual()); + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_class_prefix(), + GetArena()); } php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_php_namespace()) { - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_php_namespace(), - GetArenaNoVirtual()); + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_namespace(), + GetArena()); } php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_php_metadata_namespace()) { - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_php_metadata_namespace(), - GetArenaNoVirtual()); + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_metadata_namespace(), + GetArena()); } ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_ruby_package()) { - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_ruby_package(), - GetArenaNoVirtual()); + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_ruby_package(), + GetArena()); } ::memcpy(&java_multiple_files_, &from.java_multiple_files_, - static_cast(reinterpret_cast(&optimize_for_) - - reinterpret_cast(&java_multiple_files_)) + sizeof(optimize_for_)); + static_cast(reinterpret_cast(&cc_enable_arenas_) - + reinterpret_cast(&java_multiple_files_)) + sizeof(cc_enable_arenas_)); // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions) } @@ -6522,19 +6277,22 @@ void FileOptions::SharedCtor() { php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&java_multiple_files_, 0, static_cast( - reinterpret_cast(&cc_enable_arenas_) - - reinterpret_cast(&java_multiple_files_)) + sizeof(cc_enable_arenas_)); + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&java_multiple_files_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&deprecated_) - + reinterpret_cast(&java_multiple_files_)) + sizeof(deprecated_)); optimize_for_ = 1; + cc_enable_arenas_ = true; } FileOptions::~FileOptions() { // @@protoc_insertion_point(destructor:google.protobuf.FileOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void FileOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); java_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); java_outer_classname_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); go_package_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); @@ -6612,18 +6370,18 @@ void FileOptions::Clear() { } if (cached_has_bits & 0x000f0000u) { ::memset(&php_generic_services_, 0, static_cast( - reinterpret_cast(&cc_enable_arenas_) - - reinterpret_cast(&php_generic_services_)) + sizeof(cc_enable_arenas_)); + reinterpret_cast(&deprecated_) - + reinterpret_cast(&php_generic_services_)) + sizeof(deprecated_)); optimize_for_ = 1; + cc_enable_arenas_ = true; } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* FileOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -6730,7 +6488,7 @@ const char* FileOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID CHK_(ptr); } else goto handle_unusual; continue; - // optional bool cc_enable_arenas = 31 [default = false]; + // optional bool cc_enable_arenas = 31 [default = true]; case 31: if (PROTOBUF_PREDICT_TRUE(static_cast<::PROTOBUF_NAMESPACE_ID::uint8>(tag) == 248)) { _Internal::set_has_cc_enable_arenas(&has_bits); @@ -6847,7 +6605,9 @@ const char* FileOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -6890,7 +6650,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FileOptions::_InternalSerialize( } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (cached_has_bits & 0x00080000u) { + if (cached_has_bits & 0x00040000u) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray( 9, this->_internal_optimize_for(), target); @@ -6948,8 +6708,8 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FileOptions::_InternalSerialize( target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(27, this->_internal_java_string_check_utf8(), target); } - // optional bool cc_enable_arenas = 31 [default = false]; - if (cached_has_bits & 0x00040000u) { + // optional bool cc_enable_arenas = 31 [default = true]; + if (cached_has_bits & 0x00080000u) { target = stream->EnsureSpace(target); target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteBoolToArray(31, this->_internal_cc_enable_arenas(), target); } @@ -7044,7 +6804,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FileOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions) return target; @@ -7183,15 +6943,15 @@ size_t FileOptions::ByteSizeLong() const { total_size += 2 + 1; } - // optional bool cc_enable_arenas = 31 [default = false]; + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; if (cached_has_bits & 0x00040000u) { - total_size += 2 + 1; + total_size += 1 + + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_optimize_for()); } - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; + // optional bool cc_enable_arenas = 31 [default = true]; if (cached_has_bits & 0x00080000u) { - total_size += 1 + - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_optimize_for()); + total_size += 2 + 1; } } @@ -7223,7 +6983,7 @@ void FileOptions::MergeFrom(const FileOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -7290,10 +7050,10 @@ void FileOptions::MergeFrom(const FileOptions& from) { deprecated_ = from.deprecated_; } if (cached_has_bits & 0x00040000u) { - cc_enable_arenas_ = from.cc_enable_arenas_; + optimize_for_ = from.optimize_for_; } if (cached_has_bits & 0x00080000u) { - optimize_for_ = from.optimize_for_; + cc_enable_arenas_ = from.cc_enable_arenas_; } _has_bits_[0] |= cached_has_bits; } @@ -7325,39 +7085,27 @@ bool FileOptions::IsInitialized() const { void FileOptions::InternalSwap(FileOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - java_package_.Swap(&other->java_package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - java_outer_classname_.Swap(&other->java_outer_classname_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - go_package_.Swap(&other->go_package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - objc_class_prefix_.Swap(&other->objc_class_prefix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - csharp_namespace_.Swap(&other->csharp_namespace_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swift_prefix_.Swap(&other->swift_prefix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - php_class_prefix_.Swap(&other->php_class_prefix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - php_namespace_.Swap(&other->php_namespace_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - php_metadata_namespace_.Swap(&other->php_metadata_namespace_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - ruby_package_.Swap(&other->ruby_package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(java_multiple_files_, other->java_multiple_files_); - swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_); - swap(java_string_check_utf8_, other->java_string_check_utf8_); - swap(cc_generic_services_, other->cc_generic_services_); - swap(java_generic_services_, other->java_generic_services_); - swap(py_generic_services_, other->py_generic_services_); - swap(php_generic_services_, other->php_generic_services_); - swap(deprecated_, other->deprecated_); - swap(cc_enable_arenas_, other->cc_enable_arenas_); + java_package_.Swap(&other->java_package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + java_outer_classname_.Swap(&other->java_outer_classname_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + go_package_.Swap(&other->go_package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + objc_class_prefix_.Swap(&other->objc_class_prefix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + csharp_namespace_.Swap(&other->csharp_namespace_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + swift_prefix_.Swap(&other->swift_prefix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + php_class_prefix_.Swap(&other->php_class_prefix_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + php_namespace_.Swap(&other->php_namespace_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + php_metadata_namespace_.Swap(&other->php_metadata_namespace_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ruby_package_.Swap(&other->ruby_package_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FileOptions, deprecated_) + + sizeof(FileOptions::deprecated_) + - PROTOBUF_FIELD_OFFSET(FileOptions, java_multiple_files_)>( + reinterpret_cast(&java_multiple_files_), + reinterpret_cast(&other->java_multiple_files_)); swap(optimize_for_, other->optimize_for_); + swap(cc_enable_arenas_, other->cc_enable_arenas_); } ::PROTOBUF_NAMESPACE_ID::Metadata FileOptions::GetMetadata() const { @@ -7367,8 +7115,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata FileOptions::GetMetadata() const { // =================================================================== -void MessageOptions::InitAsDefaultInstance() { -} class MessageOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -7386,15 +7132,9 @@ class MessageOptions::_Internal { } }; -MessageOptions::MessageOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.MessageOptions) -} MessageOptions::MessageOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -7402,10 +7142,9 @@ MessageOptions::MessageOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } MessageOptions::MessageOptions(const MessageOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); ::memcpy(&message_set_wire_format_, &from.message_set_wire_format_, static_cast(reinterpret_cast(&map_entry_) - @@ -7415,18 +7154,20 @@ MessageOptions::MessageOptions(const MessageOptions& from) void MessageOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_MessageOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&message_set_wire_format_, 0, static_cast( - reinterpret_cast(&map_entry_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&message_set_wire_format_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&map_entry_) - reinterpret_cast(&message_set_wire_format_)) + sizeof(map_entry_)); } MessageOptions::~MessageOptions() { // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void MessageOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void MessageOptions::ArenaDtor(void* object) { @@ -7456,13 +7197,12 @@ void MessageOptions::Clear() { reinterpret_cast(&map_entry_) - reinterpret_cast(&message_set_wire_format_)) + sizeof(map_entry_)); _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* MessageOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -7524,7 +7264,9 @@ const char* MessageOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -7584,7 +7326,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* MessageOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions) return target; @@ -7658,7 +7400,7 @@ void MessageOptions::MergeFrom(const MessageOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -7707,13 +7449,15 @@ bool MessageOptions::IsInitialized() const { void MessageOptions::InternalSwap(MessageOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - swap(message_set_wire_format_, other->message_set_wire_format_); - swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_); - swap(deprecated_, other->deprecated_); - swap(map_entry_, other->map_entry_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(MessageOptions, map_entry_) + + sizeof(MessageOptions::map_entry_) + - PROTOBUF_FIELD_OFFSET(MessageOptions, message_set_wire_format_)>( + reinterpret_cast(&message_set_wire_format_), + reinterpret_cast(&other->message_set_wire_format_)); } ::PROTOBUF_NAMESPACE_ID::Metadata MessageOptions::GetMetadata() const { @@ -7723,8 +7467,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata MessageOptions::GetMetadata() const { // =================================================================== -void FieldOptions::InitAsDefaultInstance() { -} class FieldOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -7748,15 +7490,9 @@ class FieldOptions::_Internal { } }; -FieldOptions::FieldOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.FieldOptions) -} FieldOptions::FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -7764,10 +7500,9 @@ FieldOptions::FieldOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } FieldOptions::FieldOptions(const FieldOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); ::memcpy(&ctype_, &from.ctype_, static_cast(reinterpret_cast(&jstype_) - @@ -7777,18 +7512,20 @@ FieldOptions::FieldOptions(const FieldOptions& from) void FieldOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_FieldOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&ctype_, 0, static_cast( - reinterpret_cast(&jstype_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&ctype_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&jstype_) - reinterpret_cast(&ctype_)) + sizeof(jstype_)); } FieldOptions::~FieldOptions() { // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void FieldOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void FieldOptions::ArenaDtor(void* object) { @@ -7821,13 +7558,12 @@ void FieldOptions::Clear() { reinterpret_cast(&ctype_)) + sizeof(jstype_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* FieldOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -7913,7 +7649,9 @@ const char* FieldOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_I CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -7987,7 +7725,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FieldOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions) return target; @@ -8073,7 +7811,7 @@ void FieldOptions::MergeFrom(const FieldOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -8128,15 +7866,15 @@ bool FieldOptions::IsInitialized() const { void FieldOptions::InternalSwap(FieldOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - swap(ctype_, other->ctype_); - swap(packed_, other->packed_); - swap(lazy_, other->lazy_); - swap(deprecated_, other->deprecated_); - swap(weak_, other->weak_); - swap(jstype_, other->jstype_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(FieldOptions, jstype_) + + sizeof(FieldOptions::jstype_) + - PROTOBUF_FIELD_OFFSET(FieldOptions, ctype_)>( + reinterpret_cast(&ctype_), + reinterpret_cast(&other->ctype_)); } ::PROTOBUF_NAMESPACE_ID::Metadata FieldOptions::GetMetadata() const { @@ -8146,22 +7884,13 @@ ::PROTOBUF_NAMESPACE_ID::Metadata FieldOptions::GetMetadata() const { // =================================================================== -void OneofOptions::InitAsDefaultInstance() { -} class OneofOptions::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); }; -OneofOptions::OneofOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.OneofOptions) -} OneofOptions::OneofOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -8169,10 +7898,8 @@ OneofOptions::OneofOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } OneofOptions::OneofOptions(const OneofOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions) } @@ -8184,10 +7911,11 @@ void OneofOptions::SharedCtor() { OneofOptions::~OneofOptions() { // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void OneofOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void OneofOptions::ArenaDtor(void* object) { @@ -8213,13 +7941,11 @@ void OneofOptions::Clear() { _extensions_.Clear(); uninterpreted_option_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* OneofOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -8249,7 +7975,9 @@ const char* OneofOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_I CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -8283,7 +8011,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* OneofOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofOptions) return target; @@ -8334,7 +8062,7 @@ void OneofOptions::MergeFrom(const OneofOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -8367,8 +8095,7 @@ bool OneofOptions::IsInitialized() const { void OneofOptions::InternalSwap(OneofOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); } @@ -8379,8 +8106,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata OneofOptions::GetMetadata() const { // =================================================================== -void EnumOptions::InitAsDefaultInstance() { -} class EnumOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -8392,15 +8117,9 @@ class EnumOptions::_Internal { } }; -EnumOptions::EnumOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.EnumOptions) -} EnumOptions::EnumOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -8408,10 +8127,9 @@ EnumOptions::EnumOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } EnumOptions::EnumOptions(const EnumOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); ::memcpy(&allow_alias_, &from.allow_alias_, static_cast(reinterpret_cast(&deprecated_) - @@ -8421,18 +8139,20 @@ EnumOptions::EnumOptions(const EnumOptions& from) void EnumOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_EnumOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&allow_alias_, 0, static_cast( - reinterpret_cast(&deprecated_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&allow_alias_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&deprecated_) - reinterpret_cast(&allow_alias_)) + sizeof(deprecated_)); } EnumOptions::~EnumOptions() { // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void EnumOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void EnumOptions::ArenaDtor(void* object) { @@ -8462,13 +8182,12 @@ void EnumOptions::Clear() { reinterpret_cast(&deprecated_) - reinterpret_cast(&allow_alias_)) + sizeof(deprecated_)); _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* EnumOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -8514,7 +8233,9 @@ const char* EnumOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -8562,7 +8283,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions) return target; @@ -8626,7 +8347,7 @@ void EnumOptions::MergeFrom(const EnumOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -8669,11 +8390,15 @@ bool EnumOptions::IsInitialized() const { void EnumOptions::InternalSwap(EnumOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - swap(allow_alias_, other->allow_alias_); - swap(deprecated_, other->deprecated_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(EnumOptions, deprecated_) + + sizeof(EnumOptions::deprecated_) + - PROTOBUF_FIELD_OFFSET(EnumOptions, allow_alias_)>( + reinterpret_cast(&allow_alias_), + reinterpret_cast(&other->allow_alias_)); } ::PROTOBUF_NAMESPACE_ID::Metadata EnumOptions::GetMetadata() const { @@ -8683,8 +8408,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata EnumOptions::GetMetadata() const { // =================================================================== -void EnumValueOptions::InitAsDefaultInstance() { -} class EnumValueOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -8693,15 +8416,9 @@ class EnumValueOptions::_Internal { } }; -EnumValueOptions::EnumValueOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.EnumValueOptions) -} EnumValueOptions::EnumValueOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -8709,10 +8426,9 @@ EnumValueOptions::EnumValueOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } EnumValueOptions::EnumValueOptions(const EnumValueOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); deprecated_ = from.deprecated_; // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions) @@ -8726,10 +8442,11 @@ void EnumValueOptions::SharedCtor() { EnumValueOptions::~EnumValueOptions() { // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void EnumValueOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void EnumValueOptions::ArenaDtor(void* object) { @@ -8757,13 +8474,12 @@ void EnumValueOptions::Clear() { uninterpreted_option_.Clear(); deprecated_ = false; _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* EnumValueOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -8801,7 +8517,9 @@ const char* EnumValueOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPA CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -8843,7 +8561,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumValueOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions) return target; @@ -8900,7 +8618,7 @@ void EnumValueOptions::MergeFrom(const EnumValueOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -8936,7 +8654,7 @@ bool EnumValueOptions::IsInitialized() const { void EnumValueOptions::InternalSwap(EnumValueOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); swap(deprecated_, other->deprecated_); @@ -8949,8 +8667,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata EnumValueOptions::GetMetadata() const { // =================================================================== -void ServiceOptions::InitAsDefaultInstance() { -} class ServiceOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -8959,15 +8675,9 @@ class ServiceOptions::_Internal { } }; -ServiceOptions::ServiceOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.ServiceOptions) -} ServiceOptions::ServiceOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -8975,10 +8685,9 @@ ServiceOptions::ServiceOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } ServiceOptions::ServiceOptions(const ServiceOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); deprecated_ = from.deprecated_; // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions) @@ -8992,10 +8701,11 @@ void ServiceOptions::SharedCtor() { ServiceOptions::~ServiceOptions() { // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void ServiceOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void ServiceOptions::ArenaDtor(void* object) { @@ -9023,13 +8733,12 @@ void ServiceOptions::Clear() { uninterpreted_option_.Clear(); deprecated_ = false; _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* ServiceOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -9067,7 +8776,9 @@ const char* ServiceOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -9109,7 +8820,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* ServiceOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions) return target; @@ -9166,7 +8877,7 @@ void ServiceOptions::MergeFrom(const ServiceOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -9202,7 +8913,7 @@ bool ServiceOptions::IsInitialized() const { void ServiceOptions::InternalSwap(ServiceOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); swap(deprecated_, other->deprecated_); @@ -9215,8 +8926,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata ServiceOptions::GetMetadata() const { // =================================================================== -void MethodOptions::InitAsDefaultInstance() { -} class MethodOptions::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -9228,15 +8937,9 @@ class MethodOptions::_Internal { } }; -MethodOptions::MethodOptions() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.MethodOptions) -} MethodOptions::MethodOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), _extensions_(arena), - _internal_metadata_(arena), uninterpreted_option_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -9244,10 +8947,9 @@ MethodOptions::MethodOptions(::PROTOBUF_NAMESPACE_ID::Arena* arena) } MethodOptions::MethodOptions(const MethodOptions& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), uninterpreted_option_(from.uninterpreted_option_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); ::memcpy(&deprecated_, &from.deprecated_, static_cast(reinterpret_cast(&idempotency_level_) - @@ -9257,18 +8959,20 @@ MethodOptions::MethodOptions(const MethodOptions& from) void MethodOptions::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_MethodOptions_google_2fprotobuf_2fdescriptor_2eproto.base); - ::memset(&deprecated_, 0, static_cast( - reinterpret_cast(&idempotency_level_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&deprecated_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&idempotency_level_) - reinterpret_cast(&deprecated_)) + sizeof(idempotency_level_)); } MethodOptions::~MethodOptions() { // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void MethodOptions::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void MethodOptions::ArenaDtor(void* object) { @@ -9301,13 +9005,12 @@ void MethodOptions::Clear() { reinterpret_cast(&deprecated_)) + sizeof(idempotency_level_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* MethodOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -9357,7 +9060,9 @@ const char* MethodOptions::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ CHK_(ptr != nullptr); continue; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -9406,7 +9111,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* MethodOptions::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions) return target; @@ -9471,7 +9176,7 @@ void MethodOptions::MergeFrom(const MethodOptions& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions) GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -9514,11 +9219,15 @@ bool MethodOptions::IsInitialized() const { void MethodOptions::InternalSwap(MethodOptions* other) { using std::swap; _extensions_.Swap(&other->_extensions_); - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); - swap(deprecated_, other->deprecated_); - swap(idempotency_level_, other->idempotency_level_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(MethodOptions, idempotency_level_) + + sizeof(MethodOptions::idempotency_level_) + - PROTOBUF_FIELD_OFFSET(MethodOptions, deprecated_)>( + reinterpret_cast(&deprecated_), + reinterpret_cast(&other->deprecated_)); } ::PROTOBUF_NAMESPACE_ID::Metadata MethodOptions::GetMetadata() const { @@ -9528,8 +9237,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata MethodOptions::GetMetadata() const { // =================================================================== -void UninterpretedOption_NamePart::InitAsDefaultInstance() { -} class UninterpretedOption_NamePart::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -9539,29 +9246,25 @@ class UninterpretedOption_NamePart::_Internal { static void set_has_is_extension(HasBits* has_bits) { (*has_bits)[0] |= 2u; } + static bool MissingRequiredFields(const HasBits& has_bits) { + return ((has_bits[0] & 0x00000003) ^ 0x00000003) != 0; + } }; -UninterpretedOption_NamePart::UninterpretedOption_NamePart() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption.NamePart) -} UninterpretedOption_NamePart::UninterpretedOption_NamePart(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart) } UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_part_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name_part()) { - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name_part(), - GetArenaNoVirtual()); + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name_part(), + GetArena()); } is_extension_ = from.is_extension_; // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart) @@ -9576,10 +9279,11 @@ void UninterpretedOption_NamePart::SharedCtor() { UninterpretedOption_NamePart::~UninterpretedOption_NamePart() { // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void UninterpretedOption_NamePart::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_part_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } @@ -9610,13 +9314,12 @@ void UninterpretedOption_NamePart::Clear() { } is_extension_ = false; _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -9647,7 +9350,9 @@ const char* UninterpretedOption_NamePart::_InternalParse(const char* ptr, ::PROT ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -9687,7 +9392,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* UninterpretedOption_NamePart::_InternalSerialize if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart) return target; @@ -9758,7 +9463,7 @@ void UninterpretedOption_NamePart::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Mess void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -9789,16 +9494,15 @@ void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& } bool UninterpretedOption_NamePart::IsInitialized() const { - if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false; + if (_Internal::MissingRequiredFields(_has_bits_)) return false; return true; } void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); - name_part_.Swap(&other->name_part_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + name_part_.Swap(&other->name_part_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(is_extension_, other->is_extension_); } @@ -9809,8 +9513,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption_NamePart::GetMetadata() co // =================================================================== -void UninterpretedOption::InitAsDefaultInstance() { -} class UninterpretedOption::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -9834,14 +9536,8 @@ class UninterpretedOption::_Internal { } }; -UninterpretedOption::UninterpretedOption() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption) -} UninterpretedOption::UninterpretedOption(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), name_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -9849,24 +9545,23 @@ UninterpretedOption::UninterpretedOption(::PROTOBUF_NAMESPACE_ID::Arena* arena) } UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), name_(from.name_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_identifier_value()) { - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_identifier_value(), - GetArenaNoVirtual()); + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_identifier_value(), + GetArena()); } string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_string_value()) { - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_string_value(), - GetArenaNoVirtual()); + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_string_value(), + GetArena()); } aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_aggregate_value()) { - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_aggregate_value(), - GetArenaNoVirtual()); + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_aggregate_value(), + GetArena()); } ::memcpy(&positive_int_value_, &from.positive_int_value_, static_cast(reinterpret_cast(&double_value_) - @@ -9879,18 +9574,20 @@ void UninterpretedOption::SharedCtor() { identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&positive_int_value_, 0, static_cast( - reinterpret_cast(&double_value_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&positive_int_value_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&double_value_) - reinterpret_cast(&positive_int_value_)) + sizeof(double_value_)); } UninterpretedOption::~UninterpretedOption() { // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void UninterpretedOption::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); identifier_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); string_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); aggregate_value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); @@ -9936,13 +9633,12 @@ void UninterpretedOption::Clear() { reinterpret_cast(&positive_int_value_)) + sizeof(double_value_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* UninterpretedOption::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -10020,7 +9716,9 @@ const char* UninterpretedOption::_InternalParse(const char* ptr, ::PROTOBUF_NAME ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -10096,7 +9794,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* UninterpretedOption::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption) return target; @@ -10187,7 +9885,7 @@ void UninterpretedOption::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from void UninterpretedOption::MergeFrom(const UninterpretedOption& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -10237,18 +9935,18 @@ bool UninterpretedOption::IsInitialized() const { void UninterpretedOption::InternalSwap(UninterpretedOption* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); name_.InternalSwap(&other->name_); - identifier_value_.Swap(&other->identifier_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - string_value_.Swap(&other->string_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - aggregate_value_.Swap(&other->aggregate_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(positive_int_value_, other->positive_int_value_); - swap(negative_int_value_, other->negative_int_value_); - swap(double_value_, other->double_value_); + identifier_value_.Swap(&other->identifier_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + string_value_.Swap(&other->string_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + aggregate_value_.Swap(&other->aggregate_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(UninterpretedOption, double_value_) + + sizeof(UninterpretedOption::double_value_) + - PROTOBUF_FIELD_OFFSET(UninterpretedOption, positive_int_value_)>( + reinterpret_cast(&positive_int_value_), + reinterpret_cast(&other->positive_int_value_)); } ::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption::GetMetadata() const { @@ -10258,8 +9956,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata UninterpretedOption::GetMetadata() const { // =================================================================== -void SourceCodeInfo_Location::InitAsDefaultInstance() { -} class SourceCodeInfo_Location::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -10271,14 +9967,8 @@ class SourceCodeInfo_Location::_Internal { } }; -SourceCodeInfo_Location::SourceCodeInfo_Location() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo.Location) -} SourceCodeInfo_Location::SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), path_(arena), span_(arena), leading_detached_comments_(arena) { @@ -10288,21 +9978,20 @@ SourceCodeInfo_Location::SourceCodeInfo_Location(::PROTOBUF_NAMESPACE_ID::Arena* } SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), path_(from.path_), span_(from.span_), leading_detached_comments_(from.leading_detached_comments_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); leading_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_leading_comments()) { - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_leading_comments(), - GetArenaNoVirtual()); + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_leading_comments(), + GetArena()); } trailing_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_trailing_comments()) { - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_trailing_comments(), - GetArenaNoVirtual()); + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_trailing_comments(), + GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location) } @@ -10316,10 +10005,11 @@ void SourceCodeInfo_Location::SharedCtor() { SourceCodeInfo_Location::~SourceCodeInfo_Location() { // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void SourceCodeInfo_Location::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); leading_comments_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); trailing_comments_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } @@ -10358,13 +10048,12 @@ void SourceCodeInfo_Location::Clear() { } } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -10434,7 +10123,9 @@ const char* SourceCodeInfo_Location::_InternalParse(const char* ptr, ::PROTOBUF_ ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -10506,7 +10197,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* SourceCodeInfo_Location::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location) return target; @@ -10602,7 +10293,7 @@ void SourceCodeInfo_Location::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -10640,15 +10331,13 @@ bool SourceCodeInfo_Location::IsInitialized() const { void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); path_.InternalSwap(&other->path_); span_.InternalSwap(&other->span_); leading_detached_comments_.InternalSwap(&other->leading_detached_comments_); - leading_comments_.Swap(&other->leading_comments_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - trailing_comments_.Swap(&other->trailing_comments_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + leading_comments_.Swap(&other->leading_comments_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + trailing_comments_.Swap(&other->trailing_comments_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } ::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo_Location::GetMetadata() const { @@ -10658,21 +10347,12 @@ ::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo_Location::GetMetadata() const { // =================================================================== -void SourceCodeInfo::InitAsDefaultInstance() { -} class SourceCodeInfo::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); }; -SourceCodeInfo::SourceCodeInfo() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo) -} SourceCodeInfo::SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), location_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -10680,10 +10360,8 @@ SourceCodeInfo::SourceCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena) } SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), location_(from.location_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo) } @@ -10694,10 +10372,11 @@ void SourceCodeInfo::SharedCtor() { SourceCodeInfo::~SourceCodeInfo() { // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void SourceCodeInfo::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void SourceCodeInfo::ArenaDtor(void* object) { @@ -10722,13 +10401,11 @@ void SourceCodeInfo::Clear() { (void) cached_has_bits; location_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* SourceCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -10752,7 +10429,9 @@ const char* SourceCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -10782,7 +10461,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* SourceCodeInfo::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo) return target; @@ -10830,7 +10509,7 @@ void SourceCodeInfo::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -10857,8 +10536,7 @@ bool SourceCodeInfo::IsInitialized() const { void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); location_.InternalSwap(&other->location_); } @@ -10869,8 +10547,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata SourceCodeInfo::GetMetadata() const { // =================================================================== -void GeneratedCodeInfo_Annotation::InitAsDefaultInstance() { -} class GeneratedCodeInfo_Annotation::_Internal { public: using HasBits = decltype(std::declval()._has_bits_); @@ -10885,14 +10561,8 @@ class GeneratedCodeInfo_Annotation::_Internal { } }; -GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo.Annotation) -} GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), path_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -10900,14 +10570,13 @@ GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::PROTOBUF_NAMESPACE_ } GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), _has_bits_(from._has_bits_), path_(from.path_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_source_file()) { - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_source_file(), - GetArenaNoVirtual()); + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_source_file(), + GetArena()); } ::memcpy(&begin_, &from.begin_, static_cast(reinterpret_cast(&end_) - @@ -10918,18 +10587,20 @@ GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeIn void GeneratedCodeInfo_Annotation::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_GeneratedCodeInfo_Annotation_google_2fprotobuf_2fdescriptor_2eproto.base); source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&begin_, 0, static_cast( - reinterpret_cast(&end_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&begin_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&end_) - reinterpret_cast(&begin_)) + sizeof(end_)); } GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() { // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void GeneratedCodeInfo_Annotation::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); source_file_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } @@ -10965,13 +10636,12 @@ void GeneratedCodeInfo_Annotation::Clear() { reinterpret_cast(&begin_)) + sizeof(end_)); } _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure _Internal::HasBits has_bits{}; - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -11020,7 +10690,9 @@ const char* GeneratedCodeInfo_Annotation::_InternalParse(const char* ptr, ::PROT ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -11075,7 +10747,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* GeneratedCodeInfo_Annotation::_InternalSerialize if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo.Annotation) return target; @@ -11155,7 +10827,7 @@ void GeneratedCodeInfo_Annotation::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Mess void GeneratedCodeInfo_Annotation::MergeFrom(const GeneratedCodeInfo_Annotation& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -11195,13 +10867,16 @@ bool GeneratedCodeInfo_Annotation::IsInitialized() const { void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(_has_bits_[0], other->_has_bits_[0]); path_.InternalSwap(&other->path_); - source_file_.Swap(&other->source_file_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(begin_, other->begin_); - swap(end_, other->end_); + source_file_.Swap(&other->source_file_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, end_) + + sizeof(GeneratedCodeInfo_Annotation::end_) + - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, begin_)>( + reinterpret_cast(&begin_), + reinterpret_cast(&other->begin_)); } ::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const { @@ -11211,21 +10886,12 @@ ::PROTOBUF_NAMESPACE_ID::Metadata GeneratedCodeInfo_Annotation::GetMetadata() co // =================================================================== -void GeneratedCodeInfo::InitAsDefaultInstance() { -} class GeneratedCodeInfo::_Internal { public: - using HasBits = decltype(std::declval()._has_bits_); }; -GeneratedCodeInfo::GeneratedCodeInfo() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.GeneratedCodeInfo) -} GeneratedCodeInfo::GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), annotation_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -11233,10 +10899,8 @@ GeneratedCodeInfo::GeneratedCodeInfo(::PROTOBUF_NAMESPACE_ID::Arena* arena) } GeneratedCodeInfo::GeneratedCodeInfo(const GeneratedCodeInfo& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), - _has_bits_(from._has_bits_), annotation_(from.annotation_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); // @@protoc_insertion_point(copy_constructor:google.protobuf.GeneratedCodeInfo) } @@ -11247,10 +10911,11 @@ void GeneratedCodeInfo::SharedCtor() { GeneratedCodeInfo::~GeneratedCodeInfo() { // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void GeneratedCodeInfo::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void GeneratedCodeInfo::ArenaDtor(void* object) { @@ -11275,13 +10940,11 @@ void GeneratedCodeInfo::Clear() { (void) cached_has_bits; annotation_.Clear(); - _has_bits_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -11305,7 +10968,9 @@ const char* GeneratedCodeInfo::_InternalParse(const char* ptr, ::PROTOBUF_NAMESP ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -11335,7 +11000,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* GeneratedCodeInfo::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.GeneratedCodeInfo) return target; @@ -11383,7 +11048,7 @@ void GeneratedCodeInfo::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) void GeneratedCodeInfo::MergeFrom(const GeneratedCodeInfo& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -11410,8 +11075,7 @@ bool GeneratedCodeInfo::IsInitialized() const { void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); annotation_.InternalSwap(&other->annotation_); } diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 30e85cca7225..381eedeabf5c 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -46,7 +45,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fdescriptor_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[27] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -204,7 +203,7 @@ inline const std::string& FieldDescriptorProto_Type_Name(T enum_t_value) { FieldDescriptorProto_Type_descriptor(), enum_t_value); } inline bool FieldDescriptorProto_Type_Parse( - const std::string& name, FieldDescriptorProto_Type* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Type* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( FieldDescriptorProto_Type_descriptor(), name, value); } @@ -228,7 +227,7 @@ inline const std::string& FieldDescriptorProto_Label_Name(T enum_t_value) { FieldDescriptorProto_Label_descriptor(), enum_t_value); } inline bool FieldDescriptorProto_Label_Parse( - const std::string& name, FieldDescriptorProto_Label* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldDescriptorProto_Label* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( FieldDescriptorProto_Label_descriptor(), name, value); } @@ -252,7 +251,7 @@ inline const std::string& FileOptions_OptimizeMode_Name(T enum_t_value) { FileOptions_OptimizeMode_descriptor(), enum_t_value); } inline bool FileOptions_OptimizeMode_Parse( - const std::string& name, FileOptions_OptimizeMode* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FileOptions_OptimizeMode* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( FileOptions_OptimizeMode_descriptor(), name, value); } @@ -276,7 +275,7 @@ inline const std::string& FieldOptions_CType_Name(T enum_t_value) { FieldOptions_CType_descriptor(), enum_t_value); } inline bool FieldOptions_CType_Parse( - const std::string& name, FieldOptions_CType* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_CType* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( FieldOptions_CType_descriptor(), name, value); } @@ -300,7 +299,7 @@ inline const std::string& FieldOptions_JSType_Name(T enum_t_value) { FieldOptions_JSType_descriptor(), enum_t_value); } inline bool FieldOptions_JSType_Parse( - const std::string& name, FieldOptions_JSType* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, FieldOptions_JSType* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( FieldOptions_JSType_descriptor(), name, value); } @@ -324,16 +323,16 @@ inline const std::string& MethodOptions_IdempotencyLevel_Name(T enum_t_value) { MethodOptions_IdempotencyLevel_descriptor(), enum_t_value); } inline bool MethodOptions_IdempotencyLevel_Parse( - const std::string& name, MethodOptions_IdempotencyLevel* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, MethodOptions_IdempotencyLevel* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( MethodOptions_IdempotencyLevel_descriptor(), name, value); } // =================================================================== -class PROTOBUF_EXPORT FileDescriptorSet : +class PROTOBUF_EXPORT FileDescriptorSet PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ { public: - FileDescriptorSet(); + inline FileDescriptorSet() : FileDescriptorSet(nullptr) {} virtual ~FileDescriptorSet(); FileDescriptorSet(const FileDescriptorSet& from); @@ -347,7 +346,7 @@ class PROTOBUF_EXPORT FileDescriptorSet : return *this; } inline FileDescriptorSet& operator=(FileDescriptorSet&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -356,18 +355,12 @@ class PROTOBUF_EXPORT FileDescriptorSet : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -379,7 +372,6 @@ class PROTOBUF_EXPORT FileDescriptorSet : } static const FileDescriptorSet& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FileDescriptorSet* internal_default_instance() { return reinterpret_cast( &_FileDescriptorSet_default_instance_); @@ -392,7 +384,7 @@ class PROTOBUF_EXPORT FileDescriptorSet : } inline void Swap(FileDescriptorSet* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -400,7 +392,7 @@ class PROTOBUF_EXPORT FileDescriptorSet : } void UnsafeArenaSwap(FileDescriptorSet* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -440,13 +432,6 @@ class PROTOBUF_EXPORT FileDescriptorSet : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -487,21 +472,19 @@ class PROTOBUF_EXPORT FileDescriptorSet : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::FileDescriptorProto > file_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT FileDescriptorProto : +class PROTOBUF_EXPORT FileDescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ { public: - FileDescriptorProto(); + inline FileDescriptorProto() : FileDescriptorProto(nullptr) {} virtual ~FileDescriptorProto(); FileDescriptorProto(const FileDescriptorProto& from); @@ -515,7 +498,7 @@ class PROTOBUF_EXPORT FileDescriptorProto : return *this; } inline FileDescriptorProto& operator=(FileDescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -524,18 +507,12 @@ class PROTOBUF_EXPORT FileDescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -547,7 +524,6 @@ class PROTOBUF_EXPORT FileDescriptorProto : } static const FileDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FileDescriptorProto* internal_default_instance() { return reinterpret_cast( &_FileDescriptorProto_default_instance_); @@ -560,7 +536,7 @@ class PROTOBUF_EXPORT FileDescriptorProto : } inline void Swap(FileDescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -568,7 +544,7 @@ class PROTOBUF_EXPORT FileDescriptorProto : } void UnsafeArenaSwap(FileDescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -608,13 +584,6 @@ class PROTOBUF_EXPORT FileDescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -798,15 +767,6 @@ class PROTOBUF_EXPORT FileDescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -827,15 +787,6 @@ class PROTOBUF_EXPORT FileDescriptorProto : std::string* mutable_package(); std::string* release_package(); void set_allocated_package(std::string* package); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_package(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_package( - std::string* package); private: const std::string& _internal_package() const; void _internal_set_package(const std::string& value); @@ -856,15 +807,6 @@ class PROTOBUF_EXPORT FileDescriptorProto : std::string* mutable_syntax(); std::string* release_syntax(); void set_allocated_syntax(std::string* syntax); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_syntax(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_syntax( - std::string* syntax); private: const std::string& _internal_syntax() const; void _internal_set_syntax(const std::string& value); @@ -911,7 +853,6 @@ class PROTOBUF_EXPORT FileDescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -933,10 +874,10 @@ class PROTOBUF_EXPORT FileDescriptorProto : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : +class PROTOBUF_EXPORT DescriptorProto_ExtensionRange PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ { public: - DescriptorProto_ExtensionRange(); + inline DescriptorProto_ExtensionRange() : DescriptorProto_ExtensionRange(nullptr) {} virtual ~DescriptorProto_ExtensionRange(); DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from); @@ -950,7 +891,7 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : return *this; } inline DescriptorProto_ExtensionRange& operator=(DescriptorProto_ExtensionRange&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -959,18 +900,12 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -982,7 +917,6 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : } static const DescriptorProto_ExtensionRange& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DescriptorProto_ExtensionRange* internal_default_instance() { return reinterpret_cast( &_DescriptorProto_ExtensionRange_default_instance_); @@ -995,7 +929,7 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : } inline void Swap(DescriptorProto_ExtensionRange* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1003,7 +937,7 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : } void UnsafeArenaSwap(DescriptorProto_ExtensionRange* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1043,13 +977,6 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1118,7 +1045,6 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1131,10 +1057,10 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT DescriptorProto_ReservedRange : +class PROTOBUF_EXPORT DescriptorProto_ReservedRange PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ { public: - DescriptorProto_ReservedRange(); + inline DescriptorProto_ReservedRange() : DescriptorProto_ReservedRange(nullptr) {} virtual ~DescriptorProto_ReservedRange(); DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from); @@ -1148,7 +1074,7 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : return *this; } inline DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1157,18 +1083,12 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1180,7 +1100,6 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : } static const DescriptorProto_ReservedRange& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DescriptorProto_ReservedRange* internal_default_instance() { return reinterpret_cast( &_DescriptorProto_ReservedRange_default_instance_); @@ -1193,7 +1112,7 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : } inline void Swap(DescriptorProto_ReservedRange* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1201,7 +1120,7 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : } void UnsafeArenaSwap(DescriptorProto_ReservedRange* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1241,13 +1160,6 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1297,7 +1209,6 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1309,10 +1220,10 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT DescriptorProto : +class PROTOBUF_EXPORT DescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ { public: - DescriptorProto(); + inline DescriptorProto() : DescriptorProto(nullptr) {} virtual ~DescriptorProto(); DescriptorProto(const DescriptorProto& from); @@ -1326,7 +1237,7 @@ class PROTOBUF_EXPORT DescriptorProto : return *this; } inline DescriptorProto& operator=(DescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1335,18 +1246,12 @@ class PROTOBUF_EXPORT DescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1358,7 +1263,6 @@ class PROTOBUF_EXPORT DescriptorProto : } static const DescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DescriptorProto* internal_default_instance() { return reinterpret_cast( &_DescriptorProto_default_instance_); @@ -1371,7 +1275,7 @@ class PROTOBUF_EXPORT DescriptorProto : } inline void Swap(DescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1379,7 +1283,7 @@ class PROTOBUF_EXPORT DescriptorProto : } void UnsafeArenaSwap(DescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1419,13 +1323,6 @@ class PROTOBUF_EXPORT DescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1620,15 +1517,6 @@ class PROTOBUF_EXPORT DescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -1657,7 +1545,6 @@ class PROTOBUF_EXPORT DescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1677,10 +1564,10 @@ class PROTOBUF_EXPORT DescriptorProto : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT ExtensionRangeOptions : +class PROTOBUF_EXPORT ExtensionRangeOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ { public: - ExtensionRangeOptions(); + inline ExtensionRangeOptions() : ExtensionRangeOptions(nullptr) {} virtual ~ExtensionRangeOptions(); ExtensionRangeOptions(const ExtensionRangeOptions& from); @@ -1694,7 +1581,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions : return *this; } inline ExtensionRangeOptions& operator=(ExtensionRangeOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1703,18 +1590,12 @@ class PROTOBUF_EXPORT ExtensionRangeOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1726,7 +1607,6 @@ class PROTOBUF_EXPORT ExtensionRangeOptions : } static const ExtensionRangeOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ExtensionRangeOptions* internal_default_instance() { return reinterpret_cast( &_ExtensionRangeOptions_default_instance_); @@ -1739,7 +1619,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions : } inline void Swap(ExtensionRangeOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1747,7 +1627,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions : } void UnsafeArenaSwap(ExtensionRangeOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1787,13 +1667,6 @@ class PROTOBUF_EXPORT ExtensionRangeOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1837,21 +1710,19 @@ class PROTOBUF_EXPORT ExtensionRangeOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT FieldDescriptorProto : +class PROTOBUF_EXPORT FieldDescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ { public: - FieldDescriptorProto(); + inline FieldDescriptorProto() : FieldDescriptorProto(nullptr) {} virtual ~FieldDescriptorProto(); FieldDescriptorProto(const FieldDescriptorProto& from); @@ -1865,7 +1736,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto : return *this; } inline FieldDescriptorProto& operator=(FieldDescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1874,18 +1745,12 @@ class PROTOBUF_EXPORT FieldDescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1897,7 +1762,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : } static const FieldDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FieldDescriptorProto* internal_default_instance() { return reinterpret_cast( &_FieldDescriptorProto_default_instance_); @@ -1910,7 +1774,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto : } inline void Swap(FieldDescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1918,7 +1782,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto : } void UnsafeArenaSwap(FieldDescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1958,13 +1822,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -2035,7 +1892,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto : "Incorrect type passed to function Type_Name."); return FieldDescriptorProto_Type_Name(enum_t_value); } - static inline bool Type_Parse(const std::string& name, + static inline bool Type_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Type* value) { return FieldDescriptorProto_Type_Parse(name, value); } @@ -2067,7 +1924,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto : "Incorrect type passed to function Label_Name."); return FieldDescriptorProto_Label_Name(enum_t_value); } - static inline bool Label_Parse(const std::string& name, + static inline bool Label_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Label* value) { return FieldDescriptorProto_Label_Parse(name, value); } @@ -2083,6 +1940,7 @@ class PROTOBUF_EXPORT FieldDescriptorProto : kOptionsFieldNumber = 8, kNumberFieldNumber = 3, kOneofIndexFieldNumber = 9, + kProto3OptionalFieldNumber = 17, kLabelFieldNumber = 4, kTypeFieldNumber = 5, }; @@ -2100,15 +1958,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -2129,15 +1978,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : std::string* mutable_extendee(); std::string* release_extendee(); void set_allocated_extendee(std::string* extendee); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_extendee(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_extendee( - std::string* extendee); private: const std::string& _internal_extendee() const; void _internal_set_extendee(const std::string& value); @@ -2158,15 +1998,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : std::string* mutable_type_name(); std::string* release_type_name(); void set_allocated_type_name(std::string* type_name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_type_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_type_name( - std::string* type_name); private: const std::string& _internal_type_name() const; void _internal_set_type_name(const std::string& value); @@ -2187,15 +2018,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : std::string* mutable_default_value(); std::string* release_default_value(); void set_allocated_default_value(std::string* default_value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_default_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_default_value( - std::string* default_value); private: const std::string& _internal_default_value() const; void _internal_set_default_value(const std::string& value); @@ -2216,15 +2038,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : std::string* mutable_json_name(); std::string* release_json_name(); void set_allocated_json_name(std::string* json_name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_json_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_json_name( - std::string* json_name); private: const std::string& _internal_json_name() const; void _internal_set_json_name(const std::string& value); @@ -2275,6 +2088,19 @@ class PROTOBUF_EXPORT FieldDescriptorProto : void _internal_set_oneof_index(::PROTOBUF_NAMESPACE_ID::int32 value); public: + // optional bool proto3_optional = 17; + bool has_proto3_optional() const; + private: + bool _internal_has_proto3_optional() const; + public: + void clear_proto3_optional(); + bool proto3_optional() const; + void set_proto3_optional(bool value); + private: + bool _internal_proto3_optional() const; + void _internal_set_proto3_optional(bool value); + public: + // optional .google.protobuf.FieldDescriptorProto.Label label = 4; bool has_label() const; private: @@ -2305,7 +2131,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -2319,16 +2144,17 @@ class PROTOBUF_EXPORT FieldDescriptorProto : PROTOBUF_NAMESPACE_ID::FieldOptions* options_; ::PROTOBUF_NAMESPACE_ID::int32 number_; ::PROTOBUF_NAMESPACE_ID::int32 oneof_index_; + bool proto3_optional_; int label_; int type_; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT OneofDescriptorProto : +class PROTOBUF_EXPORT OneofDescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ { public: - OneofDescriptorProto(); + inline OneofDescriptorProto() : OneofDescriptorProto(nullptr) {} virtual ~OneofDescriptorProto(); OneofDescriptorProto(const OneofDescriptorProto& from); @@ -2342,7 +2168,7 @@ class PROTOBUF_EXPORT OneofDescriptorProto : return *this; } inline OneofDescriptorProto& operator=(OneofDescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -2351,18 +2177,12 @@ class PROTOBUF_EXPORT OneofDescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -2374,7 +2194,6 @@ class PROTOBUF_EXPORT OneofDescriptorProto : } static const OneofDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const OneofDescriptorProto* internal_default_instance() { return reinterpret_cast( &_OneofDescriptorProto_default_instance_); @@ -2387,7 +2206,7 @@ class PROTOBUF_EXPORT OneofDescriptorProto : } inline void Swap(OneofDescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -2395,7 +2214,7 @@ class PROTOBUF_EXPORT OneofDescriptorProto : } void UnsafeArenaSwap(OneofDescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -2435,13 +2254,6 @@ class PROTOBUF_EXPORT OneofDescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -2475,15 +2287,6 @@ class PROTOBUF_EXPORT OneofDescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -2512,7 +2315,6 @@ class PROTOBUF_EXPORT OneofDescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -2524,10 +2326,10 @@ class PROTOBUF_EXPORT OneofDescriptorProto : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : +class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ { public: - EnumDescriptorProto_EnumReservedRange(); + inline EnumDescriptorProto_EnumReservedRange() : EnumDescriptorProto_EnumReservedRange(nullptr) {} virtual ~EnumDescriptorProto_EnumReservedRange(); EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from); @@ -2541,7 +2343,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : return *this; } inline EnumDescriptorProto_EnumReservedRange& operator=(EnumDescriptorProto_EnumReservedRange&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -2550,18 +2352,12 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -2573,7 +2369,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : } static const EnumDescriptorProto_EnumReservedRange& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumDescriptorProto_EnumReservedRange* internal_default_instance() { return reinterpret_cast( &_EnumDescriptorProto_EnumReservedRange_default_instance_); @@ -2586,7 +2381,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : } inline void Swap(EnumDescriptorProto_EnumReservedRange* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -2594,7 +2389,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : } void UnsafeArenaSwap(EnumDescriptorProto_EnumReservedRange* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -2634,13 +2429,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -2690,7 +2478,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -2702,10 +2489,10 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumDescriptorProto : +class PROTOBUF_EXPORT EnumDescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ { public: - EnumDescriptorProto(); + inline EnumDescriptorProto() : EnumDescriptorProto(nullptr) {} virtual ~EnumDescriptorProto(); EnumDescriptorProto(const EnumDescriptorProto& from); @@ -2719,7 +2506,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto : return *this; } inline EnumDescriptorProto& operator=(EnumDescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -2728,18 +2515,12 @@ class PROTOBUF_EXPORT EnumDescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -2751,7 +2532,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto : } static const EnumDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumDescriptorProto* internal_default_instance() { return reinterpret_cast( &_EnumDescriptorProto_default_instance_); @@ -2764,7 +2544,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto : } inline void Swap(EnumDescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -2772,7 +2552,7 @@ class PROTOBUF_EXPORT EnumDescriptorProto : } void UnsafeArenaSwap(EnumDescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -2812,13 +2592,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -2917,15 +2690,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -2954,7 +2718,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -2969,10 +2732,10 @@ class PROTOBUF_EXPORT EnumDescriptorProto : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumValueDescriptorProto : +class PROTOBUF_EXPORT EnumValueDescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ { public: - EnumValueDescriptorProto(); + inline EnumValueDescriptorProto() : EnumValueDescriptorProto(nullptr) {} virtual ~EnumValueDescriptorProto(); EnumValueDescriptorProto(const EnumValueDescriptorProto& from); @@ -2986,7 +2749,7 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : return *this; } inline EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -2995,18 +2758,12 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -3018,7 +2775,6 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : } static const EnumValueDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumValueDescriptorProto* internal_default_instance() { return reinterpret_cast( &_EnumValueDescriptorProto_default_instance_); @@ -3031,7 +2787,7 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : } inline void Swap(EnumValueDescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -3039,7 +2795,7 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : } void UnsafeArenaSwap(EnumValueDescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -3079,13 +2835,6 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -3120,15 +2869,6 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -3170,7 +2910,6 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -3183,10 +2922,10 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT ServiceDescriptorProto : +class PROTOBUF_EXPORT ServiceDescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ { public: - ServiceDescriptorProto(); + inline ServiceDescriptorProto() : ServiceDescriptorProto(nullptr) {} virtual ~ServiceDescriptorProto(); ServiceDescriptorProto(const ServiceDescriptorProto& from); @@ -3200,7 +2939,7 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : return *this; } inline ServiceDescriptorProto& operator=(ServiceDescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -3209,18 +2948,12 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -3232,7 +2965,6 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : } static const ServiceDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ServiceDescriptorProto* internal_default_instance() { return reinterpret_cast( &_ServiceDescriptorProto_default_instance_); @@ -3245,7 +2977,7 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : } inline void Swap(ServiceDescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -3253,7 +2985,7 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : } void UnsafeArenaSwap(ServiceDescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -3293,13 +3025,6 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -3352,15 +3077,6 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -3389,7 +3105,6 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -3402,10 +3117,10 @@ class PROTOBUF_EXPORT ServiceDescriptorProto : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT MethodDescriptorProto : +class PROTOBUF_EXPORT MethodDescriptorProto PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ { public: - MethodDescriptorProto(); + inline MethodDescriptorProto() : MethodDescriptorProto(nullptr) {} virtual ~MethodDescriptorProto(); MethodDescriptorProto(const MethodDescriptorProto& from); @@ -3419,7 +3134,7 @@ class PROTOBUF_EXPORT MethodDescriptorProto : return *this; } inline MethodDescriptorProto& operator=(MethodDescriptorProto&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -3428,18 +3143,12 @@ class PROTOBUF_EXPORT MethodDescriptorProto : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -3451,7 +3160,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto : } static const MethodDescriptorProto& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const MethodDescriptorProto* internal_default_instance() { return reinterpret_cast( &_MethodDescriptorProto_default_instance_); @@ -3464,7 +3172,7 @@ class PROTOBUF_EXPORT MethodDescriptorProto : } inline void Swap(MethodDescriptorProto* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -3472,7 +3180,7 @@ class PROTOBUF_EXPORT MethodDescriptorProto : } void UnsafeArenaSwap(MethodDescriptorProto* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -3512,13 +3220,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -3556,15 +3257,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -3585,15 +3277,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto : std::string* mutable_input_type(); std::string* release_input_type(); void set_allocated_input_type(std::string* input_type); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_input_type(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_input_type( - std::string* input_type); private: const std::string& _internal_input_type() const; void _internal_set_input_type(const std::string& value); @@ -3614,15 +3297,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto : std::string* mutable_output_type(); std::string* release_output_type(); void set_allocated_output_type(std::string* output_type); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_output_type(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_output_type( - std::string* output_type); private: const std::string& _internal_output_type() const; void _internal_set_output_type(const std::string& value); @@ -3677,7 +3351,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -3693,10 +3366,10 @@ class PROTOBUF_EXPORT MethodDescriptorProto : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT FileOptions : +class PROTOBUF_EXPORT FileOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ { public: - FileOptions(); + inline FileOptions() : FileOptions(nullptr) {} virtual ~FileOptions(); FileOptions(const FileOptions& from); @@ -3710,7 +3383,7 @@ class PROTOBUF_EXPORT FileOptions : return *this; } inline FileOptions& operator=(FileOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -3719,18 +3392,12 @@ class PROTOBUF_EXPORT FileOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -3742,7 +3409,6 @@ class PROTOBUF_EXPORT FileOptions : } static const FileOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FileOptions* internal_default_instance() { return reinterpret_cast( &_FileOptions_default_instance_); @@ -3755,7 +3421,7 @@ class PROTOBUF_EXPORT FileOptions : } inline void Swap(FileOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -3763,7 +3429,7 @@ class PROTOBUF_EXPORT FileOptions : } void UnsafeArenaSwap(FileOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -3803,13 +3469,6 @@ class PROTOBUF_EXPORT FileOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -3850,7 +3509,7 @@ class PROTOBUF_EXPORT FileOptions : "Incorrect type passed to function OptimizeMode_Name."); return FileOptions_OptimizeMode_Name(enum_t_value); } - static inline bool OptimizeMode_Parse(const std::string& name, + static inline bool OptimizeMode_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OptimizeMode* value) { return FileOptions_OptimizeMode_Parse(name, value); } @@ -3877,8 +3536,8 @@ class PROTOBUF_EXPORT FileOptions : kPyGenericServicesFieldNumber = 18, kPhpGenericServicesFieldNumber = 42, kDeprecatedFieldNumber = 23, - kCcEnableArenasFieldNumber = 31, kOptimizeForFieldNumber = 9, + kCcEnableArenasFieldNumber = 31, }; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; int uninterpreted_option_size() const; @@ -3912,15 +3571,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_java_package(); std::string* release_java_package(); void set_allocated_java_package(std::string* java_package); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_java_package(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_java_package( - std::string* java_package); private: const std::string& _internal_java_package() const; void _internal_set_java_package(const std::string& value); @@ -3941,15 +3591,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_java_outer_classname(); std::string* release_java_outer_classname(); void set_allocated_java_outer_classname(std::string* java_outer_classname); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_java_outer_classname(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_java_outer_classname( - std::string* java_outer_classname); private: const std::string& _internal_java_outer_classname() const; void _internal_set_java_outer_classname(const std::string& value); @@ -3970,15 +3611,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_go_package(); std::string* release_go_package(); void set_allocated_go_package(std::string* go_package); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_go_package(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_go_package( - std::string* go_package); private: const std::string& _internal_go_package() const; void _internal_set_go_package(const std::string& value); @@ -3999,15 +3631,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_objc_class_prefix(); std::string* release_objc_class_prefix(); void set_allocated_objc_class_prefix(std::string* objc_class_prefix); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_objc_class_prefix(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_objc_class_prefix( - std::string* objc_class_prefix); private: const std::string& _internal_objc_class_prefix() const; void _internal_set_objc_class_prefix(const std::string& value); @@ -4028,15 +3651,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_csharp_namespace(); std::string* release_csharp_namespace(); void set_allocated_csharp_namespace(std::string* csharp_namespace); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_csharp_namespace(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_csharp_namespace( - std::string* csharp_namespace); private: const std::string& _internal_csharp_namespace() const; void _internal_set_csharp_namespace(const std::string& value); @@ -4057,15 +3671,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_swift_prefix(); std::string* release_swift_prefix(); void set_allocated_swift_prefix(std::string* swift_prefix); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_swift_prefix(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_swift_prefix( - std::string* swift_prefix); private: const std::string& _internal_swift_prefix() const; void _internal_set_swift_prefix(const std::string& value); @@ -4086,15 +3691,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_php_class_prefix(); std::string* release_php_class_prefix(); void set_allocated_php_class_prefix(std::string* php_class_prefix); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_php_class_prefix(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_php_class_prefix( - std::string* php_class_prefix); private: const std::string& _internal_php_class_prefix() const; void _internal_set_php_class_prefix(const std::string& value); @@ -4115,15 +3711,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_php_namespace(); std::string* release_php_namespace(); void set_allocated_php_namespace(std::string* php_namespace); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_php_namespace(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_php_namespace( - std::string* php_namespace); private: const std::string& _internal_php_namespace() const; void _internal_set_php_namespace(const std::string& value); @@ -4144,15 +3731,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_php_metadata_namespace(); std::string* release_php_metadata_namespace(); void set_allocated_php_metadata_namespace(std::string* php_metadata_namespace); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_php_metadata_namespace(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_php_metadata_namespace( - std::string* php_metadata_namespace); private: const std::string& _internal_php_metadata_namespace() const; void _internal_set_php_metadata_namespace(const std::string& value); @@ -4173,15 +3751,6 @@ class PROTOBUF_EXPORT FileOptions : std::string* mutable_ruby_package(); std::string* release_ruby_package(); void set_allocated_ruby_package(std::string* ruby_package); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_ruby_package(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_ruby_package( - std::string* ruby_package); private: const std::string& _internal_ruby_package() const; void _internal_set_ruby_package(const std::string& value); @@ -4292,19 +3861,6 @@ class PROTOBUF_EXPORT FileOptions : void _internal_set_deprecated(bool value); public: - // optional bool cc_enable_arenas = 31 [default = false]; - bool has_cc_enable_arenas() const; - private: - bool _internal_has_cc_enable_arenas() const; - public: - void clear_cc_enable_arenas(); - bool cc_enable_arenas() const; - void set_cc_enable_arenas(bool value); - private: - bool _internal_cc_enable_arenas() const; - void _internal_set_cc_enable_arenas(bool value); - public: - // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; bool has_optimize_for() const; private: @@ -4318,6 +3874,19 @@ class PROTOBUF_EXPORT FileOptions : void _internal_set_optimize_for(PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value); public: + // optional bool cc_enable_arenas = 31 [default = true]; + bool has_cc_enable_arenas() const; + private: + bool _internal_has_cc_enable_arenas() const; + public: + void clear_cc_enable_arenas(); + bool cc_enable_arenas() const; + void set_cc_enable_arenas(bool value); + private: + bool _internal_cc_enable_arenas() const; + void _internal_set_cc_enable_arenas(bool value); + public: + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions) // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) private: @@ -4325,7 +3894,6 @@ class PROTOBUF_EXPORT FileOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -4350,16 +3918,16 @@ class PROTOBUF_EXPORT FileOptions : bool py_generic_services_; bool php_generic_services_; bool deprecated_; - bool cc_enable_arenas_; int optimize_for_; + bool cc_enable_arenas_; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT MessageOptions : +class PROTOBUF_EXPORT MessageOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ { public: - MessageOptions(); + inline MessageOptions() : MessageOptions(nullptr) {} virtual ~MessageOptions(); MessageOptions(const MessageOptions& from); @@ -4373,7 +3941,7 @@ class PROTOBUF_EXPORT MessageOptions : return *this; } inline MessageOptions& operator=(MessageOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -4382,18 +3950,12 @@ class PROTOBUF_EXPORT MessageOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -4405,7 +3967,6 @@ class PROTOBUF_EXPORT MessageOptions : } static const MessageOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const MessageOptions* internal_default_instance() { return reinterpret_cast( &_MessageOptions_default_instance_); @@ -4418,7 +3979,7 @@ class PROTOBUF_EXPORT MessageOptions : } inline void Swap(MessageOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -4426,7 +3987,7 @@ class PROTOBUF_EXPORT MessageOptions : } void UnsafeArenaSwap(MessageOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -4466,13 +4027,6 @@ class PROTOBUF_EXPORT MessageOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -4572,7 +4126,6 @@ class PROTOBUF_EXPORT MessageOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -4587,10 +4140,10 @@ class PROTOBUF_EXPORT MessageOptions : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT FieldOptions : +class PROTOBUF_EXPORT FieldOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ { public: - FieldOptions(); + inline FieldOptions() : FieldOptions(nullptr) {} virtual ~FieldOptions(); FieldOptions(const FieldOptions& from); @@ -4604,7 +4157,7 @@ class PROTOBUF_EXPORT FieldOptions : return *this; } inline FieldOptions& operator=(FieldOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -4613,18 +4166,12 @@ class PROTOBUF_EXPORT FieldOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -4636,7 +4183,6 @@ class PROTOBUF_EXPORT FieldOptions : } static const FieldOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FieldOptions* internal_default_instance() { return reinterpret_cast( &_FieldOptions_default_instance_); @@ -4649,7 +4195,7 @@ class PROTOBUF_EXPORT FieldOptions : } inline void Swap(FieldOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -4657,7 +4203,7 @@ class PROTOBUF_EXPORT FieldOptions : } void UnsafeArenaSwap(FieldOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -4697,13 +4243,6 @@ class PROTOBUF_EXPORT FieldOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -4744,7 +4283,7 @@ class PROTOBUF_EXPORT FieldOptions : "Incorrect type passed to function CType_Name."); return FieldOptions_CType_Name(enum_t_value); } - static inline bool CType_Parse(const std::string& name, + static inline bool CType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, CType* value) { return FieldOptions_CType_Parse(name, value); } @@ -4776,7 +4315,7 @@ class PROTOBUF_EXPORT FieldOptions : "Incorrect type passed to function JSType_Name."); return FieldOptions_JSType_Name(enum_t_value); } - static inline bool JSType_Parse(const std::string& name, + static inline bool JSType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, JSType* value) { return FieldOptions_JSType_Parse(name, value); } @@ -4895,7 +4434,6 @@ class PROTOBUF_EXPORT FieldOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -4912,10 +4450,10 @@ class PROTOBUF_EXPORT FieldOptions : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT OneofOptions : +class PROTOBUF_EXPORT OneofOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ { public: - OneofOptions(); + inline OneofOptions() : OneofOptions(nullptr) {} virtual ~OneofOptions(); OneofOptions(const OneofOptions& from); @@ -4929,7 +4467,7 @@ class PROTOBUF_EXPORT OneofOptions : return *this; } inline OneofOptions& operator=(OneofOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -4938,18 +4476,12 @@ class PROTOBUF_EXPORT OneofOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -4961,7 +4493,6 @@ class PROTOBUF_EXPORT OneofOptions : } static const OneofOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const OneofOptions* internal_default_instance() { return reinterpret_cast( &_OneofOptions_default_instance_); @@ -4974,7 +4505,7 @@ class PROTOBUF_EXPORT OneofOptions : } inline void Swap(OneofOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -4982,7 +4513,7 @@ class PROTOBUF_EXPORT OneofOptions : } void UnsafeArenaSwap(OneofOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -5022,13 +4553,6 @@ class PROTOBUF_EXPORT OneofOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -5072,21 +4596,19 @@ class PROTOBUF_EXPORT OneofOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::UninterpretedOption > uninterpreted_option_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumOptions : +class PROTOBUF_EXPORT EnumOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ { public: - EnumOptions(); + inline EnumOptions() : EnumOptions(nullptr) {} virtual ~EnumOptions(); EnumOptions(const EnumOptions& from); @@ -5100,7 +4622,7 @@ class PROTOBUF_EXPORT EnumOptions : return *this; } inline EnumOptions& operator=(EnumOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -5109,18 +4631,12 @@ class PROTOBUF_EXPORT EnumOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -5132,7 +4648,6 @@ class PROTOBUF_EXPORT EnumOptions : } static const EnumOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumOptions* internal_default_instance() { return reinterpret_cast( &_EnumOptions_default_instance_); @@ -5145,7 +4660,7 @@ class PROTOBUF_EXPORT EnumOptions : } inline void Swap(EnumOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -5153,7 +4668,7 @@ class PROTOBUF_EXPORT EnumOptions : } void UnsafeArenaSwap(EnumOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -5193,13 +4708,6 @@ class PROTOBUF_EXPORT EnumOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -5271,7 +4779,6 @@ class PROTOBUF_EXPORT EnumOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -5284,10 +4791,10 @@ class PROTOBUF_EXPORT EnumOptions : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumValueOptions : +class PROTOBUF_EXPORT EnumValueOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ { public: - EnumValueOptions(); + inline EnumValueOptions() : EnumValueOptions(nullptr) {} virtual ~EnumValueOptions(); EnumValueOptions(const EnumValueOptions& from); @@ -5301,7 +4808,7 @@ class PROTOBUF_EXPORT EnumValueOptions : return *this; } inline EnumValueOptions& operator=(EnumValueOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -5310,18 +4817,12 @@ class PROTOBUF_EXPORT EnumValueOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -5333,7 +4834,6 @@ class PROTOBUF_EXPORT EnumValueOptions : } static const EnumValueOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumValueOptions* internal_default_instance() { return reinterpret_cast( &_EnumValueOptions_default_instance_); @@ -5346,7 +4846,7 @@ class PROTOBUF_EXPORT EnumValueOptions : } inline void Swap(EnumValueOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -5354,7 +4854,7 @@ class PROTOBUF_EXPORT EnumValueOptions : } void UnsafeArenaSwap(EnumValueOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -5394,13 +4894,6 @@ class PROTOBUF_EXPORT EnumValueOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -5458,7 +4951,6 @@ class PROTOBUF_EXPORT EnumValueOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -5470,10 +4962,10 @@ class PROTOBUF_EXPORT EnumValueOptions : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT ServiceOptions : +class PROTOBUF_EXPORT ServiceOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ { public: - ServiceOptions(); + inline ServiceOptions() : ServiceOptions(nullptr) {} virtual ~ServiceOptions(); ServiceOptions(const ServiceOptions& from); @@ -5487,7 +4979,7 @@ class PROTOBUF_EXPORT ServiceOptions : return *this; } inline ServiceOptions& operator=(ServiceOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -5496,18 +4988,12 @@ class PROTOBUF_EXPORT ServiceOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -5519,7 +5005,6 @@ class PROTOBUF_EXPORT ServiceOptions : } static const ServiceOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ServiceOptions* internal_default_instance() { return reinterpret_cast( &_ServiceOptions_default_instance_); @@ -5532,7 +5017,7 @@ class PROTOBUF_EXPORT ServiceOptions : } inline void Swap(ServiceOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -5540,7 +5025,7 @@ class PROTOBUF_EXPORT ServiceOptions : } void UnsafeArenaSwap(ServiceOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -5580,13 +5065,6 @@ class PROTOBUF_EXPORT ServiceOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -5644,7 +5122,6 @@ class PROTOBUF_EXPORT ServiceOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -5656,10 +5133,10 @@ class PROTOBUF_EXPORT ServiceOptions : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT MethodOptions : +class PROTOBUF_EXPORT MethodOptions PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ { public: - MethodOptions(); + inline MethodOptions() : MethodOptions(nullptr) {} virtual ~MethodOptions(); MethodOptions(const MethodOptions& from); @@ -5673,7 +5150,7 @@ class PROTOBUF_EXPORT MethodOptions : return *this; } inline MethodOptions& operator=(MethodOptions&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -5682,18 +5159,12 @@ class PROTOBUF_EXPORT MethodOptions : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -5705,7 +5176,6 @@ class PROTOBUF_EXPORT MethodOptions : } static const MethodOptions& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const MethodOptions* internal_default_instance() { return reinterpret_cast( &_MethodOptions_default_instance_); @@ -5718,7 +5188,7 @@ class PROTOBUF_EXPORT MethodOptions : } inline void Swap(MethodOptions* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -5726,7 +5196,7 @@ class PROTOBUF_EXPORT MethodOptions : } void UnsafeArenaSwap(MethodOptions* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -5766,13 +5236,6 @@ class PROTOBUF_EXPORT MethodOptions : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -5813,7 +5276,7 @@ class PROTOBUF_EXPORT MethodOptions : "Incorrect type passed to function IdempotencyLevel_Name."); return MethodOptions_IdempotencyLevel_Name(enum_t_value); } - static inline bool IdempotencyLevel_Parse(const std::string& name, + static inline bool IdempotencyLevel_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, IdempotencyLevel* value) { return MethodOptions_IdempotencyLevel_Parse(name, value); } @@ -5876,7 +5339,6 @@ class PROTOBUF_EXPORT MethodOptions : ::PROTOBUF_NAMESPACE_ID::internal::ExtensionSet _extensions_; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -5889,10 +5351,10 @@ class PROTOBUF_EXPORT MethodOptions : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT UninterpretedOption_NamePart : +class PROTOBUF_EXPORT UninterpretedOption_NamePart PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ { public: - UninterpretedOption_NamePart(); + inline UninterpretedOption_NamePart() : UninterpretedOption_NamePart(nullptr) {} virtual ~UninterpretedOption_NamePart(); UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from); @@ -5906,7 +5368,7 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : return *this; } inline UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -5915,18 +5377,12 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -5938,7 +5394,6 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : } static const UninterpretedOption_NamePart& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UninterpretedOption_NamePart* internal_default_instance() { return reinterpret_cast( &_UninterpretedOption_NamePart_default_instance_); @@ -5951,7 +5406,7 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : } inline void Swap(UninterpretedOption_NamePart* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -5959,7 +5414,7 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : } void UnsafeArenaSwap(UninterpretedOption_NamePart* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -5999,13 +5454,6 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -6039,15 +5487,6 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : std::string* mutable_name_part(); std::string* release_name_part(); void set_allocated_name_part(std::string* name_part); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name_part(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name_part( - std::string* name_part); private: const std::string& _internal_name_part() const; void _internal_set_name_part(const std::string& value); @@ -6074,7 +5513,6 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : // helper for ByteSizeLong() size_t RequiredFieldsByteSizeFallback() const; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -6086,10 +5524,10 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT UninterpretedOption : +class PROTOBUF_EXPORT UninterpretedOption PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ { public: - UninterpretedOption(); + inline UninterpretedOption() : UninterpretedOption(nullptr) {} virtual ~UninterpretedOption(); UninterpretedOption(const UninterpretedOption& from); @@ -6103,7 +5541,7 @@ class PROTOBUF_EXPORT UninterpretedOption : return *this; } inline UninterpretedOption& operator=(UninterpretedOption&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -6112,18 +5550,12 @@ class PROTOBUF_EXPORT UninterpretedOption : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -6135,7 +5567,6 @@ class PROTOBUF_EXPORT UninterpretedOption : } static const UninterpretedOption& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UninterpretedOption* internal_default_instance() { return reinterpret_cast( &_UninterpretedOption_default_instance_); @@ -6148,7 +5579,7 @@ class PROTOBUF_EXPORT UninterpretedOption : } inline void Swap(UninterpretedOption* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -6156,7 +5587,7 @@ class PROTOBUF_EXPORT UninterpretedOption : } void UnsafeArenaSwap(UninterpretedOption* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -6196,13 +5627,6 @@ class PROTOBUF_EXPORT UninterpretedOption : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -6261,15 +5685,6 @@ class PROTOBUF_EXPORT UninterpretedOption : std::string* mutable_identifier_value(); std::string* release_identifier_value(); void set_allocated_identifier_value(std::string* identifier_value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_identifier_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_identifier_value( - std::string* identifier_value); private: const std::string& _internal_identifier_value() const; void _internal_set_identifier_value(const std::string& value); @@ -6290,15 +5705,6 @@ class PROTOBUF_EXPORT UninterpretedOption : std::string* mutable_string_value(); std::string* release_string_value(); void set_allocated_string_value(std::string* string_value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_string_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_string_value( - std::string* string_value); private: const std::string& _internal_string_value() const; void _internal_set_string_value(const std::string& value); @@ -6319,15 +5725,6 @@ class PROTOBUF_EXPORT UninterpretedOption : std::string* mutable_aggregate_value(); std::string* release_aggregate_value(); void set_allocated_aggregate_value(std::string* aggregate_value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_aggregate_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_aggregate_value( - std::string* aggregate_value); private: const std::string& _internal_aggregate_value() const; void _internal_set_aggregate_value(const std::string& value); @@ -6377,7 +5774,6 @@ class PROTOBUF_EXPORT UninterpretedOption : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -6394,10 +5790,10 @@ class PROTOBUF_EXPORT UninterpretedOption : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT SourceCodeInfo_Location : +class PROTOBUF_EXPORT SourceCodeInfo_Location PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ { public: - SourceCodeInfo_Location(); + inline SourceCodeInfo_Location() : SourceCodeInfo_Location(nullptr) {} virtual ~SourceCodeInfo_Location(); SourceCodeInfo_Location(const SourceCodeInfo_Location& from); @@ -6411,7 +5807,7 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : return *this; } inline SourceCodeInfo_Location& operator=(SourceCodeInfo_Location&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -6420,18 +5816,12 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -6443,7 +5833,6 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : } static const SourceCodeInfo_Location& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const SourceCodeInfo_Location* internal_default_instance() { return reinterpret_cast( &_SourceCodeInfo_Location_default_instance_); @@ -6456,7 +5845,7 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : } inline void Swap(SourceCodeInfo_Location* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -6464,7 +5853,7 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : } void UnsafeArenaSwap(SourceCodeInfo_Location* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -6504,13 +5893,6 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -6615,15 +5997,6 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : std::string* mutable_leading_comments(); std::string* release_leading_comments(); void set_allocated_leading_comments(std::string* leading_comments); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_leading_comments(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_leading_comments( - std::string* leading_comments); private: const std::string& _internal_leading_comments() const; void _internal_set_leading_comments(const std::string& value); @@ -6644,15 +6017,6 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : std::string* mutable_trailing_comments(); std::string* release_trailing_comments(); void set_allocated_trailing_comments(std::string* trailing_comments); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_trailing_comments(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_trailing_comments( - std::string* trailing_comments); private: const std::string& _internal_trailing_comments() const; void _internal_set_trailing_comments(const std::string& value); @@ -6663,7 +6027,6 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -6680,10 +6043,10 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT SourceCodeInfo : +class PROTOBUF_EXPORT SourceCodeInfo PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ { public: - SourceCodeInfo(); + inline SourceCodeInfo() : SourceCodeInfo(nullptr) {} virtual ~SourceCodeInfo(); SourceCodeInfo(const SourceCodeInfo& from); @@ -6697,7 +6060,7 @@ class PROTOBUF_EXPORT SourceCodeInfo : return *this; } inline SourceCodeInfo& operator=(SourceCodeInfo&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -6706,18 +6069,12 @@ class PROTOBUF_EXPORT SourceCodeInfo : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -6729,7 +6086,6 @@ class PROTOBUF_EXPORT SourceCodeInfo : } static const SourceCodeInfo& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const SourceCodeInfo* internal_default_instance() { return reinterpret_cast( &_SourceCodeInfo_default_instance_); @@ -6742,7 +6098,7 @@ class PROTOBUF_EXPORT SourceCodeInfo : } inline void Swap(SourceCodeInfo* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -6750,7 +6106,7 @@ class PROTOBUF_EXPORT SourceCodeInfo : } void UnsafeArenaSwap(SourceCodeInfo* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -6790,13 +6146,6 @@ class PROTOBUF_EXPORT SourceCodeInfo : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -6839,21 +6188,19 @@ class PROTOBUF_EXPORT SourceCodeInfo : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location > location_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : +class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ { public: - GeneratedCodeInfo_Annotation(); + inline GeneratedCodeInfo_Annotation() : GeneratedCodeInfo_Annotation(nullptr) {} virtual ~GeneratedCodeInfo_Annotation(); GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from); @@ -6867,7 +6214,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : return *this; } inline GeneratedCodeInfo_Annotation& operator=(GeneratedCodeInfo_Annotation&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -6876,18 +6223,12 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -6899,7 +6240,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : } static const GeneratedCodeInfo_Annotation& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const GeneratedCodeInfo_Annotation* internal_default_instance() { return reinterpret_cast( &_GeneratedCodeInfo_Annotation_default_instance_); @@ -6912,7 +6252,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : } inline void Swap(GeneratedCodeInfo_Annotation* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -6920,7 +6260,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : } void UnsafeArenaSwap(GeneratedCodeInfo_Annotation* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -6960,13 +6300,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -7024,15 +6357,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : std::string* mutable_source_file(); std::string* release_source_file(); void set_allocated_source_file(std::string* source_file); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_source_file(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_source_file( - std::string* source_file); private: const std::string& _internal_source_file() const; void _internal_set_source_file(const std::string& value); @@ -7069,7 +6393,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -7084,10 +6407,10 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT GeneratedCodeInfo : +class PROTOBUF_EXPORT GeneratedCodeInfo PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ { public: - GeneratedCodeInfo(); + inline GeneratedCodeInfo() : GeneratedCodeInfo(nullptr) {} virtual ~GeneratedCodeInfo(); GeneratedCodeInfo(const GeneratedCodeInfo& from); @@ -7101,7 +6424,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo : return *this; } inline GeneratedCodeInfo& operator=(GeneratedCodeInfo&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -7110,18 +6433,12 @@ class PROTOBUF_EXPORT GeneratedCodeInfo : } inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const { - return _internal_metadata_.unknown_fields(); + return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance); } inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() { - return _internal_metadata_.mutable_unknown_fields(); + return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -7133,7 +6450,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo : } static const GeneratedCodeInfo& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const GeneratedCodeInfo* internal_default_instance() { return reinterpret_cast( &_GeneratedCodeInfo_default_instance_); @@ -7146,7 +6462,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo : } inline void Swap(GeneratedCodeInfo* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -7154,7 +6470,7 @@ class PROTOBUF_EXPORT GeneratedCodeInfo : } void UnsafeArenaSwap(GeneratedCodeInfo* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -7194,13 +6510,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -7243,13 +6552,11 @@ class PROTOBUF_EXPORT GeneratedCodeInfo : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_; - mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo_Annotation > annotation_; + mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; }; // =================================================================== @@ -7315,7 +6622,7 @@ inline bool FileDescriptorProto::has_name() const { return _internal_has_name(); } inline void FileDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& FileDescriptorProto::name() const { @@ -7335,31 +6642,30 @@ inline const std::string& FileDescriptorProto::_internal_name() const { } inline void FileDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.name) } inline void FileDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name) } inline void FileDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name) } inline std::string* FileDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name) @@ -7367,7 +6673,7 @@ inline std::string* FileDescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileDescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -7376,28 +6682,9 @@ inline void FileDescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name) } -inline std::string* FileDescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileDescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.name) -} // optional string package = 2; inline bool FileDescriptorProto::_internal_has_package() const { @@ -7408,7 +6695,7 @@ inline bool FileDescriptorProto::has_package() const { return _internal_has_package(); } inline void FileDescriptorProto::clear_package() { - package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& FileDescriptorProto::package() const { @@ -7428,31 +6715,30 @@ inline const std::string& FileDescriptorProto::_internal_package() const { } inline void FileDescriptorProto::_internal_set_package(const std::string& value) { _has_bits_[0] |= 0x00000002u; - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileDescriptorProto::set_package(std::string&& value) { _has_bits_[0] |= 0x00000002u; package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.package) } inline void FileDescriptorProto::set_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package) } inline void FileDescriptorProto::set_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package) } inline std::string* FileDescriptorProto::_internal_mutable_package() { _has_bits_[0] |= 0x00000002u; - return package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileDescriptorProto::release_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package) @@ -7460,7 +6746,7 @@ inline std::string* FileDescriptorProto::release_package() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - return package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileDescriptorProto::set_allocated_package(std::string* package) { if (package != nullptr) { @@ -7469,28 +6755,9 @@ inline void FileDescriptorProto::set_allocated_package(std::string* package) { _has_bits_[0] &= ~0x00000002u; } package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), package, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package) } -inline std::string* FileDescriptorProto::unsafe_arena_release_package() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.package) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000002u; - return package_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileDescriptorProto::unsafe_arena_set_allocated_package( - std::string* package) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (package != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - package_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - package, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.package) -} // repeated string dependency = 3; inline int FileDescriptorProto::_internal_dependency_size() const { @@ -7831,16 +7098,31 @@ inline void FileDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::FileOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_FileOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::FileOptions& FileDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options) return _internal_options(); } +inline void FileDescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::FileOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.options) +} inline PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000008u; + PROTOBUF_NAMESPACE_ID::FileOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -7855,7 +7137,7 @@ inline PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::unsafe_arena_rel inline PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000008u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -7865,7 +7147,7 @@ inline PROTOBUF_NAMESPACE_ID::FileOptions* FileDescriptorProto::mutable_options( return _internal_mutable_options(); } inline void FileDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::FileOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -7899,16 +7181,31 @@ inline void FileDescriptorProto::clear_source_code_info() { } inline const PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::_internal_source_code_info() const { const PROTOBUF_NAMESPACE_ID::SourceCodeInfo* p = source_code_info_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceCodeInfo_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceCodeInfo& FileDescriptorProto::source_code_info() const { // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info) return _internal_source_code_info(); } +inline void FileDescriptorProto::unsafe_arena_set_allocated_source_code_info( + PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_code_info_); + } + source_code_info_ = source_code_info; + if (source_code_info) { + _has_bits_[0] |= 0x00000010u; + } else { + _has_bits_[0] &= ~0x00000010u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.source_code_info) +} inline PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::release_source_code_info() { - auto temp = unsafe_arena_release_source_code_info(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000010u; + PROTOBUF_NAMESPACE_ID::SourceCodeInfo* temp = source_code_info_; + source_code_info_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -7923,7 +7220,7 @@ inline PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::unsafe_arena_ inline PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::_internal_mutable_source_code_info() { _has_bits_[0] |= 0x00000010u; if (source_code_info_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); source_code_info_ = p; } return source_code_info_; @@ -7933,7 +7230,7 @@ inline PROTOBUF_NAMESPACE_ID::SourceCodeInfo* FileDescriptorProto::mutable_sourc return _internal_mutable_source_code_info(); } inline void FileDescriptorProto::set_allocated_source_code_info(PROTOBUF_NAMESPACE_ID::SourceCodeInfo* source_code_info) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete source_code_info_; } @@ -7961,7 +7258,7 @@ inline bool FileDescriptorProto::has_syntax() const { return _internal_has_syntax(); } inline void FileDescriptorProto::clear_syntax() { - syntax_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + syntax_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& FileDescriptorProto::syntax() const { @@ -7981,31 +7278,30 @@ inline const std::string& FileDescriptorProto::_internal_syntax() const { } inline void FileDescriptorProto::_internal_set_syntax(const std::string& value) { _has_bits_[0] |= 0x00000004u; - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileDescriptorProto::set_syntax(std::string&& value) { _has_bits_[0] |= 0x00000004u; syntax_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.syntax) } inline void FileDescriptorProto::set_syntax(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax) } inline void FileDescriptorProto::set_syntax(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.syntax) } inline std::string* FileDescriptorProto::_internal_mutable_syntax() { _has_bits_[0] |= 0x00000004u; - return syntax_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return syntax_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileDescriptorProto::release_syntax() { // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax) @@ -8013,7 +7309,7 @@ inline std::string* FileDescriptorProto::release_syntax() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - return syntax_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return syntax_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileDescriptorProto::set_allocated_syntax(std::string* syntax) { if (syntax != nullptr) { @@ -8022,28 +7318,9 @@ inline void FileDescriptorProto::set_allocated_syntax(std::string* syntax) { _has_bits_[0] &= ~0x00000004u; } syntax_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), syntax, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.syntax) } -inline std::string* FileDescriptorProto::unsafe_arena_release_syntax() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileDescriptorProto.syntax) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000004u; - return syntax_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileDescriptorProto::unsafe_arena_set_allocated_syntax( - std::string* syntax) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (syntax != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - syntax_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - syntax, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileDescriptorProto.syntax) -} // ------------------------------------------------------------------- @@ -8120,16 +7397,31 @@ inline void DescriptorProto_ExtensionRange::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_internal_options() const { const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_ExtensionRangeOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions& DescriptorProto_ExtensionRange::options() const { // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.options) return _internal_options(); } +inline void DescriptorProto_ExtensionRange::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000001u; + } else { + _has_bits_[0] &= ~0x00000001u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.ExtensionRange.options) +} inline PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000001u; + PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -8144,7 +7436,7 @@ inline PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRa inline PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRange::_internal_mutable_options() { _has_bits_[0] |= 0x00000001u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -8154,7 +7446,7 @@ inline PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* DescriptorProto_ExtensionRa return _internal_mutable_options(); } inline void DescriptorProto_ExtensionRange::set_allocated_options(PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -8246,7 +7538,7 @@ inline bool DescriptorProto::has_name() const { return _internal_has_name(); } inline void DescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& DescriptorProto::name() const { @@ -8266,31 +7558,30 @@ inline const std::string& DescriptorProto::_internal_name() const { } inline void DescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void DescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.DescriptorProto.name) } inline void DescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name) } inline void DescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name) } inline std::string* DescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* DescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name) @@ -8298,7 +7589,7 @@ inline std::string* DescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void DescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -8307,28 +7598,9 @@ inline void DescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.name) } -inline std::string* DescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.DescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void DescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.name) -} // repeated .google.protobuf.FieldDescriptorProto field = 2; inline int DescriptorProto::_internal_field_size() const { @@ -8579,31 +7851,46 @@ inline void DescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::MessageOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_MessageOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::MessageOptions& DescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options) return _internal_options(); } -inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { - temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); +inline void DescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::MessageOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); } - return temp; -} -inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::unsafe_arena_release_options() { - // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options) - _has_bits_[0] &= ~0x00000002u; - PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_; + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.DescriptorProto.options) +} +inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::release_options() { + _has_bits_[0] &= ~0x00000002u; + PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { + temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); + } + return temp; +} +inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::unsafe_arena_release_options() { + // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.options) + _has_bits_[0] &= ~0x00000002u; + PROTOBUF_NAMESPACE_ID::MessageOptions* temp = options_; options_ = nullptr; return temp; } inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000002u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -8613,7 +7900,7 @@ inline PROTOBUF_NAMESPACE_ID::MessageOptions* DescriptorProto::mutable_options() return _internal_mutable_options(); } inline void DescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::MessageOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -8801,7 +8088,7 @@ inline bool FieldDescriptorProto::has_name() const { return _internal_has_name(); } inline void FieldDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& FieldDescriptorProto::name() const { @@ -8821,31 +8108,30 @@ inline const std::string& FieldDescriptorProto::_internal_name() const { } inline void FieldDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.name) } inline void FieldDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name) } inline void FieldDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name) } inline std::string* FieldDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name) @@ -8853,7 +8139,7 @@ inline std::string* FieldDescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FieldDescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -8862,28 +8148,9 @@ inline void FieldDescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name) } -inline std::string* FieldDescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FieldDescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.name) -} // optional int32 number = 3; inline bool FieldDescriptorProto::_internal_has_number() const { @@ -8915,7 +8182,7 @@ inline void FieldDescriptorProto::set_number(::PROTOBUF_NAMESPACE_ID::int32 valu // optional .google.protobuf.FieldDescriptorProto.Label label = 4; inline bool FieldDescriptorProto::_internal_has_label() const { - bool value = (_has_bits_[0] & 0x00000100u) != 0; + bool value = (_has_bits_[0] & 0x00000200u) != 0; return value; } inline bool FieldDescriptorProto::has_label() const { @@ -8923,7 +8190,7 @@ inline bool FieldDescriptorProto::has_label() const { } inline void FieldDescriptorProto::clear_label() { label_ = 1; - _has_bits_[0] &= ~0x00000100u; + _has_bits_[0] &= ~0x00000200u; } inline PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::_internal_label() const { return static_cast< PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label >(label_); @@ -8934,7 +8201,7 @@ inline PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label FieldDescriptorProto::l } inline void FieldDescriptorProto::_internal_set_label(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value) { assert(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label_IsValid(value)); - _has_bits_[0] |= 0x00000100u; + _has_bits_[0] |= 0x00000200u; label_ = value; } inline void FieldDescriptorProto::set_label(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value) { @@ -8944,7 +8211,7 @@ inline void FieldDescriptorProto::set_label(PROTOBUF_NAMESPACE_ID::FieldDescript // optional .google.protobuf.FieldDescriptorProto.Type type = 5; inline bool FieldDescriptorProto::_internal_has_type() const { - bool value = (_has_bits_[0] & 0x00000200u) != 0; + bool value = (_has_bits_[0] & 0x00000400u) != 0; return value; } inline bool FieldDescriptorProto::has_type() const { @@ -8952,7 +8219,7 @@ inline bool FieldDescriptorProto::has_type() const { } inline void FieldDescriptorProto::clear_type() { type_ = 1; - _has_bits_[0] &= ~0x00000200u; + _has_bits_[0] &= ~0x00000400u; } inline PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::_internal_type() const { return static_cast< PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type >(type_); @@ -8963,7 +8230,7 @@ inline PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type FieldDescriptorProto::ty } inline void FieldDescriptorProto::_internal_set_type(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value) { assert(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type_IsValid(value)); - _has_bits_[0] |= 0x00000200u; + _has_bits_[0] |= 0x00000400u; type_ = value; } inline void FieldDescriptorProto::set_type(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value) { @@ -8980,7 +8247,7 @@ inline bool FieldDescriptorProto::has_type_name() const { return _internal_has_type_name(); } inline void FieldDescriptorProto::clear_type_name() { - type_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + type_name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& FieldDescriptorProto::type_name() const { @@ -9000,31 +8267,30 @@ inline const std::string& FieldDescriptorProto::_internal_type_name() const { } inline void FieldDescriptorProto::_internal_set_type_name(const std::string& value) { _has_bits_[0] |= 0x00000004u; - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_type_name(std::string&& value) { _has_bits_[0] |= 0x00000004u; type_name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.type_name) } inline void FieldDescriptorProto::set_type_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name) } inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name) } inline std::string* FieldDescriptorProto::_internal_mutable_type_name() { _has_bits_[0] |= 0x00000004u; - return type_name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return type_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_type_name() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name) @@ -9032,7 +8298,7 @@ inline std::string* FieldDescriptorProto::release_type_name() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - return type_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return type_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FieldDescriptorProto::set_allocated_type_name(std::string* type_name) { if (type_name != nullptr) { @@ -9041,28 +8307,9 @@ inline void FieldDescriptorProto::set_allocated_type_name(std::string* type_name _has_bits_[0] &= ~0x00000004u; } type_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name) } -inline std::string* FieldDescriptorProto::unsafe_arena_release_type_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.type_name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000004u; - return type_name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FieldDescriptorProto::unsafe_arena_set_allocated_type_name( - std::string* type_name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (type_name != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - type_name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - type_name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.type_name) -} // optional string extendee = 2; inline bool FieldDescriptorProto::_internal_has_extendee() const { @@ -9073,7 +8320,7 @@ inline bool FieldDescriptorProto::has_extendee() const { return _internal_has_extendee(); } inline void FieldDescriptorProto::clear_extendee() { - extendee_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + extendee_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& FieldDescriptorProto::extendee() const { @@ -9093,31 +8340,30 @@ inline const std::string& FieldDescriptorProto::_internal_extendee() const { } inline void FieldDescriptorProto::_internal_set_extendee(const std::string& value) { _has_bits_[0] |= 0x00000002u; - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_extendee(std::string&& value) { _has_bits_[0] |= 0x00000002u; extendee_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.extendee) } inline void FieldDescriptorProto::set_extendee(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee) } inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee) } inline std::string* FieldDescriptorProto::_internal_mutable_extendee() { _has_bits_[0] |= 0x00000002u; - return extendee_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return extendee_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_extendee() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee) @@ -9125,7 +8371,7 @@ inline std::string* FieldDescriptorProto::release_extendee() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - return extendee_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return extendee_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FieldDescriptorProto::set_allocated_extendee(std::string* extendee) { if (extendee != nullptr) { @@ -9134,28 +8380,9 @@ inline void FieldDescriptorProto::set_allocated_extendee(std::string* extendee) _has_bits_[0] &= ~0x00000002u; } extendee_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), extendee, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee) } -inline std::string* FieldDescriptorProto::unsafe_arena_release_extendee() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.extendee) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000002u; - return extendee_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FieldDescriptorProto::unsafe_arena_set_allocated_extendee( - std::string* extendee) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (extendee != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - extendee_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - extendee, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.extendee) -} // optional string default_value = 7; inline bool FieldDescriptorProto::_internal_has_default_value() const { @@ -9166,7 +8393,7 @@ inline bool FieldDescriptorProto::has_default_value() const { return _internal_has_default_value(); } inline void FieldDescriptorProto::clear_default_value() { - default_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + default_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000008u; } inline const std::string& FieldDescriptorProto::default_value() const { @@ -9186,31 +8413,30 @@ inline const std::string& FieldDescriptorProto::_internal_default_value() const } inline void FieldDescriptorProto::_internal_set_default_value(const std::string& value) { _has_bits_[0] |= 0x00000008u; - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_default_value(std::string&& value) { _has_bits_[0] |= 0x00000008u; default_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.default_value) } inline void FieldDescriptorProto::set_default_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000008u; - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value) } inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) { _has_bits_[0] |= 0x00000008u; - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value) } inline std::string* FieldDescriptorProto::_internal_mutable_default_value() { _has_bits_[0] |= 0x00000008u; - return default_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_default_value() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value) @@ -9218,7 +8444,7 @@ inline std::string* FieldDescriptorProto::release_default_value() { return nullptr; } _has_bits_[0] &= ~0x00000008u; - return default_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return default_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FieldDescriptorProto::set_allocated_default_value(std::string* default_value) { if (default_value != nullptr) { @@ -9227,28 +8453,9 @@ inline void FieldDescriptorProto::set_allocated_default_value(std::string* defau _has_bits_[0] &= ~0x00000008u; } default_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_value, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value) } -inline std::string* FieldDescriptorProto::unsafe_arena_release_default_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.default_value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000008u; - return default_value_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FieldDescriptorProto::unsafe_arena_set_allocated_default_value( - std::string* default_value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (default_value != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - default_value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - default_value, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.default_value) -} // optional int32 oneof_index = 9; inline bool FieldDescriptorProto::_internal_has_oneof_index() const { @@ -9287,7 +8494,7 @@ inline bool FieldDescriptorProto::has_json_name() const { return _internal_has_json_name(); } inline void FieldDescriptorProto::clear_json_name() { - json_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + json_name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000010u; } inline const std::string& FieldDescriptorProto::json_name() const { @@ -9307,31 +8514,30 @@ inline const std::string& FieldDescriptorProto::_internal_json_name() const { } inline void FieldDescriptorProto::_internal_set_json_name(const std::string& value) { _has_bits_[0] |= 0x00000010u; - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_json_name(std::string&& value) { _has_bits_[0] |= 0x00000010u; json_name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.json_name) } inline void FieldDescriptorProto::set_json_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000010u; - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name) } inline void FieldDescriptorProto::set_json_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000010u; - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.json_name) } inline std::string* FieldDescriptorProto::_internal_mutable_json_name() { _has_bits_[0] |= 0x00000010u; - return json_name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_json_name() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name) @@ -9339,7 +8545,7 @@ inline std::string* FieldDescriptorProto::release_json_name() { return nullptr; } _has_bits_[0] &= ~0x00000010u; - return json_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return json_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FieldDescriptorProto::set_allocated_json_name(std::string* json_name) { if (json_name != nullptr) { @@ -9348,28 +8554,9 @@ inline void FieldDescriptorProto::set_allocated_json_name(std::string* json_name _has_bits_[0] &= ~0x00000010u; } json_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), json_name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.json_name) } -inline std::string* FieldDescriptorProto::unsafe_arena_release_json_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FieldDescriptorProto.json_name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000010u; - return json_name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FieldDescriptorProto::unsafe_arena_set_allocated_json_name( - std::string* json_name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (json_name != nullptr) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - json_name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - json_name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.json_name) -} // optional .google.protobuf.FieldOptions options = 8; inline bool FieldDescriptorProto::_internal_has_options() const { @@ -9386,16 +8573,31 @@ inline void FieldDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::FieldOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_FieldOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::FieldOptions& FieldDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options) return _internal_options(); } +inline void FieldDescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::FieldOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000020u; + } else { + _has_bits_[0] &= ~0x00000020u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FieldDescriptorProto.options) +} inline PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000020u; + PROTOBUF_NAMESPACE_ID::FieldOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -9410,7 +8612,7 @@ inline PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::unsafe_arena_r inline PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000020u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -9420,7 +8622,7 @@ inline PROTOBUF_NAMESPACE_ID::FieldOptions* FieldDescriptorProto::mutable_option return _internal_mutable_options(); } inline void FieldDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::FieldOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -9439,6 +8641,34 @@ inline void FieldDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::F // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options) } +// optional bool proto3_optional = 17; +inline bool FieldDescriptorProto::_internal_has_proto3_optional() const { + bool value = (_has_bits_[0] & 0x00000100u) != 0; + return value; +} +inline bool FieldDescriptorProto::has_proto3_optional() const { + return _internal_has_proto3_optional(); +} +inline void FieldDescriptorProto::clear_proto3_optional() { + proto3_optional_ = false; + _has_bits_[0] &= ~0x00000100u; +} +inline bool FieldDescriptorProto::_internal_proto3_optional() const { + return proto3_optional_; +} +inline bool FieldDescriptorProto::proto3_optional() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.proto3_optional) + return _internal_proto3_optional(); +} +inline void FieldDescriptorProto::_internal_set_proto3_optional(bool value) { + _has_bits_[0] |= 0x00000100u; + proto3_optional_ = value; +} +inline void FieldDescriptorProto::set_proto3_optional(bool value) { + _internal_set_proto3_optional(value); + // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.proto3_optional) +} + // ------------------------------------------------------------------- // OneofDescriptorProto @@ -9452,7 +8682,7 @@ inline bool OneofDescriptorProto::has_name() const { return _internal_has_name(); } inline void OneofDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& OneofDescriptorProto::name() const { @@ -9472,31 +8702,30 @@ inline const std::string& OneofDescriptorProto::_internal_name() const { } inline void OneofDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void OneofDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.OneofDescriptorProto.name) } inline void OneofDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name) } inline void OneofDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name) } inline std::string* OneofDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* OneofDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name) @@ -9504,7 +8733,7 @@ inline std::string* OneofDescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void OneofDescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -9513,28 +8742,9 @@ inline void OneofDescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name) } -inline std::string* OneofDescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.OneofDescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void OneofDescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.name) -} // optional .google.protobuf.OneofOptions options = 2; inline bool OneofDescriptorProto::_internal_has_options() const { @@ -9551,16 +8761,31 @@ inline void OneofDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::OneofOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_OneofOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::OneofOptions& OneofDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.options) return _internal_options(); } +inline void OneofDescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::OneofOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.OneofDescriptorProto.options) +} inline PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000002u; + PROTOBUF_NAMESPACE_ID::OneofOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -9575,7 +8800,7 @@ inline PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::unsafe_arena_r inline PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000002u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -9585,7 +8810,7 @@ inline PROTOBUF_NAMESPACE_ID::OneofOptions* OneofDescriptorProto::mutable_option return _internal_mutable_options(); } inline void OneofDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::OneofOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -9677,7 +8902,7 @@ inline bool EnumDescriptorProto::has_name() const { return _internal_has_name(); } inline void EnumDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& EnumDescriptorProto::name() const { @@ -9697,31 +8922,30 @@ inline const std::string& EnumDescriptorProto::_internal_name() const { } inline void EnumDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void EnumDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumDescriptorProto.name) } inline void EnumDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name) } inline void EnumDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name) } inline std::string* EnumDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* EnumDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name) @@ -9729,7 +8953,7 @@ inline std::string* EnumDescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void EnumDescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -9738,28 +8962,9 @@ inline void EnumDescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.name) } -inline std::string* EnumDescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumDescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void EnumDescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.name) -} // repeated .google.protobuf.EnumValueDescriptorProto value = 2; inline int EnumDescriptorProto::_internal_value_size() const { @@ -9815,16 +9020,31 @@ inline void EnumDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::EnumOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_EnumOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::EnumOptions& EnumDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options) return _internal_options(); } +inline void EnumDescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::EnumOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumDescriptorProto.options) +} inline PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000002u; + PROTOBUF_NAMESPACE_ID::EnumOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -9839,7 +9059,7 @@ inline PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::unsafe_arena_rel inline PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000002u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -9849,7 +9069,7 @@ inline PROTOBUF_NAMESPACE_ID::EnumOptions* EnumDescriptorProto::mutable_options( return _internal_mutable_options(); } inline void EnumDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::EnumOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -9994,7 +9214,7 @@ inline bool EnumValueDescriptorProto::has_name() const { return _internal_has_name(); } inline void EnumValueDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& EnumValueDescriptorProto::name() const { @@ -10014,31 +9234,30 @@ inline const std::string& EnumValueDescriptorProto::_internal_name() const { } inline void EnumValueDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void EnumValueDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumValueDescriptorProto.name) } inline void EnumValueDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name) } inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name) } inline std::string* EnumValueDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* EnumValueDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name) @@ -10046,7 +9265,7 @@ inline std::string* EnumValueDescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void EnumValueDescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -10055,28 +9274,9 @@ inline void EnumValueDescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name) } -inline std::string* EnumValueDescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumValueDescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void EnumValueDescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.name) -} // optional int32 number = 2; inline bool EnumValueDescriptorProto::_internal_has_number() const { @@ -10121,16 +9321,31 @@ inline void EnumValueDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::EnumValueOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_EnumValueOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::EnumValueOptions& EnumValueDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options) return _internal_options(); } +inline void EnumValueDescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValueDescriptorProto.options) +} inline PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000002u; + PROTOBUF_NAMESPACE_ID::EnumValueOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -10145,7 +9360,7 @@ inline PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::unsafe inline PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000002u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -10155,7 +9370,7 @@ inline PROTOBUF_NAMESPACE_ID::EnumValueOptions* EnumValueDescriptorProto::mutabl return _internal_mutable_options(); } inline void EnumValueDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::EnumValueOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -10187,7 +9402,7 @@ inline bool ServiceDescriptorProto::has_name() const { return _internal_has_name(); } inline void ServiceDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& ServiceDescriptorProto::name() const { @@ -10207,31 +9422,30 @@ inline const std::string& ServiceDescriptorProto::_internal_name() const { } inline void ServiceDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void ServiceDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.ServiceDescriptorProto.name) } inline void ServiceDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name) } inline void ServiceDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name) } inline std::string* ServiceDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* ServiceDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name) @@ -10239,7 +9453,7 @@ inline std::string* ServiceDescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void ServiceDescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -10248,28 +9462,9 @@ inline void ServiceDescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.name) } -inline std::string* ServiceDescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.ServiceDescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void ServiceDescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.name) -} // repeated .google.protobuf.MethodDescriptorProto method = 2; inline int ServiceDescriptorProto::_internal_method_size() const { @@ -10325,16 +9520,31 @@ inline void ServiceDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::ServiceOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_ServiceOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::ServiceOptions& ServiceDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options) return _internal_options(); } +inline void ServiceDescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::ServiceOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000002u; + } else { + _has_bits_[0] &= ~0x00000002u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.ServiceDescriptorProto.options) +} inline PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000002u; + PROTOBUF_NAMESPACE_ID::ServiceOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -10349,7 +9559,7 @@ inline PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::unsafe_are inline PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000002u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -10359,7 +9569,7 @@ inline PROTOBUF_NAMESPACE_ID::ServiceOptions* ServiceDescriptorProto::mutable_op return _internal_mutable_options(); } inline void ServiceDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::ServiceOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -10391,7 +9601,7 @@ inline bool MethodDescriptorProto::has_name() const { return _internal_has_name(); } inline void MethodDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& MethodDescriptorProto::name() const { @@ -10411,31 +9621,30 @@ inline const std::string& MethodDescriptorProto::_internal_name() const { } inline void MethodDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void MethodDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.name) } inline void MethodDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name) } inline void MethodDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name) } inline std::string* MethodDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* MethodDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name) @@ -10443,7 +9652,7 @@ inline std::string* MethodDescriptorProto::release_name() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void MethodDescriptorProto::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -10452,28 +9661,9 @@ inline void MethodDescriptorProto::set_allocated_name(std::string* name) { _has_bits_[0] &= ~0x00000001u; } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name) } -inline std::string* MethodDescriptorProto::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.MethodDescriptorProto.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void MethodDescriptorProto::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.name) -} // optional string input_type = 2; inline bool MethodDescriptorProto::_internal_has_input_type() const { @@ -10484,7 +9674,7 @@ inline bool MethodDescriptorProto::has_input_type() const { return _internal_has_input_type(); } inline void MethodDescriptorProto::clear_input_type() { - input_type_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + input_type_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& MethodDescriptorProto::input_type() const { @@ -10504,31 +9694,30 @@ inline const std::string& MethodDescriptorProto::_internal_input_type() const { } inline void MethodDescriptorProto::_internal_set_input_type(const std::string& value) { _has_bits_[0] |= 0x00000002u; - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void MethodDescriptorProto::set_input_type(std::string&& value) { _has_bits_[0] |= 0x00000002u; input_type_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.input_type) } inline void MethodDescriptorProto::set_input_type(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type) } inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type) } inline std::string* MethodDescriptorProto::_internal_mutable_input_type() { _has_bits_[0] |= 0x00000002u; - return input_type_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return input_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* MethodDescriptorProto::release_input_type() { // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type) @@ -10536,7 +9725,7 @@ inline std::string* MethodDescriptorProto::release_input_type() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - return input_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return input_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void MethodDescriptorProto::set_allocated_input_type(std::string* input_type) { if (input_type != nullptr) { @@ -10545,28 +9734,9 @@ inline void MethodDescriptorProto::set_allocated_input_type(std::string* input_t _has_bits_[0] &= ~0x00000002u; } input_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), input_type, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type) } -inline std::string* MethodDescriptorProto::unsafe_arena_release_input_type() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.MethodDescriptorProto.input_type) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000002u; - return input_type_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void MethodDescriptorProto::unsafe_arena_set_allocated_input_type( - std::string* input_type) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (input_type != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - input_type_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - input_type, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.input_type) -} // optional string output_type = 3; inline bool MethodDescriptorProto::_internal_has_output_type() const { @@ -10577,7 +9747,7 @@ inline bool MethodDescriptorProto::has_output_type() const { return _internal_has_output_type(); } inline void MethodDescriptorProto::clear_output_type() { - output_type_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + output_type_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& MethodDescriptorProto::output_type() const { @@ -10597,31 +9767,30 @@ inline const std::string& MethodDescriptorProto::_internal_output_type() const { } inline void MethodDescriptorProto::_internal_set_output_type(const std::string& value) { _has_bits_[0] |= 0x00000004u; - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void MethodDescriptorProto::set_output_type(std::string&& value) { _has_bits_[0] |= 0x00000004u; output_type_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.output_type) } inline void MethodDescriptorProto::set_output_type(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type) } inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type) } inline std::string* MethodDescriptorProto::_internal_mutable_output_type() { _has_bits_[0] |= 0x00000004u; - return output_type_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return output_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* MethodDescriptorProto::release_output_type() { // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type) @@ -10629,7 +9798,7 @@ inline std::string* MethodDescriptorProto::release_output_type() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - return output_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return output_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void MethodDescriptorProto::set_allocated_output_type(std::string* output_type) { if (output_type != nullptr) { @@ -10638,28 +9807,9 @@ inline void MethodDescriptorProto::set_allocated_output_type(std::string* output _has_bits_[0] &= ~0x00000004u; } output_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), output_type, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type) } -inline std::string* MethodDescriptorProto::unsafe_arena_release_output_type() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.MethodDescriptorProto.output_type) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000004u; - return output_type_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void MethodDescriptorProto::unsafe_arena_set_allocated_output_type( - std::string* output_type) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (output_type != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - output_type_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - output_type, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.output_type) -} // optional .google.protobuf.MethodOptions options = 4; inline bool MethodDescriptorProto::_internal_has_options() const { @@ -10676,16 +9826,31 @@ inline void MethodDescriptorProto::clear_options() { } inline const PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::_internal_options() const { const PROTOBUF_NAMESPACE_ID::MethodOptions* p = options_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_MethodOptions_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::MethodOptions& MethodDescriptorProto::options() const { // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options) return _internal_options(); } +inline void MethodDescriptorProto::unsafe_arena_set_allocated_options( + PROTOBUF_NAMESPACE_ID::MethodOptions* options) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(options_); + } + options_ = options; + if (options) { + _has_bits_[0] |= 0x00000008u; + } else { + _has_bits_[0] &= ~0x00000008u; + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.MethodDescriptorProto.options) +} inline PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::release_options() { - auto temp = unsafe_arena_release_options(); - if (GetArenaNoVirtual() != nullptr) { + _has_bits_[0] &= ~0x00000008u; + PROTOBUF_NAMESPACE_ID::MethodOptions* temp = options_; + options_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -10700,7 +9865,7 @@ inline PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::unsafe_arena inline PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::_internal_mutable_options() { _has_bits_[0] |= 0x00000008u; if (options_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); options_ = p; } return options_; @@ -10710,7 +9875,7 @@ inline PROTOBUF_NAMESPACE_ID::MethodOptions* MethodDescriptorProto::mutable_opti return _internal_mutable_options(); } inline void MethodDescriptorProto::set_allocated_options(PROTOBUF_NAMESPACE_ID::MethodOptions* options) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete options_; } @@ -10798,7 +9963,7 @@ inline bool FileOptions::has_java_package() const { return _internal_has_java_package(); } inline void FileOptions::clear_java_package() { - java_package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + java_package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& FileOptions::java_package() const { @@ -10818,31 +9983,30 @@ inline const std::string& FileOptions::_internal_java_package() const { } inline void FileOptions::_internal_set_java_package(const std::string& value) { _has_bits_[0] |= 0x00000001u; - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_java_package(std::string&& value) { _has_bits_[0] |= 0x00000001u; java_package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.java_package) } inline void FileOptions::set_java_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package) } inline void FileOptions::set_java_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package) } inline std::string* FileOptions::_internal_mutable_java_package() { _has_bits_[0] |= 0x00000001u; - return java_package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return java_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_java_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package) @@ -10850,7 +10014,7 @@ inline std::string* FileOptions::release_java_package() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return java_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return java_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_java_package(std::string* java_package) { if (java_package != nullptr) { @@ -10859,28 +10023,9 @@ inline void FileOptions::set_allocated_java_package(std::string* java_package) { _has_bits_[0] &= ~0x00000001u; } java_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), java_package, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package) } -inline std::string* FileOptions::unsafe_arena_release_java_package() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.java_package) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return java_package_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_java_package( - std::string* java_package) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (java_package != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - java_package_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - java_package, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.java_package) -} // optional string java_outer_classname = 8; inline bool FileOptions::_internal_has_java_outer_classname() const { @@ -10891,7 +10036,7 @@ inline bool FileOptions::has_java_outer_classname() const { return _internal_has_java_outer_classname(); } inline void FileOptions::clear_java_outer_classname() { - java_outer_classname_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + java_outer_classname_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& FileOptions::java_outer_classname() const { @@ -10911,31 +10056,30 @@ inline const std::string& FileOptions::_internal_java_outer_classname() const { } inline void FileOptions::_internal_set_java_outer_classname(const std::string& value) { _has_bits_[0] |= 0x00000002u; - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_java_outer_classname(std::string&& value) { _has_bits_[0] |= 0x00000002u; java_outer_classname_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.java_outer_classname) } inline void FileOptions::set_java_outer_classname(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname) } inline void FileOptions::set_java_outer_classname(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname) } inline std::string* FileOptions::_internal_mutable_java_outer_classname() { _has_bits_[0] |= 0x00000002u; - return java_outer_classname_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return java_outer_classname_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_java_outer_classname() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname) @@ -10943,7 +10087,7 @@ inline std::string* FileOptions::release_java_outer_classname() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - return java_outer_classname_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return java_outer_classname_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_java_outer_classname(std::string* java_outer_classname) { if (java_outer_classname != nullptr) { @@ -10952,28 +10096,9 @@ inline void FileOptions::set_allocated_java_outer_classname(std::string* java_ou _has_bits_[0] &= ~0x00000002u; } java_outer_classname_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), java_outer_classname, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname) } -inline std::string* FileOptions::unsafe_arena_release_java_outer_classname() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.java_outer_classname) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000002u; - return java_outer_classname_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_java_outer_classname( - std::string* java_outer_classname) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (java_outer_classname != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - java_outer_classname_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - java_outer_classname, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.java_outer_classname) -} // optional bool java_multiple_files = 10 [default = false]; inline bool FileOptions::_internal_has_java_multiple_files() const { @@ -11061,7 +10186,7 @@ inline void FileOptions::set_java_string_check_utf8(bool value) { // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; inline bool FileOptions::_internal_has_optimize_for() const { - bool value = (_has_bits_[0] & 0x00080000u) != 0; + bool value = (_has_bits_[0] & 0x00040000u) != 0; return value; } inline bool FileOptions::has_optimize_for() const { @@ -11069,7 +10194,7 @@ inline bool FileOptions::has_optimize_for() const { } inline void FileOptions::clear_optimize_for() { optimize_for_ = 1; - _has_bits_[0] &= ~0x00080000u; + _has_bits_[0] &= ~0x00040000u; } inline PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const { return static_cast< PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode >(optimize_for_); @@ -11080,7 +10205,7 @@ inline PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode FileOptions::optimize_for } inline void FileOptions::_internal_set_optimize_for(PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) { assert(PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode_IsValid(value)); - _has_bits_[0] |= 0x00080000u; + _has_bits_[0] |= 0x00040000u; optimize_for_ = value; } inline void FileOptions::set_optimize_for(PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode value) { @@ -11097,7 +10222,7 @@ inline bool FileOptions::has_go_package() const { return _internal_has_go_package(); } inline void FileOptions::clear_go_package() { - go_package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + go_package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& FileOptions::go_package() const { @@ -11117,31 +10242,30 @@ inline const std::string& FileOptions::_internal_go_package() const { } inline void FileOptions::_internal_set_go_package(const std::string& value) { _has_bits_[0] |= 0x00000004u; - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_go_package(std::string&& value) { _has_bits_[0] |= 0x00000004u; go_package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.go_package) } inline void FileOptions::set_go_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package) } inline void FileOptions::set_go_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package) } inline std::string* FileOptions::_internal_mutable_go_package() { _has_bits_[0] |= 0x00000004u; - return go_package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return go_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_go_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package) @@ -11149,7 +10273,7 @@ inline std::string* FileOptions::release_go_package() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - return go_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return go_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_go_package(std::string* go_package) { if (go_package != nullptr) { @@ -11158,28 +10282,9 @@ inline void FileOptions::set_allocated_go_package(std::string* go_package) { _has_bits_[0] &= ~0x00000004u; } go_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), go_package, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package) } -inline std::string* FileOptions::unsafe_arena_release_go_package() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.go_package) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000004u; - return go_package_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_go_package( - std::string* go_package) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (go_package != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - go_package_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - go_package, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.go_package) -} // optional bool cc_generic_services = 16 [default = false]; inline bool FileOptions::_internal_has_cc_generic_services() const { @@ -11321,17 +10426,17 @@ inline void FileOptions::set_deprecated(bool value) { // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated) } -// optional bool cc_enable_arenas = 31 [default = false]; +// optional bool cc_enable_arenas = 31 [default = true]; inline bool FileOptions::_internal_has_cc_enable_arenas() const { - bool value = (_has_bits_[0] & 0x00040000u) != 0; + bool value = (_has_bits_[0] & 0x00080000u) != 0; return value; } inline bool FileOptions::has_cc_enable_arenas() const { return _internal_has_cc_enable_arenas(); } inline void FileOptions::clear_cc_enable_arenas() { - cc_enable_arenas_ = false; - _has_bits_[0] &= ~0x00040000u; + cc_enable_arenas_ = true; + _has_bits_[0] &= ~0x00080000u; } inline bool FileOptions::_internal_cc_enable_arenas() const { return cc_enable_arenas_; @@ -11341,7 +10446,7 @@ inline bool FileOptions::cc_enable_arenas() const { return _internal_cc_enable_arenas(); } inline void FileOptions::_internal_set_cc_enable_arenas(bool value) { - _has_bits_[0] |= 0x00040000u; + _has_bits_[0] |= 0x00080000u; cc_enable_arenas_ = value; } inline void FileOptions::set_cc_enable_arenas(bool value) { @@ -11358,7 +10463,7 @@ inline bool FileOptions::has_objc_class_prefix() const { return _internal_has_objc_class_prefix(); } inline void FileOptions::clear_objc_class_prefix() { - objc_class_prefix_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + objc_class_prefix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000008u; } inline const std::string& FileOptions::objc_class_prefix() const { @@ -11378,31 +10483,30 @@ inline const std::string& FileOptions::_internal_objc_class_prefix() const { } inline void FileOptions::_internal_set_objc_class_prefix(const std::string& value) { _has_bits_[0] |= 0x00000008u; - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_objc_class_prefix(std::string&& value) { _has_bits_[0] |= 0x00000008u; objc_class_prefix_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.objc_class_prefix) } inline void FileOptions::set_objc_class_prefix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000008u; - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix) } inline void FileOptions::set_objc_class_prefix(const char* value, size_t size) { _has_bits_[0] |= 0x00000008u; - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.objc_class_prefix) } inline std::string* FileOptions::_internal_mutable_objc_class_prefix() { _has_bits_[0] |= 0x00000008u; - return objc_class_prefix_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return objc_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_objc_class_prefix() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix) @@ -11410,7 +10514,7 @@ inline std::string* FileOptions::release_objc_class_prefix() { return nullptr; } _has_bits_[0] &= ~0x00000008u; - return objc_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return objc_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_objc_class_prefix(std::string* objc_class_prefix) { if (objc_class_prefix != nullptr) { @@ -11419,28 +10523,9 @@ inline void FileOptions::set_allocated_objc_class_prefix(std::string* objc_class _has_bits_[0] &= ~0x00000008u; } objc_class_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), objc_class_prefix, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix) } -inline std::string* FileOptions::unsafe_arena_release_objc_class_prefix() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.objc_class_prefix) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000008u; - return objc_class_prefix_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_objc_class_prefix( - std::string* objc_class_prefix) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (objc_class_prefix != nullptr) { - _has_bits_[0] |= 0x00000008u; - } else { - _has_bits_[0] &= ~0x00000008u; - } - objc_class_prefix_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - objc_class_prefix, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.objc_class_prefix) -} // optional string csharp_namespace = 37; inline bool FileOptions::_internal_has_csharp_namespace() const { @@ -11451,7 +10536,7 @@ inline bool FileOptions::has_csharp_namespace() const { return _internal_has_csharp_namespace(); } inline void FileOptions::clear_csharp_namespace() { - csharp_namespace_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + csharp_namespace_.ClearToEmpty(); _has_bits_[0] &= ~0x00000010u; } inline const std::string& FileOptions::csharp_namespace() const { @@ -11471,31 +10556,30 @@ inline const std::string& FileOptions::_internal_csharp_namespace() const { } inline void FileOptions::_internal_set_csharp_namespace(const std::string& value) { _has_bits_[0] |= 0x00000010u; - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_csharp_namespace(std::string&& value) { _has_bits_[0] |= 0x00000010u; csharp_namespace_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.csharp_namespace) } inline void FileOptions::set_csharp_namespace(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000010u; - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace) } inline void FileOptions::set_csharp_namespace(const char* value, size_t size) { _has_bits_[0] |= 0x00000010u; - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace) } inline std::string* FileOptions::_internal_mutable_csharp_namespace() { _has_bits_[0] |= 0x00000010u; - return csharp_namespace_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return csharp_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_csharp_namespace() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace) @@ -11503,7 +10587,7 @@ inline std::string* FileOptions::release_csharp_namespace() { return nullptr; } _has_bits_[0] &= ~0x00000010u; - return csharp_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return csharp_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_csharp_namespace(std::string* csharp_namespace) { if (csharp_namespace != nullptr) { @@ -11512,28 +10596,9 @@ inline void FileOptions::set_allocated_csharp_namespace(std::string* csharp_name _has_bits_[0] &= ~0x00000010u; } csharp_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), csharp_namespace, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace) } -inline std::string* FileOptions::unsafe_arena_release_csharp_namespace() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.csharp_namespace) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000010u; - return csharp_namespace_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_csharp_namespace( - std::string* csharp_namespace) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (csharp_namespace != nullptr) { - _has_bits_[0] |= 0x00000010u; - } else { - _has_bits_[0] &= ~0x00000010u; - } - csharp_namespace_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - csharp_namespace, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.csharp_namespace) -} // optional string swift_prefix = 39; inline bool FileOptions::_internal_has_swift_prefix() const { @@ -11544,7 +10609,7 @@ inline bool FileOptions::has_swift_prefix() const { return _internal_has_swift_prefix(); } inline void FileOptions::clear_swift_prefix() { - swift_prefix_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + swift_prefix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000020u; } inline const std::string& FileOptions::swift_prefix() const { @@ -11564,31 +10629,30 @@ inline const std::string& FileOptions::_internal_swift_prefix() const { } inline void FileOptions::_internal_set_swift_prefix(const std::string& value) { _has_bits_[0] |= 0x00000020u; - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_swift_prefix(std::string&& value) { _has_bits_[0] |= 0x00000020u; swift_prefix_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.swift_prefix) } inline void FileOptions::set_swift_prefix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000020u; - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.swift_prefix) } inline void FileOptions::set_swift_prefix(const char* value, size_t size) { _has_bits_[0] |= 0x00000020u; - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.swift_prefix) } inline std::string* FileOptions::_internal_mutable_swift_prefix() { _has_bits_[0] |= 0x00000020u; - return swift_prefix_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return swift_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_swift_prefix() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.swift_prefix) @@ -11596,7 +10660,7 @@ inline std::string* FileOptions::release_swift_prefix() { return nullptr; } _has_bits_[0] &= ~0x00000020u; - return swift_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return swift_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_swift_prefix(std::string* swift_prefix) { if (swift_prefix != nullptr) { @@ -11605,28 +10669,9 @@ inline void FileOptions::set_allocated_swift_prefix(std::string* swift_prefix) { _has_bits_[0] &= ~0x00000020u; } swift_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), swift_prefix, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.swift_prefix) } -inline std::string* FileOptions::unsafe_arena_release_swift_prefix() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.swift_prefix) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000020u; - return swift_prefix_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_swift_prefix( - std::string* swift_prefix) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (swift_prefix != nullptr) { - _has_bits_[0] |= 0x00000020u; - } else { - _has_bits_[0] &= ~0x00000020u; - } - swift_prefix_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - swift_prefix, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.swift_prefix) -} // optional string php_class_prefix = 40; inline bool FileOptions::_internal_has_php_class_prefix() const { @@ -11637,7 +10682,7 @@ inline bool FileOptions::has_php_class_prefix() const { return _internal_has_php_class_prefix(); } inline void FileOptions::clear_php_class_prefix() { - php_class_prefix_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + php_class_prefix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000040u; } inline const std::string& FileOptions::php_class_prefix() const { @@ -11657,31 +10702,30 @@ inline const std::string& FileOptions::_internal_php_class_prefix() const { } inline void FileOptions::_internal_set_php_class_prefix(const std::string& value) { _has_bits_[0] |= 0x00000040u; - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_php_class_prefix(std::string&& value) { _has_bits_[0] |= 0x00000040u; php_class_prefix_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_class_prefix) } inline void FileOptions::set_php_class_prefix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000040u; - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix) } inline void FileOptions::set_php_class_prefix(const char* value, size_t size) { _has_bits_[0] |= 0x00000040u; - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_class_prefix) } inline std::string* FileOptions::_internal_mutable_php_class_prefix() { _has_bits_[0] |= 0x00000040u; - return php_class_prefix_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return php_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_php_class_prefix() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix) @@ -11689,7 +10733,7 @@ inline std::string* FileOptions::release_php_class_prefix() { return nullptr; } _has_bits_[0] &= ~0x00000040u; - return php_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return php_class_prefix_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_php_class_prefix(std::string* php_class_prefix) { if (php_class_prefix != nullptr) { @@ -11698,28 +10742,9 @@ inline void FileOptions::set_allocated_php_class_prefix(std::string* php_class_p _has_bits_[0] &= ~0x00000040u; } php_class_prefix_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_class_prefix, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_class_prefix) } -inline std::string* FileOptions::unsafe_arena_release_php_class_prefix() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.php_class_prefix) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000040u; - return php_class_prefix_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_php_class_prefix( - std::string* php_class_prefix) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (php_class_prefix != nullptr) { - _has_bits_[0] |= 0x00000040u; - } else { - _has_bits_[0] &= ~0x00000040u; - } - php_class_prefix_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - php_class_prefix, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.php_class_prefix) -} // optional string php_namespace = 41; inline bool FileOptions::_internal_has_php_namespace() const { @@ -11730,7 +10755,7 @@ inline bool FileOptions::has_php_namespace() const { return _internal_has_php_namespace(); } inline void FileOptions::clear_php_namespace() { - php_namespace_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + php_namespace_.ClearToEmpty(); _has_bits_[0] &= ~0x00000080u; } inline const std::string& FileOptions::php_namespace() const { @@ -11750,31 +10775,30 @@ inline const std::string& FileOptions::_internal_php_namespace() const { } inline void FileOptions::_internal_set_php_namespace(const std::string& value) { _has_bits_[0] |= 0x00000080u; - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_php_namespace(std::string&& value) { _has_bits_[0] |= 0x00000080u; php_namespace_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_namespace) } inline void FileOptions::set_php_namespace(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000080u; - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_namespace) } inline void FileOptions::set_php_namespace(const char* value, size_t size) { _has_bits_[0] |= 0x00000080u; - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_namespace) } inline std::string* FileOptions::_internal_mutable_php_namespace() { _has_bits_[0] |= 0x00000080u; - return php_namespace_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return php_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_php_namespace() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace) @@ -11782,7 +10806,7 @@ inline std::string* FileOptions::release_php_namespace() { return nullptr; } _has_bits_[0] &= ~0x00000080u; - return php_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return php_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_php_namespace(std::string* php_namespace) { if (php_namespace != nullptr) { @@ -11791,28 +10815,9 @@ inline void FileOptions::set_allocated_php_namespace(std::string* php_namespace) _has_bits_[0] &= ~0x00000080u; } php_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_namespace, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_namespace) } -inline std::string* FileOptions::unsafe_arena_release_php_namespace() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.php_namespace) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000080u; - return php_namespace_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_php_namespace( - std::string* php_namespace) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (php_namespace != nullptr) { - _has_bits_[0] |= 0x00000080u; - } else { - _has_bits_[0] &= ~0x00000080u; - } - php_namespace_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - php_namespace, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.php_namespace) -} // optional string php_metadata_namespace = 44; inline bool FileOptions::_internal_has_php_metadata_namespace() const { @@ -11823,7 +10828,7 @@ inline bool FileOptions::has_php_metadata_namespace() const { return _internal_has_php_metadata_namespace(); } inline void FileOptions::clear_php_metadata_namespace() { - php_metadata_namespace_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + php_metadata_namespace_.ClearToEmpty(); _has_bits_[0] &= ~0x00000100u; } inline const std::string& FileOptions::php_metadata_namespace() const { @@ -11843,31 +10848,30 @@ inline const std::string& FileOptions::_internal_php_metadata_namespace() const } inline void FileOptions::_internal_set_php_metadata_namespace(const std::string& value) { _has_bits_[0] |= 0x00000100u; - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_php_metadata_namespace(std::string&& value) { _has_bits_[0] |= 0x00000100u; php_metadata_namespace_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_metadata_namespace) } inline void FileOptions::set_php_metadata_namespace(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000100u; - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_metadata_namespace) } inline void FileOptions::set_php_metadata_namespace(const char* value, size_t size) { _has_bits_[0] |= 0x00000100u; - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_metadata_namespace) } inline std::string* FileOptions::_internal_mutable_php_metadata_namespace() { _has_bits_[0] |= 0x00000100u; - return php_metadata_namespace_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return php_metadata_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_php_metadata_namespace() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_metadata_namespace) @@ -11875,7 +10879,7 @@ inline std::string* FileOptions::release_php_metadata_namespace() { return nullptr; } _has_bits_[0] &= ~0x00000100u; - return php_metadata_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return php_metadata_namespace_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_php_metadata_namespace(std::string* php_metadata_namespace) { if (php_metadata_namespace != nullptr) { @@ -11884,28 +10888,9 @@ inline void FileOptions::set_allocated_php_metadata_namespace(std::string* php_m _has_bits_[0] &= ~0x00000100u; } php_metadata_namespace_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), php_metadata_namespace, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.php_metadata_namespace) } -inline std::string* FileOptions::unsafe_arena_release_php_metadata_namespace() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.php_metadata_namespace) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000100u; - return php_metadata_namespace_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_php_metadata_namespace( - std::string* php_metadata_namespace) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (php_metadata_namespace != nullptr) { - _has_bits_[0] |= 0x00000100u; - } else { - _has_bits_[0] &= ~0x00000100u; - } - php_metadata_namespace_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - php_metadata_namespace, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.php_metadata_namespace) -} // optional string ruby_package = 45; inline bool FileOptions::_internal_has_ruby_package() const { @@ -11916,7 +10901,7 @@ inline bool FileOptions::has_ruby_package() const { return _internal_has_ruby_package(); } inline void FileOptions::clear_ruby_package() { - ruby_package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + ruby_package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000200u; } inline const std::string& FileOptions::ruby_package() const { @@ -11936,31 +10921,30 @@ inline const std::string& FileOptions::_internal_ruby_package() const { } inline void FileOptions::_internal_set_ruby_package(const std::string& value) { _has_bits_[0] |= 0x00000200u; - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_ruby_package(std::string&& value) { _has_bits_[0] |= 0x00000200u; ruby_package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.ruby_package) } inline void FileOptions::set_ruby_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000200u; - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.ruby_package) } inline void FileOptions::set_ruby_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000200u; - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.ruby_package) } inline std::string* FileOptions::_internal_mutable_ruby_package() { _has_bits_[0] |= 0x00000200u; - return ruby_package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return ruby_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_ruby_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.ruby_package) @@ -11968,7 +10952,7 @@ inline std::string* FileOptions::release_ruby_package() { return nullptr; } _has_bits_[0] &= ~0x00000200u; - return ruby_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return ruby_package_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void FileOptions::set_allocated_ruby_package(std::string* ruby_package) { if (ruby_package != nullptr) { @@ -11977,28 +10961,9 @@ inline void FileOptions::set_allocated_ruby_package(std::string* ruby_package) { _has_bits_[0] &= ~0x00000200u; } ruby_package_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ruby_package, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.ruby_package) } -inline std::string* FileOptions::unsafe_arena_release_ruby_package() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.FileOptions.ruby_package) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000200u; - return ruby_package_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void FileOptions::unsafe_arena_set_allocated_ruby_package( - std::string* ruby_package) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (ruby_package != nullptr) { - _has_bits_[0] |= 0x00000200u; - } else { - _has_bits_[0] &= ~0x00000200u; - } - ruby_package_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ruby_package, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.FileOptions.ruby_package) -} // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int FileOptions::_internal_uninterpreted_option_size() const { @@ -12804,7 +11769,7 @@ inline bool UninterpretedOption_NamePart::has_name_part() const { return _internal_has_name_part(); } inline void UninterpretedOption_NamePart::clear_name_part() { - name_part_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_part_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& UninterpretedOption_NamePart::name_part() const { @@ -12824,31 +11789,30 @@ inline const std::string& UninterpretedOption_NamePart::_internal_name_part() co } inline void UninterpretedOption_NamePart::_internal_set_name_part(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption_NamePart::set_name_part(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_part_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.NamePart.name_part) } inline void UninterpretedOption_NamePart::set_name_part(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part) } inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part) } inline std::string* UninterpretedOption_NamePart::_internal_mutable_name_part() { _has_bits_[0] |= 0x00000001u; - return name_part_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_part_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption_NamePart::release_name_part() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part) @@ -12856,7 +11820,7 @@ inline std::string* UninterpretedOption_NamePart::release_name_part() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return name_part_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_part_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* name_part) { if (name_part != nullptr) { @@ -12865,28 +11829,9 @@ inline void UninterpretedOption_NamePart::set_allocated_name_part(std::string* n _has_bits_[0] &= ~0x00000001u; } name_part_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name_part, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part) } -inline std::string* UninterpretedOption_NamePart::unsafe_arena_release_name_part() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.NamePart.name_part) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return name_part_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void UninterpretedOption_NamePart::unsafe_arena_set_allocated_name_part( - std::string* name_part) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name_part != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - name_part_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name_part, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part) -} // required bool is_extension = 2; inline bool UninterpretedOption_NamePart::_internal_has_is_extension() const { @@ -12968,7 +11913,7 @@ inline bool UninterpretedOption::has_identifier_value() const { return _internal_has_identifier_value(); } inline void UninterpretedOption::clear_identifier_value() { - identifier_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + identifier_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& UninterpretedOption::identifier_value() const { @@ -12988,31 +11933,30 @@ inline const std::string& UninterpretedOption::_internal_identifier_value() cons } inline void UninterpretedOption::_internal_set_identifier_value(const std::string& value) { _has_bits_[0] |= 0x00000001u; - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption::set_identifier_value(std::string&& value) { _has_bits_[0] |= 0x00000001u; identifier_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.identifier_value) } inline void UninterpretedOption::set_identifier_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value) } inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value) } inline std::string* UninterpretedOption::_internal_mutable_identifier_value() { _has_bits_[0] |= 0x00000001u; - return identifier_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return identifier_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption::release_identifier_value() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value) @@ -13020,7 +11964,7 @@ inline std::string* UninterpretedOption::release_identifier_value() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return identifier_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return identifier_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void UninterpretedOption::set_allocated_identifier_value(std::string* identifier_value) { if (identifier_value != nullptr) { @@ -13029,28 +11973,9 @@ inline void UninterpretedOption::set_allocated_identifier_value(std::string* ide _has_bits_[0] &= ~0x00000001u; } identifier_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), identifier_value, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value) } -inline std::string* UninterpretedOption::unsafe_arena_release_identifier_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.identifier_value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return identifier_value_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void UninterpretedOption::unsafe_arena_set_allocated_identifier_value( - std::string* identifier_value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (identifier_value != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - identifier_value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - identifier_value, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.UninterpretedOption.identifier_value) -} // optional uint64 positive_int_value = 4; inline bool UninterpretedOption::_internal_has_positive_int_value() const { @@ -13145,7 +12070,7 @@ inline bool UninterpretedOption::has_string_value() const { return _internal_has_string_value(); } inline void UninterpretedOption::clear_string_value() { - string_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + string_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& UninterpretedOption::string_value() const { @@ -13165,31 +12090,30 @@ inline const std::string& UninterpretedOption::_internal_string_value() const { } inline void UninterpretedOption::_internal_set_string_value(const std::string& value) { _has_bits_[0] |= 0x00000002u; - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption::set_string_value(std::string&& value) { _has_bits_[0] |= 0x00000002u; string_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.string_value) } inline void UninterpretedOption::set_string_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value) } inline void UninterpretedOption::set_string_value(const void* value, size_t size) { _has_bits_[0] |= 0x00000002u; - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value) } inline std::string* UninterpretedOption::_internal_mutable_string_value() { _has_bits_[0] |= 0x00000002u; - return string_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return string_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption::release_string_value() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value) @@ -13197,7 +12121,7 @@ inline std::string* UninterpretedOption::release_string_value() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - return string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void UninterpretedOption::set_allocated_string_value(std::string* string_value) { if (string_value != nullptr) { @@ -13206,28 +12130,9 @@ inline void UninterpretedOption::set_allocated_string_value(std::string* string_ _has_bits_[0] &= ~0x00000002u; } string_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), string_value, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value) } -inline std::string* UninterpretedOption::unsafe_arena_release_string_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.string_value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000002u; - return string_value_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void UninterpretedOption::unsafe_arena_set_allocated_string_value( - std::string* string_value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (string_value != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - string_value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - string_value, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.UninterpretedOption.string_value) -} // optional string aggregate_value = 8; inline bool UninterpretedOption::_internal_has_aggregate_value() const { @@ -13238,7 +12143,7 @@ inline bool UninterpretedOption::has_aggregate_value() const { return _internal_has_aggregate_value(); } inline void UninterpretedOption::clear_aggregate_value() { - aggregate_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + aggregate_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& UninterpretedOption::aggregate_value() const { @@ -13258,31 +12163,30 @@ inline const std::string& UninterpretedOption::_internal_aggregate_value() const } inline void UninterpretedOption::_internal_set_aggregate_value(const std::string& value) { _has_bits_[0] |= 0x00000004u; - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption::set_aggregate_value(std::string&& value) { _has_bits_[0] |= 0x00000004u; aggregate_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.aggregate_value) } inline void UninterpretedOption::set_aggregate_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value) } inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value) } inline std::string* UninterpretedOption::_internal_mutable_aggregate_value() { _has_bits_[0] |= 0x00000004u; - return aggregate_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return aggregate_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption::release_aggregate_value() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value) @@ -13290,7 +12194,7 @@ inline std::string* UninterpretedOption::release_aggregate_value() { return nullptr; } _has_bits_[0] &= ~0x00000004u; - return aggregate_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return aggregate_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void UninterpretedOption::set_allocated_aggregate_value(std::string* aggregate_value) { if (aggregate_value != nullptr) { @@ -13299,28 +12203,9 @@ inline void UninterpretedOption::set_allocated_aggregate_value(std::string* aggr _has_bits_[0] &= ~0x00000004u; } aggregate_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), aggregate_value, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value) } -inline std::string* UninterpretedOption::unsafe_arena_release_aggregate_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.UninterpretedOption.aggregate_value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000004u; - return aggregate_value_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void UninterpretedOption::unsafe_arena_set_allocated_aggregate_value( - std::string* aggregate_value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (aggregate_value != nullptr) { - _has_bits_[0] |= 0x00000004u; - } else { - _has_bits_[0] &= ~0x00000004u; - } - aggregate_value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - aggregate_value, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.UninterpretedOption.aggregate_value) -} // ------------------------------------------------------------------- @@ -13429,7 +12314,7 @@ inline bool SourceCodeInfo_Location::has_leading_comments() const { return _internal_has_leading_comments(); } inline void SourceCodeInfo_Location::clear_leading_comments() { - leading_comments_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + leading_comments_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& SourceCodeInfo_Location::leading_comments() const { @@ -13449,31 +12334,30 @@ inline const std::string& SourceCodeInfo_Location::_internal_leading_comments() } inline void SourceCodeInfo_Location::_internal_set_leading_comments(const std::string& value) { _has_bits_[0] |= 0x00000001u; - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void SourceCodeInfo_Location::set_leading_comments(std::string&& value) { _has_bits_[0] |= 0x00000001u; leading_comments_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceCodeInfo.Location.leading_comments) } inline void SourceCodeInfo_Location::set_leading_comments(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments) } inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments) } inline std::string* SourceCodeInfo_Location::_internal_mutable_leading_comments() { _has_bits_[0] |= 0x00000001u; - return leading_comments_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return leading_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* SourceCodeInfo_Location::release_leading_comments() { // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments) @@ -13481,7 +12365,7 @@ inline std::string* SourceCodeInfo_Location::release_leading_comments() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return leading_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return leading_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* leading_comments) { if (leading_comments != nullptr) { @@ -13490,28 +12374,9 @@ inline void SourceCodeInfo_Location::set_allocated_leading_comments(std::string* _has_bits_[0] &= ~0x00000001u; } leading_comments_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), leading_comments, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments) } -inline std::string* SourceCodeInfo_Location::unsafe_arena_release_leading_comments() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.SourceCodeInfo.Location.leading_comments) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return leading_comments_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void SourceCodeInfo_Location::unsafe_arena_set_allocated_leading_comments( - std::string* leading_comments) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (leading_comments != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - leading_comments_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - leading_comments, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments) -} // optional string trailing_comments = 4; inline bool SourceCodeInfo_Location::_internal_has_trailing_comments() const { @@ -13522,7 +12387,7 @@ inline bool SourceCodeInfo_Location::has_trailing_comments() const { return _internal_has_trailing_comments(); } inline void SourceCodeInfo_Location::clear_trailing_comments() { - trailing_comments_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + trailing_comments_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& SourceCodeInfo_Location::trailing_comments() const { @@ -13542,31 +12407,30 @@ inline const std::string& SourceCodeInfo_Location::_internal_trailing_comments() } inline void SourceCodeInfo_Location::_internal_set_trailing_comments(const std::string& value) { _has_bits_[0] |= 0x00000002u; - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void SourceCodeInfo_Location::set_trailing_comments(std::string&& value) { _has_bits_[0] |= 0x00000002u; trailing_comments_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceCodeInfo.Location.trailing_comments) } inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments) } inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments) } inline std::string* SourceCodeInfo_Location::_internal_mutable_trailing_comments() { _has_bits_[0] |= 0x00000002u; - return trailing_comments_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return trailing_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* SourceCodeInfo_Location::release_trailing_comments() { // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments) @@ -13574,7 +12438,7 @@ inline std::string* SourceCodeInfo_Location::release_trailing_comments() { return nullptr; } _has_bits_[0] &= ~0x00000002u; - return trailing_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return trailing_comments_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string* trailing_comments) { if (trailing_comments != nullptr) { @@ -13583,28 +12447,9 @@ inline void SourceCodeInfo_Location::set_allocated_trailing_comments(std::string _has_bits_[0] &= ~0x00000002u; } trailing_comments_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), trailing_comments, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments) } -inline std::string* SourceCodeInfo_Location::unsafe_arena_release_trailing_comments() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.SourceCodeInfo.Location.trailing_comments) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000002u; - return trailing_comments_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void SourceCodeInfo_Location::unsafe_arena_set_allocated_trailing_comments( - std::string* trailing_comments) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (trailing_comments != nullptr) { - _has_bits_[0] |= 0x00000002u; - } else { - _has_bits_[0] &= ~0x00000002u; - } - trailing_comments_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - trailing_comments, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments) -} // repeated string leading_detached_comments = 6; inline int SourceCodeInfo_Location::_internal_leading_detached_comments_size() const { @@ -13783,7 +12628,7 @@ inline bool GeneratedCodeInfo_Annotation::has_source_file() const { return _internal_has_source_file(); } inline void GeneratedCodeInfo_Annotation::clear_source_file() { - source_file_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + source_file_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& GeneratedCodeInfo_Annotation::source_file() const { @@ -13803,31 +12648,30 @@ inline const std::string& GeneratedCodeInfo_Annotation::_internal_source_file() } inline void GeneratedCodeInfo_Annotation::_internal_set_source_file(const std::string& value) { _has_bits_[0] |= 0x00000001u; - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void GeneratedCodeInfo_Annotation::set_source_file(std::string&& value) { _has_bits_[0] |= 0x00000001u; source_file_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.GeneratedCodeInfo.Annotation.source_file) } inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file) } inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.GeneratedCodeInfo.Annotation.source_file) } inline std::string* GeneratedCodeInfo_Annotation::_internal_mutable_source_file() { _has_bits_[0] |= 0x00000001u; - return source_file_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return source_file_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* GeneratedCodeInfo_Annotation::release_source_file() { // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file) @@ -13835,7 +12679,7 @@ inline std::string* GeneratedCodeInfo_Annotation::release_source_file() { return nullptr; } _has_bits_[0] &= ~0x00000001u; - return source_file_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return source_file_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* source_file) { if (source_file != nullptr) { @@ -13844,28 +12688,9 @@ inline void GeneratedCodeInfo_Annotation::set_allocated_source_file(std::string* _has_bits_[0] &= ~0x00000001u; } source_file_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), source_file, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file) } -inline std::string* GeneratedCodeInfo_Annotation::unsafe_arena_release_source_file() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - _has_bits_[0] &= ~0x00000001u; - return source_file_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void GeneratedCodeInfo_Annotation::unsafe_arena_set_allocated_source_file( - std::string* source_file) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (source_file != nullptr) { - _has_bits_[0] |= 0x00000001u; - } else { - _has_bits_[0] &= ~0x00000001u; - } - source_file_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - source_file, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.GeneratedCodeInfo.Annotation.source_file) -} // optional int32 begin = 3; inline bool GeneratedCodeInfo_Annotation::_internal_has_begin() const { diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index a2102d7aa996..9f0ce6cde071 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -41,7 +41,7 @@ syntax = "proto2"; package google.protobuf; -option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor"; +option go_package = "google.golang.org/protobuf/types/descriptorpb"; option java_package = "com.google.protobuf"; option java_outer_classname = "DescriptorProtos"; option csharp_namespace = "Google.Protobuf.Reflection"; @@ -129,6 +129,7 @@ message ExtensionRangeOptions { // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; + // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; } @@ -212,6 +213,29 @@ message FieldDescriptorProto { optional string json_name = 10; optional FieldOptions options = 8; + + // If true, this is a proto3 "optional". When a proto3 field is optional, it + // tracks presence regardless of field type. + // + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still + // indicates the semantic detail of whether the user wrote "optional" or not. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. + // + // Proto2 optional fields do not set this flag, because they already indicate + // optional with `LABEL_OPTIONAL`. + optional bool proto3_optional = 17; } // Describes a oneof. @@ -393,7 +417,7 @@ message FileOptions { // Enables the use of arenas for the proto messages in this file. This applies // only to generated classes for C++. - optional bool cc_enable_arenas = 31 [default = false]; + optional bool cc_enable_arenas = 31 [default = true]; // Sets the objective c class prefix which is prepended to all objective c diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index b613148d3da0..5f53cd138185 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -37,10 +37,10 @@ #include #include -#include #include #include + namespace google { namespace protobuf { @@ -146,6 +146,52 @@ bool SimpleDescriptorDatabase::DescriptorIndex::AddFile( return true; } +namespace { + +// Returns true if and only if all characters in the name are alphanumerics, +// underscores, or periods. +bool ValidateSymbolName(StringPiece name) { + for (char c : name) { + // I don't trust ctype.h due to locales. :( + if (c != '.' && c != '_' && (c < '0' || c > '9') && (c < 'A' || c > 'Z') && + (c < 'a' || c > 'z')) { + return false; + } + } + return true; +} + +// Find the last key in the container which sorts less than or equal to the +// symbol name. Since upper_bound() returns the *first* key that sorts +// *greater* than the input, we want the element immediately before that. +template +typename Container::const_iterator FindLastLessOrEqual( + const Container* container, const Key& key) { + auto iter = container->upper_bound(key); + if (iter != container->begin()) --iter; + return iter; +} + +// As above, but using std::upper_bound instead. +template +typename Container::const_iterator FindLastLessOrEqual( + const Container* container, const Key& key, const Cmp& cmp) { + auto iter = std::upper_bound(container->begin(), container->end(), key, cmp); + if (iter != container->begin()) --iter; + return iter; +} + +// True if either the arguments are equal or super_symbol identifies a +// parent symbol of sub_symbol (e.g. "foo.bar" is a parent of +// "foo.bar.baz", but not a parent of "foo.barbaz"). +bool IsSubSymbol(StringPiece sub_symbol, StringPiece super_symbol) { + return sub_symbol == super_symbol || + (HasPrefixString(super_symbol, sub_symbol) && + super_symbol[sub_symbol.size()] == '.'); +} + +} // namespace + template bool SimpleDescriptorDatabase::DescriptorIndex::AddSymbol( const std::string& name, Value value) { @@ -161,8 +207,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex::AddSymbol( // Try to look up the symbol to make sure a super-symbol doesn't already // exist. - typename std::map::iterator iter = - FindLastLessOrEqual(name); + auto iter = FindLastLessOrEqual(&by_symbol_, name); if (iter == by_symbol_.end()) { // Apparently the map is currently empty. Just insert and be done with it. @@ -252,8 +297,7 @@ Value SimpleDescriptorDatabase::DescriptorIndex::FindFile( template Value SimpleDescriptorDatabase::DescriptorIndex::FindSymbol( const std::string& name) { - typename std::map::iterator iter = - FindLastLessOrEqual(name); + auto iter = FindLastLessOrEqual(&by_symbol_, name); return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ? iter->second @@ -294,40 +338,6 @@ void SimpleDescriptorDatabase::DescriptorIndex::FindAllFileNames( } } -template -typename std::map::iterator -SimpleDescriptorDatabase::DescriptorIndex::FindLastLessOrEqual( - const std::string& name) { - // Find the last key in the map which sorts less than or equal to the - // symbol name. Since upper_bound() returns the *first* key that sorts - // *greater* than the input, we want the element immediately before that. - typename std::map::iterator iter = - by_symbol_.upper_bound(name); - if (iter != by_symbol_.begin()) --iter; - return iter; -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::IsSubSymbol( - const std::string& sub_symbol, const std::string& super_symbol) { - return sub_symbol == super_symbol || - (HasPrefixString(super_symbol, sub_symbol) && - super_symbol[sub_symbol.size()] == '.'); -} - -template -bool SimpleDescriptorDatabase::DescriptorIndex::ValidateSymbolName( - const std::string& name) { - for (int i = 0; i < name.size(); i++) { - // I don't trust ctype.h due to locales. :( - if (name[i] != '.' && name[i] != '_' && (name[i] < '0' || name[i] > '9') && - (name[i] < 'A' || name[i] > 'Z') && (name[i] < 'a' || name[i] > 'z')) { - return false; - } - } - return true; -} - // ------------------------------------------------------------------- bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) { @@ -378,18 +388,173 @@ bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file, // ------------------------------------------------------------------- -EncodedDescriptorDatabase::EncodedDescriptorDatabase() {} -EncodedDescriptorDatabase::~EncodedDescriptorDatabase() { - for (int i = 0; i < files_to_delete_.size(); i++) { - operator delete(files_to_delete_[i]); - } -} +class EncodedDescriptorDatabase::DescriptorIndex { + public: + using Value = std::pair; + // Helpers to recursively add particular descriptors and all their contents + // to the index. + template + bool AddFile(const FileProto& file, Value value); + + Value FindFile(StringPiece filename); + Value FindSymbol(StringPiece name); + Value FindSymbolOnlyFlat(StringPiece name) const; + Value FindExtension(StringPiece containing_type, int field_number); + bool FindAllExtensionNumbers(StringPiece containing_type, + std::vector* output); + void FindAllFileNames(std::vector* output) const; + + private: + friend class EncodedDescriptorDatabase; + + bool AddSymbol(StringPiece symbol); + + template + bool AddNestedExtensions(StringPiece filename, + const DescProto& message_type); + template + bool AddExtension(StringPiece filename, const FieldProto& field); + + // All the maps below have two representations: + // - a std::set<> where we insert initially. + // - a std::vector<> where we flatten the structure on demand. + // The initial tree helps avoid O(N) behavior of inserting into a sorted + // vector, while the vector reduces the heap requirements of the data + // structure. + + void EnsureFlat(); + + using String = std::string; + + String EncodeString(StringPiece str) const { return String(str); } + StringPiece DecodeString(const String& str, int) const { return str; } + + struct EncodedEntry { + // Do not use `Value` here to avoid the padding of that object. + const void* data; + int size; + // Keep the package here instead of each SymbolEntry to save space. + String encoded_package; + + Value value() const { return {data, size}; } + }; + std::vector all_values_; + + struct FileEntry { + int data_offset; + String encoded_name; + + StringPiece name(const DescriptorIndex& index) const { + return index.DecodeString(encoded_name, data_offset); + } + }; + struct FileCompare { + const DescriptorIndex& index; + + bool operator()(const FileEntry& a, const FileEntry& b) const { + return a.name(index) < b.name(index); + } + bool operator()(const FileEntry& a, StringPiece b) const { + return a.name(index) < b; + } + bool operator()(StringPiece a, const FileEntry& b) const { + return a < b.name(index); + } + }; + std::set by_name_{FileCompare{*this}}; + std::vector by_name_flat_; + + struct SymbolEntry { + int data_offset; + String encoded_symbol; + + StringPiece package(const DescriptorIndex& index) const { + return index.DecodeString(index.all_values_[data_offset].encoded_package, + data_offset); + } + StringPiece symbol(const DescriptorIndex& index) const { + return index.DecodeString(encoded_symbol, data_offset); + } + + std::string AsString(const DescriptorIndex& index) const { + auto p = package(index); + return StrCat(p, p.empty() ? "" : ".", symbol(index)); + } + }; + + struct SymbolCompare { + const DescriptorIndex& index; + + std::string AsString(const SymbolEntry& entry) const { + return entry.AsString(index); + } + static StringPiece AsString(StringPiece str) { return str; } + + std::pair GetParts( + const SymbolEntry& entry) const { + auto package = entry.package(index); + if (package.empty()) return {entry.symbol(index), StringPiece{}}; + return {package, entry.symbol(index)}; + } + std::pair GetParts( + StringPiece str) const { + return {str, {}}; + } + + template + bool operator()(const T& lhs, const U& rhs) const { + auto lhs_parts = GetParts(lhs); + auto rhs_parts = GetParts(rhs); + + // Fast path to avoid making the whole string for common cases. + if (int res = + lhs_parts.first.substr(0, rhs_parts.first.size()) + .compare(rhs_parts.first.substr(0, lhs_parts.first.size()))) { + // If the packages already differ, exit early. + return res < 0; + } else if (lhs_parts.first.size() == rhs_parts.first.size()) { + return lhs_parts.second < rhs_parts.second; + } + return AsString(lhs) < AsString(rhs); + } + }; + std::set by_symbol_{SymbolCompare{*this}}; + std::vector by_symbol_flat_; + + struct ExtensionEntry { + int data_offset; + String encoded_extendee; + StringPiece extendee(const DescriptorIndex& index) const { + return index.DecodeString(encoded_extendee, data_offset).substr(1); + } + int extension_number; + }; + struct ExtensionCompare { + const DescriptorIndex& index; + + bool operator()(const ExtensionEntry& a, const ExtensionEntry& b) const { + return std::make_tuple(a.extendee(index), a.extension_number) < + std::make_tuple(b.extendee(index), b.extension_number); + } + bool operator()(const ExtensionEntry& a, + std::tuple b) const { + return std::make_tuple(a.extendee(index), a.extension_number) < b; + } + bool operator()(std::tuple a, + const ExtensionEntry& b) const { + return a < std::make_tuple(b.extendee(index), b.extension_number); + } + }; + std::set by_extension_{ + ExtensionCompare{*this}}; + std::vector by_extension_flat_; +}; bool EncodedDescriptorDatabase::Add(const void* encoded_file_descriptor, int size) { FileDescriptorProto file; if (file.ParseFromArray(encoded_file_descriptor, size)) { - return index_.AddFile(file, std::make_pair(encoded_file_descriptor, size)); + return index_->AddFile(file, std::make_pair(encoded_file_descriptor, size)); } else { GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to " "EncodedDescriptorDatabase::Add()."; @@ -407,22 +572,22 @@ bool EncodedDescriptorDatabase::AddCopy(const void* encoded_file_descriptor, bool EncodedDescriptorDatabase::FindFileByName(const std::string& filename, FileDescriptorProto* output) { - return MaybeParse(index_.FindFile(filename), output); + return MaybeParse(index_->FindFile(filename), output); } bool EncodedDescriptorDatabase::FindFileContainingSymbol( const std::string& symbol_name, FileDescriptorProto* output) { - return MaybeParse(index_.FindSymbol(symbol_name), output); + return MaybeParse(index_->FindSymbol(symbol_name), output); } bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( const std::string& symbol_name, std::string* output) { - std::pair encoded_file = index_.FindSymbol(symbol_name); + auto encoded_file = index_->FindSymbol(symbol_name); if (encoded_file.first == NULL) return false; // Optimization: The name should be the first field in the encoded message. // Try to just read it directly. - io::CodedInputStream input(reinterpret_cast(encoded_file.first), + io::CodedInputStream input(static_cast(encoded_file.first), encoded_file.second); const uint32 kNameTag = internal::WireFormatLite::MakeTag( @@ -446,18 +611,261 @@ bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol( bool EncodedDescriptorDatabase::FindFileContainingExtension( const std::string& containing_type, int field_number, FileDescriptorProto* output) { - return MaybeParse(index_.FindExtension(containing_type, field_number), + return MaybeParse(index_->FindExtension(containing_type, field_number), output); } bool EncodedDescriptorDatabase::FindAllExtensionNumbers( const std::string& extendee_type, std::vector* output) { - return index_.FindAllExtensionNumbers(extendee_type, output); + return index_->FindAllExtensionNumbers(extendee_type, output); +} + +template +bool EncodedDescriptorDatabase::DescriptorIndex::AddFile(const FileProto& file, + Value value) { + // We push `value` into the array first. This is important because the AddXXX + // functions below will expect it to be there. + all_values_.push_back({value.first, value.second, {}}); + + if (!ValidateSymbolName(file.package())) { + GOOGLE_LOG(ERROR) << "Invalid package name: " << file.package(); + return false; + } + all_values_.back().encoded_package = EncodeString(file.package()); + + if (!InsertIfNotPresent( + &by_name_, FileEntry{static_cast(all_values_.size() - 1), + EncodeString(file.name())}) || + std::binary_search(by_name_flat_.begin(), by_name_flat_.end(), + file.name(), by_name_.key_comp())) { + GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name(); + return false; + } + + for (const auto& message_type : file.message_type()) { + if (!AddSymbol(message_type.name())) return false; + if (!AddNestedExtensions(file.name(), message_type)) return false; + } + for (const auto& enum_type : file.enum_type()) { + if (!AddSymbol(enum_type.name())) return false; + } + for (const auto& extension : file.extension()) { + if (!AddSymbol(extension.name())) return false; + if (!AddExtension(file.name(), extension)) return false; + } + for (const auto& service : file.service()) { + if (!AddSymbol(service.name())) return false; + } + + return true; +} + +template +static bool CheckForMutualSubsymbols(StringPiece symbol_name, Iter* iter, + Iter2 end, const Index& index) { + if (*iter != end) { + if (IsSubSymbol((*iter)->AsString(index), symbol_name)) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << symbol_name + << "\" conflicts with the existing symbol \"" + << (*iter)->AsString(index) << "\"."; + return false; + } + + // OK, that worked. Now we have to make sure that no symbol in the map is + // a sub-symbol of the one we are inserting. The only symbol which could + // be so is the first symbol that is greater than the new symbol. Since + // |iter| points at the last symbol that is less than or equal, we just have + // to increment it. + ++*iter; + + if (*iter != end && IsSubSymbol(symbol_name, (*iter)->AsString(index))) { + GOOGLE_LOG(ERROR) << "Symbol name \"" << symbol_name + << "\" conflicts with the existing symbol \"" + << (*iter)->AsString(index) << "\"."; + return false; + } + } + return true; +} + +bool EncodedDescriptorDatabase::DescriptorIndex::AddSymbol( + StringPiece symbol) { + SymbolEntry entry = {static_cast(all_values_.size() - 1), + EncodeString(symbol)}; + std::string entry_as_string = entry.AsString(*this); + + // We need to make sure not to violate our map invariant. + + // If the symbol name is invalid it could break our lookup algorithm (which + // relies on the fact that '.' sorts before all other characters that are + // valid in symbol names). + if (!ValidateSymbolName(symbol)) { + GOOGLE_LOG(ERROR) << "Invalid symbol name: " << entry_as_string; + return false; + } + + auto iter = FindLastLessOrEqual(&by_symbol_, entry); + if (!CheckForMutualSubsymbols(entry_as_string, &iter, by_symbol_.end(), + *this)) { + return false; + } + + // Same, but on by_symbol_flat_ + auto flat_iter = + FindLastLessOrEqual(&by_symbol_flat_, entry, by_symbol_.key_comp()); + if (!CheckForMutualSubsymbols(entry_as_string, &flat_iter, + by_symbol_flat_.end(), *this)) { + return false; + } + + // OK, no conflicts. + + // Insert the new symbol using the iterator as a hint, the new entry will + // appear immediately before the one the iterator is pointing at. + by_symbol_.insert(iter, entry); + + return true; +} + +template +bool EncodedDescriptorDatabase::DescriptorIndex::AddNestedExtensions( + StringPiece filename, const DescProto& message_type) { + for (const auto& nested_type : message_type.nested_type()) { + if (!AddNestedExtensions(filename, nested_type)) return false; + } + for (const auto& extension : message_type.extension()) { + if (!AddExtension(filename, extension)) return false; + } + return true; } +template +bool EncodedDescriptorDatabase::DescriptorIndex::AddExtension( + StringPiece filename, const FieldProto& field) { + if (!field.extendee().empty() && field.extendee()[0] == '.') { + // The extension is fully-qualified. We can use it as a lookup key in + // the by_symbol_ table. + if (!InsertIfNotPresent( + &by_extension_, + ExtensionEntry{static_cast(all_values_.size() - 1), + EncodeString(field.extendee()), field.number()}) || + std::binary_search( + by_extension_flat_.begin(), by_extension_flat_.end(), + std::make_pair(field.extendee().substr(1), field.number()), + by_extension_.key_comp())) { + GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: " + "extend " + << field.extendee() << " { " << field.name() << " = " + << field.number() << " } from:" << filename; + return false; + } + } else { + // Not fully-qualified. We can't really do anything here, unfortunately. + // We don't consider this an error, though, because the descriptor is + // valid. + } + return true; +} + +std::pair +EncodedDescriptorDatabase::DescriptorIndex::FindSymbol(StringPiece name) { + EnsureFlat(); + return FindSymbolOnlyFlat(name); +} + +std::pair +EncodedDescriptorDatabase::DescriptorIndex::FindSymbolOnlyFlat( + StringPiece name) const { + auto iter = + FindLastLessOrEqual(&by_symbol_flat_, name, by_symbol_.key_comp()); + + return iter != by_symbol_flat_.end() && + IsSubSymbol(iter->AsString(*this), name) + ? all_values_[iter->data_offset].value() + : Value(); +} + +std::pair +EncodedDescriptorDatabase::DescriptorIndex::FindExtension( + StringPiece containing_type, int field_number) { + EnsureFlat(); + + auto it = std::lower_bound( + by_extension_flat_.begin(), by_extension_flat_.end(), + std::make_tuple(containing_type, field_number), by_extension_.key_comp()); + return it == by_extension_flat_.end() || + it->extendee(*this) != containing_type || + it->extension_number != field_number + ? std::make_pair(nullptr, 0) + : all_values_[it->data_offset].value(); +} + +template +static void MergeIntoFlat(std::set* s, std::vector* flat) { + if (s->empty()) return; + std::vector new_flat(s->size() + flat->size()); + std::merge(s->begin(), s->end(), flat->begin(), flat->end(), &new_flat[0], + s->key_comp()); + *flat = std::move(new_flat); + s->clear(); +} + +void EncodedDescriptorDatabase::DescriptorIndex::EnsureFlat() { + all_values_.shrink_to_fit(); + // Merge each of the sets into their flat counterpart. + MergeIntoFlat(&by_name_, &by_name_flat_); + MergeIntoFlat(&by_symbol_, &by_symbol_flat_); + MergeIntoFlat(&by_extension_, &by_extension_flat_); +} + +bool EncodedDescriptorDatabase::DescriptorIndex::FindAllExtensionNumbers( + StringPiece containing_type, std::vector* output) { + EnsureFlat(); + + bool success = false; + auto it = std::lower_bound( + by_extension_flat_.begin(), by_extension_flat_.end(), + std::make_tuple(containing_type, 0), by_extension_.key_comp()); + for (; + it != by_extension_flat_.end() && it->extendee(*this) == containing_type; + ++it) { + output->push_back(it->extension_number); + success = true; + } + + return success; +} + +void EncodedDescriptorDatabase::DescriptorIndex::FindAllFileNames( + std::vector* output) const { + output->resize(by_name_.size() + by_name_flat_.size()); + int i = 0; + for (const auto& entry : by_name_) { + (*output)[i] = std::string(entry.name(*this)); + i++; + } + for (const auto& entry : by_name_flat_) { + (*output)[i] = std::string(entry.name(*this)); + i++; + } +} + +std::pair +EncodedDescriptorDatabase::DescriptorIndex::FindFile( + StringPiece filename) { + EnsureFlat(); + + auto it = std::lower_bound(by_name_flat_.begin(), by_name_flat_.end(), + filename, by_name_.key_comp()); + return it == by_name_flat_.end() || it->name(*this) != filename + ? std::make_pair(nullptr, 0) + : all_values_[it->data_offset].value(); +} + + bool EncodedDescriptorDatabase::FindAllFileNames( std::vector* output) { - index_.FindAllFileNames(output); + index_->FindAllFileNames(output); return true; } @@ -467,6 +875,15 @@ bool EncodedDescriptorDatabase::MaybeParse( return output->ParseFromArray(encoded_file.first, encoded_file.second); } +EncodedDescriptorDatabase::EncodedDescriptorDatabase() + : index_(new DescriptorIndex()) {} + +EncodedDescriptorDatabase::~EncodedDescriptorDatabase() { + for (void* p : files_to_delete_) { + operator delete(p); + } +} + // =================================================================== DescriptorPoolDatabase::DescriptorPoolDatabase(const DescriptorPool& pool) @@ -514,8 +931,8 @@ bool DescriptorPoolDatabase::FindAllExtensionNumbers( std::vector extensions; pool_.FindAllExtensions(extendee, &extensions); - for (int i = 0; i < extensions.size(); ++i) { - output->push_back(extensions[i]->number()); + for (const FieldDescriptor* extension : extensions) { + output->push_back(extension->number()); } return true; @@ -535,8 +952,8 @@ MergedDescriptorDatabase::~MergedDescriptorDatabase() {} bool MergedDescriptorDatabase::FindFileByName(const std::string& filename, FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindFileByName(filename, output)) { + for (DescriptorDatabase* source : sources_) { + if (source->FindFileByName(filename, output)) { return true; } } @@ -545,14 +962,14 @@ bool MergedDescriptorDatabase::FindFileByName(const std::string& filename, bool MergedDescriptorDatabase::FindFileContainingSymbol( const std::string& symbol_name, FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { + for (size_t i = 0; i < sources_.size(); i++) { if (sources_[i]->FindFileContainingSymbol(symbol_name, output)) { // The symbol was found in source i. However, if one of the previous // sources defines a file with the same name (which presumably doesn't // contain the symbol, since it wasn't found in that source), then we // must hide it from the caller. FileDescriptorProto temp; - for (int j = 0; j < i; j++) { + for (size_t j = 0; j < i; j++) { if (sources_[j]->FindFileByName(output->name(), &temp)) { // Found conflicting file in a previous source. return false; @@ -567,7 +984,7 @@ bool MergedDescriptorDatabase::FindFileContainingSymbol( bool MergedDescriptorDatabase::FindFileContainingExtension( const std::string& containing_type, int field_number, FileDescriptorProto* output) { - for (int i = 0; i < sources_.size(); i++) { + for (size_t i = 0; i < sources_.size(); i++) { if (sources_[i]->FindFileContainingExtension(containing_type, field_number, output)) { // The symbol was found in source i. However, if one of the previous @@ -575,7 +992,7 @@ bool MergedDescriptorDatabase::FindFileContainingExtension( // contain the symbol, since it wasn't found in that source), then we // must hide it from the caller. FileDescriptorProto temp; - for (int j = 0; j < i; j++) { + for (size_t j = 0; j < i; j++) { if (sources_[j]->FindFileByName(output->name(), &temp)) { // Found conflicting file in a previous source. return false; @@ -593,8 +1010,8 @@ bool MergedDescriptorDatabase::FindAllExtensionNumbers( std::vector results; bool success = false; - for (int i = 0; i < sources_.size(); i++) { - if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) { + for (DescriptorDatabase* source : sources_) { + if (source->FindAllExtensionNumbers(extendee_type, &results)) { std::copy(results.begin(), results.end(), std::insert_iterator >(merged_results, merged_results.begin())); diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h index 4009f339e257..5fb593efc65c 100644 --- a/src/google/protobuf/descriptor_database.h +++ b/src/google/protobuf/descriptor_database.h @@ -187,9 +187,6 @@ class PROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { bool FindAllFileNames(std::vector* output) override; private: - // So that it can use DescriptorIndex. - friend class EncodedDescriptorDatabase; - // An index mapping file names, symbol names, and extension numbers to // some sort of values. template @@ -266,21 +263,6 @@ class PROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { // That symbol cannot be a super-symbol of the search key since if it were, // then it would be a match, and we're assuming the match key doesn't exist. // Therefore, step 2 will correctly return no match. - - // Find the last entry in the by_symbol_ map whose key is less than or - // equal to the given name. - typename std::map::iterator FindLastLessOrEqual( - const std::string& name); - - // True if either the arguments are equal or super_symbol identifies a - // parent symbol of sub_symbol (e.g. "foo.bar" is a parent of - // "foo.bar.baz", but not a parent of "foo.barbaz"). - bool IsSubSymbol(const std::string& sub_symbol, - const std::string& super_symbol); - - // Returns true if and only if all characters in the name are alphanumerics, - // underscores, or periods. - bool ValidateSymbolName(const std::string& name); }; DescriptorIndex index_; @@ -332,8 +314,10 @@ class PROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { bool FindAllFileNames(std::vector* output) override; private: - SimpleDescriptorDatabase::DescriptorIndex > - index_; + class DescriptorIndex; + // Keep DescriptorIndex by pointer to hide the implementation to keep a + // cleaner header. + std::unique_ptr index_; std::vector files_to_delete_; // If encoded_file.first is non-NULL, parse the data into *output and return diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc index 8653193abdc1..fba0b95a84db 100644 --- a/src/google/protobuf/descriptor_database_unittest.cc +++ b/src/google/protobuf/descriptor_database_unittest.cc @@ -34,20 +34,21 @@ // // This file makes extensive use of RFC 3092. :) +#include + #include #include +#include +#include #include #include -#include #include - -#include -#include #include #include #include + namespace google { namespace protobuf { namespace { @@ -546,7 +547,7 @@ TEST(SimpleDescriptorDatabaseExtraTest, FindAllPackageNames) { db.Add(f); db.Add(b); - std::vector packages; + std::vector packages; EXPECT_TRUE(db.FindAllPackageNames(&packages)); EXPECT_THAT(packages, ::testing::UnorderedElementsAre("foo", "")); } @@ -566,7 +567,7 @@ TEST(SimpleDescriptorDatabaseExtraTest, FindAllMessageNames) { db.Add(f); db.Add(b); - std::vector messages; + std::vector messages; EXPECT_TRUE(db.FindAllMessageNames(&messages)); EXPECT_THAT(messages, ::testing::UnorderedElementsAre("foo.Foo", "Bar")); } @@ -798,6 +799,7 @@ TEST_F(MergedDescriptorDatabaseTest, FindAllExtensionNumbers) { } } + } // anonymous namespace } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 1cd2897d370e..2521d92c0ae3 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -38,13 +38,13 @@ #include #include +#include #include #include #include #include #include #include -#include #include #include #include @@ -58,6 +58,7 @@ #include #include #include +#include #include @@ -243,7 +244,7 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector { } strings::SubstituteAndAppend(&text_, "$0: $1: $2: $3\n", filename, - element_name, location_name, message); + element_name, location_name, message); } // implements ErrorCollector --------------------------------------- @@ -288,7 +289,7 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector { } strings::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename, - element_name, location_name, message); + element_name, location_name, message); } }; @@ -478,7 +479,7 @@ TEST_F(FileDescriptorTest, FindExtensionByNumber) { TEST_F(FileDescriptorTest, BuildAgain) { - // Test that if te call BuildFile again on the same input we get the same + // Test that if we call BuildFile again on the same input we get the same // FileDescriptor back. FileDescriptorProto file; foo_file_->CopyTo(&file); @@ -490,7 +491,7 @@ TEST_F(FileDescriptorTest, BuildAgain) { } TEST_F(FileDescriptorTest, BuildAgainWithSyntax) { - // Test that if te call BuildFile again on the same input we get the same + // Test that if we call BuildFile again on the same input we get the same // FileDescriptor back even if syntax param is specified. FileDescriptorProto proto_syntax2; proto_syntax2.set_name("foo_syntax2"); @@ -998,6 +999,22 @@ TEST_F(DescriptorTest, IsMap) { EXPECT_TRUE(map_->message_type()->options().map_entry()); } +TEST_F(DescriptorTest, GetMap) { + const Descriptor* map_desc = map_->message_type(); + const FieldDescriptor* map_key = map_desc->map_key(); + ASSERT_TRUE(map_key != nullptr); + EXPECT_EQ(map_key->name(), "key"); + EXPECT_EQ(map_key->number(), 1); + + const FieldDescriptor* map_value = map_desc->map_value(); + ASSERT_TRUE(map_value != nullptr); + EXPECT_EQ(map_value->name(), "value"); + EXPECT_EQ(map_value->number(), 2); + + EXPECT_EQ(message_->map_key(), nullptr); + EXPECT_EQ(message_->map_value(), nullptr); +} + TEST_F(DescriptorTest, FieldHasDefault) { EXPECT_FALSE(foo_->has_default_value()); EXPECT_FALSE(bar_->has_default_value()); @@ -1834,12 +1851,17 @@ class ExtensionDescriptorTest : public testing::Test { // extensions 10 to 19; // extensions 30 to 39; // } - // extends Foo with optional int32 foo_int32 = 10; - // extends Foo with repeated TestEnum foo_enum = 19; + // extend Foo { + // optional int32 foo_int32 = 10; + // } + // extend Foo { + // repeated TestEnum foo_enum = 19; + // } // message Bar { - // extends Foo with optional Qux foo_message = 30; - // // (using Qux as the group type) - // extends Foo with repeated group foo_group = 39; + // extend Foo { + // optional Qux foo_message = 30; + // repeated Qux foo_group = 39; // (but internally set to TYPE_GROUP) + // } // } FileDescriptorProto foo_file; @@ -2575,11 +2597,9 @@ TEST_F(MiscTest, DefaultValues) { ASSERT_TRUE(message->field(10)->has_default_value()); EXPECT_EQ(-1, message->field(0)->default_value_int32()); - EXPECT_EQ(-PROTOBUF_ULONGLONG(1000000000000), - message->field(1)->default_value_int64()); + EXPECT_EQ(int64{-1000000000000}, message->field(1)->default_value_int64()); EXPECT_EQ(42, message->field(2)->default_value_uint32()); - EXPECT_EQ(PROTOBUF_ULONGLONG(2000000000000), - message->field(3)->default_value_uint64()); + EXPECT_EQ(uint64{2000000000000}, message->field(3)->default_value_uint64()); EXPECT_EQ(4.5, message->field(4)->default_value_float()); EXPECT_EQ(10e100, message->field(5)->default_value_double()); EXPECT_TRUE(message->field(6)->default_value_bool()); @@ -2652,9 +2672,11 @@ TEST_F(MiscTest, FieldOptions) { enum DescriptorPoolMode { NO_DATABASE, FALLBACK_DATABASE }; class AllowUnknownDependenciesTest - : public testing::TestWithParam { + : public testing::TestWithParam< + std::tuple> { protected: - DescriptorPoolMode mode() { return GetParam(); } + DescriptorPoolMode mode() { return std::get<0>(GetParam()); } + const char* syntax() { return std::get<1>(GetParam()); } virtual void SetUp() { FileDescriptorProto foo_proto, bar_proto; @@ -2693,10 +2715,13 @@ class AllowUnknownDependenciesTest " }" "}", &foo_proto)); + foo_proto.set_syntax(syntax()); + ASSERT_TRUE( TextFormat::ParseFromString("name: 'bar.proto'" "message_type { name: 'Bar' }", &bar_proto)); + bar_proto.set_syntax(syntax()); // Collect pointers to stuff. bar_file_ = BuildFile(bar_proto); @@ -2969,7 +2994,9 @@ TEST_P(AllowUnknownDependenciesTest, } INSTANTIATE_TEST_SUITE_P(DatabaseSource, AllowUnknownDependenciesTest, - testing::Values(NO_DATABASE, FALLBACK_DATABASE)); + testing::Combine(testing::Values(NO_DATABASE, + FALLBACK_DATABASE), + testing::Values("proto2", "proto3"))); // =================================================================== @@ -2985,11 +3012,11 @@ TEST(CustomOptions, OptionLocations) { file->FindServiceByName("TestServiceWithCustomOptions"); const MethodDescriptor* method = service->FindMethodByName("Foo"); - EXPECT_EQ(PROTOBUF_LONGLONG(9876543210), + EXPECT_EQ(int64{9876543210}, file->options().GetExtension(protobuf_unittest::file_opt1)); EXPECT_EQ(-56, message->options().GetExtension(protobuf_unittest::message_opt1)); - EXPECT_EQ(PROTOBUF_LONGLONG(8765432109), + EXPECT_EQ(int64{8765432109}, field->options().GetExtension(protobuf_unittest::field_opt1)); EXPECT_EQ(42, // Check that we get the default for an option we don't set. field->options().GetExtension(protobuf_unittest::field_opt2)); @@ -2997,7 +3024,7 @@ TEST(CustomOptions, OptionLocations) { EXPECT_EQ(-789, enm->options().GetExtension(protobuf_unittest::enum_opt1)); EXPECT_EQ(123, enm->value(1)->options().GetExtension( protobuf_unittest::enum_value_opt1)); - EXPECT_EQ(PROTOBUF_LONGLONG(-9876543210), + EXPECT_EQ(int64{-9876543210}, service->options().GetExtension(protobuf_unittest::service_opt1)); EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2, method->options().GetExtension(protobuf_unittest::method_opt1)); @@ -3126,6 +3153,11 @@ TEST(CustomOptions, OptionsFromOtherFile) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + // We have to import the Any dependency. + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3184,6 +3216,10 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3261,6 +3297,10 @@ TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3341,6 +3381,10 @@ TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) { FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); @@ -3441,6 +3485,10 @@ TEST(CustomOptions, AggregateOptions) { message_set_extension) .s()); + protobuf_unittest::AggregateMessageSetElement any_payload; + ASSERT_TRUE(file_options.any().UnpackTo(&any_payload)); + EXPECT_EQ("EmbeddedMessageSetElement", any_payload.s()); + // Simple tests for all the other types of annotations EXPECT_EQ("MessageAnnotation", msg->options().GetExtension(protobuf_unittest::msgopt).s()); @@ -3456,18 +3504,22 @@ TEST(CustomOptions, AggregateOptions) { method->options().GetExtension(protobuf_unittest::methodopt).s()); } -TEST(CustomOptions, UnusedImportWarning) { +TEST(CustomOptions, UnusedImportError) { DescriptorPool pool; FileDescriptorProto file_proto; FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); + FileDescriptorProto any_proto; + google::protobuf::Any::descriptor()->file()->CopyTo(&any_proto); + ASSERT_TRUE(pool.BuildFile(any_proto) != nullptr); + protobuf_unittest::TestMessageWithCustomOptions::descriptor()->file()->CopyTo( &file_proto); ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); - pool.AddUnusedImportTrackFile("custom_options_import.proto"); + pool.AddUnusedImportTrackFile("custom_options_import.proto", true); ASSERT_TRUE(TextFormat::ParseFromString( "name: \"custom_options_import.proto\" " "package: \"protobuf_unittest\" " @@ -3475,13 +3527,12 @@ TEST(CustomOptions, UnusedImportWarning) { &file_proto)); MockErrorCollector error_collector; - EXPECT_TRUE(pool.BuildFileCollectingErrors(file_proto, &error_collector)); + EXPECT_FALSE(pool.BuildFileCollectingErrors(file_proto, &error_collector)); EXPECT_EQ( "custom_options_import.proto: " "google/protobuf/unittest_custom_options.proto: IMPORT: Import " "google/protobuf/unittest_custom_options.proto is unused.\n", - error_collector.warning_text_); - EXPECT_EQ("", error_collector.text_); + error_collector.text_); } // Verifies that proto files can correctly be parsed, even if the @@ -6502,6 +6553,28 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) { } +TEST_F(ValidationErrorTest, UnusedImportWithOtherError) { + BuildFile( + "name: 'bar.proto' " + "message_type {" + " name: 'Bar'" + "}"); + + pool_.AddUnusedImportTrackFile("foo.proto", true); + BuildFileWithErrors( + "name: 'foo.proto' " + "dependency: 'bar.proto' " + "message_type {" + " name: 'Foo'" + " extension { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32" + " extendee: 'Baz' }" + "}", + + // Should not also contain unused import error. + "foo.proto: Foo.foo: EXTENDEE: \"Baz\" is not defined.\n"); +} + + // =================================================================== // DescriptorDatabase @@ -6950,22 +7023,21 @@ class ExponentialErrorDatabase : public DescriptorDatabase { } bool PopulateFile(int file_num, FileDescriptorProto* output) { - using strings::Substitute; GOOGLE_CHECK_GE(file_num, 0); output->Clear(); - output->set_name(Substitute("file$0.proto", file_num)); + output->set_name(strings::Substitute("file$0.proto", file_num)); // file0.proto doesn't define Message0 if (file_num > 0) { DescriptorProto* message = output->add_message_type(); - message->set_name(Substitute("Message$0", file_num)); + message->set_name(strings::Substitute("Message$0", file_num)); for (int i = 0; i < file_num; ++i) { - output->add_dependency(Substitute("file$0.proto", i)); + output->add_dependency(strings::Substitute("file$0.proto", i)); FieldDescriptorProto* field = message->add_field(); - field->set_name(Substitute("field$0", i)); + field->set_name(strings::Substitute("field$0", i)); field->set_number(i); field->set_label(FieldDescriptorProto::LABEL_OPTIONAL); field->set_type(FieldDescriptorProto::TYPE_MESSAGE); - field->set_type_name(Substitute("Message$0", i)); + field->set_type_name(strings::Substitute("Message$0", i)); } } return true; @@ -7140,8 +7212,8 @@ class SourceLocationTest : public testing::Test { static std::string PrintSourceLocation(const SourceLocation& loc) { return strings::Substitute("$0:$1-$2:$3", 1 + loc.start_line, - 1 + loc.start_column, 1 + loc.end_line, - 1 + loc.end_column); + 1 + loc.start_column, 1 + loc.end_line, + 1 + loc.end_column); } private: @@ -7156,9 +7228,9 @@ class SourceLocationTest : public testing::Test { DescriptorPool pool_; // tag number of all custom options in above test file - static const int kCustomOptionFieldNumber = 10101; + static constexpr int kCustomOptionFieldNumber = 10101; // tag number of field "a" in message type "A" in above test file - static const int kAFieldNumber = 1; + static constexpr int kAFieldNumber = 1; }; // TODO(adonovan): implement support for option fields and for @@ -8043,3 +8115,5 @@ TEST_F(LazilyBuildDependenciesTest, Dependency) { } // namespace descriptor_unittest } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index 6f829f49bfc9..87f54dff38b7 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class DurationDefaultTypeInternal { public: @@ -28,7 +30,6 @@ static void InitDefaultsscc_info_Duration_google_2fprotobuf_2fduration_2eproto() new (ptr) PROTOBUF_NAMESPACE_ID::Duration(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Duration::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Duration_google_2fprotobuf_2fduration_2eproto = @@ -58,10 +59,10 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\036google/protobuf/duration.proto\022\017google" ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r" - "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu" - "rationProtoP\001Z*github.com/golang/protobu" - "f/ptypes/duration\370\001\001\242\002\003GPB\252\002\036Google.Prot" - "obuf.WellKnownTypesb\006proto3" + "\n\005nanos\030\002 \001(\005B\203\001\n\023com.google.protobufB\rD" + "urationProtoP\001Z1google.golang.org/protob" + "uf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Goo" + "gle.Protobuf.WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fduration_2eproto_deps[1] = { }; @@ -69,42 +70,32 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_Duration_google_2fprotobuf_2fduration_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fduration_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fduration_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2eproto = { - &descriptor_table_google_2fprotobuf_2fduration_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto", 227, + false, false, descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto, "google/protobuf/duration.proto", 235, &descriptor_table_google_2fprotobuf_2fduration_2eproto_once, descriptor_table_google_2fprotobuf_2fduration_2eproto_sccs, descriptor_table_google_2fprotobuf_2fduration_2eproto_deps, 1, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fduration_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fduration_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fduration_2eproto, file_level_service_descriptors_google_2fprotobuf_2fduration_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fduration_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto(&descriptor_table_google_2fprotobuf_2fduration_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Duration::InitAsDefaultInstance() { -} class Duration::_Internal { public: }; -Duration::Duration() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Duration) -} Duration::Duration(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Duration) } Duration::Duration(const Duration& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::memcpy(&seconds_, &from.seconds_, static_cast(reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); @@ -112,18 +103,20 @@ Duration::Duration(const Duration& from) } void Duration::SharedCtor() { - ::memset(&seconds_, 0, static_cast( - reinterpret_cast(&nanos_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&seconds_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); } Duration::~Duration() { // @@protoc_insertion_point(destructor:google.protobuf.Duration) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Duration::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void Duration::ArenaDtor(void* object) { @@ -150,12 +143,11 @@ void Duration::Clear() { ::memset(&seconds_, 0, static_cast( reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Duration::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -181,7 +173,9 @@ const char* Duration::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::i ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -215,7 +209,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Duration::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Duration) return target; @@ -270,7 +264,7 @@ void Duration::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Duration::MergeFrom(const Duration& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -302,9 +296,13 @@ bool Duration::IsInitialized() const { void Duration::InternalSwap(Duration* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(seconds_, other->seconds_); - swap(nanos_, other->nanos_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Duration, nanos_) + + sizeof(Duration::nanos_) + - PROTOBUF_FIELD_OFFSET(Duration, seconds_)>( + reinterpret_cast(&seconds_), + reinterpret_cast(&other->seconds_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Duration::GetMetadata() const { diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 7b34a4bf0242..ec648a4d4e87 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -45,7 +44,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fduration_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -66,10 +65,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT Duration : +class PROTOBUF_EXPORT Duration PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ { public: - Duration(); + inline Duration() : Duration(nullptr) {} virtual ~Duration(); Duration(const Duration& from); @@ -83,7 +82,7 @@ class PROTOBUF_EXPORT Duration : return *this; } inline Duration& operator=(Duration&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -91,12 +90,6 @@ class PROTOBUF_EXPORT Duration : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -108,7 +101,6 @@ class PROTOBUF_EXPORT Duration : } static const Duration& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Duration* internal_default_instance() { return reinterpret_cast( &_Duration_default_instance_); @@ -121,7 +113,7 @@ class PROTOBUF_EXPORT Duration : } inline void Swap(Duration* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -129,7 +121,7 @@ class PROTOBUF_EXPORT Duration : } void UnsafeArenaSwap(Duration* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -169,13 +161,6 @@ class PROTOBUF_EXPORT Duration : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -217,7 +202,6 @@ class PROTOBUF_EXPORT Duration : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto index 99cb102c353f..81c3e369fd13 100644 --- a/src/google/protobuf/duration.proto +++ b/src/google/protobuf/duration.proto @@ -34,7 +34,7 @@ package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes"; option cc_enable_arenas = true; -option go_package = "github.com/golang/protobuf/ptypes/duration"; +option go_package = "google.golang.org/protobuf/types/known/durationpb"; option java_package = "com.google.protobuf"; option java_outer_classname = "DurationProto"; option java_multiple_files = true; diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 0ef5dd9a6d12..3a484941d68e 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -62,17 +62,19 @@ // Item 8 of "More Effective C++" discusses this in more detail, though // I don't have the book on me right now so I'm not sure. +#include + #include +#include #include #include -#include - #include #include -#include #include #include +#include +#include #include #include #include @@ -82,12 +84,13 @@ #include #include +#include // NOLINT + namespace google { namespace protobuf { using internal::DynamicMapField; using internal::ExtensionSet; -using internal::InternalMetadataWithArena; using internal::MapField; @@ -100,6 +103,28 @@ namespace { bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); } +// Sync with helpers.h. +inline bool HasHasbit(const FieldDescriptor* field) { + // This predicate includes proto3 message fields only if they have "optional". + // Foo submsg1 = 1; // HasHasbit() == false + // optional Foo submsg2 = 2; // HasHasbit() == true + // This is slightly odd, as adding "optional" to a singular proto3 field does + // not change the semantics or API. However whenever any field in a message + // has a hasbit, it forces reflection to include hasbit offsets for *all* + // fields, even if almost all of them are set to -1 (no hasbit). So to avoid + // causing a sudden size regression for ~all proto3 messages, we give proto3 + // message fields a hasbit only if "optional" is present. If the user is + // explicitly writing "optional", it is likely they are writing it on + // primitive fields also. + return (field->has_optional_keyword() || field->is_required()) && + !field->options().weak(); +} + +inline bool InRealOneof(const FieldDescriptor* field) { + return field->containing_oneof() && + !field->containing_oneof()->is_synthetic(); +} + // Compute the byte size of the in-memory representation of the field. int FieldSpaceUsed(const FieldDescriptor* field) { typedef FieldDescriptor FD; // avoid line wrapping @@ -235,7 +260,6 @@ class DynamicMessage : public Message { int size; int has_bits_offset; int oneof_case_offset; - int internal_metadata_offset; int extensions_offset; // Not owned by the TypeInfo. @@ -268,13 +292,19 @@ class DynamicMessage : public Message { ~DynamicMessage(); // Called on the prototype after construction to initialize message fields. + // Cross linking the default instances allows for fast reflection access of + // unset message fields. Without it we would have to go to the MessageFactory + // to get the prototype, which is a much more expensive operation. + // + // Generated messages do not cross-link to avoid dynamic initialization of the + // global instances. + // Instead, they keep the default instances in the FieldDescriptor objects. void CrossLinkPrototypes(); // implements Message ---------------------------------------------- Message* New() const override; Message* New(Arena* arena) const override; - Arena* GetArena() const override { return arena_; } int GetCachedSize() const override; void SetCachedSize(int size) const override; @@ -295,6 +325,9 @@ class DynamicMessage : public Message { void SharedCtor(bool lock_factory); + // Needed to get the offset of the internal metadata member. + friend class DynamicMessageFactory; + inline bool is_prototype() const { return type_info_->prototype == this || // If type_info_->prototype is NULL, then we must be constructing @@ -310,23 +343,24 @@ class DynamicMessage : public Message { } const TypeInfo* type_info_; - Arena* const arena_; mutable std::atomic cached_byte_size_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage); }; DynamicMessage::DynamicMessage(const TypeInfo* type_info) - : type_info_(type_info), arena_(NULL), cached_byte_size_(0) { + : type_info_(type_info), cached_byte_size_(0) { SharedCtor(true); } DynamicMessage::DynamicMessage(const TypeInfo* type_info, Arena* arena) - : type_info_(type_info), arena_(arena), cached_byte_size_(0) { + : Message(arena), + type_info_(type_info), + cached_byte_size_(0) { SharedCtor(true); } DynamicMessage::DynamicMessage(TypeInfo* type_info, bool lock_factory) - : type_info_(type_info), arena_(NULL), cached_byte_size_(0) { + : type_info_(type_info), cached_byte_size_(0) { // The prototype in type_info has to be set before creating the prototype // instance on memory. e.g., message Foo { map a = 1; }. When // creating prototype for Foo, prototype of the map entry will also be @@ -349,21 +383,21 @@ void DynamicMessage::SharedCtor(bool lock_factory) { const Descriptor* descriptor = type_info_->type; // Initialize oneof cases. + int oneof_count = 0; for (int i = 0; i < descriptor->oneof_decl_count(); ++i) { - new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) - uint32(0); + if (descriptor->oneof_decl(i)->is_synthetic()) continue; + new (OffsetToPointer(type_info_->oneof_case_offset + + sizeof(uint32) * oneof_count++)) uint32(0); } - new (OffsetToPointer(type_info_->internal_metadata_offset)) - InternalMetadataWithArena(arena_); - if (type_info_->extensions_offset != -1) { - new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet(arena_); + new (OffsetToPointer(type_info_->extensions_offset)) + ExtensionSet(GetArena()); } for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - if (field->containing_oneof()) { + if (InRealOneof(field)) { continue; } switch (field->cpp_type()) { @@ -372,7 +406,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { if (!field->is_repeated()) { \ new (field_ptr) TYPE(field->default_value_##TYPE()); \ } else { \ - new (field_ptr) RepeatedField(arena_); \ + new (field_ptr) RepeatedField(GetArena()); \ } \ break; @@ -389,7 +423,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { if (!field->is_repeated()) { new (field_ptr) int(field->default_value_enum()->number()); } else { - new (field_ptr) RepeatedField(arena_); + new (field_ptr) RepeatedField(GetArena()); } break; @@ -398,19 +432,14 @@ void DynamicMessage::SharedCtor(bool lock_factory) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: if (!field->is_repeated()) { - const std::string* default_value; - if (is_prototype()) { - default_value = &field->default_value_string(); - } else { - default_value = &(reinterpret_cast( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])) - ->Get()); - } + const std::string* default_value = + field->default_value_string().empty() + ? &internal::GetEmptyStringAlreadyInited() + : nullptr; ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr(); asp->UnsafeSetDefault(default_value); } else { - new (field_ptr) RepeatedPtrField(arena_); + new (field_ptr) RepeatedPtrField(GetArena()); } break; } @@ -425,20 +454,20 @@ void DynamicMessage::SharedCtor(bool lock_factory) { // when the constructor is called inside GetPrototype(), in which // case we have already locked the factory. if (lock_factory) { - if (arena_ != NULL) { + if (GetArena() != nullptr) { new (field_ptr) DynamicMapField( type_info_->factory->GetPrototype(field->message_type()), - arena_); + GetArena()); } else { new (field_ptr) DynamicMapField( type_info_->factory->GetPrototype(field->message_type())); } } else { - if (arena_ != NULL) { + if (GetArena() != nullptr) { new (field_ptr) DynamicMapField(type_info_->factory->GetPrototypeNoLock( field->message_type()), - arena_); + GetArena()); } else { new (field_ptr) DynamicMapField(type_info_->factory->GetPrototypeNoLock( @@ -446,7 +475,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { } } } else { - new (field_ptr) RepeatedPtrField(arena_); + new (field_ptr) RepeatedPtrField(GetArena()); } } break; @@ -458,9 +487,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { DynamicMessage::~DynamicMessage() { const Descriptor* descriptor = type_info_->type; - reinterpret_cast( - OffsetToPointer(type_info_->internal_metadata_offset)) - ->~InternalMetadataWithArena(); + _internal_metadata_.Delete(); if (type_info_->extensions_offset != -1) { reinterpret_cast( @@ -478,11 +505,11 @@ DynamicMessage::~DynamicMessage() { // be touched. for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); - if (field->containing_oneof()) { + if (InRealOneof(field)) { void* field_ptr = OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * field->containing_oneof()->index()); - if (*(reinterpret_cast(field_ptr)) == field->number()) { + if (*(reinterpret_cast(field_ptr)) == field->number()) { field_ptr = OffsetToPointer( type_info_->offsets[descriptor->field_count() + field->containing_oneof()->index()]); @@ -491,10 +518,10 @@ DynamicMessage::~DynamicMessage() { default: case FieldOptions::STRING: { const std::string* default_value = - &(reinterpret_cast( - reinterpret_cast(type_info_->prototype) + - type_info_->offsets[i]) - ->Get()); + reinterpret_cast( + reinterpret_cast(type_info_->prototype) + + type_info_->offsets[i]) + ->GetPointer(); reinterpret_cast(field_ptr)->Destroy( default_value, NULL); break; @@ -551,10 +578,10 @@ DynamicMessage::~DynamicMessage() { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { const std::string* default_value = - &(reinterpret_cast( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])) - ->Get()); + reinterpret_cast( + type_info_->prototype->OffsetToPointer( + type_info_->offsets[i])) + ->GetPointer(); reinterpret_cast(field_ptr)->Destroy(default_value, NULL); break; @@ -682,9 +709,15 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // this block. // - A big bitfield containing a bit for each field indicating whether // or not that field is set. + int real_oneof_count = 0; + for (int i = 0; i < type->oneof_decl_count(); i++) { + if (!type->oneof_decl(i)->is_synthetic()) { + real_oneof_count++; + } + } // Compute size and offsets. - uint32* offsets = new uint32[type->field_count() + type->oneof_decl_count()]; + uint32* offsets = new uint32[type->field_count() + real_oneof_count]; type_info->offsets.reset(offsets); // Decide all field offsets by packing in order. @@ -694,26 +727,35 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( size = AlignOffset(size); // Next the has_bits, which is an array of uint32s. - if (type->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { - type_info->has_bits_offset = -1; - } else { - type_info->has_bits_offset = size; - int has_bits_array_size = - DivideRoundingUp(type->field_count(), bitsizeof(uint32)); + type_info->has_bits_offset = -1; + int max_hasbit = 0; + for (int i = 0; i < type->field_count(); i++) { + if (HasHasbit(type->field(i))) { + if (type_info->has_bits_offset == -1) { + // At least one field in the message requires a hasbit, so allocate + // hasbits. + type_info->has_bits_offset = size; + uint32* has_bits_indices = new uint32[type->field_count()]; + for (int i = 0; i < type->field_count(); i++) { + // Initialize to -1, fields that need a hasbit will overwrite. + has_bits_indices[i] = static_cast(-1); + } + type_info->has_bits_indices.reset(has_bits_indices); + } + type_info->has_bits_indices[i] = max_hasbit++; + } + } + + if (max_hasbit > 0) { + int has_bits_array_size = DivideRoundingUp(max_hasbit, bitsizeof(uint32)); size += has_bits_array_size * sizeof(uint32); size = AlignOffset(size); - - uint32* has_bits_indices = new uint32[type->field_count()]; - for (int i = 0; i < type->field_count(); i++) { - has_bits_indices[i] = i; - } - type_info->has_bits_indices.reset(has_bits_indices); } // The oneof_case, if any. It is an array of uint32s. - if (type->oneof_decl_count() > 0) { + if (real_oneof_count > 0) { type_info->oneof_case_offset = size; - size += type->oneof_decl_count() * sizeof(uint32); + size += real_oneof_count * sizeof(uint32); size = AlignOffset(size); } @@ -734,7 +776,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( for (int i = 0; i < type->field_count(); i++) { // Make sure field is aligned to avoid bus errors. // Oneof fields do not use any space. - if (!type->field(i)->containing_oneof()) { + if (!InRealOneof(type->field(i))) { int field_size = FieldSpaceUsed(type->field(i)); size = AlignTo(size, std::min(kSafeAlignment, field_size)); offsets[i] = size; @@ -744,16 +786,13 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // The oneofs. for (int i = 0; i < type->oneof_decl_count(); i++) { - size = AlignTo(size, kSafeAlignment); - offsets[type->field_count() + i] = size; - size += kMaxOneofUnionSize; + if (!type->oneof_decl(i)->is_synthetic()) { + size = AlignTo(size, kSafeAlignment); + offsets[type->field_count() + i] = size; + size += kMaxOneofUnionSize; + } } - // Add the InternalMetadataWithArena to the end. - size = AlignOffset(size); - type_info->internal_metadata_offset = size; - size += sizeof(InternalMetadataWithArena); - type_info->weak_field_map_offset = -1; // Align the final size to make sure no clever allocators think that @@ -762,17 +801,16 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // Construct the reflection object. - if (type->oneof_decl_count() > 0) { - // Compute the size of default oneof instance and offsets of default - // oneof fields. - for (int i = 0; i < type->oneof_decl_count(); i++) { - for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = type->oneof_decl(i)->field(j); - int field_size = OneofFieldSpaceUsed(field); - size = AlignTo(size, std::min(kSafeAlignment, field_size)); - offsets[field->index()] = size; - size += field_size; - } + // Compute the size of default oneof instance and offsets of default + // oneof fields. + for (int i = 0; i < type->oneof_decl_count(); i++) { + if (type->oneof_decl(i)->is_synthetic()) continue; + for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = type->oneof_decl(i)->field(j); + int field_size = OneofFieldSpaceUsed(field); + size = AlignTo(size, std::min(kSafeAlignment, field_size)); + offsets[field->index()] = size; + size += field_size; } } size = AlignOffset(size); @@ -784,21 +822,22 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // of dynamic message to avoid dead lock. DynamicMessage* prototype = new (base) DynamicMessage(type_info, false); - if (type->oneof_decl_count() > 0 || num_weak_fields > 0) { + if (real_oneof_count > 0 || num_weak_fields > 0) { // Construct default oneof instance. ConstructDefaultOneofInstance(type_info->type, type_info->offsets.get(), prototype); } - internal::ReflectionSchema schema = {type_info->prototype, - type_info->offsets.get(), - type_info->has_bits_indices.get(), - type_info->has_bits_offset, - type_info->internal_metadata_offset, - type_info->extensions_offset, - type_info->oneof_case_offset, - type_info->size, - type_info->weak_field_map_offset}; + internal::ReflectionSchema schema = { + type_info->prototype, + type_info->offsets.get(), + type_info->has_bits_indices.get(), + type_info->has_bits_offset, + PROTOBUF_FIELD_OFFSET(DynamicMessage, _internal_metadata_), + type_info->extensions_offset, + type_info->oneof_case_offset, + type_info->size, + type_info->weak_field_map_offset}; type_info->reflection.reset( new Reflection(type_info->type, schema, type_info->pool, this)); @@ -813,6 +852,7 @@ void DynamicMessageFactory::ConstructDefaultOneofInstance( const Descriptor* type, const uint32 offsets[], void* default_oneof_or_weak_instance) { for (int i = 0; i < type->oneof_decl_count(); i++) { + if (type->oneof_decl(i)->is_synthetic()) continue; for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = type->oneof_decl(i)->field(j); void* field_ptr = @@ -859,6 +899,7 @@ void DynamicMessageFactory::DeleteDefaultOneofInstance( const Descriptor* type, const uint32 offsets[], const void* default_oneof_instance) { for (int i = 0; i < type->oneof_decl_count(); i++) { + if (type->oneof_decl(i)->is_synthetic()) continue; for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = type->oneof_decl(i)->field(j); if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { @@ -874,3 +915,5 @@ void DynamicMessageFactory::DeleteDefaultOneofInstance( } // namespace protobuf } // namespace google + +#include // NOLINT diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc index 6db6f5cfaaf1..37f9574b0b0b 100644 --- a/src/google/protobuf/dynamic_message_unittest.cc +++ b/src/google/protobuf/dynamic_message_unittest.cc @@ -252,7 +252,7 @@ TEST_P(DynamicMessageTest, Oneof) { } TEST_P(DynamicMessageTest, SpaceUsed) { - // Test that SpaceUsed() works properly + // Test that SpaceUsedLong() works properly // Since we share the implementation with generated messages, we don't need // to test very much here. Just make sure it appears to be working. @@ -261,10 +261,10 @@ TEST_P(DynamicMessageTest, SpaceUsed) { Message* message = prototype_->New(GetParam() ? &arena : NULL); TestUtil::ReflectionTester reflection_tester(descriptor_); - int initial_space_used = message->SpaceUsed(); + size_t initial_space_used = message->SpaceUsedLong(); reflection_tester.SetAllFieldsViaReflection(message); - EXPECT_LT(initial_space_used, message->SpaceUsed()); + EXPECT_LT(initial_space_used, message->SpaceUsedLong()); if (!GetParam()) { delete message; diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index ce7d1a052d58..2c6346d7e6bc 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class EmptyDefaultTypeInternal { public: @@ -28,7 +30,6 @@ static void InitDefaultsscc_info_Empty_google_2fprotobuf_2fempty_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Empty(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Empty::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Empty_google_2fprotobuf_2fempty_2eproto = @@ -55,10 +56,10 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\033google/protobuf/empty.proto\022\017google.pr" - "otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n" - "EmptyProtoP\001Z\'github.com/golang/protobuf" - "/ptypes/empty\370\001\001\242\002\003GPB\252\002\036Google.Protobuf" - ".WellKnownTypesb\006proto3" + "otobuf\"\007\n\005EmptyB}\n\023com.google.protobufB\n" + "EmptyProtoP\001Z.google.golang.org/protobuf" + "/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.P" + "rotobuf.WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fempty_2eproto_deps[1] = { }; @@ -66,42 +67,32 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_Empty_google_2fprotobuf_2fempty_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fempty_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fempty_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto = { - &descriptor_table_google_2fprotobuf_2fempty_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto", 183, + false, false, descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto, "google/protobuf/empty.proto", 190, &descriptor_table_google_2fprotobuf_2fempty_2eproto_once, descriptor_table_google_2fprotobuf_2fempty_2eproto_sccs, descriptor_table_google_2fprotobuf_2fempty_2eproto_deps, 1, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fempty_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fempty_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fempty_2eproto, file_level_service_descriptors_google_2fprotobuf_2fempty_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fempty_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto(&descriptor_table_google_2fprotobuf_2fempty_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Empty::InitAsDefaultInstance() { -} class Empty::_Internal { public: }; -Empty::Empty() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Empty) -} Empty::Empty(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Empty) } Empty::Empty(const Empty& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); // @@protoc_insertion_point(copy_constructor:google.protobuf.Empty) } @@ -111,10 +102,11 @@ void Empty::SharedCtor() { Empty::~Empty() { // @@protoc_insertion_point(destructor:google.protobuf.Empty) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Empty::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void Empty::ArenaDtor(void* object) { @@ -138,12 +130,11 @@ void Empty::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Empty::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -152,7 +143,9 @@ const char* Empty::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } // while @@ -172,7 +165,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Empty::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty) return target; @@ -213,7 +206,7 @@ void Empty::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Empty::MergeFrom(const Empty& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -239,7 +232,7 @@ bool Empty::IsInitialized() const { void Empty::InternalSwap(Empty* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); } ::PROTOBUF_NAMESPACE_ID::Metadata Empty::GetMetadata() const { diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 66312bc1cc5c..73080030f9d8 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -45,7 +44,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fempty_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -66,10 +65,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT Empty : +class PROTOBUF_EXPORT Empty PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { public: - Empty(); + inline Empty() : Empty(nullptr) {} virtual ~Empty(); Empty(const Empty& from); @@ -83,7 +82,7 @@ class PROTOBUF_EXPORT Empty : return *this; } inline Empty& operator=(Empty&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -91,12 +90,6 @@ class PROTOBUF_EXPORT Empty : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -108,7 +101,6 @@ class PROTOBUF_EXPORT Empty : } static const Empty& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Empty* internal_default_instance() { return reinterpret_cast( &_Empty_default_instance_); @@ -121,7 +113,7 @@ class PROTOBUF_EXPORT Empty : } inline void Swap(Empty* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -129,7 +121,7 @@ class PROTOBUF_EXPORT Empty : } void UnsafeArenaSwap(Empty* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -169,13 +161,6 @@ class PROTOBUF_EXPORT Empty : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -195,7 +180,6 @@ class PROTOBUF_EXPORT Empty : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; diff --git a/src/google/protobuf/empty.proto b/src/google/protobuf/empty.proto index 03cacd233088..5f992de94ab4 100644 --- a/src/google/protobuf/empty.proto +++ b/src/google/protobuf/empty.proto @@ -33,7 +33,7 @@ syntax = "proto3"; package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option go_package = "github.com/golang/protobuf/ptypes/empty"; +option go_package = "google.golang.org/protobuf/types/known/emptypb"; option java_package = "com.google.protobuf"; option java_outer_classname = "EmptyProto"; option java_multiple_files = true; diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index b4eb6e186cd1..08848c8e8313 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -180,7 +180,6 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type, Register(containing_type, number, info); } - // =================================================================== // Constructors and basic methods. @@ -192,14 +191,6 @@ ExtensionSet::ExtensionSet(Arena* arena) ? NULL : Arena::CreateArray(arena_, flat_capacity_)} {} -ExtensionSet::ExtensionSet() - : arena_(NULL), - flat_capacity_(0), - flat_size_(0), - map_{flat_capacity_ == 0 - ? NULL - : Arena::CreateArray(arena_, flat_capacity_)} {} - ExtensionSet::~ExtensionSet() { // Deletes all allocated extensions. if (arena_ == NULL) { @@ -1063,7 +1054,7 @@ void ExtensionSet::InternalExtensionMergeFrom( } void ExtensionSet::Swap(ExtensionSet* x) { - if (GetArenaNoVirtual() == x->GetArenaNoVirtual()) { + if (GetArena() == x->GetArena()) { using std::swap; swap(flat_capacity_, x->flat_capacity_); swap(flat_size_, x->flat_size_); @@ -1091,7 +1082,7 @@ void ExtensionSet::SwapExtension(ExtensionSet* other, int number) { } if (this_ext != NULL && other_ext != NULL) { - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { using std::swap; swap(*this_ext, *other_ext); } else { @@ -1112,7 +1103,7 @@ void ExtensionSet::SwapExtension(ExtensionSet* other, int number) { } if (this_ext == NULL) { - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { *Insert(number).first = *other_ext; } else { InternalExtensionMergeFrom(number, *other_ext); @@ -1122,7 +1113,7 @@ void ExtensionSet::SwapExtension(ExtensionSet* other, int number) { } if (other_ext == NULL) { - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { *other->Insert(number).first = *this_ext; } else { other->InternalExtensionMergeFrom(number, *this_ext); @@ -1196,27 +1187,28 @@ bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, } } -const char* ExtensionSet::ParseField( - uint64 tag, const char* ptr, const MessageLite* containing_type, - internal::InternalMetadataWithArenaLite* metadata, - internal::ParseContext* ctx) { +const char* ExtensionSet::ParseField(uint64 tag, const char* ptr, + const MessageLite* containing_type, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { GeneratedExtensionFinder finder(containing_type); int number = tag >> 3; bool was_packed_on_wire; ExtensionInfo extension; if (!FindExtensionInfoFromFieldNumber(tag & 7, number, &finder, &extension, &was_packed_on_wire)) { - return UnknownFieldParse(tag, metadata->mutable_unknown_fields(), ptr, ctx); + return UnknownFieldParse( + tag, metadata->mutable_unknown_fields(), ptr, ctx); } - return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension, - metadata, ptr, ctx); + return ParseFieldWithExtensionInfo( + number, was_packed_on_wire, extension, metadata, ptr, ctx); } const char* ExtensionSet::ParseMessageSetItem( const char* ptr, const MessageLite* containing_type, - internal::InternalMetadataWithArenaLite* metadata, - internal::ParseContext* ctx) { - return ParseMessageSetItemTmpl(ptr, containing_type, metadata, ctx); + internal::InternalMetadata* metadata, internal::ParseContext* ctx) { + return ParseMessageSetItemTmpl(ptr, containing_type, + metadata, ctx); } bool ExtensionSet::ParseFieldWithExtensionInfo(int number, @@ -1869,28 +1861,32 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) { return; } - const auto old_flat_capacity = flat_capacity_; - + auto new_flat_capacity = flat_capacity_; do { - flat_capacity_ = flat_capacity_ == 0 ? 1 : flat_capacity_ * 4; - } while (flat_capacity_ < minimum_new_capacity); + new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 4; + } while (new_flat_capacity < minimum_new_capacity); const KeyValue* begin = flat_begin(); const KeyValue* end = flat_end(); - if (flat_capacity_ > kMaximumFlatCapacity) { - // Switch to LargeMap - map_.large = Arena::Create(arena_); - LargeMap::iterator hint = map_.large->begin(); + AllocatedData new_map; + if (new_flat_capacity > kMaximumFlatCapacity) { + new_map.large = Arena::Create(arena_); + LargeMap::iterator hint = new_map.large->begin(); for (const KeyValue* it = begin; it != end; ++it) { - hint = map_.large->insert(hint, {it->first, it->second}); + hint = new_map.large->insert(hint, {it->first, it->second}); } - flat_size_ = 0; } else { - map_.flat = Arena::CreateArray(arena_, flat_capacity_); - std::copy(begin, end, map_.flat); + new_map.flat = Arena::CreateArray(arena_, new_flat_capacity); + std::copy(begin, end, new_map.flat); } + if (arena_ == nullptr) { - DeleteFlatMap(begin, old_flat_capacity); + DeleteFlatMap(begin, flat_capacity_); + } + flat_capacity_ = new_flat_capacity; + map_ = new_map; + if (is_large()) { + flat_size_ = 0; } } @@ -2144,3 +2140,5 @@ size_t ExtensionSet::MessageSetByteSize() const { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index 4dbf5abb8a0e..a74d2a96a6df 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -79,8 +79,7 @@ namespace google { namespace protobuf { namespace internal { -class InternalMetadataWithArenaLite; -class InternalMetadataWithArena; +class InternalMetadata; // Used to store values of type WireFormatLite::FieldType without having to // #include wire_format_lite.h. Also, ensures that we use only one byte to @@ -174,7 +173,7 @@ class MessageSetFieldSkipper; // off to the ExtensionSet for parsing. Etc. class PROTOBUF_EXPORT ExtensionSet { public: - ExtensionSet(); + constexpr ExtensionSet(); explicit ExtensionSet(Arena* arena); ~ExtensionSet(); @@ -292,7 +291,7 @@ class PROTOBUF_EXPORT ExtensionSet { MessageLite* UnsafeArenaReleaseMessage(const FieldDescriptor* descriptor, MessageFactory* factory); #undef desc - Arena* GetArenaNoVirtual() const { return arena_; } + Arena* GetArena() const { return arena_; } // repeated fields ------------------------------------------------- @@ -397,23 +396,24 @@ class PROTOBUF_EXPORT ExtensionSet { // Lite parser const char* ParseField(uint64 tag, const char* ptr, const MessageLite* containing_type, - internal::InternalMetadataWithArenaLite* metadata, + internal::InternalMetadata* metadata, internal::ParseContext* ctx); // Full parser const char* ParseField(uint64 tag, const char* ptr, const Message* containing_type, - internal::InternalMetadataWithArena* metadata, + internal::InternalMetadata* metadata, internal::ParseContext* ctx); - template + template const char* ParseMessageSet(const char* ptr, const Msg* containing_type, - Metadata* metadata, internal::ParseContext* ctx) { + InternalMetadata* metadata, + internal::ParseContext* ctx) { struct MessageSetItem { const char* _InternalParse(const char* ptr, ParseContext* ctx) { return me->ParseMessageSetItem(ptr, containing_type, metadata, ctx); } ExtensionSet* me; const Msg* containing_type; - Metadata* metadata; + InternalMetadata* metadata; } item{this, containing_type, metadata}; while (!ctx->Done(&ptr)) { uint32 tag; @@ -770,36 +770,37 @@ class PROTOBUF_EXPORT ExtensionSet { const internal::ParseContext* ctx, ExtensionInfo* extension, bool* was_packed_on_wire); // Used for MessageSet only - const char* ParseFieldMaybeLazily( - uint64 tag, const char* ptr, const MessageLite* containing_type, - internal::InternalMetadataWithArenaLite* metadata, - internal::ParseContext* ctx) { + const char* ParseFieldMaybeLazily(uint64 tag, const char* ptr, + const MessageLite* containing_type, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { // Lite MessageSet doesn't implement lazy. return ParseField(tag, ptr, containing_type, metadata, ctx); } - const char* ParseFieldMaybeLazily( - uint64 tag, const char* ptr, const Message* containing_type, - internal::InternalMetadataWithArena* metadata, - internal::ParseContext* ctx); - const char* ParseMessageSetItem( - const char* ptr, const MessageLite* containing_type, - internal::InternalMetadataWithArenaLite* metadata, - internal::ParseContext* ctx); + const char* ParseFieldMaybeLazily(uint64 tag, const char* ptr, + const Message* containing_type, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); + const char* ParseMessageSetItem(const char* ptr, + const MessageLite* containing_type, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx); const char* ParseMessageSetItem(const char* ptr, const Message* containing_type, - internal::InternalMetadataWithArena* metadata, + internal::InternalMetadata* metadata, internal::ParseContext* ctx); // Implemented in extension_set_inl.h to keep code out of the header file. template const char* ParseFieldWithExtensionInfo(int number, bool was_packed_on_wire, const ExtensionInfo& info, - T* metadata, const char* ptr, + internal::InternalMetadata* metadata, + const char* ptr, internal::ParseContext* ctx); - template + template const char* ParseMessageSetItemTmpl(const char* ptr, const Msg* containing_type, - Metadata* metadata, + internal::InternalMetadata* metadata, internal::ParseContext* ctx); // Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This @@ -849,6 +850,9 @@ class PROTOBUF_EXPORT ExtensionSet { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet); }; +constexpr ExtensionSet::ExtensionSet() + : arena_(nullptr), flat_capacity_(0), flat_size_(0), map_{nullptr} {} + // These are just for convenience... inline void ExtensionSet::SetString(int number, FieldType type, std::string value, @@ -1324,7 +1328,9 @@ RepeatedMessageTypeTraits::GetDefaultRepeatedField() { // ExtensionIdentifier // This is the type of actual extension objects. E.g. if you have: -// extends Foo with optional int32 bar = 1234; +// extend Foo { +// optional int32 bar = 1234; +// } // then "bar" will be defined in C++ as: // ExtensionIdentifier, 5, false> bar(1234); // diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 9b7ee4d0a43c..76ac0766f6d4 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -340,33 +340,33 @@ bool ExtensionSet::FindExtension(int wire_type, uint32 field, return true; } -const char* ExtensionSet::ParseField( - uint64 tag, const char* ptr, const Message* containing_type, - internal::InternalMetadataWithArena* metadata, - internal::ParseContext* ctx) { +const char* ExtensionSet::ParseField(uint64 tag, const char* ptr, + const Message* containing_type, + internal::InternalMetadata* metadata, + internal::ParseContext* ctx) { int number = tag >> 3; bool was_packed_on_wire; ExtensionInfo extension; if (!FindExtension(tag & 7, number, containing_type, ctx, &extension, &was_packed_on_wire)) { - return UnknownFieldParse(tag, metadata->mutable_unknown_fields(), ptr, ctx); + return UnknownFieldParse( + tag, metadata->mutable_unknown_fields(), ptr, ctx); } - return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension, - metadata, ptr, ctx); + return ParseFieldWithExtensionInfo( + number, was_packed_on_wire, extension, metadata, ptr, ctx); } const char* ExtensionSet::ParseFieldMaybeLazily( uint64 tag, const char* ptr, const Message* containing_type, - internal::InternalMetadataWithArena* metadata, - internal::ParseContext* ctx) { + internal::InternalMetadata* metadata, internal::ParseContext* ctx) { return ParseField(tag, ptr, containing_type, metadata, ctx); } const char* ExtensionSet::ParseMessageSetItem( const char* ptr, const Message* containing_type, - internal::InternalMetadataWithArena* metadata, - internal::ParseContext* ctx) { - return ParseMessageSetItemTmpl(ptr, containing_type, metadata, ctx); + internal::InternalMetadata* metadata, internal::ParseContext* ctx) { + return ParseMessageSetItemTmpl(ptr, containing_type, + metadata, ctx); } bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input, @@ -534,3 +534,5 @@ bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/extension_set_inl.h b/src/google/protobuf/extension_set_inl.h index 087a3a442c82..074784b96d50 100644 --- a/src/google/protobuf/extension_set_inl.h +++ b/src/google/protobuf/extension_set_inl.h @@ -33,6 +33,7 @@ #include #include +#include namespace google { namespace protobuf { @@ -41,7 +42,7 @@ namespace internal { template const char* ExtensionSet::ParseFieldWithExtensionInfo( int number, bool was_packed_on_wire, const ExtensionInfo& extension, - T* metadata, const char* ptr, internal::ParseContext* ctx) { + InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx) { if (was_packed_on_wire) { switch (extension.type) { #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE) \ @@ -66,7 +67,7 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo( #undef HANDLE_TYPE case WireFormatLite::TYPE_ENUM: - return internal::PackedEnumParserArg( + return internal::PackedEnumParserArg( MutableRawRepeatedField(number, extension.type, extension.is_packed, extension.descriptor), ptr, ctx, extension.enum_validity_check.func, @@ -98,6 +99,7 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo( HANDLE_VARINT_TYPE(INT64, Int64); HANDLE_VARINT_TYPE(UINT32, UInt32); HANDLE_VARINT_TYPE(UINT64, UInt64); + HANDLE_VARINT_TYPE(BOOL, Bool); #undef HANDLE_VARINT_TYPE #define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE) \ case WireFormatLite::TYPE_##UPPERCASE: { \ @@ -136,7 +138,6 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo( HANDLE_FIXED_TYPE(SFIXED64, Int64, int64); HANDLE_FIXED_TYPE(FLOAT, Float, float); HANDLE_FIXED_TYPE(DOUBLE, Double, double); - HANDLE_FIXED_TYPE(BOOL, Bool, bool); #undef HANDLE_FIXED_TYPE case WireFormatLite::TYPE_ENUM: { @@ -147,7 +148,7 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo( if (!extension.enum_validity_check.func( extension.enum_validity_check.arg, value)) { - WriteVarint(number, val, metadata->mutable_unknown_fields()); + WriteVarint(number, val, metadata->mutable_unknown_fields()); } else if (extension.is_repeated) { AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value, extension.descriptor); @@ -200,13 +201,13 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo( return ptr; } -template -const char* ExtensionSet::ParseMessageSetItemTmpl(const char* ptr, - const Msg* containing_type, - Metadata* metadata, - internal::ParseContext* ctx) { +template +const char* ExtensionSet::ParseMessageSetItemTmpl( + const char* ptr, const Msg* containing_type, + internal::InternalMetadata* metadata, internal::ParseContext* ctx) { std::string payload; uint32 type_id = 0; + bool payload_read = false; while (!ctx->Done(&ptr)) { uint32 tag = static_cast(*ptr++); if (tag == WireFormatLite::kMessageSetTypeIdTag) { @@ -214,13 +215,13 @@ const char* ExtensionSet::ParseMessageSetItemTmpl(const char* ptr, ptr = ParseBigVarint(ptr, &tmp); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); type_id = tmp; - if (!payload.empty()) { + if (payload_read) { ExtensionInfo extension; bool was_packed_on_wire; if (!FindExtension(2, type_id, containing_type, ctx, &extension, &was_packed_on_wire)) { WriteLengthDelimited(type_id, payload, - metadata->mutable_unknown_fields()); + metadata->mutable_unknown_fields()); } else { MessageLite* value = extension.is_repeated @@ -253,6 +254,7 @@ const char* ExtensionSet::ParseMessageSetItemTmpl(const char* ptr, GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); ptr = ctx->ReadString(ptr, size, &payload); GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + payload_read = true; } } else { ptr = ReadTag(ptr - 1, &tag); diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index c08782b589d7..6a6fc25b3cd5 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -46,13 +46,15 @@ #include #include #include - #include #include #include #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -514,7 +516,7 @@ TEST(ExtensionSetTest, SerializationToArray) { unittest::TestAllExtensions source; unittest::TestAllTypes destination; TestUtil::SetAllExtensions(&source); - int size = source.ByteSize(); + size_t size = source.ByteSizeLong(); std::string data; data.resize(size); uint8* target = reinterpret_cast(::google::protobuf::string_as_array(&data)); @@ -535,7 +537,7 @@ TEST(ExtensionSetTest, SerializationToStream) { unittest::TestAllExtensions source; unittest::TestAllTypes destination; TestUtil::SetAllExtensions(&source); - int size = source.ByteSize(); + size_t size = source.ByteSizeLong(); std::string data; data.resize(size); { @@ -558,7 +560,7 @@ TEST(ExtensionSetTest, PackedSerializationToArray) { unittest::TestPackedExtensions source; unittest::TestPackedTypes destination; TestUtil::SetPackedExtensions(&source); - int size = source.ByteSize(); + size_t size = source.ByteSizeLong(); std::string data; data.resize(size); uint8* target = reinterpret_cast(::google::protobuf::string_as_array(&data)); @@ -579,7 +581,7 @@ TEST(ExtensionSetTest, PackedSerializationToStream) { unittest::TestPackedExtensions source; unittest::TestPackedTypes destination; TestUtil::SetPackedExtensions(&source); - int size = source.ByteSize(); + size_t size = source.ByteSizeLong(); std::string data; data.resize(size); { @@ -739,12 +741,12 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { #define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \ do { \ unittest::TestAllExtensions message; \ - const int base_size = message.SpaceUsed(); \ + const int base_size = message.SpaceUsedLong(); \ message.SetExtension(unittest::optional_##type##_extension, value); \ int min_expected_size = \ base_size + \ sizeof(message.GetExtension(unittest::optional_##type##_extension)); \ - EXPECT_LE(min_expected_size, message.SpaceUsed()); \ + EXPECT_LE(min_expected_size, message.SpaceUsedLong()); \ } while (0) TEST_SCALAR_EXTENSIONS_SPACE_USED(int32, 101); @@ -763,36 +765,36 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { #undef TEST_SCALAR_EXTENSIONS_SPACE_USED { unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); + const int base_size = message.SpaceUsedLong(); message.SetExtension(unittest::optional_nested_enum_extension, unittest::TestAllTypes::FOO); int min_expected_size = base_size + sizeof(message.GetExtension(unittest::optional_nested_enum_extension)); - EXPECT_LE(min_expected_size, message.SpaceUsed()); + EXPECT_LE(min_expected_size, message.SpaceUsedLong()); } { // Strings may cause extra allocations depending on their length; ensure // that gets included as well. unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); + const int base_size = message.SpaceUsedLong(); const std::string s( "this is a fairly large string that will cause some " "allocation in order to store it in the extension"); message.SetExtension(unittest::optional_string_extension, s); int min_expected_size = base_size + s.length(); - EXPECT_LE(min_expected_size, message.SpaceUsed()); + EXPECT_LE(min_expected_size, message.SpaceUsedLong()); } { // Messages also have additional allocation that need to be counted. unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); + const int base_size = message.SpaceUsedLong(); unittest::ForeignMessage foreign; foreign.set_c(42); message.MutableExtension(unittest::optional_foreign_message_extension) ->CopyFrom(foreign); - int min_expected_size = base_size + foreign.SpaceUsed(); - EXPECT_LE(min_expected_size, message.SpaceUsed()); + int min_expected_size = base_size + foreign.SpaceUsedLong(); + EXPECT_LE(min_expected_size, message.SpaceUsedLong()); } // Repeated primitive extensions will increase space used by at least a @@ -802,26 +804,26 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { // - Adds a value to the repeated extension, then clears it, establishing // the base size. // - Adds a small number of values, testing that it doesn't increase the - // SpaceUsed() + // SpaceUsedLong() // - Adds a large number of values (requiring allocation in the repeated - // field), and ensures that that allocation is included in SpaceUsed() + // field), and ensures that that allocation is included in SpaceUsedLong() #define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \ do { \ unittest::TestAllExtensions message; \ - const int base_size = message.SpaceUsed(); \ - int min_expected_size = sizeof(RepeatedField) + base_size; \ + const size_t base_size = message.SpaceUsedLong(); \ + size_t min_expected_size = sizeof(RepeatedField) + base_size; \ message.AddExtension(unittest::repeated_##type##_extension, value); \ message.ClearExtension(unittest::repeated_##type##_extension); \ - const int empty_repeated_field_size = message.SpaceUsed(); \ + const size_t empty_repeated_field_size = message.SpaceUsedLong(); \ EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \ message.AddExtension(unittest::repeated_##type##_extension, value); \ message.AddExtension(unittest::repeated_##type##_extension, value); \ - EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type; \ + EXPECT_EQ(empty_repeated_field_size, message.SpaceUsedLong()) << #type; \ message.ClearExtension(unittest::repeated_##type##_extension); \ - const int old_capacity = \ + const size_t old_capacity = \ message.GetRepeatedExtension(unittest::repeated_##type##_extension) \ .Capacity(); \ - EXPECT_GE(old_capacity, kMinRepeatedFieldAllocationSize); \ + EXPECT_GE(old_capacity, kRepeatedFieldLowerClampLimit); \ for (int i = 0; i < 16; ++i) { \ message.AddExtension(unittest::repeated_##type##_extension, value); \ } \ @@ -832,7 +834,7 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { .Capacity() - \ old_capacity) + \ empty_repeated_field_size; \ - EXPECT_LE(expected_size, message.SpaceUsed()) << #type; \ + EXPECT_LE(expected_size, message.SpaceUsedLong()) << #type; \ } while (0) TEST_REPEATED_EXTENSIONS_SPACE_USED(int32, int32, 101); @@ -854,8 +856,9 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { // Repeated strings { unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); - int min_expected_size = sizeof(RepeatedPtrField) + base_size; + const size_t base_size = message.SpaceUsedLong(); + size_t min_expected_size = + sizeof(RepeatedPtrField) + base_size; const std::string value(256, 'x'); // Once items are allocated, they may stick around even when cleared so // without the hardcore memory management accessors there isn't a notion of @@ -864,14 +867,14 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { message.AddExtension(unittest::repeated_string_extension, value); } min_expected_size += - (sizeof(value) + value.size()) * (16 - kMinRepeatedFieldAllocationSize); - EXPECT_LE(min_expected_size, message.SpaceUsed()); + (sizeof(value) + value.size()) * (16 - kRepeatedFieldLowerClampLimit); + EXPECT_LE(min_expected_size, message.SpaceUsedLong()); } // Repeated messages { unittest::TestAllExtensions message; - const int base_size = message.SpaceUsed(); - int min_expected_size = + const size_t base_size = message.SpaceUsedLong(); + size_t min_expected_size = sizeof(RepeatedPtrField) + base_size; unittest::ForeignMessage prototype; prototype.set_c(2); @@ -880,8 +883,8 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { ->CopyFrom(prototype); } min_expected_size += - (16 - kMinRepeatedFieldAllocationSize) * prototype.SpaceUsed(); - EXPECT_LE(min_expected_size, message.SpaceUsed()); + (16 - kRepeatedFieldLowerClampLimit) * prototype.SpaceUsedLong(); + EXPECT_LE(min_expected_size, message.SpaceUsedLong()); } } @@ -1104,8 +1107,6 @@ TEST(ExtensionSetTest, RepeatedFields) { ASSERT_EQ(msg_const_iter->bb(), 1234); } - // Test range-based for as well, but only if compiled as C++11. -#if __cplusplus >= 201103L // Test one primitive field. for (auto& x : *message.MutableRepeatedExtension(unittest::repeated_int32_extension)) { @@ -1133,7 +1134,6 @@ TEST(ExtensionSetTest, RepeatedFields) { unittest::repeated_nested_message_extension)) { ASSERT_EQ(x.bb(), 4321); } -#endif } // From b/12926163 @@ -1319,7 +1319,21 @@ TEST(ExtensionSetTest, DynamicExtensions) { } } +TEST(ExtensionSetTest, BoolExtension) { + unittest::TestAllExtensions msg; + uint8 wire_bytes[2] = {13 * 8, 42 /* out of bounds payload for bool */}; + EXPECT_TRUE(msg.ParseFromArray(wire_bytes, 2)); + EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension)); +} + +TEST(ExtensionSetTest, ConstInit) { + PROTOBUF_CONSTINIT static ExtensionSet set{}; + EXPECT_EQ(set.NumExtensions(), 0); +} + } // namespace } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index dff19872adcf..a3822eaca707 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class FieldMaskDefaultTypeInternal { public: @@ -28,7 +30,6 @@ static void InitDefaultsscc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2epr new (ptr) PROTOBUF_NAMESPACE_ID::FieldMask(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FieldMask::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto = @@ -57,10 +58,10 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n google/protobuf/field_mask.proto\022\017goog" "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB" - "\214\001\n\023com.google.protobufB\016FieldMaskProtoP" - "\001Z9google.golang.org/genproto/protobuf/f" - "ield_mask;field_mask\370\001\001\242\002\003GPB\252\002\036Google.P" - "rotobuf.WellKnownTypesb\006proto3" + "\205\001\n\023com.google.protobufB\016FieldMaskProtoP" + "\001Z2google.golang.org/protobuf/types/know" + "n/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf" + ".WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_deps[1] = { }; @@ -68,34 +69,25 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_FieldMask_google_2fprotobuf_2ffield_5fmask_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto = { - &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto", 230, + false, false, descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto, "google/protobuf/field_mask.proto", 223, &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once, descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_sccs, descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_deps, 1, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto::offsets, file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, file_level_service_descriptors_google_2fprotobuf_2ffield_5fmask_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void FieldMask::InitAsDefaultInstance() { -} class FieldMask::_Internal { public: }; -FieldMask::FieldMask() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.FieldMask) -} FieldMask::FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), paths_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -103,9 +95,8 @@ FieldMask::FieldMask(::PROTOBUF_NAMESPACE_ID::Arena* arena) } FieldMask::FieldMask(const FieldMask& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), paths_(from.paths_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask) } @@ -116,10 +107,11 @@ void FieldMask::SharedCtor() { FieldMask::~FieldMask() { // @@protoc_insertion_point(destructor:google.protobuf.FieldMask) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void FieldMask::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void FieldMask::ArenaDtor(void* object) { @@ -144,12 +136,11 @@ void FieldMask::Clear() { (void) cached_has_bits; paths_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* FieldMask::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -175,7 +166,9 @@ const char* FieldMask::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID:: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -207,7 +200,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FieldMask::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldMask) return target; @@ -256,7 +249,7 @@ void FieldMask::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void FieldMask::MergeFrom(const FieldMask& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -283,7 +276,7 @@ bool FieldMask::IsInitialized() const { void FieldMask::InternalSwap(FieldMask* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); paths_.InternalSwap(&other->paths_); } diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index f3f83194d858..0fa822f722cc 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -45,7 +44,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ffield_5fmask_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -66,10 +65,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT FieldMask : +class PROTOBUF_EXPORT FieldMask PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ { public: - FieldMask(); + inline FieldMask() : FieldMask(nullptr) {} virtual ~FieldMask(); FieldMask(const FieldMask& from); @@ -83,7 +82,7 @@ class PROTOBUF_EXPORT FieldMask : return *this; } inline FieldMask& operator=(FieldMask&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -91,12 +90,6 @@ class PROTOBUF_EXPORT FieldMask : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -108,7 +101,6 @@ class PROTOBUF_EXPORT FieldMask : } static const FieldMask& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FieldMask* internal_default_instance() { return reinterpret_cast( &_FieldMask_default_instance_); @@ -121,7 +113,7 @@ class PROTOBUF_EXPORT FieldMask : } inline void Swap(FieldMask* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -129,7 +121,7 @@ class PROTOBUF_EXPORT FieldMask : } void UnsafeArenaSwap(FieldMask* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -169,13 +161,6 @@ class PROTOBUF_EXPORT FieldMask : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -222,7 +207,6 @@ class PROTOBUF_EXPORT FieldMask : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto index baac8744cb2a..6b5104f188aa 100644 --- a/src/google/protobuf/field_mask.proto +++ b/src/google/protobuf/field_mask.proto @@ -37,7 +37,7 @@ option java_package = "com.google.protobuf"; option java_outer_classname = "FieldMaskProto"; option java_multiple_files = true; option objc_class_prefix = "GPB"; -option go_package = "google.golang.org/genproto/protobuf/field_mask;field_mask"; +option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb"; option cc_enable_arenas = true; // `FieldMask` represents a set of symbolic field paths, for example: diff --git a/src/google/protobuf/generated_enum_reflection.h b/src/google/protobuf/generated_enum_reflection.h index c25e51bc12ae..5debc0a2564e 100644 --- a/src/google/protobuf/generated_enum_reflection.h +++ b/src/google/protobuf/generated_enum_reflection.h @@ -43,6 +43,7 @@ #include #include +#include #ifdef SWIG #error "You cannot SWIG proto headers" @@ -71,10 +72,10 @@ namespace internal { // an enum name of the given type, returning true and filling in value on // success, or returning false and leaving value unchanged on failure. PROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor, - const std::string& name, int* value); + ConstStringParam name, int* value); template -bool ParseNamedEnum(const EnumDescriptor* descriptor, const std::string& name, +bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name, EnumType* value) { int tmp; if (!ParseNamedEnum(descriptor, name, &tmp)) return false; diff --git a/src/google/protobuf/generated_enum_util.cc b/src/google/protobuf/generated_enum_util.cc old mode 100755 new mode 100644 index d0c25a96d963..df7583e99984 --- a/src/google/protobuf/generated_enum_util.cc +++ b/src/google/protobuf/generated_enum_util.cc @@ -83,7 +83,7 @@ int LookUpEnumName(const EnumEntry* enums, const int* sorted_indices, bool InitializeEnumStrings( const EnumEntry* enums, const int* sorted_indices, size_t size, internal::ExplicitlyConstructed* enum_strings) { - for (int i = 0; i < size; ++i) { + for (size_t i = 0; i < size; ++i) { enum_strings[i].Construct(enums[sorted_indices[i]].name); internal::OnShutdownDestroyString(enum_strings[i].get_mutable()); } diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index f44cde2c4a01..b81f58339736 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -32,6 +32,8 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include @@ -40,14 +42,14 @@ #include #include #include -#include #include -#include #include #include #include #include +#include #include +#include #include @@ -59,8 +61,7 @@ using google::protobuf::internal::DescriptorTable; using google::protobuf::internal::ExtensionSet; using google::protobuf::internal::GenericTypeHandler; using google::protobuf::internal::GetEmptyString; -using google::protobuf::internal::InlinedStringField; -using google::protobuf::internal::InternalMetadataWithArena; +using google::protobuf::internal::InternalMetadata; using google::protobuf::internal::LazyField; using google::protobuf::internal::MapFieldBase; using google::protobuf::internal::MigrationSchema; @@ -79,7 +80,7 @@ bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); } namespace internal { -bool ParseNamedEnum(const EnumDescriptor* descriptor, const std::string& name, +bool ParseNamedEnum(const EnumDescriptor* descriptor, ConstStringParam name, int* value) { const EnumValueDescriptor* d = descriptor->FindValueByName(name); if (d == nullptr) return false; @@ -100,21 +101,9 @@ const std::string& NameOfEnum(const EnumDescriptor* descriptor, int value) { namespace { -template -To* GetPointerAtOffset(Message* message, uint32 offset) { - return reinterpret_cast(reinterpret_cast(message) + offset); -} - -template -const To* GetConstPointerAtOffset(const Message* message, uint32 offset) { - return reinterpret_cast(reinterpret_cast(message) + - offset); -} - -template -const To& GetConstRefAtOffset(const Message& message, uint32 offset) { - return *GetConstPointerAtOffset(&message, offset); -} +using internal::GetConstPointerAtOffset; +using internal::GetConstRefAtOffset; +using internal::GetPointerAtOffset; void ReportReflectionUsageError(const Descriptor* descriptor, const FieldDescriptor* field, @@ -181,6 +170,12 @@ static void ReportReflectionUsageEnumTypeError( << value->full_name(); } +inline void CheckInvalidAccess(const internal::ReflectionSchema& schema, + const FieldDescriptor* field) { + GOOGLE_CHECK(!schema.IsFieldStripped(field)) + << "invalid access to a stripped field " << field->full_name(); +} + #define USAGE_CHECK(CONDITION, METHOD, ERROR_DESCRIPTION) \ if (!(CONDITION)) \ ReportReflectionUsageError(descriptor_, field, #METHOD, ERROR_DESCRIPTION) @@ -231,11 +226,13 @@ Reflection::Reflection(const Descriptor* descriptor, const UnknownFieldSet& Reflection::GetUnknownFields( const Message& message) const { - return GetInternalMetadataWithArena(message).unknown_fields(); + return GetInternalMetadata(message).unknown_fields( + UnknownFieldSet::default_instance); } UnknownFieldSet* Reflection::MutableUnknownFields(Message* message) const { - return MutableInternalMetadataWithArena(message)->mutable_unknown_fields(); + return MutableInternalMetadata(message) + ->mutable_unknown_fields(); } size_t Reflection::SpaceUsedLong(const Message& message) const { @@ -295,7 +292,7 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { break; } } else { - if (field->containing_oneof() && !HasOneofField(message, field)) { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { continue; } switch (field->cpp_type()) { @@ -314,22 +311,16 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - const std::string* ptr = - &GetField(message, field).GetNoArena(); - total_size += StringSpaceUsedExcludingSelfLong(*ptr); - break; - } + const std::string* ptr = + GetField(message, field).GetPointer(); // Initially, the string points to the default value stored // in the prototype. Only count the string if it has been // changed from the default value. - const std::string* default_ptr = - &DefaultRaw(field).Get(); - const std::string* ptr = - &GetField(message, field).Get(); - - if (ptr != default_ptr) { + // Except oneof fields, those never point to a default instance, + // and there is no default instance to point to. + if (schema_.InRealOneof(field) || + ptr != DefaultRaw(field).GetPointer()) { // string fields are represented by just a pointer, so also // include sizeof(string) as well. total_size += @@ -450,27 +441,27 @@ void Reflection::SwapField(Message* message1, Message* message2, Arena* arena1 = GetArena(message1); Arena* arena2 = GetArena(message2); - if (IsInlined(field)) { - InlinedStringField* string1 = - MutableRaw(message1, field); - InlinedStringField* string2 = - MutableRaw(message2, field); - string1->Swap(string2); - break; - } - ArenaStringPtr* string1 = MutableRaw(message1, field); ArenaStringPtr* string2 = MutableRaw(message2, field); const std::string* default_ptr = - &DefaultRaw(field).Get(); + DefaultRaw(field).GetPointer(); if (arena1 == arena2) { string1->Swap(string2, default_ptr, arena1); + } else if (string1->IsDefault(default_ptr) && + string2->IsDefault(default_ptr)) { + // Nothing to do. + } else if (string1->IsDefault(default_ptr)) { + string1->Set(default_ptr, string2->Get(), arena1); + string2->UnsafeSetDefault(default_ptr); + } else if (string2->IsDefault(default_ptr)) { + string2->Set(default_ptr, string1->Get(), arena2); + string1->UnsafeSetDefault(default_ptr); } else { - const std::string temp = string1->Get(); + std::string temp = string1->Get(); string1->Set(default_ptr, string2->Get(), arena1); - string2->Set(default_ptr, temp, arena2); + string2->Set(default_ptr, std::move(temp), arena2); } } break; } @@ -484,6 +475,7 @@ void Reflection::SwapField(Message* message1, Message* message2, void Reflection::SwapOneofField(Message* message1, Message* message2, const OneofDescriptor* oneof_descriptor) const { + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor); uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor); @@ -640,7 +632,7 @@ void Reflection::Swap(Message* message1, Message* message2) const { int fields_with_has_bits = 0; for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->is_repeated() || field->containing_oneof()) { + if (field->is_repeated() || schema_.InRealOneof(field)) { continue; } fields_with_has_bits++; @@ -655,12 +647,16 @@ void Reflection::Swap(Message* message1, Message* message2) const { for (int i = 0; i <= last_non_weak_field_index_; i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->containing_oneof()) continue; + if (schema_.InRealOneof(field)) continue; + if (schema_.IsFieldStripped(field)) continue; SwapField(message1, message2, field); } const int oneof_decl_count = descriptor_->oneof_decl_count(); for (int i = 0; i < oneof_decl_count; i++) { - SwapOneofField(message1, message2, descriptor_->oneof_decl(i)); + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + if (!oneof->is_synthetic()) { + SwapOneofField(message1, message2, oneof); + } } if (schema_.HasExtensionSet()) { @@ -698,11 +694,12 @@ void Reflection::SwapFields( const int fields_size = static_cast(fields.size()); for (int i = 0; i < fields_size; i++) { const FieldDescriptor* field = fields[i]; + CheckInvalidAccess(schema_, field); if (field->is_extension()) { MutableExtensionSet(message1)->SwapExtension( MutableExtensionSet(message2), field->number()); } else { - if (field->containing_oneof()) { + if (schema_.InRealOneof(field)) { int oneof_index = field->containing_oneof()->index(); // Only swap the oneof field once. if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) { @@ -729,11 +726,12 @@ bool Reflection::HasField(const Message& message, const FieldDescriptor* field) const { USAGE_CHECK_MESSAGE_TYPE(HasField); USAGE_CHECK_SINGULAR(HasField); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { return GetExtensionSet(message).Has(field->number()); } else { - if (field->containing_oneof()) { + if (schema_.InRealOneof(field)) { return HasOneofField(message, field); } else { return HasBit(message, field); @@ -745,6 +743,7 @@ int Reflection::FieldSize(const Message& message, const FieldDescriptor* field) const { USAGE_CHECK_MESSAGE_TYPE(FieldSize); USAGE_CHECK_REPEATED(FieldSize); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { return GetExtensionSet(message).ExtensionSize(field->number()); @@ -789,11 +788,12 @@ int Reflection::FieldSize(const Message& message, void Reflection::ClearField(Message* message, const FieldDescriptor* field) const { USAGE_CHECK_MESSAGE_TYPE(ClearField); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { MutableExtensionSet(message)->ClearExtension(field->number()); } else if (!field->is_repeated()) { - if (field->containing_oneof()) { + if (schema_.InRealOneof(field)) { ClearOneofField(message, field); return; } @@ -825,16 +825,8 @@ void Reflection::ClearField(Message* message, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - const std::string* default_ptr = - &DefaultRaw(field).GetNoArena(); - MutableRaw(message, field) - ->SetNoArena(default_ptr, *default_ptr); - break; - } - const std::string* default_ptr = - &DefaultRaw(field).Get(); + DefaultRaw(field).GetPointer(); MutableRaw(message, field) ->SetAllocated(default_ptr, nullptr, GetArena(message)); break; @@ -844,7 +836,7 @@ void Reflection::ClearField(Message* message, } case FieldDescriptor::CPPTYPE_MESSAGE: - if (!schema_.HasHasbits()) { + if (schema_.HasBitIndex(field) == static_cast(-1)) { // Proto3 does not have has-bits and we need to set a message field // to nullptr in order to indicate its un-presence. if (GetArena(message) == nullptr) { @@ -903,6 +895,7 @@ void Reflection::RemoveLast(Message* message, const FieldDescriptor* field) const { USAGE_CHECK_MESSAGE_TYPE(RemoveLast); USAGE_CHECK_REPEATED(RemoveLast); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { MutableExtensionSet(message)->RemoveLast(field->number()); @@ -950,6 +943,7 @@ void Reflection::RemoveLast(Message* message, Message* Reflection::ReleaseLast(Message* message, const FieldDescriptor* field) const { USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { return static_cast( @@ -970,6 +964,7 @@ void Reflection::SwapElements(Message* message, const FieldDescriptor* field, int index1, int index2) const { USAGE_CHECK_MESSAGE_TYPE(Swap); USAGE_CHECK_REPEATED(Swap); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { MutableExtensionSet(message)->SwapElements(field->number(), index1, index2); @@ -1026,8 +1021,17 @@ bool CreateUnknownEnumValues(const FileDescriptor* file) { } } // namespace -void Reflection::ListFields(const Message& message, - std::vector* output) const { +namespace internal { +bool CreateUnknownEnumValues(const FieldDescriptor* field) { + bool open_enum = false; + return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || open_enum; +} +} // namespace internal +using internal::CreateUnknownEnumValues; + +void Reflection::ListFieldsMayFailOnStripped( + const Message& message, bool should_fail, + std::vector* output) const { output->clear(); // Optimization: The default instance never has any fields set. @@ -1042,22 +1046,28 @@ void Reflection::ListFields(const Message& message, schema_.HasHasbits() ? GetHasBits(message) : nullptr; const uint32* const has_bits_indices = schema_.has_bit_indices_; output->reserve(descriptor_->field_count()); - for (int i = 0; i <= last_non_weak_field_index_; i++) { + const int last_non_weak_field_index = last_non_weak_field_index_; + for (int i = 0; i <= last_non_weak_field_index; i++) { const FieldDescriptor* field = descriptor_->field(i); + if (!should_fail && schema_.IsFieldStripped(field)) { + continue; + } if (field->is_repeated()) { if (FieldSize(message, field) > 0) { output->push_back(field); } } else { const OneofDescriptor* containing_oneof = field->containing_oneof(); - if (containing_oneof) { + if (schema_.InRealOneof(field)) { const uint32* const oneof_case_array = GetConstPointerAtOffset( &message, schema_.oneof_case_offset_); // Equivalent to: HasOneofField(message, field) - if (oneof_case_array[containing_oneof->index()] == field->number()) { + if (static_cast(oneof_case_array[containing_oneof->index()]) == + field->number()) { output->push_back(field); } - } else if (has_bits) { + } else if (has_bits && has_bits_indices[i] != static_cast(-1)) { + CheckInvalidAccess(schema_, field); // Equivalent to: HasBit(message, field) if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) { output->push_back(field); @@ -1076,6 +1086,16 @@ void Reflection::ListFields(const Message& message, std::sort(output->begin(), output->end(), FieldNumberSorter()); } +void Reflection::ListFields(const Message& message, + std::vector* output) const { + ListFieldsMayFailOnStripped(message, true, output); +} + +void Reflection::ListFieldsOmitStripped( + const Message& message, std::vector* output) const { + ListFieldsMayFailOnStripped(message, false, output); +} + // ------------------------------------------------------------------- #undef DEFINE_PRIMITIVE_ACCESSORS @@ -1086,6 +1106,8 @@ void Reflection::ListFields(const Message& message, if (field->is_extension()) { \ return GetExtensionSet(message).Get##TYPENAME( \ field->number(), field->default_value_##PASSTYPE()); \ + } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { \ + return field->default_value_##PASSTYPE(); \ } else { \ return GetField(message, field); \ } \ @@ -1155,14 +1177,17 @@ std::string Reflection::GetString(const Message& message, return GetExtensionSet(message).GetString(field->number(), field->default_value_string()); } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return field->default_value_string(); + } switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - return GetField(message, field).GetNoArena(); + if (auto* value = + GetField(message, field).GetPointer()) { + return *value; } - - return GetField(message, field).Get(); + return field->default_value_string(); } } } @@ -1176,14 +1201,17 @@ const std::string& Reflection::GetStringReference(const Message& message, return GetExtensionSet(message).GetString(field->number(), field->default_value_string()); } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return field->default_value_string(); + } switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - return GetField(message, field).GetNoArena(); + if (auto* value = + GetField(message, field).GetPointer()) { + return *value; } - - return GetField(message, field).Get(); + return field->default_value_string(); } } } @@ -1200,22 +1228,21 @@ void Reflection::SetString(Message* message, const FieldDescriptor* field, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - MutableField(message, field) - ->SetNoArena(nullptr, std::move(value)); - break; - } - + // Oneof string fields are never set as a default instance. + // We just need to pass some arbitrary default string to make it work. + // This allows us to not have the real default accessible from + // reflection. const std::string* default_ptr = - &DefaultRaw(field).Get(); - if (field->containing_oneof() && !HasOneofField(*message, field)) { + schema_.InRealOneof(field) + ? nullptr + : DefaultRaw(field).GetPointer(); + if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); MutableField(message, field) ->UnsafeSetDefault(default_ptr); } MutableField(message, field) - ->Mutable(default_ptr, GetArena(message)) - ->assign(std::move(value)); + ->Set(default_ptr, std::move(value), GetArena(message)); break; } } @@ -1307,6 +1334,8 @@ int Reflection::GetEnumValue(const Message& message, if (field->is_extension()) { value = GetExtensionSet(message).GetEnum( field->number(), field->default_value_enum()->number()); + } else if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + value = field->default_value_enum()->number(); } else { value = GetField(message, field); } @@ -1323,7 +1352,7 @@ void Reflection::SetEnum(Message* message, const FieldDescriptor* field, void Reflection::SetEnumValue(Message* message, const FieldDescriptor* field, int value) const { USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM); - if (!CreateUnknownEnumValues(descriptor_->file())) { + if (!CreateUnknownEnumValues(field)) { // Check that the value is valid if we don't support direct storage of // unknown enum values. const EnumValueDescriptor* value_desc = @@ -1380,7 +1409,7 @@ void Reflection::SetRepeatedEnumValue(Message* message, const FieldDescriptor* field, int index, int value) const { USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM); - if (!CreateUnknownEnumValues(descriptor_->file())) { + if (!CreateUnknownEnumValues(field)) { // Check that the value is valid if we don't support direct storage of // unknown enum values. const EnumValueDescriptor* value_desc = @@ -1414,7 +1443,7 @@ void Reflection::AddEnum(Message* message, const FieldDescriptor* field, void Reflection::AddEnumValue(Message* message, const FieldDescriptor* field, int value) const { USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM); - if (!CreateUnknownEnumValues(descriptor_->file())) { + if (!CreateUnknownEnumValues(field)) { // Check that the value is valid if we don't support direct storage of // unknown enum values. const EnumValueDescriptor* value_desc = @@ -1441,10 +1470,45 @@ void Reflection::AddEnumValueInternal(Message* message, // ------------------------------------------------------------------- +const Message* Reflection::GetDefaultMessageInstance( + const FieldDescriptor* field) const { + // If we are using the generated factory, we cache the prototype in the field + // descriptor for faster access. + // The default instances of generated messages are not cross-linked, which + // means they contain null pointers on their message fields and can't be used + // to get the default of submessages. + if (message_factory_ == MessageFactory::generated_factory()) { + auto& ptr = field->default_generated_instance_; + auto* res = ptr.load(std::memory_order_acquire); + if (res == nullptr) { + // First time asking for this field's default. Load it and cache it. + res = message_factory_->GetPrototype(field->message_type()); + ptr.store(res, std::memory_order_release); + } + return res; + } + + // For other factories, we try the default's object field. + // In particular, the DynamicMessageFactory will cross link the default + // instances to allow for this. But only do this for real fields. + // This is an optimization to avoid going to GetPrototype() below, as that + // requires a lock and a map lookup. + if (!field->is_extension() && !field->options().weak() && + !field->options().lazy() && !schema_.InRealOneof(field)) { + auto* res = DefaultRaw(field); + if (res != nullptr) { + return res; + } + } + // Otherwise, just go to the factory. + return message_factory_->GetPrototype(field->message_type()); +} + const Message& Reflection::GetMessage(const Message& message, const FieldDescriptor* field, MessageFactory* factory) const { USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); if (factory == nullptr) factory = message_factory_; @@ -1452,9 +1516,12 @@ const Message& Reflection::GetMessage(const Message& message, return static_cast(GetExtensionSet(message).GetMessage( field->number(), field->message_type(), factory)); } else { + if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { + return *GetDefaultMessageInstance(field); + } const Message* result = GetRaw(message, field); if (result == nullptr) { - result = DefaultRaw(field); + result = GetDefaultMessageInstance(field); } return *result; } @@ -1464,6 +1531,7 @@ Message* Reflection::MutableMessage(Message* message, const FieldDescriptor* field, MessageFactory* factory) const { USAGE_CHECK_ALL(MutableMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); if (factory == nullptr) factory = message_factory_; @@ -1475,11 +1543,11 @@ Message* Reflection::MutableMessage(Message* message, Message** result_holder = MutableRaw(message, field); - if (field->containing_oneof()) { + if (schema_.InRealOneof(field)) { if (!HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); result_holder = MutableField(message, field); - const Message* default_message = DefaultRaw(field); + const Message* default_message = GetDefaultMessageInstance(field); *result_holder = default_message->New(message->GetArena()); } } else { @@ -1487,7 +1555,7 @@ Message* Reflection::MutableMessage(Message* message, } if (*result_holder == nullptr) { - const Message* default_message = DefaultRaw(field); + const Message* default_message = GetDefaultMessageInstance(field); *result_holder = default_message->New(message->GetArena()); } result = *result_holder; @@ -1499,12 +1567,13 @@ void Reflection::UnsafeArenaSetAllocatedMessage( Message* message, Message* sub_message, const FieldDescriptor* field) const { USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage( field->number(), field->type(), field, sub_message); } else { - if (field->containing_oneof()) { + if (schema_.InRealOneof(field)) { if (sub_message == nullptr) { ClearOneof(message, field->containing_oneof()); return; @@ -1530,6 +1599,8 @@ void Reflection::UnsafeArenaSetAllocatedMessage( void Reflection::SetAllocatedMessage(Message* message, Message* sub_message, const FieldDescriptor* field) const { + CheckInvalidAccess(schema_, field); + // If message and sub-message are in different memory ownership domains // (different arenas, or one is on heap and one is not), then we may need to // do a copy. @@ -1558,6 +1629,7 @@ Message* Reflection::UnsafeArenaReleaseMessage(Message* message, const FieldDescriptor* field, MessageFactory* factory) const { USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE); + CheckInvalidAccess(schema_, field); if (factory == nullptr) factory = message_factory_; @@ -1566,10 +1638,10 @@ Message* Reflection::UnsafeArenaReleaseMessage(Message* message, MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field, factory)); } else { - if (!(field->is_repeated() || field->containing_oneof())) { + if (!(field->is_repeated() || schema_.InRealOneof(field))) { ClearBit(message, field); } - if (field->containing_oneof()) { + if (schema_.InRealOneof(field)) { if (HasOneofField(*message, field)) { *MutableOneofCase(message, field->containing_oneof()) = 0; } else { @@ -1586,6 +1658,8 @@ Message* Reflection::UnsafeArenaReleaseMessage(Message* message, Message* Reflection::ReleaseMessage(Message* message, const FieldDescriptor* field, MessageFactory* factory) const { + CheckInvalidAccess(schema_, field); + Message* released = UnsafeArenaReleaseMessage(message, field, factory); if (GetArena(message) != nullptr && released != nullptr) { Message* copy_from_arena = released->New(); @@ -1599,6 +1673,7 @@ const Message& Reflection::GetRepeatedMessage(const Message& message, const FieldDescriptor* field, int index) const { USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { return static_cast( @@ -1619,6 +1694,7 @@ Message* Reflection::MutableRepeatedMessage(Message* message, const FieldDescriptor* field, int index) const { USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { return static_cast( @@ -1639,6 +1715,7 @@ Message* Reflection::MutableRepeatedMessage(Message* message, Message* Reflection::AddMessage(Message* message, const FieldDescriptor* field, MessageFactory* factory) const { USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); if (factory == nullptr) factory = message_factory_; @@ -1681,6 +1758,7 @@ void Reflection::AddAllocatedMessage(Message* message, const FieldDescriptor* field, Message* new_entry) const { USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE); + CheckInvalidAccess(schema_, field); if (field->is_extension()) { MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry); @@ -1702,6 +1780,8 @@ void* Reflection::MutableRawRepeatedField(Message* message, int ctype, const Descriptor* desc) const { USAGE_CHECK_REPEATED("MutableRawRepeatedField"); + CheckInvalidAccess(schema_, field); + if (field->cpp_type() != cpptype && (field->cpp_type() != FieldDescriptor::CPPTYPE_ENUM || cpptype != FieldDescriptor::CPPTYPE_INT32)) @@ -1754,6 +1834,10 @@ const void* Reflection::GetRawRepeatedField(const Message& message, const FieldDescriptor* Reflection::GetOneofFieldDescriptor( const Message& message, const OneofDescriptor* oneof_descriptor) const { + if (oneof_descriptor->is_synthetic()) { + const FieldDescriptor* field = oneof_descriptor->field(0); + return HasField(message, field) ? field : nullptr; + } uint32 field_number = GetOneofCase(message, oneof_descriptor); if (field_number == 0) { return nullptr; @@ -1780,6 +1864,15 @@ bool Reflection::InsertOrLookupMapValue(Message* message, ->InsertOrLookupMapValue(key, val); } +bool Reflection::LookupMapValue(const Message& message, + const FieldDescriptor* field, const MapKey& key, + MapValueConstRef* val) const { + USAGE_CHECK(IsMapFieldInApi(field), "LookupMapValue", + "Field is not a map field."); + val->SetType(field->message_type()->FindFieldByName("value")->cpp_type()); + return GetRaw(message, field).LookupMapValue(key, val); +} + bool Reflection::DeleteMapValue(Message* message, const FieldDescriptor* field, const MapKey& key) const { USAGE_CHECK(IsMapFieldInApi(field), "DeleteMapValue", @@ -1850,16 +1943,11 @@ Type* Reflection::MutableRawNonOneof(Message* message, template const Type& Reflection::GetRaw(const Message& message, const FieldDescriptor* field) const { - if (field->containing_oneof() && !HasOneofField(message, field)) { - return DefaultRaw(field); - } + GOOGLE_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field)) + << "Field = " << field->full_name(); return GetConstRefAtOffset(message, schema_.GetFieldOffset(field)); } -bool Reflection::IsInlined(const FieldDescriptor* field) const { - return schema_.IsFieldInlined(field); -} - template Type* Reflection::MutableRaw(Message* message, const FieldDescriptor* field) const { @@ -1878,12 +1966,14 @@ uint32* Reflection::MutableHasBits(Message* message) const { uint32 Reflection::GetOneofCase(const Message& message, const OneofDescriptor* oneof_descriptor) const { + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); return GetConstRefAtOffset( message, schema_.GetOneofCaseOffset(oneof_descriptor)); } uint32* Reflection::MutableOneofCase( Message* message, const OneofDescriptor* oneof_descriptor) const { + GOOGLE_DCHECK(!oneof_descriptor->is_synthetic()); return GetPointerAtOffset( message, schema_.GetOneofCaseOffset(oneof_descriptor)); } @@ -1899,34 +1989,31 @@ ExtensionSet* Reflection::MutableExtensionSet(Message* message) const { } Arena* Reflection::GetArena(Message* message) const { - return GetInternalMetadataWithArena(*message).arena(); + return GetInternalMetadata(*message).arena(); } -const InternalMetadataWithArena& Reflection::GetInternalMetadataWithArena( +const InternalMetadata& Reflection::GetInternalMetadata( const Message& message) const { - return GetConstRefAtOffset( - message, schema_.GetMetadataOffset()); -} - -InternalMetadataWithArena* Reflection::MutableInternalMetadataWithArena( - Message* message) const { - return GetPointerAtOffset( - message, schema_.GetMetadataOffset()); + return GetConstRefAtOffset(message, + schema_.GetMetadataOffset()); } -template -const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const { - return *reinterpret_cast(schema_.GetFieldDefault(field)); +InternalMetadata* Reflection::MutableInternalMetadata(Message* message) const { + return GetPointerAtOffset(message, + schema_.GetMetadataOffset()); } // Simple accessors for manipulating has_bits_. bool Reflection::HasBit(const Message& message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); - if (schema_.HasHasbits()) { + if (schema_.HasBitIndex(field) != static_cast(-1)) { return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field)); } + // Intentionally check here because HasBitIndex(field) != -1 means valid. + CheckInvalidAccess(schema_, field); + // proto3: no has-bits. All fields present except messages, which are // present only if their message-field pointer is non-null. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { @@ -1947,11 +2034,6 @@ bool Reflection::HasBit(const Message& message, case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) { default: { - if (IsInlined(field)) { - return !GetField(message, field) - .GetNoArena() - .empty(); - } return GetField(message, field).Get().size() > 0; } } @@ -1983,10 +2065,8 @@ bool Reflection::HasBit(const Message& message, void Reflection::SetBit(Message* message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); - if (!schema_.HasHasbits()) { - return; - } const uint32 index = schema_.HasBitIndex(field); + if (index == static_cast(-1)) return; MutableHasBits(message)[index / 32] |= (static_cast(1) << (index % 32)); } @@ -1994,10 +2074,8 @@ void Reflection::SetBit(Message* message, const FieldDescriptor* field) const { void Reflection::ClearBit(Message* message, const FieldDescriptor* field) const { GOOGLE_DCHECK(!field->options().weak()); - if (!schema_.HasHasbits()) { - return; - } const uint32 index = schema_.HasBitIndex(field); + if (index == static_cast(-1)) return; MutableHasBits(message)[index / 32] &= ~(static_cast(1) << (index % 32)); } @@ -2023,12 +2101,16 @@ void Reflection::SwapBit(Message* message1, Message* message2, bool Reflection::HasOneof(const Message& message, const OneofDescriptor* oneof_descriptor) const { + if (oneof_descriptor->is_synthetic()) { + return HasField(message, oneof_descriptor->field(0)); + } return (GetOneofCase(message, oneof_descriptor) > 0); } bool Reflection::HasOneofField(const Message& message, const FieldDescriptor* field) const { - return (GetOneofCase(message, field->containing_oneof()) == field->number()); + return (GetOneofCase(message, field->containing_oneof()) == + static_cast(field->number())); } void Reflection::SetOneofCase(Message* message, @@ -2045,6 +2127,10 @@ void Reflection::ClearOneofField(Message* message, void Reflection::ClearOneof(Message* message, const OneofDescriptor* oneof_descriptor) const { + if (oneof_descriptor->is_synthetic()) { + ClearField(message, oneof_descriptor->field(0)); + return; + } // TODO(jieluo): Consider to cache the unused object instead of deleting // it. It will be much faster if an application switches a lot from // a few oneof fields. Time/space tradeoff @@ -2057,10 +2143,12 @@ void Reflection::ClearOneof(Message* message, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - const std::string* default_ptr = - &DefaultRaw(field).Get(); + // Oneof string fields are never set as a default instance. + // We just need to pass some arbitrary default string to make it + // work. This allows us to not have the real default accessible + // from reflection. MutableField(message, field) - ->Destroy(default_ptr, GetArena(message)); + ->Destroy(nullptr, GetArena(message)); break; } } @@ -2125,19 +2213,19 @@ const Type& Reflection::GetField(const Message& message, template void Reflection::SetField(Message* message, const FieldDescriptor* field, const Type& value) const { - if (field->containing_oneof() && !HasOneofField(*message, field)) { + bool real_oneof = schema_.InRealOneof(field); + if (real_oneof && !HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); } *MutableRaw(message, field) = value; - field->containing_oneof() ? SetOneofCase(message, field) - : SetBit(message, field); + real_oneof ? SetOneofCase(message, field) : SetBit(message, field); } template Type* Reflection::MutableField(Message* message, const FieldDescriptor* field) const { - field->containing_oneof() ? SetOneofCase(message, field) - : SetBit(message, field); + schema_.InRealOneof(field) ? SetOneofCase(message, field) + : SetBit(message, field); return MutableRaw(message, field); } @@ -2331,7 +2419,9 @@ struct MetadataOwner { std::vector > metadata_arrays_; }; -void AssignDescriptorsImpl(const DescriptorTable* table) { +void AddDescriptors(const DescriptorTable* table); + +void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) { // Ensure the file descriptor is added to the pool. { // This only happens once per proto file. So a global mutex to serialize @@ -2341,6 +2431,25 @@ void AssignDescriptorsImpl(const DescriptorTable* table) { AddDescriptors(table); mu.Unlock(); } + if (eager) { + // Normally we do not want to eagerly build descriptors of our deps. + // However if this proto is optimized for code size (ie using reflection) + // and it has a message extending a custom option of a descriptor with that + // message being optimized for code size as well. Building the descriptors + // in this file requires parsing the serialized file descriptor, which now + // requires parsing the message extension, which potentially requires + // building the descriptor of the message extending one of the options. + // However we are already updating descriptor pool under a lock. To prevent + // this the compiler statically looks for this case and we just make sure we + // first build the descriptors of all our dependencies, preventing the + // deadlock. + int num_deps = table->num_deps; + for (int i = 0; i < num_deps; i++) { + // In case of weak fields deps[i] could be null. + if (table->deps[i]) AssignDescriptors(table->deps[i], true); + } + } + // Fill the arrays with pointers to descriptors and reflection classes. const FileDescriptor* file = DescriptorPool::internal_generated_pool()->FindFileByName( @@ -2378,7 +2487,8 @@ void AddDescriptorsImpl(const DescriptorTable* table) { // Ensure all dependent descriptors are registered to the generated descriptor // pool and message factory. - for (int i = 0; i < table->num_deps; i++) { + int num_deps = table->num_deps; + for (int i = 0; i < num_deps; i++) { // In case of weak fields deps[i] could be null. if (table->deps[i]) AddDescriptors(table->deps[i]); } @@ -2388,6 +2498,16 @@ void AddDescriptorsImpl(const DescriptorTable* table) { MessageFactory::InternalRegisterGeneratedFile(table); } +void AddDescriptors(const DescriptorTable* table) { + // AddDescriptors is not thread safe. Callers need to ensure calls are + // properly serialized. This function is only called pre-main by global + // descriptors and we can assume single threaded access or it's called + // by AssignDescriptorImpl which uses a mutex to sequence calls. + if (table->is_initialized) return; + table->is_initialized = true; + AddDescriptorsImpl(table); +} + } // namespace // Separate function because it needs to be a friend of @@ -2403,18 +2523,13 @@ void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) { namespace internal { -void AssignDescriptors(const DescriptorTable* table) { - call_once(*table->once, AssignDescriptorsImpl, table); +void AssignDescriptors(const DescriptorTable* table, bool eager) { + if (!eager) eager = table->is_eager; + call_once(*table->once, AssignDescriptorsImpl, table, eager); } -void AddDescriptors(const DescriptorTable* table) { - // AddDescriptors is not thread safe. Callers need to ensure calls are - // properly serialized. This function is only called pre-main by global - // descriptors and we can assume single threaded access or it's called - // by AssignDescriptorImpl which uses a mutex to sequence calls. - if (*table->is_initialized) return; - *table->is_initialized = true; - AddDescriptorsImpl(table); +AddDescriptorsRunner::AddDescriptorsRunner(const DescriptorTable* table) { + AddDescriptors(table); } void RegisterFileLevelMetadata(const DescriptorTable* table) { @@ -2426,14 +2541,17 @@ void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag, uint32 has_offset, io::CodedOutputStream* output) { const void* ptr = base + offset; - const InternalMetadataWithArena* metadata = - static_cast(ptr); + const InternalMetadata* metadata = static_cast(ptr); if (metadata->have_unknown_fields()) { - internal::WireFormat::SerializeUnknownFields(metadata->unknown_fields(), - output); + internal::WireFormat::SerializeUnknownFields( + metadata->unknown_fields( + UnknownFieldSet::default_instance), + output); } } } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index cbfab5e1c716..ff96bea23422 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -42,11 +42,8 @@ #include #include #include -// TODO(jasonh): Remove this once the compiler change to directly include this -// is released to components. #include #include -#include #include #include #include @@ -60,7 +57,6 @@ namespace google { namespace protobuf { -class DescriptorPool; class MapKey; class MapValueRef; class MessageLayoutInspector; @@ -73,8 +69,6 @@ namespace google { namespace protobuf { namespace internal { class DefaultEmptyOneof; -class ReflectionAccessor; - // Defined in other files. class ExtensionSet; // extension_set.h class WeakFieldMap; // weak_field_map.h @@ -127,16 +121,21 @@ struct ReflectionSchema { // Size of a google::protobuf::Message object of this type. uint32 GetObjectSize() const { return static_cast(object_size_); } + bool InRealOneof(const FieldDescriptor* field) const { + return field->containing_oneof() && + !field->containing_oneof()->is_synthetic(); + } + // Offset of a non-oneof field. Getting a field offset is slightly more // efficient when we know statically that it is not a oneof field. uint32 GetFieldOffsetNonOneof(const FieldDescriptor* field) const { - GOOGLE_DCHECK(!field->containing_oneof()); + GOOGLE_DCHECK(!InRealOneof(field)); return OffsetValue(offsets_[field->index()], field->type()); } // Offset of any field. uint32 GetFieldOffset(const FieldDescriptor* field) const { - if (field->containing_oneof()) { + if (InRealOneof(field)) { size_t offset = static_cast(field->containing_type()->field_count() + field->containing_oneof()->index()); @@ -146,17 +145,6 @@ struct ReflectionSchema { } } - bool IsFieldInlined(const FieldDescriptor* field) const { - if (field->containing_oneof()) { - size_t offset = - static_cast(field->containing_type()->field_count() + - field->containing_oneof()->index()); - return Inlined(offsets_[offset], field->type()); - } else { - return Inlined(offsets_[field->index()], field->type()); - } - } - uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const { return static_cast(oneof_case_offset_) + static_cast(static_cast(oneof_descriptor->index()) * @@ -167,6 +155,7 @@ struct ReflectionSchema { // Bit index within the bit array of hasbits. Bit order is low-to-high. uint32 HasBitIndex(const FieldDescriptor* field) const { + if (has_bits_offset_ == -1) return static_cast(-1); GOOGLE_DCHECK(HasHasbits()); return has_bit_indices_[field->index()]; } @@ -209,6 +198,23 @@ struct ReflectionSchema { OffsetValue(offsets_[field->index()], field->type()); } + // Returns true if the field's accessor is called by any external code (aka, + // non proto library code). + bool IsFieldUsed(const FieldDescriptor* field) const { + (void)field; + return true; + } + + bool IsFieldStripped(const FieldDescriptor* field) const { + (void)field; + return false; + } + + bool IsMessageStripped(const Descriptor* descriptor) const { + (void)descriptor; + return false; + } + bool HasWeakFields() const { return weak_field_map_offset_ > 0; } @@ -229,24 +235,9 @@ struct ReflectionSchema { int weak_field_map_offset_; // We tag offset values to provide additional data about fields (such as - // inlined). - static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) { - if (type == FieldDescriptor::TYPE_STRING || - type == FieldDescriptor::TYPE_BYTES) { - return v & ~1u; - } else { - return v; - } - } - - static bool Inlined(uint32 v, FieldDescriptor::Type type) { - if (type == FieldDescriptor::TYPE_STRING || - type == FieldDescriptor::TYPE_BYTES) { - return v & 1u; - } else { - // Non string/byte fields are not inlined. - return false; - } + // "unused"). + static uint32 OffsetValue(uint32 v, FieldDescriptor::Type /* type */) { + return v & 0x7FFFFFFFu; } }; @@ -262,8 +253,11 @@ struct MigrationSchema { int object_size; }; +struct SCCInfoBase; + struct PROTOBUF_EXPORT DescriptorTable { - bool* is_initialized; + mutable bool is_initialized; + bool is_eager; const char* descriptor; const char* filename; int size; // of serialized descriptor @@ -282,25 +276,30 @@ struct PROTOBUF_EXPORT DescriptorTable { const ServiceDescriptor** file_level_service_descriptors; }; +enum { + // Tag used on offsets for fields that don't have a real offset. + // For example, weak message fields go into the WeakFieldMap and not in an + // actual field. + kInvalidFieldOffsetTag = 0x40000000u, +}; + // AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool // and uses it to populate all of the global variables which store pointers to // the descriptor objects. It also constructs the reflection objects. It is // called the first time anyone calls descriptor() or GetReflection() on one of // the types defined in the file. AssignDescriptors() is thread-safe. -void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table); - -// AddDescriptors() is a file-level procedure which adds the encoded -// FileDescriptorProto for this .proto file to the global DescriptorPool for -// generated files (DescriptorPool::generated_pool()). It ordinarily runs at -// static initialization time, but is not used at all in LITE_RUNTIME mode. -// AddDescriptors() is *not* thread-safe. -void PROTOBUF_EXPORT AddDescriptors(const DescriptorTable* table); +void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table, + bool eager = false); // These cannot be in lite so we put them in the reflection. PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag, uint32 has_offset, io::CodedOutputStream* output); +struct PROTOBUF_EXPORT AddDescriptorsRunner { + explicit AddDescriptorsRunner(const DescriptorTable* table); +}; + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc index eea5da53d754..7234f5f9321b 100644 --- a/src/google/protobuf/generated_message_reflection_unittest.cc +++ b/src/google/protobuf/generated_message_reflection_unittest.cc @@ -43,15 +43,15 @@ // rather than generated accessors. #include + #include +#include +#include #include #include #include #include - -#include -#include #include #include @@ -486,6 +486,7 @@ TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) { ->FindKnownExtensionByName(extension1->full_name()) == NULL); } + TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) { unittest::TestAllTypes from_message1; unittest::TestAllTypes from_message2; diff --git a/src/google/protobuf/generated_message_table_driven.cc b/src/google/protobuf/generated_message_table_driven.cc index fb82a8ec373c..56f1a6af841e 100644 --- a/src/google/protobuf/generated_message_table_driven.cc +++ b/src/google/protobuf/generated_message_table_driven.cc @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -47,8 +46,8 @@ namespace internal { namespace { UnknownFieldSet* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { - return Raw(msg, arena_offset) - ->mutable_unknown_fields(); + return Raw(msg, arena_offset) + ->mutable_unknown_fields(); } struct UnknownFieldHandler { @@ -95,9 +94,8 @@ struct UnknownFieldHandler { bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) { - return MergePartialFromCodedStreamImpl(msg, table, - input); + return MergePartialFromCodedStreamImpl(msg, table, + input); } } // namespace internal diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h index 94770a41a5cd..68d80dcc89b1 100644 --- a/src/google/protobuf/generated_message_table_driven.h +++ b/src/google/protobuf/generated_message_table_driven.h @@ -73,9 +73,7 @@ enum ProcessingTypes { TYPE_STRING_STRING_PIECE = 20, TYPE_BYTES_CORD = 21, TYPE_BYTES_STRING_PIECE = 22, - TYPE_STRING_INLINED = 23, - TYPE_BYTES_INLINED = 24, - TYPE_MAP = 25, + TYPE_MAP = 23, }; static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum"); @@ -102,12 +100,11 @@ struct PROTOBUF_EXPORT FieldMetadata { kNumTypeClasses // must be last enum }; // C++ protobuf has 20 fundamental types, were we added Cord and StringPiece - // and also distinquish the same types if they have different wire format. + // and also distinguish the same types if they have different wire format. enum { kCordType = 19, kStringPieceType = 20, - kInlinedType = 21, - kNumTypes = 21, + kNumTypes = 20, kSpecial = kNumTypes * kNumTypeClasses, }; @@ -120,7 +117,7 @@ struct PROTOBUF_EXPORT FieldMetadata { // ParseTableField is kept small to help simplify instructions for computing // offsets, as we will always need this information to parse a field. // Additional data, needed for some types, is stored in -// AuxillaryParseTableField. +// AuxiliaryParseTableField. struct ParseTableField { uint32 offset; // The presence_index ordinarily represents a has_bit index, but for fields @@ -138,7 +135,7 @@ struct ParseTableField { struct ParseTable; -union AuxillaryParseTableField { +union AuxiliaryParseTableField { typedef bool (*EnumValidator)(int); // Enums @@ -169,20 +166,20 @@ union AuxillaryParseTableField { }; map_aux maps; - AuxillaryParseTableField() = default; - constexpr AuxillaryParseTableField(AuxillaryParseTableField::enum_aux e) + AuxiliaryParseTableField() = default; + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::enum_aux e) : enums(e) {} - constexpr AuxillaryParseTableField(AuxillaryParseTableField::message_aux m) + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::message_aux m) : messages(m) {} - constexpr AuxillaryParseTableField(AuxillaryParseTableField::string_aux s) + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::string_aux s) : strings(s) {} - constexpr AuxillaryParseTableField(AuxillaryParseTableField::map_aux m) + constexpr AuxiliaryParseTableField(AuxiliaryParseTableField::map_aux m) : maps(m) {} }; struct ParseTable { const ParseTableField* fields; - const AuxillaryParseTableField* aux; + const AuxiliaryParseTableField* aux; int max_field_number; // TODO(ckennelly): Do something with this padding. @@ -208,14 +205,14 @@ static_assert(sizeof(ParseTableField) <= 16, "ParseTableField is too large"); // initialization. static_assert(std::is_standard_layout::value, ""); static_assert(std::is_trivial::value, ""); -static_assert(std::is_standard_layout::value, ""); -static_assert(std::is_trivial::value, ""); -static_assert(std::is_standard_layout::value, ""); -static_assert(std::is_trivial::value, ""); -static_assert(std::is_standard_layout::value, ""); -static_assert(std::is_trivial::value, ""); -static_assert(std::is_standard_layout::value, ""); -static_assert(std::is_trivial::value, ""); +static_assert(std::is_standard_layout::value, ""); +static_assert(std::is_trivial::value, ""); +static_assert(std::is_standard_layout::value, ""); +static_assert(std::is_trivial::value, ""); +static_assert(std::is_standard_layout::value, ""); +static_assert(std::is_trivial::value, ""); +static_assert(std::is_standard_layout::value, ""); +static_assert(std::is_trivial::value, ""); static_assert(std::is_standard_layout::value, ""); static_assert(std::is_trivial::value, ""); diff --git a/src/google/protobuf/generated_message_table_driven_lite.cc b/src/google/protobuf/generated_message_table_driven_lite.cc index 82de6bc9b00c..02e6dacee6d6 100644 --- a/src/google/protobuf/generated_message_table_driven_lite.cc +++ b/src/google/protobuf/generated_message_table_driven_lite.cc @@ -44,8 +44,8 @@ namespace internal { namespace { std::string* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { - return Raw(msg, arena_offset) - ->mutable_unknown_fields(); + return Raw(msg, arena_offset) + ->mutable_unknown_fields(); } struct UnknownFieldHandlerLite { @@ -97,9 +97,8 @@ struct UnknownFieldHandlerLite { bool MergePartialFromCodedStreamLite(MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) { - return MergePartialFromCodedStreamImpl( - msg, table, input); + return MergePartialFromCodedStreamImpl(msg, table, + input); } } // namespace internal diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h index 358d12e6d309..9fc910a01e97 100644 --- a/src/google/protobuf/generated_message_table_driven_lite.h +++ b/src/google/protobuf/generated_message_table_driven_lite.h @@ -31,13 +31,10 @@ #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__ #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__ -#include - #include #include +#include #include -#include -#include #include #include #include @@ -52,7 +49,6 @@ namespace internal { enum StringType { StringType_STRING = 0, - StringType_INLINED = 3 }; // Logically a superset of StringType, consisting of all field types that @@ -61,8 +57,7 @@ enum ProcessingType { ProcessingType_STRING = 0, ProcessingType_CORD = 1, ProcessingType_STRING_PIECE = 2, - ProcessingType_INLINED = 3, - ProcessingType_MESSAGE = 4, + ProcessingType_MESSAGE = 3, }; enum Cardinality { @@ -82,15 +77,6 @@ inline const Type* Raw(const MessageLite* msg, int64 offset) { offset); } -template -inline Arena* GetArena(MessageLite* msg, int64 arena_offset) { - if (PROTOBUF_PREDICT_FALSE(arena_offset == -1)) { - return NULL; - } - - return Raw(msg, arena_offset)->arena(); -} - inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) { if (extension_offset == -1) { return NULL; @@ -101,8 +87,7 @@ inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) { template inline Type* AddField(MessageLite* msg, int64 offset) { - static_assert((std::is_standard_layout::value && std::is_trivial::value) || - std::is_same::value, + static_assert(std::is_standard_layout::value && std::is_trivial::value, "Do not assign"); RepeatedField* repeated = Raw>(msg, offset); @@ -168,12 +153,7 @@ inline void ClearOneofField(const ParseTableField& field, Arena* arena, case WireFormatLite::TYPE_STRING: case WireFormatLite::TYPE_BYTES: Raw(msg, field.offset) - ->Destroy(&GetEmptyStringAlreadyInited(), arena); - break; - - case TYPE_STRING_INLINED: - case TYPE_BYTES_INLINED: - Raw(msg, field.offset)->DestroyNoArena(NULL); + ->Destroy(ArenaStringPtr::EmptyDefault{}, arena); break; default: @@ -192,7 +172,7 @@ template inline void ResetOneofField(const ParseTable& table, int field_number, Arena* arena, MessageLite* msg, uint32* oneof_case, int64 offset, const void* default_ptr) { - if (*oneof_case == field_number) { + if (static_cast(*oneof_case) == field_number) { // The oneof is already set to the right type, so there is no need to clear // it. return; @@ -208,10 +188,6 @@ inline void ResetOneofField(const ParseTable& table, int field_number, Raw(msg, offset) ->UnsafeSetDefault(static_cast(default_ptr)); break; - case ProcessingType_INLINED: - new (Raw(msg, offset)) - InlinedStringField(*static_cast(default_ptr)); - break; case ProcessingType_MESSAGE: MessageLite** submessage = Raw(msg, offset); const MessageLite* prototype = @@ -236,35 +212,12 @@ static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, #endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED switch (ctype) { - case StringType_INLINED: { - InlinedStringField* s = nullptr; - switch (cardinality) { - case Cardinality_SINGULAR: - // TODO(ckennelly): Is this optimal? - s = MutableField(msg, has_bits, has_bit_index, - offset); - break; - case Cardinality_REPEATED: - s = AddField(msg, offset); - break; - case Cardinality_ONEOF: - s = Raw(msg, offset); - break; - } - GOOGLE_DCHECK(s != nullptr); - std::string* value = s->MutableNoArena(NULL); - if (PROTOBUF_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) { - return false; - } - utf8_string_data = *value; - break; - } case StringType_STRING: { switch (cardinality) { case Cardinality_SINGULAR: { ArenaStringPtr* field = MutableField( msg, has_bits, has_bit_index, offset); - std::string* value = field->Mutable( + std::string* value = field->MutableNoCopy( static_cast(default_ptr), arena); if (PROTOBUF_PREDICT_FALSE( !WireFormatLite::ReadString(input, value))) { @@ -282,7 +235,7 @@ static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, } break; case Cardinality_ONEOF: { ArenaStringPtr* field = Raw(msg, offset); - std::string* value = field->Mutable( + std::string* value = field->MutableNoCopy( static_cast(default_ptr), arena); if (PROTOBUF_PREDICT_FALSE( !WireFormatLite::ReadString(input, value))) { @@ -290,9 +243,13 @@ static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, } utf8_string_data = field->Get(); } break; + default: + PROTOBUF_ASSUME(false); } break; } + default: + PROTOBUF_ASSUME(false); } if (kValidateUtf8) { @@ -304,8 +261,7 @@ static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, return true; } -template +template inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input, MessageLite* msg, uint32* presence, uint32 presence_index, int64 offset, uint32 tag, @@ -317,7 +273,7 @@ inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input, return false; } - AuxillaryParseTableField::EnumValidator validator = + AuxiliaryParseTableField::EnumValidator validator = table.aux[field_number].enums.validator; if (validator == nullptr || validator(value)) { switch (cardinality) { @@ -328,12 +284,13 @@ inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input, AddField(msg, offset, value); break; case Cardinality_ONEOF: - ClearOneofField(table.fields[presence[presence_index]], - GetArena(msg, table.arena_offset), + ClearOneofField(table.fields[presence[presence_index]], msg->GetArena(), msg); SetOneofField(msg, presence, presence_index, offset, field_number, value); break; + default: + PROTOBUF_ASSUME(false); } } else { UnknownFieldHandler::Varint(msg, table, tag, value); @@ -372,8 +329,7 @@ class MergePartialFromCodedStreamHelper { } }; -template +template bool MergePartialFromCodedStreamInlined(MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) { @@ -419,9 +375,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, const unsigned char processing_type = data->processing_type; if (data->normal_wiretype == static_cast(wire_type)) { - // TODO(ckennelly): Use a computed goto on GCC/LLVM or otherwise eliminate - // the bounds check on processing_type. - switch (processing_type) { #define HANDLE_TYPE(TYPE, CPPTYPE) \ case (WireFormatLite::TYPE_##TYPE): { \ @@ -451,8 +404,8 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \ return false; \ } \ - ClearOneofField(table.fields[oneof_case[presence_index]], \ - GetArena(msg, table.arena_offset), msg); \ + ClearOneofField(table.fields[oneof_case[presence_index]], msg->GetArena(), \ + msg); \ SetOneofField(msg, oneof_case, presence_index, offset, field_number, \ value); \ break; \ @@ -480,8 +433,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, case WireFormatLite::TYPE_STRING: #endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); const void* default_ptr = table.aux[field_number].strings.default_ptr; if (PROTOBUF_PREDICT_FALSE( @@ -493,31 +445,12 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } break; } - case TYPE_BYTES_INLINED: -#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - case TYPE_STRING_INLINED: -#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - { - Arena* const arena = - GetArena(msg, table.arena_offset); - const void* default_ptr = table.aux[field_number].strings.default_ptr; - - if (PROTOBUF_PREDICT_FALSE( - (!HandleString( - input, msg, arena, has_bits, presence_index, offset, - default_ptr, nullptr)))) { - return false; - } - break; - } case WireFormatLite::TYPE_BYTES | kOneofMask: #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case WireFormatLite::TYPE_STRING | kOneofMask: #endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); uint32* oneof_case = Raw(msg, table.oneof_case_offset); const void* default_ptr = table.aux[field_number].strings.default_ptr; @@ -535,14 +468,11 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, break; } case (WireFormatLite::TYPE_BYTES) | kRepeatedMask: - case TYPE_BYTES_INLINED | kRepeatedMask: #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case (WireFormatLite::TYPE_STRING) | kRepeatedMask: - case TYPE_STRING_INLINED | kRepeatedMask: #endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); const void* default_ptr = table.aux[field_number].strings.default_ptr; if (PROTOBUF_PREDICT_FALSE( @@ -556,8 +486,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } #ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case (WireFormatLite::TYPE_STRING): { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); const void* default_ptr = table.aux[field_number].strings.default_ptr; const char* field_name = table.aux[field_number].strings.field_name; @@ -570,10 +499,8 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } break; } - case TYPE_STRING_INLINED | kRepeatedMask: case (WireFormatLite::TYPE_STRING) | kRepeatedMask: { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); const void* default_ptr = table.aux[field_number].strings.default_ptr; const char* field_name = table.aux[field_number].strings.field_name; @@ -587,8 +514,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, break; } case (WireFormatLite::TYPE_STRING) | kOneofMask: { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); uint32* oneof_case = Raw(msg, table.oneof_case_offset); const void* default_ptr = table.aux[field_number].strings.default_ptr; const char* field_name = table.aux[field_number].strings.field_name; @@ -609,8 +535,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, #endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case WireFormatLite::TYPE_ENUM: { if (PROTOBUF_PREDICT_FALSE( - (!HandleEnum( + (!HandleEnum( table, input, msg, has_bits, presence_index, offset, tag, field_number)))) { return false; @@ -619,8 +544,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } case WireFormatLite::TYPE_ENUM | kRepeatedMask: { if (PROTOBUF_PREDICT_FALSE( - (!HandleEnum( + (!HandleEnum( table, input, msg, has_bits, presence_index, offset, tag, field_number)))) { return false; @@ -630,10 +554,9 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, case WireFormatLite::TYPE_ENUM | kOneofMask: { uint32* oneof_case = Raw(msg, table.oneof_case_offset); if (PROTOBUF_PREDICT_FALSE( - (!HandleEnum(table, input, msg, oneof_case, - presence_index, offset, tag, - field_number)))) { + (!HandleEnum( + table, input, msg, oneof_case, presence_index, offset, + tag, field_number)))) { return false; } break; @@ -644,8 +567,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, MessageLite* submsg = *submsg_holder; if (submsg == NULL) { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); const MessageLite* prototype = table.aux[field_number].messages.default_message(); submsg = prototype->New(arena); @@ -681,8 +603,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, MessageLite* submsg = *submsg_holder; if (submsg == NULL) { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); const MessageLite* prototype = table.aux[field_number].messages.default_message(); if (prototype == NULL) { @@ -720,8 +641,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, break; } case WireFormatLite::TYPE_MESSAGE | kOneofMask: { - Arena* const arena = - GetArena(msg, table.arena_offset); + Arena* const arena = msg->GetArena(); uint32* oneof_case = Raw(msg, table.oneof_case_offset); MessageLite** submsg_holder = Raw(msg, offset); ResetOneofField( @@ -736,23 +656,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, break; } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - case TYPE_STRING_INLINED: { - Arena* const arena = - GetArena(msg, table.arena_offset); - const void* default_ptr = table.aux[field_number].strings.default_ptr; - const char* field_name = table.aux[field_number].strings.field_name; - - if (PROTOBUF_PREDICT_FALSE( - (!HandleString( - input, msg, arena, has_bits, presence_index, offset, - default_ptr, field_name)))) { - return false; - } - break; - } -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case TYPE_MAP: { if (PROTOBUF_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)( input, Raw(msg, offset)))) { @@ -766,7 +669,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, return true; } default: - break; + PROTOBUF_ASSUME(false); } } else if (data->packed_wiretype == static_cast(wire_type)) { // Non-packable fields have their packed_wiretype masked with @@ -775,11 +678,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, GOOGLE_DCHECK_NE(processing_type, kRepeatedMask); GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask); - GOOGLE_DCHECK_NE(TYPE_BYTES_INLINED | kRepeatedMask, processing_type); - GOOGLE_DCHECK_NE(TYPE_STRING_INLINED | kRepeatedMask, processing_type); - // TODO(ckennelly): Use a computed goto on GCC/LLVM. - // // Mask out kRepeatedMask bit, allowing the jump table to be smaller. switch (static_cast(processing_type ^ kRepeatedMask)) { @@ -813,7 +712,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, #undef HANDLE_PACKED_TYPE case WireFormatLite::TYPE_ENUM: { // To avoid unnecessarily calling MutableUnknownFields (which mutates - // InternalMetadataWithArena) when all inputs in the repeated series + // InternalMetadata) when all inputs in the repeated series // are valid, we implement our own parser rather than call // WireFormat::ReadPackedEnumPreserveUnknowns. uint32 length; @@ -821,7 +720,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, return false; } - AuxillaryParseTableField::EnumValidator validator = + AuxiliaryParseTableField::EnumValidator validator = table.aux[field_number].enums.validator; RepeatedField* values = Raw>(msg, offset); @@ -852,7 +751,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, GOOGLE_DCHECK(false); return false; default: - break; + PROTOBUF_ASSUME(false); } } else { if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { @@ -874,25 +773,23 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } } } -} +} // NOLINT(readability/fn_size) -template +template bool MergePartialFromCodedStreamImpl(MessageLite* msg, const ParseTable& table, io::CodedInputStream* input) { // The main beneficial cutoff values are 1 and 2 byte tags. // Instantiate calls with the appropriate upper tag range if (table.max_field_number <= (0x7F >> 3)) { - return MergePartialFromCodedStreamInlined( + return MergePartialFromCodedStreamInlined( msg, table, input); } else if (table.max_field_number <= (0x3FFF >> 3)) { - return MergePartialFromCodedStreamInlined( + return MergePartialFromCodedStreamInlined( msg, table, input); } else { return MergePartialFromCodedStreamInlined< - UnknownFieldHandler, InternalMetadata, - std::numeric_limits::max()>(msg, table, input); + UnknownFieldHandler, std::numeric_limits::max()>(msg, table, + input); } } diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index bdeabddf3c89..8f86f6087456 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -52,10 +52,14 @@ #include #include #include -#include #include #include +// Must be included last +#include + +PROTOBUF_PRAGMA_INIT_SEG + namespace google { namespace protobuf { @@ -65,22 +69,37 @@ void DestroyMessage(const void* message) { static_cast(message)->~MessageLite(); } void DestroyString(const void* s) { - static_cast(s)->~string(); + static_cast(s)->~basic_string(); } -ExplicitlyConstructed fixed_address_empty_string; +PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY EmptyString + fixed_address_empty_string; // NOLINT +PROTOBUF_CONSTINIT std::atomic init_protobuf_defaults_state{false}; static bool InitProtobufDefaultsImpl() { - fixed_address_empty_string.DefaultConstruct(); - OnShutdownDestroyString(fixed_address_empty_string.get_mutable()); + ::new (static_cast(&fixed_address_empty_string.value)) std::string(); + OnShutdownDestroyString(&fixed_address_empty_string.value); + + // Verify that we can indeed get the address during constant evaluation. + PROTOBUF_CONSTINIT static const std::string& fixed_address_empty_string_test = + GetEmptyStringAlreadyInited(); + (void)fixed_address_empty_string_test; + + init_protobuf_defaults_state.store(true, std::memory_order_release); return true; } -void InitProtobufDefaults() { +void InitProtobufDefaultsSlow() { static bool is_inited = InitProtobufDefaultsImpl(); (void)is_inited; } +// Force the initialization of the empty string. +// Normally, registration would do it, but we don't have any guarantee that +// there is any object with reflection. +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static std::true_type init_empty_string = + (InitProtobufDefaultsSlow(), std::true_type{}); size_t StringSpaceUsedExcludingSelfLong(const std::string& str) { const void* start = &str; @@ -246,10 +265,6 @@ struct PrimitiveTypeHelper : PrimitiveTypeHelper {}; -template <> -struct PrimitiveTypeHelper - : PrimitiveTypeHelper {}; - // We want to serialize to both CodedOutputStream and directly into byte arrays // without duplicating the code. In fact we might want extra output channels in // the future. @@ -408,15 +423,6 @@ struct SingularFieldHelper { } }; -template <> -struct SingularFieldHelper { - template - static void Serialize(const void* field, const FieldMetadata& md, O* output) { - WriteTagTo(md.tag, output); - SerializeTo(&Get(field), output); - } -}; - template struct RepeatedFieldHelper { template @@ -489,10 +495,6 @@ struct RepeatedFieldHelper { }; -template <> -struct RepeatedFieldHelper - : RepeatedFieldHelper {}; - template struct PackedFieldHelper { template @@ -528,9 +530,6 @@ struct PackedFieldHelper template <> struct PackedFieldHelper : PackedFieldHelper {}; -template <> -struct PackedFieldHelper - : PackedFieldHelper {}; template struct OneOfFieldHelper { @@ -541,15 +540,6 @@ struct OneOfFieldHelper { }; -template <> -struct OneOfFieldHelper { - template - static void Serialize(const void* field, const FieldMetadata& md, O* output) { - SingularFieldHelper::Serialize( - Get(field), md, output); - } -}; - void SerializeNotImplemented(int field) { GOOGLE_LOG(FATAL) << "Not implemented field number " << field; } @@ -590,11 +580,6 @@ bool IsNull(const void* ptr) { } -template <> -bool IsNull(const void* ptr) { - return static_cast(ptr)->empty(); -} - #define SERIALIZERS_FOR_TYPE(type) \ case SERIALIZE_TABLE_OP(type, FieldMetadata::kPresence): \ if (!IsPresent(base, field_metadata.has_offset)) continue; \ @@ -642,7 +627,6 @@ void SerializeInternal(const uint8* base, SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); - SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); // Special cases case FieldMetadata::kSpecial: @@ -687,7 +671,6 @@ uint8* SerializeInternalToArray(const uint8* base, SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); - SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); // Special cases case FieldMetadata::kSpecial: { io::ArrayOutputStream array_stream(array_output.ptr, INT_MAX); @@ -718,8 +701,8 @@ void UnknownFieldSerializerLite(const uint8* ptr, uint32 offset, uint32 tag, uint32 has_offset, io::CodedOutputStream* output) { output->WriteString( - reinterpret_cast(ptr + offset) - ->unknown_fields()); + reinterpret_cast(ptr + offset) + ->unknown_fields(&internal::GetEmptyString)); } MessageLite* DuplicateIfNonNullInternal(MessageLite* message) { @@ -829,3 +812,5 @@ void InitSCCImpl(SCCInfoBase* scc) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 11cf9aa42f99..bae0c1f760a4 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -67,6 +67,7 @@ namespace google { namespace protobuf { class Arena; +class Message; namespace io { class CodedInputStream; @@ -84,7 +85,17 @@ inline To DownCast(From& f) { } -PROTOBUF_EXPORT void InitProtobufDefaults(); +// This fastpath inlines a single branch instead of having to make the +// InitProtobufDefaults function call. +// It also generates less inlined code than a function-scope static initializer. +PROTOBUF_EXPORT extern std::atomic init_protobuf_defaults_state; +PROTOBUF_EXPORT void InitProtobufDefaultsSlow(); +PROTOBUF_EXPORT inline void InitProtobufDefaults() { + if (PROTOBUF_PREDICT_FALSE( + !init_protobuf_defaults_state.load(std::memory_order_acquire))) { + InitProtobufDefaultsSlow(); + } +} // This used by proto1 PROTOBUF_EXPORT inline const std::string& GetEmptyString() { @@ -149,6 +160,8 @@ PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena, MessageLite* submessage, Arena* submessage_arena); PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2); +// We specialize GenericSwap for non-lite messages to benefit from reflection. +PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2); template T* DuplicateIfNonNull(T* message) { diff --git a/src/google/protobuf/has_bits.h b/src/google/protobuf/has_bits.h index 540cac282f02..1144b9f4618c 100644 --- a/src/google/protobuf/has_bits.h +++ b/src/google/protobuf/has_bits.h @@ -47,7 +47,7 @@ namespace internal { template class HasBits { public: - HasBits() PROTOBUF_ALWAYS_INLINE { Clear(); } + constexpr HasBits() PROTOBUF_ALWAYS_INLINE : has_bits_{} {} void Clear() PROTOBUF_ALWAYS_INLINE { memset(has_bits_, 0, sizeof(has_bits_)); diff --git a/src/google/protobuf/implicit_weak_message.cc b/src/google/protobuf/implicit_weak_message.cc index 539061693c79..528cf95d4108 100644 --- a/src/google/protobuf/implicit_weak_message.cc +++ b/src/google/protobuf/implicit_weak_message.cc @@ -63,3 +63,5 @@ const ImplicitWeakMessage* ImplicitWeakMessage::default_instance() { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h index a3348daacb6a..bfa6a813b3a6 100644 --- a/src/google/protobuf/implicit_weak_message.h +++ b/src/google/protobuf/implicit_weak_message.h @@ -56,8 +56,8 @@ namespace internal { // message type does not get linked into the binary. class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { public: - ImplicitWeakMessage() : arena_(NULL) {} - explicit ImplicitWeakMessage(Arena* arena) : arena_(arena) {} + ImplicitWeakMessage() {} + explicit ImplicitWeakMessage(Arena* arena) : MessageLite(arena) {} static const ImplicitWeakMessage* default_instance(); @@ -68,8 +68,6 @@ class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { return Arena::CreateMessage(arena); } - Arena* GetArena() const override { return arena_; } - void Clear() override { data_.clear(); } bool IsInitialized() const override { return true; } @@ -93,7 +91,6 @@ class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { typedef void InternalArenaConstructable_; private: - Arena* const arena_; std::string data_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImplicitWeakMessage); }; @@ -103,7 +100,7 @@ template class ImplicitWeakTypeHandler { public: typedef MessageLite Type; - static const bool Moveable = false; + static constexpr bool Moveable = false; static inline MessageLite* NewFromPrototype(const MessageLite* prototype, Arena* arena = NULL) { @@ -132,7 +129,7 @@ class ImplicitWeakTypeHandler { template struct WeakRepeatedPtrField { using TypeHandler = internal::ImplicitWeakTypeHandler; - WeakRepeatedPtrField() : weak() {} + constexpr WeakRepeatedPtrField() : weak() {} explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {} ~WeakRepeatedPtrField() { weak.template Destroy(); } diff --git a/src/google/protobuf/inlined_string_field.h b/src/google/protobuf/inlined_string_field.h deleted file mode 100644 index 991c0e1f3f3e..000000000000 --- a/src/google/protobuf/inlined_string_field.h +++ /dev/null @@ -1,260 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. - -#ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ -#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ - -#include -#include - -#include -#include - -// Must be included last. -#include - -#ifdef SWIG -#error "You cannot SWIG proto headers" -#endif - -namespace google { -namespace protobuf { - -class Arena; - -namespace internal { - -// InlinedStringField wraps a std::string instance and exposes an API similar to -// ArenaStringPtr's wrapping of a std::string* instance. As std::string is -// never allocated on the Arena, we expose only the *NoArena methods of -// ArenaStringPtr. -// -// default_value parameters are taken for consistency with ArenaStringPtr, but -// are not used for most methods. With inlining, these should be removed from -// the generated binary. -class PROTOBUF_EXPORT InlinedStringField { - public: - InlinedStringField() PROTOBUF_ALWAYS_INLINE; - explicit InlinedStringField(const std::string& default_value); - - void AssignWithDefault(const std::string* default_value, - const InlinedStringField& from) PROTOBUF_ALWAYS_INLINE; - - void ClearToEmpty(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - ClearToEmptyNoArena(default_value); - } - void ClearNonDefaultToEmpty() PROTOBUF_ALWAYS_INLINE { - ClearNonDefaultToEmptyNoArena(); - } - void ClearToEmptyNoArena(const std::string* /*default_value*/) - PROTOBUF_ALWAYS_INLINE { - ClearNonDefaultToEmptyNoArena(); - } - void ClearNonDefaultToEmptyNoArena() PROTOBUF_ALWAYS_INLINE; - - void ClearToDefault(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - ClearToDefaultNoArena(default_value); - } - void ClearToDefaultNoArena(const std::string* default_value) - PROTOBUF_ALWAYS_INLINE; - - void Destroy(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - DestroyNoArena(default_value); - } - void DestroyNoArena(const std::string* default_value) PROTOBUF_ALWAYS_INLINE; - - const std::string& Get() const PROTOBUF_ALWAYS_INLINE { return GetNoArena(); } - const std::string& GetNoArena() const PROTOBUF_ALWAYS_INLINE; - - std::string* Mutable(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - return MutableNoArena(default_value); - } - std::string* MutableNoArena(const std::string* default_value) - PROTOBUF_ALWAYS_INLINE; - - std::string* Release(const std::string* default_value, Arena* /*arena*/) { - return ReleaseNoArena(default_value); - } - std::string* ReleaseNonDefault(const std::string* default_value, - Arena* /*arena*/) { - return ReleaseNonDefaultNoArena(default_value); - } - std::string* ReleaseNoArena(const std::string* default_value) { - return ReleaseNonDefaultNoArena(default_value); - } - std::string* ReleaseNonDefaultNoArena(const std::string* default_value); - - void Set(const std::string* default_value, StringPiece value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetLite(const std::string* default_value, StringPiece value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetNoArena(const std::string* default_value, - StringPiece value) PROTOBUF_ALWAYS_INLINE; - - void Set(const std::string* default_value, const std::string& value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetLite(const std::string* default_value, const std::string& value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetNoArena(const std::string* default_value, - const std::string& value) PROTOBUF_ALWAYS_INLINE; - - void SetNoArena(const std::string* default_value, - std::string&& value) PROTOBUF_ALWAYS_INLINE; - void SetAllocated(const std::string* default_value, std::string* value, - Arena* /*arena*/) { - SetAllocatedNoArena(default_value, value); - } - void SetAllocatedNoArena(const std::string* default_value, - std::string* value); - void Swap(InlinedStringField* from) PROTOBUF_ALWAYS_INLINE; - std::string* UnsafeMutablePointer(); - void UnsafeSetDefault(const std::string* default_value); - std::string* UnsafeArenaRelease(const std::string* default_value, - Arena* arena); - void UnsafeArenaSetAllocated(const std::string* default_value, - std::string* value, Arena* arena); - - bool IsDefault(const std::string* /*default_value*/) { return false; } - - private: - std::string value_; -}; - -inline InlinedStringField::InlinedStringField() {} - -inline InlinedStringField::InlinedStringField(const std::string& default_value) - : value_(default_value) {} - -inline void InlinedStringField::AssignWithDefault( - const std::string* /*default_value*/, const InlinedStringField& from) { - value_ = from.value_; -} - -inline const std::string& InlinedStringField::GetNoArena() const { - return value_; -} - -inline std::string* InlinedStringField::MutableNoArena(const std::string*) { - return &value_; -} - -inline void InlinedStringField::SetAllocatedNoArena( - const std::string* default_value, std::string* value) { - if (value == NULL) { - value_.assign(*default_value); - } else { - value_.assign(std::move(*value)); - delete value; - } -} - -inline void InlinedStringField::DestroyNoArena(const std::string*) { - // This is invoked from the generated message's ArenaDtor, which is used to - // clean up objects not allocated on the Arena. - this->~InlinedStringField(); -} - -inline void InlinedStringField::ClearNonDefaultToEmptyNoArena() { - value_.clear(); -} - -inline void InlinedStringField::ClearToDefaultNoArena( - const std::string* default_value) { - value_.assign(*default_value); -} - -inline std::string* InlinedStringField::ReleaseNonDefaultNoArena( - const std::string* default_value) { - std::string* released = new std::string(*default_value); - value_.swap(*released); - return released; -} - -inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, - StringPiece value) { - value_.assign(value.data(), value.length()); -} - -inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, - const std::string& value) { - value_.assign(value); -} - -inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, - std::string&& value) { - value_.assign(std::move(value)); -} - -inline void InlinedStringField::Swap(InlinedStringField* from) { - value_.swap(from->value_); -} - -inline std::string* InlinedStringField::UnsafeMutablePointer() { - return &value_; -} - -inline void InlinedStringField::UnsafeSetDefault( - const std::string* default_value) { - value_.assign(*default_value); -} - -inline std::string* InlinedStringField::UnsafeArenaRelease( - const std::string* default_value, Arena* /*arena*/) { - return ReleaseNoArena(default_value); -} - -inline void InlinedStringField::UnsafeArenaSetAllocated( - const std::string* default_value, std::string* value, Arena* /*arena*/) { - if (value == NULL) { - value_.assign(*default_value); - } else { - value_.assign(*value); - } -} - -} // namespace internal -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index 59d86f98333e..2b20e0a5ce6e 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -312,7 +312,7 @@ bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) { uint8 bytes[sizeof(*value)]; const uint8* ptr; - if (BufferSize() >= sizeof(*value)) { + if (BufferSize() >= static_cast(sizeof(*value))) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -329,7 +329,7 @@ bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { uint8 bytes[sizeof(*value)]; const uint8* ptr; - if (BufferSize() >= sizeof(*value)) { + if (BufferSize() >= static_cast(sizeof(*value))) { // Fast path: Enough bytes in the buffer to read directly. ptr = buffer_; Advance(sizeof(*value)); @@ -351,7 +351,7 @@ template const uint8* DecodeVarint64KnownSize(const uint8* buffer, uint64* value) { GOOGLE_DCHECK_GT(N, 0); uint64 result = static_cast(buffer[N - 1]) << (7 * (N - 1)); - for (int i = 0, offset = 0; i < N - 1; i++, offset += 7) { + for (size_t i = 0, offset = 0; i < N - 1; i++, offset += 7) { result += static_cast(buffer[i] - 0x80) << offset; } *value = result; @@ -954,3 +954,5 @@ uint8* CodedOutputStream::WriteStringWithSizeToArray(const std::string& str, } // namespace io } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h old mode 100755 new mode 100644 index 5f9feb80c361..0fff1782cf07 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -960,7 +960,7 @@ class PROTOBUF_EXPORT EpsCopyOutputStream { // buffers to ensure there is no error as of yet. uint8* FlushAndResetBuffer(uint8*); - // The following functions mimick the old CodedOutputStream behavior as close + // The following functions mimic the old CodedOutputStream behavior as close // as possible. They flush the current state to the stream, behave as // the old CodedOutputStream and then return to normal operation. bool Skip(int count, uint8** pp); @@ -1159,7 +1159,7 @@ class PROTOBUF_EXPORT CodedOutputStream { // This is identical to WriteVarint32(), but optimized for writing tags. // In particular, if the input is a compile-time constant, this method // compiles down to a couple instructions. - // Always inline because otherwise the aformentioned optimization can't work, + // Always inline because otherwise the aforementioned optimization can't work, // but GCC by default doesn't want to inline this. void WriteTag(uint32 value); // Like WriteTag() but writing directly to the target array. diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc index 7a80aed34079..d2f8959c7b7a 100644 --- a/src/google/protobuf/io/coded_stream_unittest.cc +++ b/src/google/protobuf/io/coded_stream_unittest.cc @@ -132,7 +132,7 @@ namespace { class CodedStreamTest : public testing::Test { protected: // Buffer used during most of the tests. This assumes tests run sequentially. - static const int kBufferSize = 1024 * 64; + static constexpr int kBufferSize = 1024 * 64; static uint8 buffer_[kBufferSize]; }; @@ -1344,3 +1344,5 @@ TEST_F(CodedStreamTest, InputOver2G) { } // namespace io } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc index 86e212677e94..ad6bb5f1c422 100644 --- a/src/google/protobuf/io/gzip_stream.cc +++ b/src/google/protobuf/io/gzip_stream.cc @@ -298,7 +298,7 @@ bool GzipOutputStream::Next(void** data, int* size) { return true; } void GzipOutputStream::BackUp(int count) { - GOOGLE_CHECK_GE(zcontext_.avail_in, count); + GOOGLE_CHECK_GE(zcontext_.avail_in, static_cast(count)); zcontext_.avail_in -= count; } int64_t GzipOutputStream::ByteCount() const { diff --git a/src/google/protobuf/io/io_win32.cc b/src/google/protobuf/io/io_win32.cc old mode 100755 new mode 100644 diff --git a/src/google/protobuf/io/io_win32.h b/src/google/protobuf/io/io_win32.h old mode 100755 new mode 100644 diff --git a/src/google/protobuf/io/io_win32_unittest.cc b/src/google/protobuf/io/io_win32_unittest.cc old mode 100755 new mode 100644 diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc index f8d4d2b1f951..230960c908ad 100644 --- a/src/google/protobuf/io/printer.cc +++ b/src/google/protobuf/io/printer.cc @@ -296,7 +296,7 @@ void Printer::FormatInternal(const std::vector& args, } push_back(c); } - if (arg_index != args.size()) { + if (arg_index != static_cast(args.size())) { GOOGLE_LOG(FATAL) << " Unused arguments. " << save; } if (!annotations.empty()) { @@ -305,7 +305,7 @@ void Printer::FormatInternal(const std::vector& args, } const char* Printer::WriteVariable( - const std::vector& args, + const std::vector& args, const std::map& vars, const char* format, int* arg_index, std::vector* annotations) { auto start = format; @@ -324,7 +324,7 @@ const char* Printer::WriteVariable( GOOGLE_CHECK(std::isdigit(start[1])); GOOGLE_CHECK_EQ(end - start, 2); int idx = start[1] - '1'; - if (idx < 0 || idx >= args.size()) { + if (idx < 0 || static_cast(idx) >= args.size()) { GOOGLE_LOG(FATAL) << "Annotation ${" << idx + 1 << "$ is out of bounds."; } if (idx > *arg_index) { @@ -358,10 +358,10 @@ const char* Printer::WriteVariable( start_var, static_cast(end_var - start_var)}; std::string sub; if (std::isdigit(var_name[0])) { - GOOGLE_CHECK_EQ(var_name.size(), 1); // No need for multi-digits + GOOGLE_CHECK_EQ(var_name.size(), 1U); // No need for multi-digits int idx = var_name[0] - '1'; // Start counting at 1 GOOGLE_CHECK_GE(idx, 0); - if (idx >= args.size()) { + if (static_cast(idx) >= args.size()) { GOOGLE_LOG(FATAL) << "Argument $" << idx + 1 << "$ is out of bounds."; } if (idx > *arg_index) { diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h old mode 100755 new mode 100644 index a6e619e4f713..64336ebcefed --- a/src/google/protobuf/io/printer.h +++ b/src/google/protobuf/io/printer.h @@ -194,8 +194,8 @@ class PROTOBUF_EXPORT Printer { ~Printer(); - // Link a substitution variable emitted by the last call to Print to the object - // described by descriptor. + // Link a substitution variable emitted by the last call to Print to the + // object described by descriptor. template void Annotate(const char* varname, const SomeDescriptor* descriptor) { Annotate(varname, varname, descriptor); diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc index ca45d6781370..ed54d1dd1d06 100644 --- a/src/google/protobuf/io/printer_unittest.cc +++ b/src/google/protobuf/io/printer_unittest.cc @@ -573,7 +573,7 @@ TEST(Printer, WriteFailurePartial) { EXPECT_TRUE(printer.failed()); // Buffer should contain the first 17 bytes written. - EXPECT_EQ("0123456789abcdef<", string(buffer, sizeof(buffer))); + EXPECT_EQ("0123456789abcdef<", std::string(buffer, sizeof(buffer))); } TEST(Printer, WriteFailureExact) { @@ -595,7 +595,7 @@ TEST(Printer, WriteFailureExact) { EXPECT_TRUE(printer.failed()); // Buffer should contain the first 16 bytes written. - EXPECT_EQ("0123456789abcdef", string(buffer, sizeof(buffer))); + EXPECT_EQ("0123456789abcdef", std::string(buffer, sizeof(buffer))); } TEST(Printer, FormatInternal) { diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index ff839467cba8..129b4889e53d 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc @@ -888,7 +888,8 @@ bool Tokenizer::ParseInteger(const std::string& text, uint64 max_value, // token, but Tokenizer still think it's integer. return false; } - if (digit > max_value || result > (max_value - digit) / base) { + if (static_cast(digit) > max_value || + result > (max_value - digit) / base) { // Overflow. return false; } @@ -918,7 +919,8 @@ double Tokenizer::ParseFloat(const std::string& text) { ++end; } - GOOGLE_LOG_IF(DFATAL, end - start != text.size() || *start == '-') + GOOGLE_LOG_IF(DFATAL, + static_cast(end - start) != text.size() || *start == '-') << " Tokenizer::ParseFloat() passed text that could not have been" " tokenized as a float: " << CEscape(text); @@ -940,14 +942,15 @@ static void AppendUTF8(uint32 code_point, std::string* output) { tmp = 0x00e08080 | ((code_point & 0xf000) << 4) | ((code_point & 0x0fc0) << 2) | (code_point & 0x003f); len = 3; - } else if (code_point <= 0x1fffff) { + } else if (code_point <= 0x10ffff) { tmp = 0xf0808080 | ((code_point & 0x1c0000) << 6) | ((code_point & 0x03f000) << 4) | ((code_point & 0x000fc0) << 2) | (code_point & 0x003f); len = 4; } else { - // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is - // normally only defined up to there as well. + // Unicode code points end at 0x10FFFF, so this is out-of-range. + // ConsumeString permits hex values up to 0x1FFFFF, and FetchUnicodePoint + // doesn't perform a range check. StringAppendF(output, "\\U%08x", code_point); return; } @@ -1113,8 +1116,8 @@ void Tokenizer::ParseStringAppend(const std::string& text, template static bool AllInClass(const std::string& s) { - for (int i = 0; i < s.size(); ++i) { - if (!CharacterClass::InClass(s[i])) return false; + for (const char character : s) { + if (!CharacterClass::InClass(character)) return false; } return true; } diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc index b14eddf9d8a0..91c440cebfa3 100644 --- a/src/google/protobuf/io/tokenizer_unittest.cc +++ b/src/google/protobuf/io/tokenizer_unittest.cc @@ -808,8 +808,11 @@ TEST_F(TokenizerTest, ParseString) { Tokenizer::ParseString("'\\ud852XX'", &output); EXPECT_EQ("\xed\xa1\x92XX", output); // Malformed escape: Demons may fly out of the nose. - Tokenizer::ParseString("\\u0", &output); + Tokenizer::ParseString("'\\u0'", &output); EXPECT_EQ("u0", output); + // Beyond the range of valid UTF-32 code units. + Tokenizer::ParseString("'\\U00110000\\U00200000\\UFFFFFFFF'", &output); + EXPECT_EQ("\\U00110000\\U00200000\\Uffffffff", output); // Test invalid strings that will never be tokenized as strings. #ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc index 4b1bf802e007..52617e9efec9 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl.cc @@ -165,25 +165,14 @@ int FileInputStream::CopyingFileInputStream::Skip(int count) { // =================================================================== FileOutputStream::FileOutputStream(int file_descriptor, int block_size) - : copying_output_(file_descriptor), impl_(©ing_output_, block_size) {} - -FileOutputStream::~FileOutputStream() { impl_.Flush(); } + : CopyingOutputStreamAdaptor(©ing_output_), + copying_output_(file_descriptor) {} bool FileOutputStream::Close() { - bool flush_succeeded = impl_.Flush(); + bool flush_succeeded = Flush(); return copying_output_.Close() && flush_succeeded; } -bool FileOutputStream::Flush() { return impl_.Flush(); } - -bool FileOutputStream::Next(void** data, int* size) { - return impl_.Next(data, size); -} - -void FileOutputStream::BackUp(int count) { impl_.BackUp(count); } - -int64_t FileOutputStream::ByteCount() const { return impl_.ByteCount(); } - FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( int file_descriptor) : file_(file_descriptor), @@ -191,6 +180,8 @@ FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( is_closed_(false), errno_(0) {} +FileOutputStream::~FileOutputStream() { Flush(); } + FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() { if (close_on_delete_) { if (!Close()) { diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index b23a86d4f6fe..0206e3887eb7 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h @@ -48,7 +48,6 @@ #include #include - #include namespace google { @@ -140,13 +139,14 @@ class PROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { // harming performance. Also, it's conceivable that FileOutputStream could // someday be enhanced to use zero-copy file descriptors on OSs which // support them. -class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { +class PROTOBUF_EXPORT FileOutputStream : public CopyingOutputStreamAdaptor { public: // Creates a stream that writes to the given Unix file descriptor. // If a block_size is given, it specifies the size of the buffers // that should be returned by Next(). Otherwise, a reasonable default // is used. explicit FileOutputStream(int file_descriptor, int block_size = -1); + ~FileOutputStream() override; // Flushes any buffers and closes the underlying file. Returns false if @@ -154,11 +154,6 @@ class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { // Even if an error occurs, the file descriptor is closed when this returns. bool Close(); - // Flushes FileOutputStream's buffers but does not close the - // underlying file. No special measures are taken to ensure that - // underlying operating system file object is synchronized to disk. - bool Flush(); - // By default, the file descriptor is not closed when the stream is // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: // This leaves no way for the caller to detect if close() fails. If @@ -172,11 +167,6 @@ class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { // fail. int GetErrno() const { return copying_output_.GetErrno(); } - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size) override; - void BackUp(int count) override; - int64_t ByteCount() const override; - private: class PROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { public: @@ -203,7 +193,6 @@ class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { }; CopyingFileOutputStream copying_output_; - CopyingOutputStreamAdaptor impl_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); }; diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index 51cda2a88e82..0eeeb0e760ab 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -140,29 +140,25 @@ StringOutputStream::StringOutputStream(std::string* target) : target_(target) {} bool StringOutputStream::Next(void** data, int* size) { GOOGLE_CHECK(target_ != NULL); - int old_size = target_->size(); + size_t old_size = target_->size(); // Grow the string. + size_t new_size; if (old_size < target_->capacity()) { // Resize the string to match its capacity, since we can get away // without a memory allocation this way. - STLStringResizeUninitialized(target_, target_->capacity()); + new_size = target_->capacity(); } else { - // Size has reached capacity, try to double the size. - if (old_size > std::numeric_limits::max() / 2) { - // Can not double the size otherwise it is going to cause integer - // overflow in the expression below: old_size * 2 "; - GOOGLE_LOG(ERROR) << "Cannot allocate buffer larger than kint32max for " - << "StringOutputStream."; - return false; - } - // Double the size, also make sure that the new size is at least - // kMinimumSize. - STLStringResizeUninitialized( - target_, - std::max(old_size * 2, - kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. + // Size has reached capacity, try to double it. + new_size = old_size * 2; } + // Avoid integer overflow in returned '*size'. + new_size = std::min(new_size, old_size + std::numeric_limits::max()); + // Increase the size, also make sure that it is at least kMinimumSize. + STLStringResizeUninitialized( + target_, + std::max(new_size, + kMinimumSize + 0)); // "+ 0" works around GCC4 weirdness. *data = mutable_string_data(target_) + old_size; *size = target_->size() - old_size; @@ -172,7 +168,7 @@ bool StringOutputStream::Next(void** data, int* size) { void StringOutputStream::BackUp(int count) { GOOGLE_CHECK_GE(count, 0); GOOGLE_CHECK(target_ != NULL); - GOOGLE_CHECK_LE(count, target_->size()); + GOOGLE_CHECK_LE(static_cast(count), target_->size()); target_->resize(target_->size() - count); } @@ -346,6 +342,37 @@ int64_t CopyingOutputStreamAdaptor::ByteCount() const { return position_ + buffer_used_; } +bool CopyingOutputStreamAdaptor::WriteAliasedRaw(const void* data, int size) { + if (size >= buffer_size_) { + if (!Flush() || !copying_stream_->Write(data, size)) { + return false; + } + GOOGLE_DCHECK_EQ(buffer_used_, 0); + position_ += size; + return true; + } + + void* out; + int out_size; + while (true) { + if (!Next(&out, &out_size)) { + return false; + } + + if (size <= out_size) { + std::memcpy(out, data, size); + BackUp(out_size - size); + return true; + } + + std::memcpy(out, data, out_size); + data = static_cast(data) + out_size; + size -= out_size; + } + return true; +} + + bool CopyingOutputStreamAdaptor::WriteBuffer() { if (failed_) { // Already failed on a previous write. diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index 26572cc55c20..cfe81d2cc1f4 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -150,7 +150,7 @@ class PROTOBUF_EXPORT StringOutputStream : public ZeroCopyOutputStream { int64_t ByteCount() const override; private: - static const int kMinimumSize = 16; + static constexpr size_t kMinimumSize = 16; std::string* target_; @@ -307,6 +307,8 @@ class PROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { bool Next(void** data, int* size) override; void BackUp(int count) override; int64_t ByteCount() const override; + bool WriteAliasedRaw(const void* data, int size) override; + bool AllowsAliasing() const override { return true; } private: // Write the current buffer, if it is present. diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index bec9df0af6c6..cc53949fce58 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -112,7 +112,7 @@ class IoTest : public testing::Test { // that it matches the string. void ReadString(ZeroCopyInputStream* input, const std::string& str); // Writes some text to the output stream in a particular order. Returns - // the number of bytes written, incase the caller needs that to set up an + // the number of bytes written, in case the caller needs that to set up an // input stream. int WriteStuff(ZeroCopyOutputStream* output); // Reads text from an input stream and expects it to match what @@ -712,6 +712,21 @@ TEST_F(IoTest, StringIo) { } } +// Verifies that outputs up to kint32max can be created. +TEST_F(IoTest, LargeOutput) { + std::string str; + StringOutputStream output(&str); + void* unused_data; + int size; + // Repeatedly calling Next should eventually grow the buffer to kint32max. + do { + EXPECT_TRUE(output.Next(&unused_data, &size)); + } while (str.size() < std::numeric_limits::max()); + // Further increases should be possible. + output.Next(&unused_data, &size); + EXPECT_GT(size, 0); +} + // To test files, we create a temporary file, write, read, truncate, repeat. TEST_F(IoTest, FileIo) { diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc index cd5ccc4eab07..deb5f06b8335 100644 --- a/src/google/protobuf/lite_unittest.cc +++ b/src/google/protobuf/lite_unittest.cc @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include @@ -613,7 +615,7 @@ TEST(Lite, AllLite28) { protobuf_unittest::TestMapLite message1, message2; std::string data; MapLiteTestUtil::SetMapFields(&message1); - int size = message1.ByteSize(); + size_t size = message1.ByteSizeLong(); data.resize(size); ::google::protobuf::uint8* start = reinterpret_cast<::google::protobuf::uint8*>(::google::protobuf::string_as_array(&data)); ::google::protobuf::uint8* end = message1.SerializeWithCachedSizesToArray(start); @@ -630,7 +632,7 @@ TEST(Lite, AllLite29) { // Test the generated SerializeWithCachedSizes() protobuf_unittest::TestMapLite message1, message2; MapLiteTestUtil::SetMapFields(&message1); - int size = message1.ByteSize(); + size_t size = message1.ByteSizeLong(); std::string data; data.resize(size); { @@ -1187,5 +1189,84 @@ TEST(Lite, AliasedEnum) { EXPECT_EQ(protobuf_unittest::DupEnum::FOO2, value); } + +TEST(Lite, CodedInputStreamRollback) { + { + protobuf_unittest::TestAllTypesLite m; + m.set_optional_bytes(std::string(30, 'a')); + std::string serialized = m.SerializeAsString(); + serialized += '\014'; + serialized += std::string(3, ' '); + io::ArrayInputStream is(serialized.data(), serialized.size(), + serialized.size() - 6); + { + io::CodedInputStream cis(&is); + m.Clear(); + m.MergePartialFromCodedStream(&cis); + EXPECT_TRUE(cis.LastTagWas(12)); + EXPECT_FALSE(cis.ConsumedEntireMessage()); + // Should leave is with 3 spaces; + } + const void* data; + int size; + ASSERT_TRUE(is.Next(&data, &size)); + ASSERT_EQ(size, 3); + EXPECT_EQ(memcmp(data, " ", 3), 0); + } + { + protobuf_unittest::TestPackedTypesLite m; + constexpr int kCount = 30; + for (int i = 0; i < kCount; i++) m.add_packed_fixed32(i); + std::string serialized = m.SerializeAsString(); + serialized += '\014'; + serialized += std::string(3, ' '); + // Buffer breaks in middle of a fixed32. + io::ArrayInputStream is(serialized.data(), serialized.size(), + serialized.size() - 7); + { + io::CodedInputStream cis(&is); + m.Clear(); + m.MergePartialFromCodedStream(&cis); + EXPECT_TRUE(cis.LastTagWas(12)); + EXPECT_FALSE(cis.ConsumedEntireMessage()); + // Should leave is with 3 spaces; + } + ASSERT_EQ(m.packed_fixed32_size(), kCount); + for (int i = 0; i < kCount; i++) EXPECT_EQ(m.packed_fixed32(i), i); + const void* data; + int size; + ASSERT_TRUE(is.Next(&data, &size)); + ASSERT_EQ(size, 3); + EXPECT_EQ(memcmp(data, " ", 3), 0); + } + { + protobuf_unittest::TestPackedTypesLite m; + constexpr int kCount = 30; + // Make sure we output 2 byte varints + for (int i = 0; i < kCount; i++) m.add_packed_fixed32(128 + i); + std::string serialized = m.SerializeAsString(); + serialized += '\014'; + serialized += std::string(3, ' '); + // Buffer breaks in middle of a 2 byte varint. + io::ArrayInputStream is(serialized.data(), serialized.size(), + serialized.size() - 5); + { + io::CodedInputStream cis(&is); + m.Clear(); + m.MergePartialFromCodedStream(&cis); + EXPECT_TRUE(cis.LastTagWas(12)); + EXPECT_FALSE(cis.ConsumedEntireMessage()); + // Should leave is with 3 spaces; + } + ASSERT_EQ(m.packed_fixed32_size(), kCount); + for (int i = 0; i < kCount; i++) EXPECT_EQ(m.packed_fixed32(i), i + 128); + const void* data; + int size; + ASSERT_TRUE(is.Next(&data, &size)); + ASSERT_EQ(size, 3); + EXPECT_EQ(memcmp(data, " ", 3), 0); + } +} + } // namespace protobuf } // namespace google diff --git a/php/ext/google/protobuf/utf8.h b/src/google/protobuf/map.cc similarity index 87% rename from php/ext/google/protobuf/utf8.h rename to src/google/protobuf/map.cc index 28b8d874a8b5..d60a9a285cc8 100644 --- a/php/ext/google/protobuf/utf8.h +++ b/src/google/protobuf/map.cc @@ -28,9 +28,14 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef GOOGLE_PROTOBUF_UTF8_H_ -#define GOOGLE_PROTOBUF_UTF8_H_ +#include -bool is_structurally_valid_utf8(const char* buf, int len); +namespace google { +namespace protobuf { +namespace internal { -#endif // GOOGLE_PROTOBUF_UTF8_H_ +void* const kGlobalEmptyTable[kGlobalEmptyTableSize] = {nullptr}; + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index bc977015970a..7efee12526a9 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -37,12 +37,19 @@ #ifndef GOOGLE_PROTOBUF_MAP_H__ #define GOOGLE_PROTOBUF_MAP_H__ +#include #include #include #include // To support Visual Studio 2008 -#include +#include +#include +#include #include +#if defined(__cpp_lib_string_view) +#include +#endif // defined(__cpp_lib_string_view) + #include #include #include @@ -69,12 +76,12 @@ struct is_proto_enum; namespace internal { template + WireFormatLite::FieldType value_wire_type> class MapFieldLite; template + WireFormatLite::FieldType value_wire_type> class MapField; template @@ -83,27 +90,262 @@ class TypeDefinedMapFieldBase; class DynamicMapField; class GeneratedMessageReflection; + +// re-implement std::allocator to use arena allocator for memory allocation. +// Used for Map implementation. Users should not use this class +// directly. +template +class MapAllocator { + public: + using value_type = U; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; + using size_type = size_t; + using difference_type = ptrdiff_t; + + constexpr MapAllocator() : arena_(nullptr) {} + explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {} + template + MapAllocator(const MapAllocator& allocator) // NOLINT(runtime/explicit) + : arena_(allocator.arena()) {} + + pointer allocate(size_type n, const void* /* hint */ = nullptr) { + // If arena is not given, malloc needs to be called which doesn't + // construct element object. + if (arena_ == nullptr) { + return static_cast(::operator new(n * sizeof(value_type))); + } else { + return reinterpret_cast( + Arena::CreateArray(arena_, n * sizeof(value_type))); + } + } + + void deallocate(pointer p, size_type n) { + if (arena_ == nullptr) { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(p, n * sizeof(value_type)); +#else + (void)n; + ::operator delete(p); +#endif + } + } + +#if !defined(GOOGLE_PROTOBUF_OS_APPLE) && !defined(GOOGLE_PROTOBUF_OS_NACL) && \ + !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN) + template + void construct(NodeType* p, Args&&... args) { + // Clang 3.6 doesn't compile static casting to void* directly. (Issue + // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall + // not cast away constness". So first the maybe const pointer is casted to + // const void* and after the const void* is const casted. + new (const_cast(static_cast(p))) + NodeType(std::forward(args)...); + } + + template + void destroy(NodeType* p) { + p->~NodeType(); + } +#else + void construct(pointer p, const_reference t) { new (p) value_type(t); } + + void destroy(pointer p) { p->~value_type(); } +#endif + + template + struct rebind { + using other = MapAllocator; + }; + + template + bool operator==(const MapAllocator& other) const { + return arena_ == other.arena_; + } + + template + bool operator!=(const MapAllocator& other) const { + return arena_ != other.arena_; + } + + // To support Visual Studio 2008 + size_type max_size() const { + // parentheses around (std::...:max) prevents macro warning of max() + return (std::numeric_limits::max)(); + } + + // To support gcc-4.4, which does not properly + // support templated friend classes + Arena* arena() const { return arena_; } + + private: + using DestructorSkippable_ = void; + Arena* arena_; +}; + +template +using KeyForTree = + typename std::conditional::value, T, + std::reference_wrapper>::type; + +// Default case: Not transparent. +// We use std::hash/std::less and all the lookup functions +// only accept `key_type`. +template +struct TransparentSupport { + using hash = std::hash; + using less = std::less; + + static bool Equals(const key_type& a, const key_type& b) { return a == b; } + + template + using key_arg = key_type; +}; + +#if defined(__cpp_lib_string_view) +// If std::string_view is available, we add transparent support for std::string +// keys. We use std::hash as it supports the input types we +// care about. The lookup functions accept arbitrary `K`. This will include any +// key type that is convertible to std::string_view. +template <> +struct TransparentSupport { + static std::string_view ImplicitConvert(std::string_view str) { return str; } + // If the element is not convertible to std::string_view, try to convert to + // std::string first. + // The template makes this overload lose resolution when both have the same + // rank otherwise. + template + static std::string_view ImplicitConvert(const std::string& str) { + return str; + } + + struct hash : private std::hash { + using is_transparent = void; + + template + size_t operator()(const T& str) const { + return base()(ImplicitConvert(str)); + } + + private: + const std::hash& base() const { return *this; } + }; + struct less { + using is_transparent = void; + + template + bool operator()(const T& t, const U& u) const { + return ImplicitConvert(t) < ImplicitConvert(u); + } + }; + + template + static bool Equals(const T& t, const U& u) { + return ImplicitConvert(t) == ImplicitConvert(u); + } + + template + using key_arg = K; +}; +#endif // defined(__cpp_lib_string_view) + +template +using TreeForMap = + std::map, void*, typename TransparentSupport::less, + MapAllocator, void*>>>; + +inline bool TableEntryIsEmpty(void* const* table, size_t b) { + return table[b] == nullptr; +} +inline bool TableEntryIsNonEmptyList(void* const* table, size_t b) { + return table[b] != nullptr && table[b] != table[b ^ 1]; +} +inline bool TableEntryIsTree(void* const* table, size_t b) { + return !TableEntryIsEmpty(table, b) && !TableEntryIsNonEmptyList(table, b); +} +inline bool TableEntryIsList(void* const* table, size_t b) { + return !TableEntryIsTree(table, b); +} + +// This captures all numeric types. +inline size_t MapValueSpaceUsedExcludingSelfLong(bool) { return 0; } +inline size_t MapValueSpaceUsedExcludingSelfLong(const std::string& str) { + return StringSpaceUsedExcludingSelfLong(str); +} +template ().SpaceUsedLong())> +size_t MapValueSpaceUsedExcludingSelfLong(const T& message) { + return message.SpaceUsedLong() - sizeof(T); +} + +constexpr size_t kGlobalEmptyTableSize = 1; +PROTOBUF_EXPORT extern void* const kGlobalEmptyTable[kGlobalEmptyTableSize]; + +// Space used for the table, trees, and nodes. +// Does not include the indirect space used. Eg the data of a std::string. +template +PROTOBUF_NOINLINE size_t SpaceUsedInTable(void** table, size_t num_buckets, + size_t num_elements, + size_t sizeof_node) { + size_t size = 0; + // The size of the table. + size += sizeof(void*) * num_buckets; + // All the nodes. + size += sizeof_node * num_elements; + // For each tree, count the overhead of the those nodes. + // Two buckets at a time because we only care about trees. + for (size_t b = 0; b < num_buckets; b += 2) { + if (internal::TableEntryIsTree(table, b)) { + using Tree = TreeForMap; + Tree* tree = static_cast(table[b]); + // Estimated cost of the red-black tree nodes, 3 pointers plus a + // bool (plus alignment, so 4 pointers). + size += tree->size() * + (sizeof(typename Tree::value_type) + sizeof(void*) * 4); + } + } + return size; +} + +template ::value || + !std::is_scalar::value>::type> +size_t SpaceUsedInValues(const Map* map) { + size_t size = 0; + for (const auto& v : *map) { + size += internal::MapValueSpaceUsedExcludingSelfLong(v.first) + + internal::MapValueSpaceUsedExcludingSelfLong(v.second); + } + return size; +} + +inline size_t SpaceUsedInValues(const void*) { return 0; } + } // namespace internal // This is the class for Map's internal value_type. Instead of using // std::pair as value_type, we use this class which provides us more control of // its process of construction and destruction. template -class MapPair { - public: - typedef const Key first_type; - typedef T second_type; +struct MapPair { + using first_type = const Key; + using second_type = T; MapPair(const Key& other_first, const T& other_second) : first(other_first), second(other_second) {} explicit MapPair(const Key& other_first) : first(other_first), second() {} + explicit MapPair(Key&& other_first) + : first(std::move(other_first)), second() {} MapPair(const MapPair& other) : first(other.first), second(other.second) {} ~MapPair() {} // Implicitly convertible to std::pair of compatible types. template - operator std::pair() const { + operator std::pair() const { // NOLINT(runtime/explicit) return std::pair(first, second); } @@ -128,37 +370,34 @@ class MapPair { template class Map { public: - typedef Key key_type; - typedef T mapped_type; - typedef MapPair value_type; + using key_type = Key; + using mapped_type = T; + using value_type = MapPair; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; + using pointer = value_type*; + using const_pointer = const value_type*; + using reference = value_type&; + using const_reference = const value_type&; - typedef size_t size_type; - typedef hash hasher; + using size_type = size_t; + using hasher = typename internal::TransparentSupport::hash; - Map() : arena_(NULL), default_enum_value_(0) { Init(); } - explicit Map(Arena* arena) : arena_(arena), default_enum_value_(0) { Init(); } + constexpr Map() : elements_(nullptr) {} + explicit Map(Arena* arena) : elements_(arena) {} - Map(const Map& other) - : arena_(NULL), default_enum_value_(other.default_enum_value_) { - Init(); - insert(other.begin(), other.end()); - } + Map(const Map& other) : Map() { insert(other.begin(), other.end()); } Map(Map&& other) noexcept : Map() { - if (other.arena_) { + if (other.arena() != nullptr) { *this = other; } else { swap(other); } } + Map& operator=(Map&& other) noexcept { if (this != &other) { - if (arena_ != other.arena_) { + if (arena() != other.arena()) { *this = other; } else { swap(other); @@ -168,139 +407,14 @@ class Map { } template - Map(const InputIt& first, const InputIt& last) - : arena_(NULL), default_enum_value_(0) { - Init(); + Map(const InputIt& first, const InputIt& last) : Map() { insert(first, last); } - ~Map() { - clear(); - if (arena_ == NULL) { - delete elements_; - } - } + ~Map() {} private: - void Init() { - elements_ = - Arena::Create(arena_, 0u, hasher(), Allocator(arena_)); - } - - // re-implement std::allocator to use arena allocator for memory allocation. - // Used for Map implementation. Users should not use this class - // directly. - template - class MapAllocator { - public: - typedef U value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - - MapAllocator() : arena_(NULL) {} - explicit MapAllocator(Arena* arena) : arena_(arena) {} - template - MapAllocator(const MapAllocator& allocator) - : arena_(allocator.arena()) {} - - pointer allocate(size_type n, const void* /* hint */ = 0) { - // If arena is not given, malloc needs to be called which doesn't - // construct element object. - if (arena_ == NULL) { - return static_cast(::operator new(n * sizeof(value_type))); - } else { - return reinterpret_cast( - Arena::CreateArray(arena_, n * sizeof(value_type))); - } - } - - void deallocate(pointer p, size_type n) { - if (arena_ == NULL) { -#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) - ::operator delete(p, n * sizeof(value_type)); -#else - (void)n; - ::operator delete(p); -#endif - } - } - -#if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) && \ - !defined(GOOGLE_PROTOBUF_OS_NACL) && \ - !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN) - template - void construct(NodeType* p, Args&&... args) { - // Clang 3.6 doesn't compile static casting to void* directly. (Issue - // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall - // not cast away constness". So first the maybe const pointer is casted to - // const void* and after the const void* is const casted. - new (const_cast(static_cast(p))) - NodeType(std::forward(args)...); - } - - template - void destroy(NodeType* p) { - p->~NodeType(); - } -#else - void construct(pointer p, const_reference t) { new (p) value_type(t); } - - void destroy(pointer p) { p->~value_type(); } -#endif - - template - struct rebind { - typedef MapAllocator other; - }; - - template - bool operator==(const MapAllocator& other) const { - return arena_ == other.arena_; - } - - template - bool operator!=(const MapAllocator& other) const { - return arena_ != other.arena_; - } - - // To support Visual Studio 2008 - size_type max_size() const { - // parentheses around (std::...:max) prevents macro warning of max() - return (std::numeric_limits::max)(); - } - - // To support gcc-4.4, which does not properly - // support templated friend classes - Arena* arena() const { return arena_; } - - private: - typedef void DestructorSkippable_; - Arena* const arena_; - }; - - // InnerMap's key type is Key and its value type is value_type*. We use a - // custom class here and for Node, below, to ensure that k_ is at offset 0, - // allowing safe conversion from pointer to Node to pointer to Key, and vice - // versa when appropriate. - class KeyValuePair { - public: - KeyValuePair(const Key& k, value_type* v) : k_(k), v_(v) {} - - const Key& key() const { return k_; } - Key& key() { return k_; } - value_type* value() const { return v_; } - value_type*& value() { return v_; } - - private: - Key k_; - value_type* v_; - }; - - typedef MapAllocator Allocator; + using Allocator = internal::MapAllocator; // InnerMap is a generic hash-based map. It doesn't contain any // protocol-buffer-specific logic. It is a chaining hash map with the @@ -317,7 +431,7 @@ class Map { // 2. The number of buckets is a power of two. // 3. Buckets are converted to trees in pairs: if we convert bucket b then // buckets b and b^1 will share a tree. Invariant: buckets b and b^1 have - // the same non-NULL value iff they are sharing a tree. (An alternative + // the same non-null value iff they are sharing a tree. (An alternative // implementation strategy would be to have a tag bit per bucket.) // 4. As is typical for hash_map and such, the Keys and Values are always // stored in linked list nodes. Pointers to elements are never invalidated @@ -327,27 +441,27 @@ class Map { // 6. Once we've tree-converted a bucket, it is never converted back. However, // the items a tree contains may wind up assigned to trees or lists upon a // rehash. - // 7. The code requires no C++ features from C++11 or later. + // 7. The code requires no C++ features from C++14 or later. // 8. Mutations to a map do not invalidate the map's iterators, pointers to // elements, or references to elements. // 9. Except for erase(iterator), any non-const method can reorder iterators. + // 10. InnerMap uses KeyForTree when using the Tree representation, which + // is either `Key`, if Key is a scalar, or `reference_wrapper` + // otherwise. This avoids unnecessary copies of string keys, for example. class InnerMap : private hasher { public: - typedef value_type* Value; - - InnerMap(size_type n, hasher h, Allocator alloc) - : hasher(h), + explicit constexpr InnerMap(Arena* arena) + : hasher(), num_elements_(0), - seed_(Seed()), - table_(NULL), - alloc_(alloc) { - n = TableSize(n); - table_ = CreateEmptyTable(n); - num_buckets_ = index_of_first_non_null_ = n; - } + num_buckets_(internal::kGlobalEmptyTableSize), + seed_(0), + index_of_first_non_null_(internal::kGlobalEmptyTableSize), + table_(const_cast(internal::kGlobalEmptyTable)), + alloc_(arena) {} ~InnerMap() { - if (table_ != NULL) { + if (alloc_.arena() == nullptr && + num_buckets_ != internal::kGlobalEmptyTableSize) { clear(); Dealloc(table_, num_buckets_); } @@ -358,42 +472,37 @@ class Map { // Linked-list nodes, as one would expect for a chaining hash table. struct Node { - KeyValuePair kv; + value_type kv; Node* next; }; - // This is safe only if the given pointer is known to point to a Key that is - // part of a Node. - static Node* NodePtrFromKeyPtr(Key* k) { - return reinterpret_cast(k); - } - - static Key* KeyPtrFromNodePtr(Node* node) { return &node->kv.key(); } + // Trees. The payload type is a copy of Key, so that we can query the tree + // with Keys that are not in any particular data structure. + // The value is a void* pointing to Node. We use void* instead of Node* to + // avoid code bloat. That way there is only one instantiation of the tree + // class per key type. + using Tree = internal::TreeForMap; + using TreeIterator = typename Tree::iterator; - // Trees. The payload type is pointer to Key, so that we can query the tree - // with Keys that are not in any particular data structure. When we insert, - // though, the pointer is always pointing to a Key that is inside a Node. - struct KeyCompare { - bool operator()(const Key* n0, const Key* n1) const { return *n0 < *n1; } - }; - typedef typename Allocator::template rebind::other KeyPtrAllocator; - typedef std::set Tree; - typedef typename Tree::iterator TreeIterator; + static Node* NodeFromTreeIterator(TreeIterator it) { + return static_cast(it->second); + } // iterator and const_iterator are instantiations of iterator_base. template - struct iterator_base { - typedef KeyValueType& reference; - typedef KeyValueType* pointer; + class iterator_base { + public: + using reference = KeyValueType&; + using pointer = KeyValueType*; // Invariants: // node_ is always correct. This is handy because the most common // operations are operator* and operator-> and they only use node_. - // When node_ is set to a non-NULL value, all the other non-const fields + // When node_ is set to a non-null value, all the other non-const fields // are updated to be correct also, but those fields can become stale // if the underlying map is modified. When those fields are needed they // are rechecked, and updated if necessary. - iterator_base() : node_(NULL), m_(NULL), bucket_index_(0) {} + iterator_base() : node_(nullptr), m_(nullptr), bucket_index_(0) {} explicit iterator_base(const InnerMap* m) : m_(m) { SearchFrom(m->index_of_first_non_null_); @@ -410,18 +519,18 @@ class Map { : node_(n), m_(m), bucket_index_(index) {} iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index) - : node_(NodePtrFromKeyPtr(*tree_it)), m_(m), bucket_index_(index) { + : node_(NodeFromTreeIterator(tree_it)), m_(m), bucket_index_(index) { // Invariant: iterators that use buckets with trees have an even // bucket_index_. GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0u); } // Advance through buckets, looking for the first that isn't empty. - // If nothing non-empty is found then leave node_ == NULL. + // If nothing non-empty is found then leave node_ == nullptr. void SearchFrom(size_type start_bucket) { GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ || - m_->table_[m_->index_of_first_non_null_] != NULL); - node_ = NULL; + m_->table_[m_->index_of_first_non_null_] != nullptr); + node_ = nullptr; for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_; bucket_index_++) { if (m_->TableEntryIsNonEmptyList(bucket_index_)) { @@ -430,7 +539,7 @@ class Map { } else if (m_->TableEntryIsTree(bucket_index_)) { Tree* tree = static_cast(m_->table_[bucket_index_]); GOOGLE_DCHECK(!tree->empty()); - node_ = NodePtrFromKeyPtr(*tree->begin()); + node_ = NodeFromTreeIterator(tree->begin()); break; } } @@ -447,7 +556,7 @@ class Map { } iterator_base& operator++() { - if (node_->next == NULL) { + if (node_->next == nullptr) { TreeIterator tree_it; const bool is_list = revalidate_if_necessary(&tree_it); if (is_list) { @@ -458,7 +567,7 @@ class Map { if (++tree_it == tree->end()) { SearchFrom(bucket_index_ + 2); } else { - node_ = NodePtrFromKeyPtr(*tree_it); + node_ = NodeFromTreeIterator(tree_it); } } } else { @@ -473,12 +582,12 @@ class Map { return tmp; } - // Assumes node_ and m_ are correct and non-NULL, but other fields may be + // Assumes node_ and m_ are correct and non-null, but other fields may be // stale. Fix them as needed. Then return true iff node_ points to a // Node in a list. If false is returned then *it is modified to be // a valid iterator for node_. bool revalidate_if_necessary(TreeIterator* it) { - GOOGLE_DCHECK(node_ != NULL && m_ != NULL); + GOOGLE_DCHECK(node_ != nullptr && m_ != nullptr); // Force bucket_index_ to be in range. bucket_index_ &= (m_->num_buckets_ - 1); // Common case: the bucket we think is relevant points to node_. @@ -487,7 +596,7 @@ class Map { // but not at the head. if (m_->TableEntryIsNonEmptyList(bucket_index_)) { Node* l = static_cast(m_->table_[bucket_index_]); - while ((l = l->next) != NULL) { + while ((l = l->next) != nullptr) { if (l == node_) { return true; } @@ -496,8 +605,8 @@ class Map { // Well, bucket_index_ still might be correct, but probably // not. Revalidate just to be sure. This case is rare enough that we // don't worry about potential optimizations, such as having a custom - // find-like method that compares Node* instead of const Key&. - iterator_base i(m_->find(*KeyPtrFromNodePtr(node_), it)); + // find-like method that compares Node* instead of the key. + iterator_base i(m_->find(node_->kv.first, it)); bucket_index_ = i.bucket_index_; return m_->TableEntryIsList(bucket_index_); } @@ -508,8 +617,19 @@ class Map { }; public: - typedef iterator_base iterator; - typedef iterator_base const_iterator; + using iterator = iterator_base; + using const_iterator = iterator_base; + + Arena* arena() const { return alloc_.arena(); } + + void Swap(InnerMap* other) { + std::swap(num_elements_, other->num_elements_); + std::swap(num_buckets_, other->num_buckets_); + std::swap(seed_, other->seed_); + std::swap(index_of_first_non_null_, other->index_of_first_non_null_); + std::swap(table_, other->table_); + std::swap(alloc_, other->alloc_); + } iterator begin() { return iterator(this); } iterator end() { return iterator(); } @@ -520,19 +640,19 @@ class Map { for (size_type b = 0; b < num_buckets_; b++) { if (TableEntryIsNonEmptyList(b)) { Node* node = static_cast(table_[b]); - table_[b] = NULL; + table_[b] = nullptr; do { Node* next = node->next; DestroyNode(node); node = next; - } while (node != NULL); + } while (node != nullptr); } else if (TableEntryIsTree(b)) { Tree* tree = static_cast(table_[b]); GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0); - table_[b] = table_[b + 1] = NULL; + table_[b] = table_[b + 1] = nullptr; typename Tree::iterator tree_it = tree->begin(); do { - Node* node = NodePtrFromKeyPtr(*tree_it); + Node* node = NodeFromTreeIterator(tree_it); typename Tree::iterator next = tree_it; ++next; tree->erase(tree_it); @@ -555,51 +675,53 @@ class Map { size_type size() const { return num_elements_; } bool empty() const { return size() == 0; } - iterator find(const Key& k) { return iterator(FindHelper(k).first); } - const_iterator find(const Key& k) const { return find(k, NULL); } - bool contains(const Key& k) const { return find(k) != end(); } + template + iterator find(const K& k) { + return iterator(FindHelper(k).first); + } - // In traditional C++ style, this performs "insert if not present." - std::pair insert(const KeyValuePair& kv) { - std::pair p = FindHelper(kv.key()); - // Case 1: key was already present. - if (p.first.node_ != NULL) - return std::make_pair(iterator(p.first), false); - // Case 2: insert. - if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) { - p = FindHelper(kv.key()); - } - const size_type b = p.second; // bucket number - Node* node = Alloc(1); - alloc_.construct(&node->kv, kv); - iterator result = InsertUnique(b, node); - ++num_elements_; - return std::make_pair(result, true); + template + const_iterator find(const K& k) const { + return FindHelper(k).first; } - // The same, but if an insertion is necessary then the value portion of the - // inserted key-value pair is left uninitialized. - std::pair insert(const Key& k) { + // Insert the key into the map, if not present. In that case, the value will + // be value initialized. + template + std::pair insert(K&& k) { std::pair p = FindHelper(k); // Case 1: key was already present. - if (p.first.node_ != NULL) + if (p.first.node_ != nullptr) return std::make_pair(iterator(p.first), false); // Case 2: insert. if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) { p = FindHelper(k); } const size_type b = p.second; // bucket number - Node* node = Alloc(1); - typedef typename Allocator::template rebind::other KeyAllocator; - KeyAllocator(alloc_).construct(&node->kv.key(), k); + Node* node; + // If K is not key_type, make the conversion to key_type explicit. + using TypeToInit = typename std::conditional< + std::is_same::type, key_type>::value, K&&, + key_type>::type; + if (alloc_.arena() == nullptr) { + node = new Node{value_type(static_cast(std::forward(k))), + nullptr}; + } else { + node = Alloc(1); + Arena::CreateInArenaStorage( + const_cast(&node->kv.first), alloc_.arena(), + static_cast(std::forward(k))); + Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena()); + } + iterator result = InsertUnique(b, node); ++num_elements_; return std::make_pair(result, true); } - Value& operator[](const Key& k) { - KeyValuePair kv(k, Value()); - return insert(kv).first->value(); + template + value_type& operator[](K&& k) { + return *insert(std::forward(k)).first; } void erase(iterator it) { @@ -616,52 +738,58 @@ class Map { } else { GOOGLE_DCHECK(TableEntryIsTree(b)); Tree* tree = static_cast(table_[b]); - tree->erase(*tree_it); + tree->erase(tree_it); if (tree->empty()) { // Force b to be the minimum of b and b ^ 1. This is important // only because we want index_of_first_non_null_ to be correct. b &= ~static_cast(1); DestroyTree(tree); - table_[b] = table_[b + 1] = NULL; + table_[b] = table_[b + 1] = nullptr; } } DestroyNode(item); --num_elements_; if (PROTOBUF_PREDICT_FALSE(b == index_of_first_non_null_)) { while (index_of_first_non_null_ < num_buckets_ && - table_[index_of_first_non_null_] == NULL) { + table_[index_of_first_non_null_] == nullptr) { ++index_of_first_non_null_; } } } + size_t SpaceUsedInternal() const { + return internal::SpaceUsedInTable(table_, num_buckets_, + num_elements_, sizeof(Node)); + } + private: const_iterator find(const Key& k, TreeIterator* it) const { return FindHelper(k, it).first; } - std::pair FindHelper(const Key& k) const { - return FindHelper(k, NULL); + template + std::pair FindHelper(const K& k) const { + return FindHelper(k, nullptr); } - std::pair FindHelper(const Key& k, + template + std::pair FindHelper(const K& k, TreeIterator* it) const { size_type b = BucketNumber(k); if (TableEntryIsNonEmptyList(b)) { Node* node = static_cast(table_[b]); do { - if (IsMatch(*KeyPtrFromNodePtr(node), k)) { + if (internal::TransparentSupport::Equals(node->kv.first, k)) { return std::make_pair(const_iterator(node, this, b), b); } else { node = node->next; } - } while (node != NULL); + } while (node != nullptr); } else if (TableEntryIsTree(b)) { GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]); b &= ~static_cast(1); Tree* tree = static_cast(table_[b]); - Key* key = const_cast(&k); - typename Tree::iterator tree_it = tree->find(key); + auto tree_it = tree->find(k); if (tree_it != tree->end()) { - if (it != NULL) *it = tree_it; + if (it != nullptr) *it = tree_it; return std::make_pair(const_iterator(tree_it, this, b), b); } } @@ -674,13 +802,13 @@ class Map { // bucket. num_elements_ is not modified. iterator InsertUnique(size_type b, Node* node) { GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ || - table_[index_of_first_non_null_] != NULL); + table_[index_of_first_non_null_] != nullptr); // In practice, the code that led to this point may have already // determined whether we are inserting into an empty list, a short list, // or whatever. But it's probably cheap enough to recompute that here; // it's likely that we're inserting into an empty or short list. iterator result; - GOOGLE_DCHECK(find(*KeyPtrFromNodePtr(node)) == end()); + GOOGLE_DCHECK(find(node->kv.first) == end()); if (TableEntryIsEmpty(b)) { result = InsertUniqueInList(b, node); } else if (TableEntryIsNonEmptyList(b)) { @@ -704,9 +832,30 @@ class Map { return result; } + // Returns whether we should insert after the head of the list. For + // non-optimized builds, we randomly decide whether to insert right at the + // head of the list or just after the head. This helps add a little bit of + // non-determinism to the map ordering. + bool ShouldInsertAfterHead(void* node) { +#ifdef NDEBUG + (void)node; + return false; +#else + // Doing modulo with a prime mixes the bits more. + return (reinterpret_cast(node) ^ seed_) % 13 > 6; +#endif + } + // Helper for InsertUnique. Handles the case where bucket b is a // not-too-long linked list. iterator InsertUniqueInList(size_type b, Node* node) { + if (table_[b] != nullptr && ShouldInsertAfterHead(node)) { + Node* first = static_cast(table_[b]); + node->next = first->next; + first->next = node; + return iterator(node, this, b); + } + node->next = static_cast(table_[b]); table_[b] = static_cast(node); return iterator(node, this, b); @@ -716,10 +865,10 @@ class Map { // Tree. iterator InsertUniqueInTree(size_type b, Node* node) { GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]); - // Maintain the invariant that node->next is NULL for all Nodes in Trees. - node->next = NULL; + // Maintain the invariant that node->next is null for all Nodes in Trees. + node->next = nullptr; return iterator( - static_cast(table_[b])->insert(KeyPtrFromNodePtr(node)).first, + static_cast(table_[b])->insert({node->kv.first, node}).first, this, b & ~static_cast(1)); } @@ -766,6 +915,15 @@ class Map { // Resize to the given number of buckets. void Resize(size_t new_num_buckets) { + if (num_buckets_ == internal::kGlobalEmptyTableSize) { + // This is the global empty array. + // Just overwrite with a new one. No need to transfer or free anything. + num_buckets_ = index_of_first_non_null_ = kMinTableSize; + table_ = CreateEmptyTable(num_buckets_); + seed_ = Seed(); + return; + } + GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize); void** const old_table = table_; const size_type old_table_size = num_buckets_; @@ -774,9 +932,9 @@ class Map { const size_type start = index_of_first_non_null_; index_of_first_non_null_ = num_buckets_; for (size_type i = start; i < old_table_size; i++) { - if (TableEntryIsNonEmptyList(old_table, i)) { + if (internal::TableEntryIsNonEmptyList(old_table, i)) { TransferList(old_table, i); - } else if (TableEntryIsTree(old_table, i)) { + } else if (internal::TableEntryIsTree(old_table, i)) { TransferTree(old_table, i++); } } @@ -787,17 +945,17 @@ class Map { Node* node = static_cast(table[index]); do { Node* next = node->next; - InsertUnique(BucketNumber(*KeyPtrFromNodePtr(node)), node); + InsertUnique(BucketNumber(node->kv.first), node); node = next; - } while (node != NULL); + } while (node != nullptr); } void TransferTree(void* const* table, size_type index) { Tree* tree = static_cast(table[index]); typename Tree::iterator tree_it = tree->begin(); do { - Node* node = NodePtrFromKeyPtr(*tree_it); - InsertUnique(BucketNumber(**tree_it), node); + InsertUnique(BucketNumber(std::cref(tree_it->first).get()), + NodeFromTreeIterator(tree_it)); } while (++tree_it != tree->end()); DestroyTree(tree); } @@ -812,42 +970,23 @@ class Map { } bool TableEntryIsEmpty(size_type b) const { - return TableEntryIsEmpty(table_, b); + return internal::TableEntryIsEmpty(table_, b); } bool TableEntryIsNonEmptyList(size_type b) const { - return TableEntryIsNonEmptyList(table_, b); + return internal::TableEntryIsNonEmptyList(table_, b); } bool TableEntryIsTree(size_type b) const { - return TableEntryIsTree(table_, b); + return internal::TableEntryIsTree(table_, b); } bool TableEntryIsList(size_type b) const { - return TableEntryIsList(table_, b); - } - static bool TableEntryIsEmpty(void* const* table, size_type b) { - return table[b] == NULL; - } - static bool TableEntryIsNonEmptyList(void* const* table, size_type b) { - return table[b] != NULL && table[b] != table[b ^ 1]; - } - static bool TableEntryIsTree(void* const* table, size_type b) { - return !TableEntryIsEmpty(table, b) && - !TableEntryIsNonEmptyList(table, b); - } - static bool TableEntryIsList(void* const* table, size_type b) { - return !TableEntryIsTree(table, b); + return internal::TableEntryIsList(table_, b); } void TreeConvert(size_type b) { GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1)); - typename Allocator::template rebind::other tree_allocator(alloc_); - Tree* tree = tree_allocator.allocate(1); - // We want to use the three-arg form of construct, if it exists, but we - // create a temporary and use the two-arg construct that's known to exist. - // It's clunky, but the compiler should be able to generate more-or-less - // the same code. - tree_allocator.construct(tree, - Tree(KeyCompare(), KeyPtrAllocator(alloc_))); - // Now the tree is ready to use. + Tree* tree = + Arena::Create(alloc_.arena(), typename Tree::key_compare(), + typename Tree::allocator_type(alloc_)); size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree); GOOGLE_DCHECK_EQ(count, tree->size()); table_[b] = table_[b ^ 1] = static_cast(tree); @@ -858,11 +997,11 @@ class Map { size_type CopyListToTree(size_type b, Tree* tree) { size_type count = 0; Node* node = static_cast(table_[b]); - while (node != NULL) { - tree->insert(KeyPtrFromNodePtr(node)); + while (node != nullptr) { + tree->insert({node->kv.first, node}); ++count; Node* next = node->next; - node->next = NULL; + node->next = nullptr; node = next; } return count; @@ -877,20 +1016,23 @@ class Map { do { ++count; node = node->next; - } while (node != NULL); + } while (node != nullptr); // Invariant: no linked list ever is more than kMaxLength in length. GOOGLE_DCHECK_LE(count, kMaxLength); return count >= kMaxLength; } - size_type BucketNumber(const Key& k) const { - // We inherit from hasher, so one-arg operator() provides a hash function. - size_type h = (*const_cast(this))(k); - return (h + seed_) & (num_buckets_ - 1); - } + template + size_type BucketNumber(const K& k) const { + // We xor the hash value against the random seed so that we effectively + // have a random hash function. + uint64 h = hash_function()(k) ^ seed_; - bool IsMatch(const Key& k0, const Key& k1) const { - return std::equal_to()(k0, k1); + // We use the multiplication method to determine the bucket number from + // the hash value. The constant kPhi (suggested by Knuth) is roughly + // (sqrt(5) - 1) / 2 * 2^64. + constexpr uint64 kPhi = uint64{0x9e3779b97f4a7c15}; + return ((kPhi * h) >> 32) & (num_buckets_ - 1); } // Return a power of two no less than max(kMinTableSize, n). @@ -904,26 +1046,27 @@ class Map { // Use alloc_ to allocate an array of n objects of type U. template U* Alloc(size_type n) { - typedef typename Allocator::template rebind::other alloc_type; + using alloc_type = typename Allocator::template rebind::other; return alloc_type(alloc_).allocate(n); } // Use alloc_ to deallocate an array of n objects of type U. template void Dealloc(U* t, size_type n) { - typedef typename Allocator::template rebind::other alloc_type; + using alloc_type = typename Allocator::template rebind::other; alloc_type(alloc_).deallocate(t, n); } void DestroyNode(Node* node) { - alloc_.destroy(&node->kv); - Dealloc(node, 1); + if (alloc_.arena() == nullptr) { + delete node; + } } void DestroyTree(Tree* tree) { - typename Allocator::template rebind::other tree_allocator(alloc_); - tree_allocator.destroy(tree); - tree_allocator.deallocate(tree, 1); + if (alloc_.arena() == nullptr) { + delete tree; + } } void** CreateEmptyTable(size_type n) { @@ -936,16 +1079,23 @@ class Map { // Return a randomish value. size_type Seed() const { - size_type s = static_cast(reinterpret_cast(this)); + // We get a little bit of randomness from the address of the map. The + // lower bits are not very random, due to alignment, so we discard them + // and shift the higher bits into their place. + size_type s = reinterpret_cast(this) >> 12; #if defined(__x86_64__) && defined(__GNUC__) && \ !defined(GOOGLE_PROTOBUF_NO_RDTSC) uint32 hi, lo; - asm("rdtsc" : "=a"(lo), "=d"(hi)); + asm volatile("rdtsc" : "=a"(lo), "=d"(hi)); s += ((static_cast(hi) << 32) | lo); #endif return s; } + friend class Arena; + using InternalArenaConstructable_ = void; + using DestructorSkippable_ = void; + size_type num_elements_; size_type num_buckets_; size_type seed_; @@ -955,22 +1105,26 @@ class Map { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap); }; // end of class InnerMap + template + using key_arg = typename internal::TransparentSupport< + key_type>::template key_arg; + public: // Iterators class const_iterator { - typedef typename InnerMap::const_iterator InnerIt; + using InnerIt = typename InnerMap::const_iterator; public: - typedef std::forward_iterator_tag iterator_category; - typedef typename Map::value_type value_type; - typedef ptrdiff_t difference_type; - typedef const value_type* pointer; - typedef const value_type& reference; + using iterator_category = std::forward_iterator_tag; + using value_type = typename Map::value_type; + using difference_type = ptrdiff_t; + using pointer = const value_type*; + using reference = const value_type&; const_iterator() {} explicit const_iterator(const InnerIt& it) : it_(it) {} - const_reference operator*() const { return *it_->value(); } + const_reference operator*() const { return *it_; } const_pointer operator->() const { return &(operator*()); } const_iterator& operator++() { @@ -991,19 +1145,19 @@ class Map { }; class iterator { - typedef typename InnerMap::iterator InnerIt; + using InnerIt = typename InnerMap::iterator; public: - typedef std::forward_iterator_tag iterator_category; - typedef typename Map::value_type value_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef value_type& reference; + using iterator_category = std::forward_iterator_tag; + using value_type = typename Map::value_type; + using difference_type = ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; iterator() {} explicit iterator(const InnerIt& it) : it_(it) {} - reference operator*() const { return *it_->value(); } + reference operator*() const { return *it_; } pointer operator->() const { return &(operator*()); } iterator& operator++() { @@ -1013,7 +1167,7 @@ class Map { iterator operator++(int) { return iterator(it_++); } // Allow implicit conversion to const_iterator. - operator const_iterator() const { + operator const_iterator() const { // NOLINT(runtime/explicit) return const_iterator(typename InnerMap::const_iterator(it_)); } @@ -1030,55 +1184,67 @@ class Map { InnerIt it_; }; - iterator begin() { return iterator(elements_->begin()); } - iterator end() { return iterator(elements_->end()); } - const_iterator begin() const { - return const_iterator(iterator(elements_->begin())); - } - const_iterator end() const { - return const_iterator(iterator(elements_->end())); - } + iterator begin() { return iterator(elements_.begin()); } + iterator end() { return iterator(elements_.end()); } + const_iterator begin() const { return const_iterator(elements_.begin()); } + const_iterator end() const { return const_iterator(elements_.end()); } const_iterator cbegin() const { return begin(); } const_iterator cend() const { return end(); } // Capacity - size_type size() const { return elements_->size(); } + size_type size() const { return elements_.size(); } bool empty() const { return size() == 0; } // Element access - T& operator[](const key_type& key) { - value_type** value = &(*elements_)[key]; - if (*value == NULL) { - *value = CreateValueTypeInternal(key); - internal::MapValueInitializer::value, T>::Initialize( - (*value)->second, default_enum_value_); - } - return (*value)->second; + template + T& operator[](const key_arg& key) { + return elements_[key].second; } - const T& at(const key_type& key) const { + template < + typename K = key_type, + // Disable for integral types to reduce code bloat. + typename = typename std::enable_if::value>::type> + T& operator[](key_arg&& key) { + return elements_[std::forward(key)].second; + } + + template + const T& at(const key_arg& key) const { const_iterator it = find(key); - GOOGLE_CHECK(it != end()) << "key not found: " << key; + GOOGLE_CHECK(it != end()) << "key not found: " << static_cast(key); return it->second; } - T& at(const key_type& key) { + + template + T& at(const key_arg& key) { iterator it = find(key); - GOOGLE_CHECK(it != end()) << "key not found: " << key; + GOOGLE_CHECK(it != end()) << "key not found: " << static_cast(key); return it->second; } // Lookup - size_type count(const key_type& key) const { - const_iterator it = find(key); - GOOGLE_DCHECK(it == end() || key == it->first); - return it == end() ? 0 : 1; + template + size_type count(const key_arg& key) const { + return find(key) == end() ? 0 : 1; + } + + template + const_iterator find(const key_arg& key) const { + return const_iterator(elements_.find(key)); } - const_iterator find(const key_type& key) const { - return const_iterator(iterator(elements_->find(key))); + template + iterator find(const key_arg& key) { + return iterator(elements_.find(key)); } - iterator find(const key_type& key) { return iterator(elements_->find(key)); } - bool contains(const Key& key) const { return elements_->contains(key); } + + template + bool contains(const key_arg& key) const { + return find(key) != end(); + } + + template std::pair equal_range( - const key_type& key) const { + const key_arg& key) const { const_iterator it = find(key); if (it == end()) { return std::pair(it, it); @@ -1087,7 +1253,9 @@ class Map { return std::pair(begin, it); } } - std::pair equal_range(const key_type& key) { + + template + std::pair equal_range(const key_arg& key) { iterator it = find(key); if (it == end()) { return std::pair(it, it); @@ -1100,9 +1268,9 @@ class Map { // insert std::pair insert(const value_type& value) { std::pair p = - elements_->insert(value.first); + elements_.insert(value.first); if (p.second) { - p.first->value() = CreateValueTypeInternal(value); + p.first->second = value.second; } return std::pair(iterator(p.first), p.second); } @@ -1120,7 +1288,8 @@ class Map { } // Erase and clear - size_type erase(const key_type& key) { + template + size_type erase(const key_arg& key) { iterator it = find(key); if (it == end()) { return 0; @@ -1130,9 +1299,8 @@ class Map { } } iterator erase(iterator pos) { - if (arena_ == NULL) delete pos.operator->(); iterator i = pos++; - elements_->erase(i.it_); + elements_.erase(i.it_); return pos; } void erase(iterator first, iterator last) { @@ -1140,7 +1308,7 @@ class Map { first = erase(first); } } - void clear() { erase(begin(), end()); } + void clear() { elements_.clear(); } // Assign Map& operator=(const Map& other) { @@ -1152,9 +1320,8 @@ class Map { } void swap(Map& other) { - if (arena_ == other.arena_) { - std::swap(default_enum_value_, other.default_enum_value_); - std::swap(elements_, other.elements_); + if (arena() == other.arena()) { + elements_.Swap(&other.elements_); } else { // TODO(zuguang): optimize this. The temporary copy can be allocated // in the same arena as the other message, and the "other = copy" can @@ -1167,52 +1334,23 @@ class Map { // Access to hasher. Currently this returns a copy, but it may // be modified to return a const reference in the future. - hasher hash_function() const { return elements_->hash_function(); } + hasher hash_function() const { return elements_.hash_function(); } - private: - // Set default enum value only for proto2 map field whose value is enum type. - void SetDefaultEnumValue(int default_enum_value) { - default_enum_value_ = default_enum_value; + size_t SpaceUsedExcludingSelfLong() const { + if (empty()) return 0; + return elements_.SpaceUsedInternal() + internal::SpaceUsedInValues(this); } - value_type* CreateValueTypeInternal(const Key& key) { - if (arena_ == NULL) { - return new value_type(key); - } else { - value_type* value = reinterpret_cast( - Arena::CreateArray(arena_, sizeof(value_type))); - Arena::CreateInArenaStorage(const_cast(&value->first), arena_); - Arena::CreateInArenaStorage(&value->second, arena_); - const_cast(value->first) = key; - return value; - } - } - - value_type* CreateValueTypeInternal(const value_type& value) { - if (arena_ == NULL) { - return new value_type(value); - } else { - value_type* p = reinterpret_cast( - Arena::CreateArray(arena_, sizeof(value_type))); - Arena::CreateInArenaStorage(const_cast(&p->first), arena_); - Arena::CreateInArenaStorage(&p->second, arena_); - const_cast(p->first) = value.first; - p->second = value.second; - return p; - } - } - - Arena* arena_; - int default_enum_value_; - InnerMap* elements_; + private: + Arena* arena() const { return elements_.arena(); } + InnerMap elements_; friend class Arena; - typedef void InternalArenaConstructable_; - typedef void DestructorSkippable_; + using InternalArenaConstructable_ = void; + using DestructorSkippable_ = void; template + internal::WireFormatLite::FieldType value_wire_type> friend class internal::MapFieldLite; }; diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index a650c875eaeb..9e35795f9b53 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -52,7 +51,7 @@ class Arena; namespace internal { template + WireFormatLite::FieldType kValueFieldType> class MapField; } } // namespace protobuf @@ -87,30 +86,30 @@ namespace internal { // // The in-memory types of primitive types can be inferred from its proto type, // while we need to explicitly specify the cpp type if proto type is -// TYPE_MESSAGE to infer the in-memory type. Moreover, default_enum_value is -// used to initialize enum field in proto2. +// TYPE_MESSAGE to infer the in-memory type. template -class MapEntry - : public MapEntryImpl { + WireFormatLite::FieldType kValueFieldType> +class MapEntry : public MapEntryImpl { public: - MapEntry() : _internal_metadata_(NULL) {} + constexpr MapEntry() : _internal_metadata_() {} explicit MapEntry(Arena* arena) : MapEntryImpl(arena), + kValueFieldType>(arena), _internal_metadata_(arena) {} + ~MapEntry() { + Message::_internal_metadata_.Delete(); + _internal_metadata_.Delete(); + } typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; + typedef typename MapEntryImpl::KeyTypeHandler KeyTypeHandler; typedef typename MapEntryImpl::KeyTypeHandler - KeyTypeHandler; - typedef typename MapEntryImpl< - Derived, Message, Key, Value, kKeyFieldType, kValueFieldType, - default_enum_value>::ValueTypeHandler ValueTypeHandler; + kValueFieldType>::ValueTypeHandler ValueTypeHandler; size_t SpaceUsedLong() const override { size_t size = sizeof(Derived); size += KeyTypeHandler::SpaceUsedInMapEntryLong(this->key_); @@ -118,13 +117,12 @@ class MapEntry return size; } - InternalMetadataWithArena _internal_metadata_; + InternalMetadata _internal_metadata_; private: friend class ::PROTOBUF_NAMESPACE_ID::Arena; template + WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType> friend class internal::MapField; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry); @@ -133,26 +131,24 @@ class MapEntry // Specialization for the full runtime template -struct MapEntryHelper > - : MapEntryHelper > { + WireFormatLite::FieldType kValueFieldType> +struct MapEntryHelper< + MapEntry > + : MapEntryHelper< + MapEntryLite > { explicit MapEntryHelper(const MapPair& map_pair) - : MapEntryHelper >( + : MapEntryHelper< + MapEntryLite >( map_pair) {} }; template -struct DeconstructMapEntry > { + WireFormatLite::FieldType key, WireFormatLite::FieldType value> +struct DeconstructMapEntry > { typedef K Key; typedef V Value; - static const WireFormatLite::FieldType kKeyFieldType = key; - static const WireFormatLite::FieldType kValueFieldType = value; - static const int default_enum_value = default_enum; + static constexpr WireFormatLite::FieldType kKeyFieldType = key; + static constexpr WireFormatLite::FieldType kValueFieldType = value; }; } // namespace internal diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index fe8a2d72645f..1caf59dfedc5 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -55,11 +55,11 @@ namespace protobuf { namespace internal { template + WireFormatLite::FieldType kValueFieldType> class MapEntry; template + WireFormatLite::FieldType kValueFieldType> class MapFieldLite; } // namespace internal } // namespace protobuf @@ -93,11 +93,7 @@ struct MoveHelper { // messages template struct MoveHelper { // strings and similar static void Move(T* src, T* dest) { -#if __cplusplus >= 201103L *dest = std::move(*src); -#else - dest->swap(*src); -#endif } }; @@ -144,7 +140,7 @@ struct MapEntryFuncs { // the eventual code to the template code. template + WireFormatLite::FieldType kValueFieldType> class MapEntryImpl : public Base { public: typedef MapEntryFuncs Funcs; @@ -185,24 +181,20 @@ class MapEntryImpl : public Base { typedef Value EntryValueType; static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType; static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType; - static const int kEntryDefaultEnumValue = default_enum_value; - MapEntryImpl() : arena_(NULL) { - KeyTypeHandler::Initialize(&key_, NULL); - ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value, - NULL); - _has_bits_[0] = 0; - } + constexpr MapEntryImpl() + : key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} - explicit MapEntryImpl(Arena* arena) : arena_(arena) { - KeyTypeHandler::Initialize(&key_, arena); - ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value, - arena); - _has_bits_[0] = 0; - } + explicit MapEntryImpl(Arena* arena) + : Base(arena), + key_(KeyTypeHandler::Constinit()), + value_(ValueTypeHandler::Constinit()), + _has_bits_{} {} ~MapEntryImpl() { - if (GetArenaNoVirtual() != NULL) return; + if (Base::GetArena() != NULL) return; KeyTypeHandler::DeleteNoArena(key_); ValueTypeHandler::DeleteNoArena(value_); } @@ -213,16 +205,15 @@ class MapEntryImpl : public Base { return KeyTypeHandler::GetExternalReference(key_); } virtual inline const ValueMapEntryAccessorType& value() const { - return ValueTypeHandler::DefaultIfNotInitialized( - value_, Derived::internal_default_instance()->value_); + return ValueTypeHandler::DefaultIfNotInitialized(value_); } inline KeyMapEntryAccessorType* mutable_key() { set_has_key(); - return KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual()); + return KeyTypeHandler::EnsureMutable(&key_, Base::GetArena()); } inline ValueMapEntryAccessorType* mutable_value() { set_has_value(); - return ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual()); + return ValueTypeHandler::EnsureMutable(&value_, Base::GetArena()); } // implements MessageLite ========================================= @@ -266,13 +257,8 @@ class MapEntryImpl : public Base { size_t ByteSizeLong() const override { size_t size = 0; - size += has_key() ? kTagSize + - static_cast(KeyTypeHandler::ByteSize(key())) - : 0; - size += has_value() - ? kTagSize + - static_cast(ValueTypeHandler::ByteSize(value())) - : 0; + size += kTagSize + static_cast(KeyTypeHandler::ByteSize(key())); + size += kTagSize + static_cast(ValueTypeHandler::ByteSize(value())); return size; } @@ -315,13 +301,13 @@ class MapEntryImpl : public Base { void MergeFromInternal(const MapEntryImpl& from) { if (from._has_bits_[0]) { if (from.has_key()) { - KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual()); - KeyTypeHandler::Merge(from.key(), &key_, GetArenaNoVirtual()); + KeyTypeHandler::EnsureMutable(&key_, Base::GetArena()); + KeyTypeHandler::Merge(from.key(), &key_, Base::GetArena()); set_has_key(); } if (from.has_value()) { - ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual()); - ValueTypeHandler::Merge(from.value(), &value_, GetArenaNoVirtual()); + ValueTypeHandler::EnsureMutable(&value_, Base::GetArena()); + ValueTypeHandler::Merge(from.value(), &value_, Base::GetArena()); set_has_value(); } } @@ -329,21 +315,12 @@ class MapEntryImpl : public Base { public: void Clear() override { - KeyTypeHandler::Clear(&key_, GetArenaNoVirtual()); - ValueTypeHandler::ClearMaybeByDefaultEnum(&value_, GetArenaNoVirtual(), - default_enum_value); + KeyTypeHandler::Clear(&key_, Base::GetArena()); + ValueTypeHandler::Clear(&value_, Base::GetArena()); clear_has_key(); clear_has_value(); } - static void InitAsDefaultInstance() { - Derived* d = const_cast(Derived::internal_default_instance()); - KeyTypeHandler::AssignDefaultValue(&d->key_); - ValueTypeHandler::AssignDefaultValue(&d->value_); - } - - Arena* GetArena() const override { return GetArenaNoVirtual(); } - // Parsing using MergePartialFromCodedStream, above, is not as // efficient as it could be. This helper class provides a speedier way. template @@ -440,10 +417,10 @@ class MapEntryImpl : public Base { return ptr; } - template + template const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, bool (*is_valid)(int), uint32 field_num, - Metadata* metadata) { + InternalMetadata* metadata) { auto entry = NewEntry(); ptr = entry->_InternalParse(ptr, ctx); if (!ptr) return nullptr; @@ -451,7 +428,7 @@ class MapEntryImpl : public Base { UseKeyAndValueFromEntry(); } else { WriteLengthDelimited(field_num, entry->SerializeAsString(), - metadata->mutable_unknown_fields()); + metadata->mutable_unknown_fields()); } return ptr; } @@ -515,12 +492,11 @@ class MapEntryImpl : public Base { void clear_has_value() { _has_bits_[0] &= ~0x00000002u; } public: - inline Arena* GetArenaNoVirtual() const { return arena_; } + inline Arena* GetArena() const { return Base::GetArena(); } public: // Needed for constructing tables KeyOnMemory key_; ValueOnMemory value_; - Arena* arena_; uint32 _has_bits_[1]; private: @@ -528,10 +504,10 @@ class MapEntryImpl : public Base { typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; template + WireFormatLite::FieldType> friend class internal::MapEntry; template + WireFormatLite::FieldType> friend class internal::MapFieldLite; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryImpl); @@ -539,16 +515,16 @@ class MapEntryImpl : public Base { template -class MapEntryLite - : public MapEntryImpl { + WireFormatLite::FieldType kValueFieldType> +class MapEntryLite : public MapEntryImpl { public: typedef MapEntryImpl + kValueFieldType> SuperType; - MapEntryLite() {} + constexpr MapEntryLite() {} explicit MapEntryLite(Arena* arena) : SuperType(arena) {} + ~MapEntryLite() { MessageLite::_internal_metadata_.Delete(); } void MergeFrom(const MapEntryLite& other) { MergeFromInternal(other); } private: @@ -561,13 +537,12 @@ template struct DeconstructMapEntry; template -struct DeconstructMapEntry > { + WireFormatLite::FieldType value> +struct DeconstructMapEntry > { typedef K Key; typedef V Value; static const WireFormatLite::FieldType kKeyFieldType = key; static const WireFormatLite::FieldType kValueFieldType = value; - static const int default_enum_value = default_enum; }; // Helpers for deterministic serialization ============================= @@ -638,9 +613,9 @@ struct MapEntryHelper; template -struct MapEntryHelper > { + WireFormatLite::FieldType kValueFieldType> +struct MapEntryHelper< + MapEntryLite > { // Provide utilities to parse/serialize key/value. Provide utilities to // manipulate internal stored type. typedef MapTypeHandler KeyTypeHandler; diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index d61fddd61c6f..542a1f8335b3 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -44,20 +44,24 @@ MapFieldBase::~MapFieldBase() { } const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const { + ConstAccess(); SyncRepeatedFieldWithMap(); return *reinterpret_cast(repeated_field_); } RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() { + MutableAccess(); SyncRepeatedFieldWithMap(); SetRepeatedDirty(); return reinterpret_cast(repeated_field_); } size_t MapFieldBase::SpaceUsedExcludingSelfLong() const { + ConstAccess(); mutex_.Lock(); size_t size = SpaceUsedExcludingSelfNoLock(); mutex_.Unlock(); + ConstAccess(); return size; } @@ -70,6 +74,7 @@ size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const { } bool MapFieldBase::IsMapValid() const { + ConstAccess(); // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get // executed before state_ is checked. int state = state_.load(std::memory_order_acquire); @@ -77,23 +82,27 @@ bool MapFieldBase::IsMapValid() const { } bool MapFieldBase::IsRepeatedFieldValid() const { + ConstAccess(); int state = state_.load(std::memory_order_acquire); return state != STATE_MODIFIED_MAP; } void MapFieldBase::SetMapDirty() { + MutableAccess(); // These are called by (non-const) mutator functions. So by our API it's the // callers responsibility to have these calls properly ordered. state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed); } void MapFieldBase::SetRepeatedDirty() { + MutableAccess(); // These are called by (non-const) mutator functions. So by our API it's the // callers responsibility to have these calls properly ordered. state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed); } void MapFieldBase::SyncRepeatedFieldWithMap() const { + ConstAccess(); // acquire here matches with release below to ensure that we can only see a // value of CLEAN after all previous changes have been synced. switch (state_.load(std::memory_order_acquire)) { @@ -106,6 +115,7 @@ void MapFieldBase::SyncRepeatedFieldWithMap() const { state_.store(CLEAN, std::memory_order_release); } mutex_.Unlock(); + ConstAccess(); break; case CLEAN: mutex_.Lock(); @@ -122,6 +132,7 @@ void MapFieldBase::SyncRepeatedFieldWithMap() const { state_.store(CLEAN, std::memory_order_release); } mutex_.Unlock(); + ConstAccess(); break; default: break; @@ -135,6 +146,7 @@ void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const { } void MapFieldBase::SyncMapWithRepeatedField() const { + ConstAccess(); // acquire here matches with release below to ensure that we can only see a // value of CLEAN after all previous changes have been synced. if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) { @@ -146,6 +158,7 @@ void MapFieldBase::SyncMapWithRepeatedField() const { state_.store(CLEAN, std::memory_order_release); } mutex_.Unlock(); + ConstAccess(); } } @@ -196,8 +209,7 @@ bool DynamicMapField::ContainsMapKey(const MapKey& map_key) const { } void DynamicMapField::AllocateMapValue(MapValueRef* map_val) { - const FieldDescriptor* val_des = - default_entry_->GetDescriptor()->FindFieldByName("value"); + const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value(); map_val->SetType(val_des->cpp_type()); // Allocate memory for the MapValueRef, and initialize to // default value. @@ -246,6 +258,19 @@ bool DynamicMapField::InsertOrLookupMapValue(const MapKey& map_key, return false; } +bool DynamicMapField::LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const { + const Map& map = GetMap(); + Map::const_iterator iter = map.find(map_key); + if (iter == map.end()) { + return false; + } + // map_key is already in the map. Make sure (*map)[map_key] is not called. + // [] may reorder the map and iterators. + val->CopyFrom(iter->second); + return true; +} + bool DynamicMapField::DeleteMapValue(const MapKey& map_key) { MapFieldBase::SyncMapWithRepeatedField(); Map::iterator iter = map_.find(map_key); @@ -300,7 +325,7 @@ void DynamicMapField::MergeFrom(const MapFieldBase& other) { // Copy map value const FieldDescriptor* field_descriptor = - default_entry_->GetDescriptor()->FindFieldByName("value"); + default_entry_->GetDescriptor()->map_value(); switch (field_descriptor->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: { map_val->SetInt32Value(other_it->second.GetInt32Value()); @@ -360,10 +385,8 @@ void DynamicMapField::Swap(MapFieldBase* other) { void DynamicMapField::SyncRepeatedFieldWithMapNoLock() const { const Reflection* reflection = default_entry_->GetReflection(); - const FieldDescriptor* key_des = - default_entry_->GetDescriptor()->FindFieldByName("key"); - const FieldDescriptor* val_des = - default_entry_->GetDescriptor()->FindFieldByName("value"); + const FieldDescriptor* key_des = default_entry_->GetDescriptor()->map_key(); + const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value(); if (MapFieldBase::repeated_field_ == NULL) { if (MapFieldBase::arena_ == NULL) { MapFieldBase::repeated_field_ = new RepeatedPtrField(); @@ -448,10 +471,8 @@ void DynamicMapField::SyncRepeatedFieldWithMapNoLock() const { void DynamicMapField::SyncMapWithRepeatedFieldNoLock() const { Map* map = &const_cast(this)->map_; const Reflection* reflection = default_entry_->GetReflection(); - const FieldDescriptor* key_des = - default_entry_->GetDescriptor()->FindFieldByName("key"); - const FieldDescriptor* val_des = - default_entry_->GetDescriptor()->FindFieldByName("value"); + const FieldDescriptor* key_des = default_entry_->GetDescriptor()->map_key(); + const FieldDescriptor* val_des = default_entry_->GetDescriptor()->map_value(); // DynamicMapField owns map values. Need to delete them before clearing // the map. if (MapFieldBase::arena_ == nullptr) { @@ -580,3 +601,5 @@ size_t DynamicMapField::SpaceUsedExcludingSelfNoLock() const { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 38bf26aebb97..e05d3ee04da2 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -32,6 +32,7 @@ #define GOOGLE_PROTOBUF_MAP_FIELD_H__ #include +#include #include #include @@ -56,8 +57,261 @@ namespace google { namespace protobuf { class DynamicMessage; -class MapKey; class MapIterator; + +#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \ + if (type() != EXPECTEDTYPE) { \ + GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" \ + << METHOD << " type does not match\n" \ + << " Expected : " \ + << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \ + << " Actual : " << FieldDescriptor::CppTypeName(type()); \ + } + +// MapKey is an union type for representing any possible +// map key. +class PROTOBUF_EXPORT MapKey { + public: + MapKey() : type_() {} + MapKey(const MapKey& other) : type_() { CopyFrom(other); } + + MapKey& operator=(const MapKey& other) { + CopyFrom(other); + return *this; + } + + ~MapKey() { + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + val_.string_value_.Destruct(); + } + } + + FieldDescriptor::CppType type() const { + if (type_ == FieldDescriptor::CppType()) { + GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" + << "MapKey::type MapKey is not initialized. " + << "Call set methods to initialize MapKey."; + } + return type_; + } + + void SetInt64Value(int64 value) { + SetType(FieldDescriptor::CPPTYPE_INT64); + val_.int64_value_ = value; + } + void SetUInt64Value(uint64 value) { + SetType(FieldDescriptor::CPPTYPE_UINT64); + val_.uint64_value_ = value; + } + void SetInt32Value(int32 value) { + SetType(FieldDescriptor::CPPTYPE_INT32); + val_.int32_value_ = value; + } + void SetUInt32Value(uint32 value) { + SetType(FieldDescriptor::CPPTYPE_UINT32); + val_.uint32_value_ = value; + } + void SetBoolValue(bool value) { + SetType(FieldDescriptor::CPPTYPE_BOOL); + val_.bool_value_ = value; + } + void SetStringValue(std::string val) { + SetType(FieldDescriptor::CPPTYPE_STRING); + *val_.string_value_.get_mutable() = std::move(val); + } + + int64 GetInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value"); + return val_.int64_value_; + } + uint64 GetUInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value"); + return val_.uint64_value_; + } + int32 GetInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value"); + return val_.int32_value_; + } + uint32 GetUInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value"); + return val_.uint32_value_; + } + bool GetBoolValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapKey::GetBoolValue"); + return val_.bool_value_; + } + const std::string& GetStringValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapKey::GetStringValue"); + return val_.string_value_.get(); + } + + bool operator<(const MapKey& other) const { + if (type_ != other.type_) { + // We could define a total order that handles this case, but + // there currently no need. So, for now, fail. + GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; + } + switch (type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + return false; + case FieldDescriptor::CPPTYPE_STRING: + return val_.string_value_.get() < other.val_.string_value_.get(); + case FieldDescriptor::CPPTYPE_INT64: + return val_.int64_value_ < other.val_.int64_value_; + case FieldDescriptor::CPPTYPE_INT32: + return val_.int32_value_ < other.val_.int32_value_; + case FieldDescriptor::CPPTYPE_UINT64: + return val_.uint64_value_ < other.val_.uint64_value_; + case FieldDescriptor::CPPTYPE_UINT32: + return val_.uint32_value_ < other.val_.uint32_value_; + case FieldDescriptor::CPPTYPE_BOOL: + return val_.bool_value_ < other.val_.bool_value_; + } + return false; + } + + bool operator==(const MapKey& other) const { + if (type_ != other.type_) { + // To be consistent with operator<, we don't allow this either. + GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; + } + switch (type()) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case FieldDescriptor::CPPTYPE_STRING: + return val_.string_value_.get() == other.val_.string_value_.get(); + case FieldDescriptor::CPPTYPE_INT64: + return val_.int64_value_ == other.val_.int64_value_; + case FieldDescriptor::CPPTYPE_INT32: + return val_.int32_value_ == other.val_.int32_value_; + case FieldDescriptor::CPPTYPE_UINT64: + return val_.uint64_value_ == other.val_.uint64_value_; + case FieldDescriptor::CPPTYPE_UINT32: + return val_.uint32_value_ == other.val_.uint32_value_; + case FieldDescriptor::CPPTYPE_BOOL: + return val_.bool_value_ == other.val_.bool_value_; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; + } + + void CopyFrom(const MapKey& other) { + SetType(other.type()); + switch (type_) { + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case FieldDescriptor::CPPTYPE_STRING: + *val_.string_value_.get_mutable() = other.val_.string_value_.get(); + break; + case FieldDescriptor::CPPTYPE_INT64: + val_.int64_value_ = other.val_.int64_value_; + break; + case FieldDescriptor::CPPTYPE_INT32: + val_.int32_value_ = other.val_.int32_value_; + break; + case FieldDescriptor::CPPTYPE_UINT64: + val_.uint64_value_ = other.val_.uint64_value_; + break; + case FieldDescriptor::CPPTYPE_UINT32: + val_.uint32_value_ = other.val_.uint32_value_; + break; + case FieldDescriptor::CPPTYPE_BOOL: + val_.bool_value_ = other.val_.bool_value_; + break; + } + } + + private: + template + friend class internal::TypeDefinedMapFieldBase; + friend class ::PROTOBUF_NAMESPACE_ID::MapIterator; + friend class internal::DynamicMapField; + + union KeyValue { + KeyValue() {} + internal::ExplicitlyConstructed string_value_; + int64 int64_value_; + int32 int32_value_; + uint64 uint64_value_; + uint32 uint32_value_; + bool bool_value_; + } val_; + + void SetType(FieldDescriptor::CppType type) { + if (type_ == type) return; + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + val_.string_value_.Destruct(); + } + type_ = type; + if (type_ == FieldDescriptor::CPPTYPE_STRING) { + val_.string_value_.DefaultConstruct(); + } + } + + // type_ is 0 or a valid FieldDescriptor::CppType. + // Use "CppType()" to indicate zero. + FieldDescriptor::CppType type_; +}; + +} // namespace protobuf +} // namespace google +namespace std { +template <> +struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> { + size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const { + switch (map_key.type()) { + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM: + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING: + return hash()(map_key.GetStringValue()); + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: { + auto value = map_key.GetInt64Value(); + return hash()(value); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: { + auto value = map_key.GetInt32Value(); + return hash()(map_key.GetInt32Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: { + auto value = map_key.GetUInt64Value(); + return hash()(map_key.GetUInt64Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: { + auto value = map_key.GetUInt32Value(); + return hash()(map_key.GetUInt32Value()); + } + case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: { + return hash()(map_key.GetBoolValue()); + } + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; + } + bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1, + const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const { + return map_key1 < map_key2; + } +}; +} // namespace std + +namespace google { +namespace protobuf { namespace internal { class ContendedMapCleanTest; @@ -66,16 +320,28 @@ class MapFieldAccessor; // This class provides access to map field using reflection, which is the same // as those provided for RepeatedPtrField. It is used for internal -// reflection implentation only. Users should never use this directly. +// reflection implementation only. Users should never use this directly. class PROTOBUF_EXPORT MapFieldBase { public: MapFieldBase() : arena_(NULL), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + // Except in MSVC, where we can't have a constinit mutex. + explicit constexpr MapFieldBase(ConstantInitialized) + : arena_(nullptr), + repeated_field_(nullptr), + mutex_(GOOGLE_PROTOBUF_LINKER_INITIALIZED), + state_(STATE_MODIFIED_MAP) {} explicit MapFieldBase(Arena* arena) : arena_(arena), repeated_field_(NULL), state_(STATE_MODIFIED_MAP) { // Mutex's destructor needs to be called explicitly to release resources // acquired in its constructor. - arena->OwnDestructor(&mutex_); + if (arena) { + arena->OwnDestructor(&mutex_); + } } virtual ~MapFieldBase(); @@ -91,6 +357,10 @@ class PROTOBUF_EXPORT MapFieldBase { virtual bool ContainsMapKey(const MapKey& map_key) const = 0; virtual bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) = 0; + virtual bool LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const = 0; + bool LookupMapValue(const MapKey&, MapValueRef*) const = delete; + // Returns whether changes to the map are reflected in the repeated field. bool IsRepeatedFieldValid() const; // Insures operations after won't get executed before calling this. @@ -131,12 +401,31 @@ class PROTOBUF_EXPORT MapFieldBase { // Tells MapFieldBase that there is new change to Map. void SetMapDirty(); - // Tells MapFieldBase that there is new change to RepeatedPTrField. + // Tells MapFieldBase that there is new change to RepeatedPtrField. void SetRepeatedDirty(); // Provides derived class the access to repeated field. void* MutableRepeatedPtrField() const; + // Support thread sanitizer (tsan) by making const / mutable races + // more apparent. If one thread calls MutableAccess() while another + // thread calls either ConstAccess() or MutableAccess(), on the same + // MapFieldBase-derived object, and there is no synchronization going + // on between them, tsan will alert. +#if defined(__SANITIZE_THREAD__) || defined(THREAD_SANITIZER) + void ConstAccess() const { GOOGLE_CHECK_EQ(seq1_, seq2_); } + void MutableAccess() { + if (seq1_ & 1) { + seq2_ = ++seq1_; + } else { + seq1_ = ++seq2_; + } + } + unsigned int seq1_ = 0, seq2_ = 0; +#else + void ConstAccess() const {} + void MutableAccess() {} +#endif enum State { STATE_MODIFIED_MAP = 0, // map has newly added data that has not been // synchronized to repeated field @@ -188,6 +477,12 @@ template class TypeDefinedMapFieldBase : public MapFieldBase { public: TypeDefinedMapFieldBase() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr TypeDefinedMapFieldBase(ConstantInitialized tag) + : MapFieldBase(tag) {} explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {} ~TypeDefinedMapFieldBase() override {} void MapBegin(MapIterator* map_iter) const override; @@ -213,11 +508,11 @@ class TypeDefinedMapFieldBase : public MapFieldBase { }; // This class provides access to map field using generated api. It is used for -// internal generated message implentation only. Users should never use this +// internal generated message implementation only. Users should never use this // directly. template + WireFormatLite::FieldType kValueFieldType> class MapField : public TypeDefinedMapFieldBase { // Provide utilities to parse/serialize key/value. Provide utilities to // manipulate internal stored type. @@ -228,15 +523,14 @@ class MapField : public TypeDefinedMapFieldBase { typedef Derived EntryType; // Define abbreviation for parent MapFieldLite - typedef MapFieldLite + typedef MapFieldLite MapFieldLiteType; // Enum needs to be handled differently from other types because it has // different exposed type in Map's api and repeated field's api. For // details see the comment in the implementation of // SyncMapWithRepeatedFieldNoLock. - static const bool kIsValueEnum = ValueTypeHandler::kIsEnum; + static constexpr bool kIsValueEnum = ValueTypeHandler::kIsEnum; typedef typename MapIf::type CastValueType; public: @@ -244,12 +538,21 @@ class MapField : public TypeDefinedMapFieldBase { typedef Map MapType; MapField() {} + + // This constructor is for constant initialized global instances. + // It uses a linker initialized mutex, so it is not compatible with regular + // runtime instances. + explicit constexpr MapField(ConstantInitialized tag) + : TypeDefinedMapFieldBase(tag), impl_() {} explicit MapField(Arena* arena) : TypeDefinedMapFieldBase(arena), impl_(arena) {} // Implement MapFieldBase bool ContainsMapKey(const MapKey& map_key) const override; bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; + bool LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const override; + bool LookupMapValue(const MapKey&, MapValueRef*) const = delete; bool DeleteMapValue(const MapKey& map_key) override; const Map& GetMap() const override { @@ -286,12 +589,12 @@ class MapField : public TypeDefinedMapFieldBase { const char* _InternalParse(const char* ptr, ParseContext* ctx) { return impl_._InternalParse(ptr, ctx); } - template + template const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, bool (*is_valid)(int), uint32 field_num, - Metadata* metadata) { - return impl_.ParseWithEnumValidation(ptr, ctx, is_valid, field_num, - metadata); + InternalMetadata* metadata) { + return impl_.template ParseWithEnumValidation( + ptr, ctx, is_valid, field_num, metadata); } private: @@ -314,10 +617,9 @@ class MapField : public TypeDefinedMapFieldBase { template + WireFormatLite::FieldType value_wire_type> bool AllAreInitialized( - const MapField& field) { + const MapField& field) { const auto& t = field.GetMap(); for (typename Map::const_iterator it = t.begin(); it != t.end(); ++it) { @@ -328,12 +630,10 @@ bool AllAreInitialized( template -struct MapEntryToMapField> { - typedef MapField - MapFieldType; + WireFormatLite::FieldType kValueFieldType> +struct MapEntryToMapField< + MapEntry> { + typedef MapField MapFieldType; }; class PROTOBUF_EXPORT DynamicMapField @@ -346,6 +646,9 @@ class PROTOBUF_EXPORT DynamicMapField // Implement MapFieldBase bool ContainsMapKey(const MapKey& map_key) const override; bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) override; + bool LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const override; + bool LookupMapValue(const MapKey&, MapValueRef*) const = delete; bool DeleteMapValue(const MapKey& map_key) override; void MergeFrom(const MapFieldBase& other) override; void Swap(MapFieldBase* other) override; @@ -372,215 +675,103 @@ class PROTOBUF_EXPORT DynamicMapField } // namespace internal -#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \ - if (type() != EXPECTEDTYPE) { \ - GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" \ - << METHOD << " type does not match\n" \ - << " Expected : " \ - << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \ - << " Actual : " << FieldDescriptor::CppTypeName(type()); \ - } - -// MapKey is an union type for representing any possible -// map key. -class PROTOBUF_EXPORT MapKey { +// MapValueConstRef points to a map value. Users can NOT modify +// the map value. +class PROTOBUF_EXPORT MapValueConstRef { public: - MapKey() : type_(0) {} - MapKey(const MapKey& other) : type_(0) { CopyFrom(other); } + MapValueConstRef() : data_(nullptr), type_() {} - MapKey& operator=(const MapKey& other) { - CopyFrom(other); - return *this; - } - - ~MapKey() { - if (type_ == FieldDescriptor::CPPTYPE_STRING) { - val_.string_value_.Destruct(); - } - } - - FieldDescriptor::CppType type() const { - if (type_ == 0) { - GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" - << "MapKey::type MapKey is not initialized. " - << "Call set methods to initialize MapKey."; - } - return (FieldDescriptor::CppType)type_; - } - - void SetInt64Value(int64 value) { - SetType(FieldDescriptor::CPPTYPE_INT64); - val_.int64_value_ = value; - } - void SetUInt64Value(uint64 value) { - SetType(FieldDescriptor::CPPTYPE_UINT64); - val_.uint64_value_ = value; - } - void SetInt32Value(int32 value) { - SetType(FieldDescriptor::CPPTYPE_INT32); - val_.int32_value_ = value; - } - void SetUInt32Value(uint32 value) { - SetType(FieldDescriptor::CPPTYPE_UINT32); - val_.uint32_value_ = value; - } - void SetBoolValue(bool value) { - SetType(FieldDescriptor::CPPTYPE_BOOL); - val_.bool_value_ = value; - } - void SetStringValue(std::string val) { - SetType(FieldDescriptor::CPPTYPE_STRING); - *val_.string_value_.get_mutable() = std::move(val); - } - - int64 GetInt64Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapKey::GetInt64Value"); - return val_.int64_value_; + int64 GetInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, + "MapValueConstRef::GetInt64Value"); + return *reinterpret_cast(data_); } uint64 GetUInt64Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapKey::GetUInt64Value"); - return val_.uint64_value_; + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, + "MapValueConstRef::GetUInt64Value"); + return *reinterpret_cast(data_); } int32 GetInt32Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapKey::GetInt32Value"); - return val_.int32_value_; + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, + "MapValueConstRef::GetInt32Value"); + return *reinterpret_cast(data_); } uint32 GetUInt32Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapKey::GetUInt32Value"); - return val_.uint32_value_; + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, + "MapValueConstRef::GetUInt32Value"); + return *reinterpret_cast(data_); } bool GetBoolValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapKey::GetBoolValue"); - return val_.bool_value_; + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueConstRef::GetBoolValue"); + return *reinterpret_cast(data_); + } + int GetEnumValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueConstRef::GetEnumValue"); + return *reinterpret_cast(data_); } const std::string& GetStringValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapKey::GetStringValue"); - return val_.string_value_.get(); + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, + "MapValueConstRef::GetStringValue"); + return *reinterpret_cast(data_); } - - bool operator<(const MapKey& other) const { - if (type_ != other.type_) { - // We could define a total order that handles this case, but - // there currently no need. So, for now, fail. - GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; - } - switch (type()) { - case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - return false; - case FieldDescriptor::CPPTYPE_STRING: - return val_.string_value_.get() < other.val_.string_value_.get(); - case FieldDescriptor::CPPTYPE_INT64: - return val_.int64_value_ < other.val_.int64_value_; - case FieldDescriptor::CPPTYPE_INT32: - return val_.int32_value_ < other.val_.int32_value_; - case FieldDescriptor::CPPTYPE_UINT64: - return val_.uint64_value_ < other.val_.uint64_value_; - case FieldDescriptor::CPPTYPE_UINT32: - return val_.uint32_value_ < other.val_.uint32_value_; - case FieldDescriptor::CPPTYPE_BOOL: - return val_.bool_value_ < other.val_.bool_value_; - } - return false; + float GetFloatValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, + "MapValueConstRef::GetFloatValue"); + return *reinterpret_cast(data_); + } + double GetDoubleValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, + "MapValueConstRef::GetDoubleValue"); + return *reinterpret_cast(data_); } - bool operator==(const MapKey& other) const { - if (type_ != other.type_) { - // To be consistent with operator<, we don't allow this either. - GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; - } - switch (type()) { - case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - break; - case FieldDescriptor::CPPTYPE_STRING: - return val_.string_value_.get() == other.val_.string_value_.get(); - case FieldDescriptor::CPPTYPE_INT64: - return val_.int64_value_ == other.val_.int64_value_; - case FieldDescriptor::CPPTYPE_INT32: - return val_.int32_value_ == other.val_.int32_value_; - case FieldDescriptor::CPPTYPE_UINT64: - return val_.uint64_value_ == other.val_.uint64_value_; - case FieldDescriptor::CPPTYPE_UINT32: - return val_.uint32_value_ == other.val_.uint32_value_; - case FieldDescriptor::CPPTYPE_BOOL: - return val_.bool_value_ == other.val_.bool_value_; - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return false; + const Message& GetMessageValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, + "MapValueConstRef::GetMessageValue"); + return *reinterpret_cast(data_); } - void CopyFrom(const MapKey& other) { - SetType(other.type()); - switch (type_) { - case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - break; - case FieldDescriptor::CPPTYPE_STRING: - *val_.string_value_.get_mutable() = other.val_.string_value_.get(); - break; - case FieldDescriptor::CPPTYPE_INT64: - val_.int64_value_ = other.val_.int64_value_; - break; - case FieldDescriptor::CPPTYPE_INT32: - val_.int32_value_ = other.val_.int32_value_; - break; - case FieldDescriptor::CPPTYPE_UINT64: - val_.uint64_value_ = other.val_.uint64_value_; - break; - case FieldDescriptor::CPPTYPE_UINT32: - val_.uint32_value_ = other.val_.uint32_value_; - break; - case FieldDescriptor::CPPTYPE_BOOL: - val_.bool_value_ = other.val_.bool_value_; - break; + protected: + // data_ point to a map value. MapValueConstRef does not + // own this value. + void* data_; + // type_ is 0 or a valid FieldDescriptor::CppType. + // Use "CppType()" to indicate zero. + FieldDescriptor::CppType type_; + + FieldDescriptor::CppType type() const { + if (type_ == FieldDescriptor::CppType() || data_ == nullptr) { + GOOGLE_LOG(FATAL) + << "Protocol Buffer map usage error:\n" + << "MapValueConstRef::type MapValueConstRef is not initialized."; } + return type_; } private: + template + friend class internal::MapField; template friend class internal::TypeDefinedMapFieldBase; friend class ::PROTOBUF_NAMESPACE_ID::MapIterator; + friend class Reflection; friend class internal::DynamicMapField; - union KeyValue { - KeyValue() {} - internal::ExplicitlyConstructed string_value_; - int64 int64_value_; - int32 int32_value_; - uint64 uint64_value_; - uint32 uint32_value_; - bool bool_value_; - } val_; - - void SetType(FieldDescriptor::CppType type) { - if (type_ == type) return; - if (type_ == FieldDescriptor::CPPTYPE_STRING) { - val_.string_value_.Destruct(); - } - type_ = type; - if (type_ == FieldDescriptor::CPPTYPE_STRING) { - val_.string_value_.DefaultConstruct(); - } + void SetType(FieldDescriptor::CppType type) { type_ = type; } + void SetValue(const void* val) { data_ = const_cast(val); } + void CopyFrom(const MapValueConstRef& other) { + type_ = other.type_; + data_ = other.data_; } - - // type_ is 0 or a valid FieldDescriptor::CppType. - int type_; }; -// MapValueRef points to a map value. -class PROTOBUF_EXPORT MapValueRef { +// MapValueRef points to a map value. Users are able to modify +// the map value. +class PROTOBUF_EXPORT MapValueRef final : public MapValueConstRef { public: - MapValueRef() : data_(NULL), type_(0) {} + MapValueRef() {} void SetInt64Value(int64 value) { TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::SetInt64Value"); @@ -620,49 +811,6 @@ class PROTOBUF_EXPORT MapValueRef { *reinterpret_cast(data_) = value; } - int64 GetInt64Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, "MapValueRef::GetInt64Value"); - return *reinterpret_cast(data_); - } - uint64 GetUInt64Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, "MapValueRef::GetUInt64Value"); - return *reinterpret_cast(data_); - } - int32 GetInt32Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, "MapValueRef::GetInt32Value"); - return *reinterpret_cast(data_); - } - uint32 GetUInt32Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, "MapValueRef::GetUInt32Value"); - return *reinterpret_cast(data_); - } - bool GetBoolValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, "MapValueRef::GetBoolValue"); - return *reinterpret_cast(data_); - } - int GetEnumValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, "MapValueRef::GetEnumValue"); - return *reinterpret_cast(data_); - } - const std::string& GetStringValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, "MapValueRef::GetStringValue"); - return *reinterpret_cast(data_); - } - float GetFloatValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, "MapValueRef::GetFloatValue"); - return *reinterpret_cast(data_); - } - double GetDoubleValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, "MapValueRef::GetDoubleValue"); - return *reinterpret_cast(data_); - } - - const Message& GetMessageValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, - "MapValueRef::GetMessageValue"); - return *reinterpret_cast(data_); - } - Message* MutableMessageValue() { TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, "MapValueRef::MutableMessageValue"); @@ -670,31 +818,8 @@ class PROTOBUF_EXPORT MapValueRef { } private: - template - friend class internal::MapField; - template - friend class internal::TypeDefinedMapFieldBase; - friend class ::PROTOBUF_NAMESPACE_ID::MapIterator; - friend class Reflection; friend class internal::DynamicMapField; - void SetType(FieldDescriptor::CppType type) { type_ = type; } - - FieldDescriptor::CppType type() const { - if (type_ == 0 || data_ == NULL) { - GOOGLE_LOG(FATAL) << "Protocol Buffer map usage error:\n" - << "MapValueRef::type MapValueRef is not initialized."; - } - return (FieldDescriptor::CppType)type_; - } - void SetValue(const void* val) { data_ = const_cast(val); } - void CopyFrom(const MapValueRef& other) { - type_ = other.type_; - data_ = other.data_; - } // Only used in DynamicMapField void DeleteData() { switch (type_) { @@ -716,11 +841,6 @@ class PROTOBUF_EXPORT MapValueRef { #undef HANDLE_TYPE } } - // data_ point to a map value. MapValueRef does not - // own this value. - void* data_; - // type_ is 0 or a valid FieldDescriptor::CppType. - int type_; }; #undef TYPE_CHECK @@ -775,8 +895,7 @@ class PROTOBUF_EXPORT MapIterator { friend class internal::DynamicMapField; template + internal::WireFormatLite::FieldType kValueFieldType> friend class internal::MapField; // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns @@ -794,40 +913,6 @@ class PROTOBUF_EXPORT MapIterator { } // namespace protobuf } // namespace google -GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START -template <> -struct hash<::PROTOBUF_NAMESPACE_ID::MapKey> { - size_t operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key) const { - switch (map_key.type()) { - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_DOUBLE: - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_FLOAT: - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_ENUM: - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - break; - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_STRING: - return hash()(map_key.GetStringValue()); - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT64: - return hash()(map_key.GetInt64Value()); - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_INT32: - return hash()(map_key.GetInt32Value()); - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT64: - return hash()(map_key.GetUInt64Value()); - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_UINT32: - return hash()(map_key.GetUInt32Value()); - case ::PROTOBUF_NAMESPACE_ID::FieldDescriptor::CPPTYPE_BOOL: - return hash()(map_key.GetBoolValue()); - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return 0; - } - bool operator()(const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key1, - const ::PROTOBUF_NAMESPACE_ID::MapKey& map_key2) const { - return map_key1 < map_key2; - } -}; -GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END - #include #endif // GOOGLE_PROTOBUF_MAP_FIELD_H__ diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h index 7baaa5ff318a..8e921708de8f 100644 --- a/src/google/protobuf/map_field_inl.h +++ b/src/google/protobuf/map_field_inl.h @@ -164,18 +164,16 @@ void TypeDefinedMapFieldBase::CopyIterator( template -int MapField::size() const { + WireFormatLite::FieldType kValueFieldType> +int MapField::size() const { MapFieldBase::SyncMapWithRepeatedField(); return static_cast(impl_.GetMap().size()); } template -void MapField::Clear() { + WireFormatLite::FieldType kValueFieldType> +void MapField::Clear() { if (this->MapFieldBase::repeated_field_ != nullptr) { RepeatedPtrField* repeated_field = reinterpret_cast*>( @@ -192,9 +190,9 @@ void MapField -void MapField::SetMapIteratorValue(MapIterator* map_iter) + WireFormatLite::FieldType kValueFieldType> +void MapField::SetMapIteratorValue(MapIterator* map_iter) const { const Map& map = impl_.GetMap(); typename Map::const_iterator iter = @@ -206,9 +204,9 @@ void MapField -bool MapField::ContainsMapKey(const MapKey& map_key) const { + WireFormatLite::FieldType kValueFieldType> +bool MapField::ContainsMapKey( + const MapKey& map_key) const { const Map& map = impl_.GetMap(); const Key& key = UnwrapMapKey(map_key); typename Map::const_iterator iter = map.find(key); @@ -217,10 +215,10 @@ bool MapField -bool MapField::InsertOrLookupMapValue(const MapKey& map_key, - MapValueRef* val) { + WireFormatLite::FieldType kValueFieldType> +bool MapField::InsertOrLookupMapValue(const MapKey& map_key, + MapValueRef* val) { // Always use mutable map because users may change the map value by // MapValueRef. Map* map = MutableMap(); @@ -238,18 +236,35 @@ bool MapField -bool MapField::DeleteMapValue(const MapKey& map_key) { + WireFormatLite::FieldType kValueFieldType> +bool MapField::LookupMapValue( + const MapKey& map_key, MapValueConstRef* val) const { + const Map& map = GetMap(); + const Key& key = UnwrapMapKey(map_key); + typename Map::const_iterator iter = map.find(key); + if (map.end() == iter) { + return false; + } + // Key is already in the map. Make sure (*map)[key] is not called. + // [] may reorder the map and iterators. + val->SetValue(&(iter->second)); + return true; +} + +template +bool MapField::DeleteMapValue( + const MapKey& map_key) { const Key& key = UnwrapMapKey(map_key); return MutableMap()->erase(key); } template -void MapField::MergeFrom(const MapFieldBase& other) { + WireFormatLite::FieldType kValueFieldType> +void MapField::MergeFrom( + const MapFieldBase& other) { MapFieldBase::SyncMapWithRepeatedField(); const MapField& other_field = static_cast(other); other_field.SyncMapWithRepeatedField(); @@ -259,9 +274,9 @@ void MapField -void MapField::Swap(MapFieldBase* other) { + WireFormatLite::FieldType kValueFieldType> +void MapField::Swap( + MapFieldBase* other) { MapField* other_field = down_cast(other); std::swap(this->MapFieldBase::repeated_field_, other_field->repeated_field_); impl_.Swap(&other_field->impl_); @@ -274,9 +289,9 @@ void MapField -void MapField::SyncRepeatedFieldWithMapNoLock() const { + WireFormatLite::FieldType kValueFieldType> +void MapField::SyncRepeatedFieldWithMapNoLock() const { if (this->MapFieldBase::repeated_field_ == NULL) { if (this->MapFieldBase::arena_ == NULL) { this->MapFieldBase::repeated_field_ = new RepeatedPtrField(); @@ -311,9 +326,9 @@ void MapField -void MapField::SyncMapWithRepeatedFieldNoLock() const { + WireFormatLite::FieldType kValueFieldType> +void MapField::SyncMapWithRepeatedFieldNoLock() const { Map* map = const_cast(this)->impl_.MutableMap(); RepeatedPtrField* repeated_field = reinterpret_cast*>( @@ -334,20 +349,15 @@ void MapField -size_t MapField::SpaceUsedExcludingSelfNoLock() const { + WireFormatLite::FieldType kValueFieldType> +size_t MapField::SpaceUsedExcludingSelfNoLock() const { size_t size = 0; if (this->MapFieldBase::repeated_field_ != NULL) { size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong(); } - Map* map = const_cast(this)->impl_.MutableMap(); - size += sizeof(*map); - for (typename Map::iterator it = map->begin(); it != map->end(); - ++it) { - size += KeyTypeHandler::SpaceUsedInMapLong(it->first); - size += ValueTypeHandler::SpaceUsedInMapLong(it->second); - } + size += impl_.GetMap().SpaceUsedExcludingSelfLong(); + return size; } } // namespace internal diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index 3f2f6324ab66..665cb0eebe87 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h @@ -50,11 +50,11 @@ namespace protobuf { namespace internal { // This class provides access to map field using generated api. It is used for -// internal generated message implentation only. Users should never use this +// internal generated message implementation only. Users should never use this // directly. template + WireFormatLite::FieldType value_wire_type> class MapFieldLite { // Define message type for internal repeated field. typedef Derived EntryType; @@ -63,9 +63,9 @@ class MapFieldLite { typedef Map MapType; typedef EntryType EntryTypeTrait; - MapFieldLite() { SetDefaultEnumValue(); } + constexpr MapFieldLite() {} - explicit MapFieldLite(Arena* arena) : map_(arena) { SetDefaultEnumValue(); } + explicit MapFieldLite(Arena* arena) : map_(arena) {} // Accessors const Map& GetMap() const { return map_; } @@ -82,15 +82,10 @@ class MapFieldLite { } void Swap(MapFieldLite* other) { map_.swap(other->map_); } - // Set default enum value only for proto2 map field whose value is enum type. - void SetDefaultEnumValue() { - MutableMap()->SetDefaultEnumValue(default_enum_value); - } - // Used in the implementation of parsing. Caller should take the ownership iff // arena_ is NULL. EntryType* NewEntry() const { - return Arena::CreateMessage(map_.arena_); + return Arena::CreateMessage(map_.arena()); } // Used in the implementation of serializing enum value type. Caller should // take the ownership iff arena_ is NULL. @@ -108,13 +103,13 @@ class MapFieldLite { return parser._InternalParse(ptr, ctx); } - template + template const char* ParseWithEnumValidation(const char* ptr, ParseContext* ctx, bool (*is_valid)(int), uint32 field_num, - Metadata* metadata) { + InternalMetadata* metadata) { typename Derived::template Parser> parser(this); - return parser.ParseWithEnumValidation(ptr, ctx, is_valid, field_num, - metadata); + return parser.template ParseWithEnumValidation( + ptr, ctx, is_valid, field_num, metadata); } private: @@ -125,28 +120,27 @@ class MapFieldLite { friend class ::PROTOBUF_NAMESPACE_ID::Arena; }; -template +template struct EnumParseWrapper { const char* _InternalParse(const char* ptr, ParseContext* ctx) { - return map_field->ParseWithEnumValidation(ptr, ctx, is_valid, field_num, - metadata); + return map_field->template ParseWithEnumValidation( + ptr, ctx, is_valid, field_num, metadata); } T* map_field; bool (*is_valid)(int); uint32 field_num; - Metadata* metadata; + InternalMetadata* metadata; }; // Helper function because the typenames of maps are horrendous to print. This // leverages compiler type deduction, to keep all type data out of the // generated code -template -EnumParseWrapper InitEnumParseWrapper(T* map_field, - bool (*is_valid)(int), - uint32 field_num, - Metadata* metadata) { - return EnumParseWrapper{map_field, is_valid, field_num, - metadata}; +template +EnumParseWrapper InitEnumParseWrapper( + T* map_field, bool (*is_valid)(int), uint32 field_num, + InternalMetadata* metadata) { + return EnumParseWrapper{map_field, is_valid, field_num, + metadata}; } // True if IsInitialized() is true for value field in all elements of t. T is @@ -155,10 +149,9 @@ EnumParseWrapper InitEnumParseWrapper(T* map_field, // We want the C++ compiler to inline this or not as it sees fit. template -bool AllAreInitialized( - const MapFieldLite& field) { + WireFormatLite::FieldType value_wire_type> +bool AllAreInitialized(const MapFieldLite& field) { const auto& t = field.GetMap(); for (typename Map::const_iterator it = t.begin(); it != t.end(); ++it) { @@ -172,13 +165,12 @@ struct MapEntryToMapField : MapEntryToMapField {}; template -struct MapEntryToMapField> { - typedef MapFieldLite, - Key, Value, kKeyFieldType, kValueFieldType, - default_enum_value> + WireFormatLite::FieldType kValueFieldType> +struct MapEntryToMapField< + MapEntryLite> { + typedef MapFieldLite< + MapEntryLite, Key, Value, + kKeyFieldType, kValueFieldType> MapFieldType; }; diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 05f83e23fa72..dd70e989d0e1 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -45,6 +45,9 @@ #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -77,6 +80,10 @@ class MapFieldBaseStub : public MapFieldBase { MapValueRef* val) override { return false; } + bool LookupMapValue(const MapKey& map_key, + MapValueConstRef* val) const override { + return false; + } bool DeleteMapValue(const MapKey& map_key) override { return false; } bool EqualIterator(const MapIterator& a, const MapIterator& b) const override { @@ -99,7 +106,7 @@ class MapFieldBasePrimitiveTest : public ::testing::Test { protected: typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType; typedef MapField + WireFormatLite::TYPE_INT32> MapFieldType; MapFieldBasePrimitiveTest() { @@ -107,8 +114,8 @@ class MapFieldBasePrimitiveTest : public ::testing::Test { map_descriptor_ = unittest::TestMap::descriptor() ->FindFieldByName("map_int32_int32") ->message_type(); - key_descriptor_ = map_descriptor_->FindFieldByName("key"); - value_descriptor_ = map_descriptor_->FindFieldByName("value"); + key_descriptor_ = map_descriptor_->map_key(); + value_descriptor_ = map_descriptor_->map_value(); // Build map field map_field_.reset(new MapFieldType); @@ -203,7 +210,7 @@ class MapFieldStateTest : public testing::TestWithParam { protected: typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType; typedef MapField + WireFormatLite::TYPE_INT32> MapFieldType; MapFieldStateTest() : state_(GetParam()) { // Build map field @@ -474,7 +481,25 @@ TEST_P(MapFieldStateTest, MutableMapField) { } } +class MyMapField + : public MapField { + public: + constexpr MyMapField() + : MyMapField::MapField(internal::ConstantInitialized{}) {} +}; + +TEST(MapFieldTest, ConstInit) { + // This tests that `MapField` and all its base classes can be constant + // initialized. + PROTOBUF_CONSTINIT static MyMapField field; // NOLINT + EXPECT_EQ(field.size(), 0); +} + } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/map_lite_unittest.proto b/src/google/protobuf/map_lite_unittest.proto index 0135fff30543..cc00deec25d1 100644 --- a/src/google/protobuf/map_lite_unittest.proto +++ b/src/google/protobuf/map_lite_unittest.proto @@ -30,55 +30,52 @@ syntax = "proto2"; -option cc_enable_arenas = true; -option optimize_for = LITE_RUNTIME; +package protobuf_unittest; import "google/protobuf/unittest_lite.proto"; -import "google/protobuf/unittest_no_arena_lite.proto"; -package protobuf_unittest; +option cc_enable_arenas = true; +option optimize_for = LITE_RUNTIME; message TestMapLite { - map map_int32_int32 = 1; - map map_int64_int64 = 2; - map map_uint32_uint32 = 3; - map map_uint64_uint64 = 4; - map map_sint32_sint32 = 5; - map map_sint64_sint64 = 6; - map map_fixed32_fixed32 = 7; - map map_fixed64_fixed64 = 8; + map map_int32_int32 = 1; + map map_int64_int64 = 2; + map map_uint32_uint32 = 3; + map map_uint64_uint64 = 4; + map map_sint32_sint32 = 5; + map map_sint64_sint64 = 6; + map map_fixed32_fixed32 = 7; + map map_fixed64_fixed64 = 8; map map_sfixed32_sfixed32 = 9; map map_sfixed64_sfixed64 = 10; - map map_int32_float = 11; - map map_int32_double = 12; - map map_bool_bool = 13; - map map_string_string = 14; - map map_int32_bytes = 15; - map map_int32_enum = 16; - map map_int32_foreign_message = 17; + map map_int32_float = 11; + map map_int32_double = 12; + map map_bool_bool = 13; + map map_string_string = 14; + map map_int32_bytes = 15; + map map_int32_enum = 16; + map map_int32_foreign_message = 17; map teboring = 18; } message TestArenaMapLite { - map map_int32_int32 = 1; - map map_int64_int64 = 2; - map map_uint32_uint32 = 3; - map map_uint64_uint64 = 4; - map map_sint32_sint32 = 5; - map map_sint64_sint64 = 6; - map map_fixed32_fixed32 = 7; - map map_fixed64_fixed64 = 8; + map map_int32_int32 = 1; + map map_int64_int64 = 2; + map map_uint32_uint32 = 3; + map map_uint64_uint64 = 4; + map map_sint32_sint32 = 5; + map map_sint64_sint64 = 6; + map map_fixed32_fixed32 = 7; + map map_fixed64_fixed64 = 8; map map_sfixed32_sfixed32 = 9; map map_sfixed64_sfixed64 = 10; - map map_int32_float = 11; - map map_int32_double = 12; - map map_bool_bool = 13; - map map_string_string = 14; - map map_int32_bytes = 15; - map map_int32_enum = 16; - map map_int32_foreign_message = 17; - map - map_int32_foreign_message_no_arena = 18; + map map_int32_float = 11; + map map_int32_double = 12; + map map_bool_bool = 13; + map map_string_string = 14; + map map_int32_bytes = 15; + map map_int32_enum = 16; + map map_int32_foreign_message = 17; } // Test embedded message with required fields @@ -107,9 +104,9 @@ enum Proto2MapEnumLite { } enum Proto2MapEnumPlusExtraLite { - E_PROTO2_MAP_ENUM_FOO_LITE = 0; - E_PROTO2_MAP_ENUM_BAR_LITE = 1; - E_PROTO2_MAP_ENUM_BAZ_LITE = 2; + E_PROTO2_MAP_ENUM_FOO_LITE = 0; + E_PROTO2_MAP_ENUM_BAR_LITE = 1; + E_PROTO2_MAP_ENUM_BAZ_LITE = 2; E_PROTO2_MAP_ENUM_EXTRA_LITE = 3; } diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 742cc0031a8c..8fb0b908f5a9 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -39,9 +39,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -78,6 +80,7 @@ #include +// Must be included last. #include namespace google { @@ -94,6 +97,8 @@ void MapTestForceDeterministic() { io::CodedOutputStream::SetDefaultSerializationDeterministic(); } +namespace { + // Map API Test ===================================================== class MapImplTest : public ::testing::Test { @@ -190,6 +195,62 @@ TEST_F(MapImplTest, OperatorBracket) { ExpectSingleElement(key, value2); } +struct MoveTestKey { + MoveTestKey(int data, int* copies) : data(data), copies(copies) {} + + MoveTestKey(const MoveTestKey& other) + : data(other.data), copies(other.copies) { + ++*copies; + } + + MoveTestKey(MoveTestKey&& other) noexcept + : data(other.data), copies(other.copies) {} + + friend bool operator==(const MoveTestKey& lhs, const MoveTestKey& rhs) { + return lhs.data == rhs.data; + } + friend bool operator<(const MoveTestKey& lhs, const MoveTestKey& rhs) { + return lhs.data < rhs.data; + } + + int data; + int* copies; +}; + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google + +namespace std { + +template <> // NOLINT +struct hash { + size_t operator()(const google::protobuf::internal::MoveTestKey& key) const { + return hash{}(key.data); + } +}; +} // namespace std + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST_F(MapImplTest, OperatorBracketRValue) { + Arena arena; + for (Arena* arena_to_use : {&arena, static_cast(nullptr)}) { + int copies = 0; + Map map(arena_to_use); + MoveTestKey key1(1, &copies); + EXPECT_EQ(copies, 0); + map[key1] = 0; + EXPECT_EQ(copies, 1); + map[MoveTestKey(2, &copies)] = 2; + EXPECT_EQ(copies, 1); + } +} + TEST_F(MapImplTest, OperatorBracketNonExist) { int32 key = 0; int32 default_value = 0; @@ -230,9 +291,10 @@ TEST_F(MapImplTest, UsageErrors) { " Actual : int64"); MapValueRef value; - EXPECT_DEATH(value.SetFloatValue(0.1), - "Protocol Buffer map usage error:\n" - "MapValueRef::type MapValueRef is not initialized."); + EXPECT_DEATH( + value.SetFloatValue(0.1), + "Protocol Buffer map usage error:\n" + "MapValue[Const]*Ref::type MapValue[Const]*Ref is not initialized."); } #endif // PROTOBUF_HAS_DEATH_TEST @@ -976,15 +1038,159 @@ TEST_F(MapImplTest, CopyAssignMapIterator) { EXPECT_EQ(it1.GetKey().GetInt32Value(), it2.GetKey().GetInt32Value()); } +TEST_F(MapImplTest, SpaceUsed) { + constexpr size_t kMinCap = 8; + + Map m; + // An newly constructed map should have no space used. + EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), 0); + + size_t capacity = kMinCap; + for (int i = 0; i < 100; ++i) { + m[i]; + static constexpr double kMaxLoadFactor = .75; + if (m.size() >= capacity * kMaxLoadFactor) { + capacity *= 2; + } + EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), + sizeof(void*) * capacity + + m.size() * sizeof(std::pair, void*>)); + } + + // Test string, and non-scalar keys. + Map m2; + std::string str = "Some arbitrarily large string"; + m2[str] = 1; + EXPECT_EQ(m2.SpaceUsedExcludingSelfLong(), + sizeof(void*) * kMinCap + + sizeof(std::pair, void*>) + + internal::StringSpaceUsedExcludingSelfLong(str)); + + // Test messages, and non-scalar values. + Map m3; + m3[0].set_optional_string(str); + EXPECT_EQ(m3.SpaceUsedExcludingSelfLong(), + sizeof(void*) * kMinCap + + sizeof(std::pair, void*>) + + m3[0].SpaceUsedLong() - sizeof(m3[0])); +} + +// Attempts to verify that a map with keys a and b has a random ordering. This +// function returns true if it succeeds in observing both possible orderings. +bool MapOrderingIsRandom(int a, int b) { + bool saw_a_first = false; + bool saw_b_first = false; + + for (int i = 0; i < 50; ++i) { + Map m; + m[a] = 0; + m[b] = 0; + int32 first_element = m.begin()->first; + if (first_element == a) saw_a_first = true; + if (first_element == b) saw_b_first = true; + if (saw_a_first && saw_b_first) { + return true; + } + } + + return false; +} + +// This test verifies that the iteration order is reasonably random even for +// small maps. Currently we only have sufficient randomness for debug builds and +// builds where we can use the RDTSC instruction, so we only test for those +// builds. +#if defined(__x86_64__) && defined(__GNUC__) && \ + !defined(GOOGLE_PROTOBUF_NO_RDTSC) +TEST_F(MapImplTest, RandomOrdering) { + for (int i = 0; i < 10; ++i) { + for (int j = i + 1; j < 10; ++j) { + EXPECT_TRUE(MapOrderingIsRandom(i, j)) + << "Map with keys " << i << " and " << j + << " has deterministic ordering"; + } + } +} +#endif + +template +void TestTransparent(const Key& key, const Key& miss_key) { + Map m; + const auto& cm = m; + + m.insert({"ABC", 1}); + + const auto abc_it = m.begin(); + + m.insert({"DEF", 2}); + + using testing::Pair; + using testing::UnorderedElementsAre; + + EXPECT_EQ(m.at(key), 1); + EXPECT_EQ(cm.at(key), 1); + +#ifdef PROTOBUF_HAS_DEATH_TEST + EXPECT_DEATH(m.at(miss_key), ""); + EXPECT_DEATH(cm.at(miss_key), ""); +#endif // PROTOBUF_HAS_DEATH_TEST + + EXPECT_EQ(m.count(key), 1); + EXPECT_EQ(cm.count(key), 1); + EXPECT_EQ(m.count(miss_key), 0); + EXPECT_EQ(cm.count(miss_key), 0); + + EXPECT_EQ(m.find(key), abc_it); + EXPECT_EQ(cm.find(key), abc_it); + EXPECT_EQ(m.find(miss_key), m.end()); + EXPECT_EQ(cm.find(miss_key), cm.end()); + + EXPECT_TRUE(m.contains(key)); + EXPECT_TRUE(cm.contains(key)); + EXPECT_FALSE(m.contains(miss_key)); + EXPECT_FALSE(cm.contains(miss_key)); + + EXPECT_THAT(m.equal_range(key), Pair(abc_it, std::next(abc_it))); + EXPECT_THAT(cm.equal_range(key), Pair(abc_it, std::next(abc_it))); + EXPECT_THAT(m.equal_range(miss_key), Pair(m.end(), m.end())); + EXPECT_THAT(cm.equal_range(miss_key), Pair(m.end(), m.end())); + + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2))); + EXPECT_EQ(m.erase(key), 1); + EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2))); + EXPECT_EQ(m.erase(key), 0); + EXPECT_EQ(m.erase(miss_key), 0); + EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2))); + + m[key]; + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 0), Pair("DEF", 2))); + m[key] = 1; + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2))); +} + +TEST_F(MapImplTest, TransparentLookupForString) { + TestTransparent("ABC", "LKJ"); + TestTransparent(std::string("ABC"), std::string("LKJ")); +#if defined(__cpp_lib_string_view) + TestTransparent(std::string_view("ABC"), std::string_view("LKJ")); +#endif // defined(__cpp_lib_string_view) + + // std::reference_wrapper + std::string abc = "ABC", lkj = "LKJ"; + TestTransparent(std::ref(abc), std::ref(lkj)); + TestTransparent(std::cref(abc), std::cref(lkj)); +} + +TEST_F(MapImplTest, ConstInit) { + PROTOBUF_CONSTINIT static Map map; // NOLINT + EXPECT_TRUE(map.empty()); +} + // Map Field Reflection Test ======================================== static int Func(int i, int j) { return i * j; } -static std::string StrFunc(int i, int j) { - std::string str; - SStringPrintf(&str, "%d", Func(i, j)); - return str; -} +static std::string StrFunc(int i, int j) { return StrCat(Func(i, j)); } static int Int(const std::string& value) { int result = 0; @@ -992,6 +1198,9 @@ static int Int(const std::string& value) { return result; } +} // namespace + +// This class is a friend, so no anonymous namespace. class MapFieldReflectionTest : public testing::Test { protected: typedef FieldDescriptor FD; @@ -1002,6 +1211,8 @@ class MapFieldReflectionTest : public testing::Test { } }; +namespace { + TEST_F(MapFieldReflectionTest, RegularFields) { TestMap message; const Reflection* refl = message.GetReflection(); @@ -1842,6 +2053,39 @@ TEST_F(MapFieldReflectionTest, UninitializedEntry) { EXPECT_FALSE(message.IsInitialized()); } +class MyMapEntry + : public internal::MapEntry { + public: + constexpr MyMapEntry() {} + MyMapEntry(Arena*) { std::abort(); } + Metadata GetMetadata() const override { std::abort(); } + static bool ValidateKey(void*) { return true; } + static bool ValidateValue(void*) { return true; } +}; + +class MyMapEntryLite + : public internal::MapEntryLite { + public: + constexpr MyMapEntryLite() {} + explicit MyMapEntryLite(Arena*) { std::abort(); } + static bool ValidateKey(void*) { return true; } + static bool ValidateValue(void*) { return true; } +}; + +TEST(MapEntryTest, ConstInit) { + // This verifies that `MapEntry`, `MapEntryLite` and `MapEntryImpl` can be + // constant initialized. + PROTOBUF_CONSTINIT static MyMapEntry entry{}; + EXPECT_NE(entry.SpaceUsed(), 0); + + PROTOBUF_CONSTINIT static MyMapEntryLite entry_lite{}; // NOLINT + EXPECT_TRUE(entry_lite.IsInitialized()); +} + // Generated Message Test =========================================== TEST(GeneratedMapFieldTest, Accessors) { @@ -2134,7 +2378,7 @@ TEST(GeneratedMapFieldTest, SerializationToArray) { unittest::TestMap message1, message2; std::string data; MapTestUtil::SetMapFields(&message1); - int size = message1.ByteSize(); + size_t size = message1.ByteSizeLong(); data.resize(size); uint8* start = reinterpret_cast(::google::protobuf::string_as_array(&data)); uint8* end = message1.SerializeWithCachedSizesToArray(start); @@ -2147,7 +2391,7 @@ TEST(GeneratedMapFieldTest, SerializationToArray) { TEST(GeneratedMapFieldTest, SerializationToStream) { unittest::TestMap message1, message2; MapTestUtil::SetMapFields(&message1); - int size = message1.ByteSize(); + size_t size = message1.ByteSizeLong(); std::string data; data.resize(size); { @@ -2364,7 +2608,7 @@ TEST(GeneratedMapFieldTest, MissedValueTextFormat) { EXPECT_TRUE(TextFormat::ParseFromString(text, &message)); EXPECT_EQ(1, message.map_int32_foreign_message().size()); - EXPECT_EQ(11, message.ByteSize()); + EXPECT_EQ(11, message.ByteSizeLong()); } TEST(GeneratedMapFieldTest, UnknownFieldWireFormat) { @@ -2401,47 +2645,68 @@ TEST(GeneratedMapFieldTest, IsInitialized) { EXPECT_TRUE(map_message.IsInitialized()); } +TEST(GeneratedMapFieldTest, SpaceUsed) { + unittest::TestRequiredMessageMap map_message; + const size_t initial = map_message.SpaceUsed(); + const size_t space_used_message = unittest::TestRequired().SpaceUsed(); + + auto& m = *map_message.mutable_map_field(); + constexpr int kNumValues = 100; + for (int i = 0; i < kNumValues; ++i) { + m[i]; + } + + // The exact value will depend on internal state, like collisions, + // so we can't predict it. But we can predict a lower bound. + size_t lower_bound = + initial + kNumValues * (space_used_message + sizeof(int32) + + /* Node::next */ sizeof(void*) + + /* table entry */ sizeof(void*)); + + EXPECT_LE(lower_bound, map_message.SpaceUsed()); +} + TEST(GeneratedMapFieldTest, MessagesMustMerge) { unittest::TestRequiredMessageMap map_message; + unittest::TestRequired with_dummy4; with_dummy4.set_a(97); - with_dummy4.set_b(0); - with_dummy4.set_c(0); + with_dummy4.set_b(91); with_dummy4.set_dummy4(98); - - EXPECT_TRUE(with_dummy4.IsInitialized()); + EXPECT_FALSE(with_dummy4.IsInitialized()); (*map_message.mutable_map_field())[0] = with_dummy4; - EXPECT_TRUE(map_message.IsInitialized()); - std::string s = map_message.SerializeAsString(); + EXPECT_FALSE(map_message.IsInitialized()); - // Modify s so that there are two values in the entry for key 0. - // The first will have no value for c. The second will have no value for a. - // Those are required fields. Also, make some other little changes, to - // ensure we are merging the two values (because they're messages). - ASSERT_EQ(s.size() - 2, s[1]); // encoding of the length of what follows - std::string encoded_val(s.data() + 4, s.data() + s.size()); - // In s, change the encoding of c to an encoding of dummy32. - s[s.size() - 3] -= 8; - // Make encoded_val slightly different from what's in s. - encoded_val[encoded_val.size() - 1] += 33; // Encode c = 33. - for (int i = 0; i < encoded_val.size(); i++) { - if (encoded_val[i] == 97) { - // Encode b = 91 instead of a = 97. But this won't matter, because - // we also encode b = 0 right after this. The point is to leave out - // a required field, and make sure the parser doesn't complain, because - // every required field is set after the merge of the two values. - encoded_val[i - 1] += 16; - encoded_val[i] = 91; - } else if (encoded_val[i] == 98) { - // Encode dummy5 = 99 instead of dummy4 = 98. - encoded_val[i - 1] += 8; // The tag for dummy5 is 8 more. - encoded_val[i]++; - break; - } - } + unittest::TestRequired with_dummy5; + with_dummy5.set_b(0); + with_dummy5.set_c(33); + with_dummy5.set_dummy5(99); + EXPECT_FALSE(with_dummy5.IsInitialized()); + (*map_message.mutable_map_field())[0] = with_dummy5; + EXPECT_FALSE(map_message.IsInitialized()); - s += encoded_val; // Add the second message. - s[1] += encoded_val.size(); // Adjust encoded size. + // The wire format of MapEntry is straightforward (*) and can be manually + // constructed to force merging of two uninitialized messages that would + // result in an initialized message. + // + // (*) http://google3/net/proto2/internal/map_test.cc?l=2433&rcl=310012028 + std::string dummy4_s = with_dummy4.SerializePartialAsString(); + std::string dummy5_s = with_dummy5.SerializePartialAsString(); + int payload_size = dummy4_s.size() + dummy5_s.size(); + // Makes sure the payload size fits into one byte. + ASSERT_LT(payload_size, 128); + + std::string s(6, 0); + char* p = &s[0]; + *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + // Length: 2B for key tag & val and 2B for val tag and length of the following + // payload. + *p++ = 4 + payload_size; + *p++ = WireFormatLite::MakeTag(1, WireFormatLite::WIRETYPE_VARINT); + *p++ = 0; + *p++ = WireFormatLite::MakeTag(2, WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + *p++ = payload_size; + StrAppend(&s, dummy4_s, dummy5_s); // Test key then value then value. int key = 0; @@ -2476,7 +2741,7 @@ TEST(GeneratedMapFieldReflectionTest, SpaceUsed) { MapReflectionTester reflection_tester(unittest::TestMap::descriptor()); reflection_tester.SetMapFieldsViaReflection(&message); - EXPECT_LT(0, message.GetReflection()->SpaceUsed(message)); + EXPECT_LT(0, message.GetReflection()->SpaceUsedLong(message)); } TEST(GeneratedMapFieldReflectionTest, Accessors) { @@ -2762,7 +3027,7 @@ TEST_F(MapFieldInDynamicMessageTest, DynamicMapReflection) { } TEST_F(MapFieldInDynamicMessageTest, MapSpaceUsed) { - // Test that SpaceUsed() works properly + // Test that SpaceUsedLong() works properly // Since we share the implementation with generated messages, we don't need // to test very much here. Just make sure it appears to be working. @@ -2770,10 +3035,10 @@ TEST_F(MapFieldInDynamicMessageTest, MapSpaceUsed) { std::unique_ptr message(map_prototype_->New()); MapReflectionTester reflection_tester(map_descriptor_); - int initial_space_used = message->SpaceUsed(); + int initial_space_used = message->SpaceUsedLong(); reflection_tester.SetMapFieldsViaReflection(message.get()); - EXPECT_LT(initial_space_used, message->SpaceUsed()); + EXPECT_LT(initial_space_used, message->SpaceUsedLong()); } TEST_F(MapFieldInDynamicMessageTest, RecursiveMap) { @@ -2947,9 +3212,9 @@ TEST(WireFormatForMapFieldTest, MapByteSize) { unittest::TestMap message; MapTestUtil::SetMapFields(&message); - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); message.Clear(); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); EXPECT_EQ(0, WireFormat::ByteSize(message)); } @@ -2962,7 +3227,7 @@ TEST(WireFormatForMapFieldTest, SerializeMap) { // Serialize using the generated code. { - message.ByteSize(); + message.ByteSizeLong(); io::StringOutputStream raw_output(&generated_data); io::CodedOutputStream output(&raw_output); message.SerializeWithCachedSizes(&output); @@ -2973,15 +3238,14 @@ TEST(WireFormatForMapFieldTest, SerializeMap) { { io::StringOutputStream raw_output(&dynamic_data); io::CodedOutputStream output(&raw_output); - int size = WireFormat::ByteSize(message); + size_t size = WireFormat::ByteSize(message); WireFormat::SerializeWithCachedSizes(message, size, &output); ASSERT_FALSE(output.HadError()); } - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); } TEST(WireFormatForMapFieldTest, SerializeMapDynamicMessage) { @@ -3021,7 +3285,7 @@ TEST(WireFormatForMapFieldTest, MapByteSizeDynamicMessage) { std::string expected_serialized_data; dynamic_message->SerializeToString(&expected_serialized_data); int expected_size = expected_serialized_data.size(); - EXPECT_EQ(dynamic_message->ByteSize(), expected_size); + EXPECT_EQ(dynamic_message->ByteSizeLong(), expected_size); std::unique_ptr message2; message2.reset(factory.GetPrototype(unittest::TestMap::descriptor())->New()); @@ -3035,27 +3299,27 @@ TEST(WireFormatForMapFieldTest, MapByteSizeDynamicMessage) { reflection->RemoveLast(dynamic_message.get(), field); dynamic_message->MergeFrom(*message2); dynamic_message->MergeFrom(*message2); - // The map field is marked as STATE_MODIFIED_REPEATED, ByteSize() will use + // The map field is marked as STATE_MODIFIED_REPEATED, ByteSizeLong() will use // repeated field which have duplicate keys to calculate. - int duplicate_size = dynamic_message->ByteSize(); + size_t duplicate_size = dynamic_message->ByteSizeLong(); EXPECT_TRUE(duplicate_size > expected_size); std::string duplicate_serialized_data; dynamic_message->SerializeToString(&duplicate_serialized_data); - EXPECT_EQ(dynamic_message->ByteSize(), duplicate_serialized_data.size()); + EXPECT_EQ(dynamic_message->ByteSizeLong(), duplicate_serialized_data.size()); // Force the map field to mark with map CLEAN EXPECT_EQ(reflection_tester.MapSize(*dynamic_message, "map_int32_int32"), 2); - // The map field is marked as CLEAN, ByteSize() will use map which do not + // The map field is marked as CLEAN, ByteSizeLong() will use map which do not // have duplicate keys to calculate. - int size = dynamic_message->ByteSize(); + int size = dynamic_message->ByteSizeLong(); EXPECT_EQ(expected_size, size); // Protobuf used to have a bug for serialize when map it marked CLEAN. It used - // repeated field to calculate ByteSize but use map to serialize the real data, - // thus the ByteSize may bigger than real serialized size. A crash might be - // happen at SerializeToString(). Or an "unexpect end group" warning was - // raised at parse back if user use SerializeWithCachedSizes() which avoids - // size check at serialize. + // repeated field to calculate ByteSizeLong but use map to serialize the real + // data, thus the ByteSizeLong may bigger than real serialized size. A crash + // might be happen at SerializeToString(). Or an "unexpected end group" + // warning was raised at parse back if user use SerializeWithCachedSizes() + // which avoids size check at serialize. std::string serialized_data; dynamic_message->SerializeToString(&serialized_data); EXPECT_EQ(serialized_data, expected_serialized_data); @@ -3113,7 +3377,7 @@ TEST(WireFormatForMapFieldTest, MapParseHelpers) { template static std::string DeterministicSerializationWithSerializePartialToCodedStream( const T& t) { - const int size = t.ByteSize(); + const size_t size = t.ByteSizeLong(); std::string result(size, '\0'); io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); io::CodedOutputStream output_stream(&array_stream); @@ -3127,7 +3391,7 @@ static std::string DeterministicSerializationWithSerializePartialToCodedStream( template static std::string DeterministicSerializationWithSerializeToCodedStream( const T& t) { - const int size = t.ByteSize(); + const size_t size = t.ByteSizeLong(); std::string result(size, '\0'); io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); io::CodedOutputStream output_stream(&array_stream); @@ -3140,7 +3404,7 @@ static std::string DeterministicSerializationWithSerializeToCodedStream( template static std::string DeterministicSerialization(const T& t) { - const int size = t.ByteSize(); + const size_t size = t.ByteSizeLong(); std::string result(size, '\0'); io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&result), size); { @@ -3156,20 +3420,6 @@ static std::string DeterministicSerialization(const T& t) { return result; } -// Helper to test the serialization of the first arg against a golden file. -static void TestDeterministicSerialization(const protobuf_unittest::TestMaps& t, - const std::string& filename) { - std::string expected; - GOOGLE_CHECK_OK(File::GetContents( - TestUtil::GetTestDataPath("net/proto2/internal/testdata/" + filename), - &expected, true)); - const std::string actual = DeterministicSerialization(t); - EXPECT_EQ(expected, actual); - protobuf_unittest::TestMaps u; - EXPECT_TRUE(u.ParseFromString(actual)); - EXPECT_TRUE(util::MessageDifferencer::Equals(u, t)); -} - // Helper for MapSerializationTest. Return a 7-bit ASCII string. static std::string ConstructKey(uint64 n) { std::string s(n % static_cast(9), '\0'); @@ -3214,7 +3464,17 @@ TEST(MapSerializationTest, Deterministic) { frog = frog * multiplier + i; frog ^= (frog >> 41); } - TestDeterministicSerialization(t, "golden_message_maps"); + + // Verifies if two consecutive calls to deterministic serialization produce + // the same bytes. Deterministic serialization means the same serialization + // bytes in the same binary. + const std::string s1 = DeterministicSerialization(t); + const std::string s2 = DeterministicSerialization(t); + EXPECT_EQ(s1, s2); + + protobuf_unittest::TestMaps u; + EXPECT_TRUE(u.ParseFromString(s1)); + EXPECT_TRUE(util::MessageDifferencer::Equals(u, t)); } TEST(MapSerializationTest, DeterministicSubmessage) { @@ -3505,6 +3765,10 @@ TEST(MoveTest, MoveAssignmentWorks) { EXPECT_EQ(nested_msg43_ptr, &moved_to_map[43].optional_nested_message()); } + +} // namespace } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/map_test_util.h b/src/google/protobuf/map_test_util.h index 9787d3d1e6d3..c3b84d1eddd8 100644 --- a/src/google/protobuf/map_test_util.h +++ b/src/google/protobuf/map_test_util.h @@ -238,6 +238,51 @@ inline MapReflectionTester::MapReflectionTester( EXPECT_FALSE(map_int32_enum_val_ == nullptr); EXPECT_FALSE(map_int32_foreign_message_key_ == nullptr); EXPECT_FALSE(map_int32_foreign_message_val_ == nullptr); + + std::vector all_map_descriptors = { + map_int32_int32_key_, + map_int32_int32_val_, + map_int64_int64_key_, + map_int64_int64_val_, + map_uint32_uint32_key_, + map_uint32_uint32_val_, + map_uint64_uint64_key_, + map_uint64_uint64_val_, + map_sint32_sint32_key_, + map_sint32_sint32_val_, + map_sint64_sint64_key_, + map_sint64_sint64_val_, + map_fixed32_fixed32_key_, + map_fixed32_fixed32_val_, + map_fixed64_fixed64_key_, + map_fixed64_fixed64_val_, + map_sfixed32_sfixed32_key_, + map_sfixed32_sfixed32_val_, + map_sfixed64_sfixed64_key_, + map_sfixed64_sfixed64_val_, + map_int32_float_key_, + map_int32_float_val_, + map_int32_double_key_, + map_int32_double_val_, + map_bool_bool_key_, + map_bool_bool_val_, + map_string_string_key_, + map_string_string_val_, + map_int32_bytes_key_, + map_int32_bytes_val_, + map_int32_enum_key_, + map_int32_enum_val_, + map_int32_foreign_message_key_, + map_int32_foreign_message_val_}; + for (const FieldDescriptor* fdesc : all_map_descriptors) { + GOOGLE_CHECK(fdesc->containing_type() != nullptr) << fdesc->name(); + if (fdesc->name() == "key") { + EXPECT_EQ(fdesc->containing_type()->map_key(), fdesc); + } else { + EXPECT_EQ(fdesc->name(), "value"); + EXPECT_EQ(fdesc->containing_type()->map_value(), fdesc); + } + } } // Shorthand to get a FieldDescriptor for a field of unittest::TestMap. @@ -450,20 +495,27 @@ inline void MapReflectionTester::SetMapFieldsViaMapReflection( Message* sub_foreign_message = nullptr; MapValueRef map_val; + MapValueConstRef map_val_const; // Add first element. MapKey map_key; map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_int32"), + map_key, &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_int32"), map_key, &map_val)); map_val.SetInt32Value(0); map_key.SetInt64Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int64_int64"), + map_key, &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int64_int64"), map_key, &map_val)); map_val.SetInt64Value(0); map_key.SetUInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_uint32_uint32"), + map_key, &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue( message, F("map_uint32_uint32"), map_key, &map_val)); map_val.SetUInt32Value(0); @@ -514,26 +566,36 @@ inline void MapReflectionTester::SetMapFieldsViaMapReflection( map_val.SetDoubleValue(0.0); map_key.SetBoolValue(false); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_bool_bool"), map_key, + &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_bool_bool"), map_key, &map_val)); map_val.SetBoolValue(false); map_key.SetStringValue("0"); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_string_string"), + map_key, &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue( message, F("map_string_string"), map_key, &map_val)); map_val.SetStringValue("0"); map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_bytes"), + map_key, &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_bytes"), map_key, &map_val)); map_val.SetStringValue("0"); map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue(*message, F("map_int32_enum"), + map_key, &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue(message, F("map_int32_enum"), map_key, &map_val)); map_val.SetEnumValue(map_enum_bar_->number()); map_key.SetInt32Value(0); + EXPECT_FALSE(reflection->LookupMapValue( + *message, F("map_int32_foreign_message"), map_key, &map_val_const)); EXPECT_TRUE(reflection->InsertOrLookupMapValue( message, F("map_int32_foreign_message"), map_key, &map_val)); sub_foreign_message = map_val.MutableMessageValue(); @@ -888,6 +950,7 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( const Reflection* reflection = message.GetReflection(); const Message* sub_message; MapKey map_key; + MapValueConstRef map_value_const_ref; // ----------------------------------------------------------------- @@ -926,6 +989,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_TRUE( reflection->ContainsMapKey(message, F("map_int32_int32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_int32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt32Value(), val); } } { @@ -945,6 +1011,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt64Value(key); EXPECT_TRUE( reflection->ContainsMapKey(message, F("map_int64_int64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int64_int64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt64Value(), val); } } { @@ -964,6 +1033,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetUInt32Value(key); EXPECT_TRUE( reflection->ContainsMapKey(message, F("map_uint32_uint32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint32_uint32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt32Value(), val); } } { @@ -982,6 +1054,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetUInt64Value(key); EXPECT_TRUE( reflection->ContainsMapKey(message, F("map_uint64_uint64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_uint64_uint64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt64Value(), val); } } { @@ -1000,6 +1075,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_sint32_sint32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint32_sint32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt32Value(), val); } } { @@ -1018,6 +1096,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt64Value(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_sint64_sint64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_sint64_sint64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt64Value(), val); } } { @@ -1036,6 +1117,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetUInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_fixed32_fixed32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_fixed32_fixed32"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt32Value(), val); } } { @@ -1054,6 +1138,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetUInt64Value(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_fixed64_fixed64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_fixed64_fixed64"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetUInt64Value(), val); } } { @@ -1072,6 +1159,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_sfixed32_sfixed32"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue( + message, F("map_sfixed32_sfixed32"), map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt32Value(), val); } } { @@ -1090,6 +1180,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt64Value(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_sfixed64_sfixed64"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue( + message, F("map_sfixed64_sfixed64"), map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetInt64Value(), val); } } { @@ -1108,6 +1201,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_float"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_float"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetFloatValue(), val); } } { @@ -1126,6 +1222,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_double"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_double"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetDoubleValue(), val); } } { @@ -1144,6 +1243,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetBoolValue(key); EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_bool_bool"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_bool_bool"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetBoolValue(), val); } } { @@ -1162,6 +1264,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetStringValue(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_string_string"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_string_string"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetStringValue(), val); } } { @@ -1180,6 +1285,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_bytes"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_bytes"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetStringValue(), val); } } { @@ -1198,6 +1306,9 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey(message, F("map_int32_enum"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, F("map_int32_enum"), + map_key, &map_value_const_ref)); + EXPECT_EQ(map_value_const_ref.GetEnumValue(), val->number()); } } { @@ -1218,6 +1329,12 @@ inline void MapReflectionTester::ExpectMapFieldsSetViaReflection( map_key.SetInt32Value(key); EXPECT_EQ(true, reflection->ContainsMapKey( message, F("map_int32_foreign_message"), map_key)); + EXPECT_TRUE(reflection->LookupMapValue(message, + F("map_int32_foreign_message"), + map_key, &map_value_const_ref)); + EXPECT_EQ(foreign_message.GetReflection()->GetInt32( + map_value_const_ref.GetMessageValue(), foreign_c_), + val); } } } diff --git a/src/google/protobuf/map_test_util.inc b/src/google/protobuf/map_test_util.inc old mode 100755 new mode 100644 diff --git a/src/google/protobuf/map_test_util_impl.h b/src/google/protobuf/map_test_util_impl.h index 70145b7e5151..655aec8384d4 100644 --- a/src/google/protobuf/map_test_util_impl.h +++ b/src/google/protobuf/map_test_util_impl.h @@ -167,7 +167,6 @@ void MapTestUtilImpl::SetArenaMapFields(MapMessage* message) { (*message->mutable_map_int32_bytes())[0] = "0"; (*message->mutable_map_int32_enum())[0] = enum_value0; (*message->mutable_map_int32_foreign_message())[0].set_c(0); - (*message->mutable_map_int32_foreign_message_no_arena())[0].set_c(0); // Add second element (*message->mutable_map_int32_int32())[1] = 1; @@ -187,7 +186,6 @@ void MapTestUtilImpl::SetArenaMapFields(MapMessage* message) { (*message->mutable_map_int32_bytes())[1] = "1"; (*message->mutable_map_int32_enum())[1] = enum_value1; (*message->mutable_map_int32_foreign_message())[1].set_c(1); - (*message->mutable_map_int32_foreign_message_no_arena())[1].set_c(1); } template @@ -333,7 +331,6 @@ void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) { EXPECT_EQ(2, message.map_int32_bytes().size()); EXPECT_EQ(2, message.map_int32_enum().size()); EXPECT_EQ(2, message.map_int32_foreign_message().size()); - EXPECT_EQ(2, message.map_int32_foreign_message_no_arena().size()); EXPECT_EQ(0, message.map_int32_int32().at(0)); EXPECT_EQ(0, message.map_int64_int64().at(0)); @@ -352,7 +349,6 @@ void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) { EXPECT_EQ("0", message.map_int32_bytes().at(0)); EXPECT_EQ(enum_value0, message.map_int32_enum().at(0)); EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c()); - EXPECT_EQ(0, message.map_int32_foreign_message_no_arena().at(0).c()); EXPECT_EQ(1, message.map_int32_int32().at(1)); EXPECT_EQ(1, message.map_int64_int64().at(1)); @@ -371,7 +367,6 @@ void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) { EXPECT_EQ("1", message.map_int32_bytes().at(1)); EXPECT_EQ(enum_value1, message.map_int32_enum().at(1)); EXPECT_EQ(1, message.map_int32_foreign_message().at(1).c()); - EXPECT_EQ(1, message.map_int32_foreign_message_no_arena().at(1).c()); } template @@ -410,7 +405,7 @@ void MapTestUtilImpl::ExpectMapFieldsSetInitialized(const MapMessage& message) { EXPECT_EQ("", message.map_string_string().at("0")); EXPECT_EQ("", message.map_int32_bytes().at(0)); EXPECT_EQ(enum_value, message.map_int32_enum().at(0)); - EXPECT_EQ(0, message.map_int32_foreign_message().at(0).ByteSize()); + EXPECT_EQ(0, message.map_int32_foreign_message().at(0).ByteSizeLong()); } template { typedef FalseType type; }; -// In proto2 Map, enum needs to be initialized to given default value, while -// other types' default value can be inferred from the type. -template -class MapValueInitializer { - public: - static inline void Initialize(Type& type, int default_enum_value); -}; - -template -class MapValueInitializer { - public: - static inline void Initialize(Type& value, int default_enum_value) { - value = static_cast(default_enum_value); - } -}; - -template -class MapValueInitializer { - public: - static inline void Initialize(Type& /* value */, - int /* default_enum_value */) {} -}; - template class MapArenaMessageCreator { public: @@ -155,13 +132,13 @@ class MapTypeHandler { typedef typename MapWireFieldTypeTraits::TypeOnMemory TypeOnMemory; // Corresponding wire type for field type. - static const WireFormatLite::WireType kWireType = + static constexpr WireFormatLite::WireType kWireType = MapWireFieldTypeTraits::kWireType; // Whether wire type is for message. - static const bool kIsMessage = + static constexpr bool kIsMessage = MapWireFieldTypeTraits::kIsMessage; // Whether wire type is for enum. - static const bool kIsEnum = + static constexpr bool kIsEnum = MapWireFieldTypeTraits::kIsEnum; // Functions used in parsing and serialization. =================== @@ -180,25 +157,15 @@ class MapTypeHandler { static inline void DeleteNoArena(const Type* x); static inline void Merge(const Type& from, Type** to, Arena* arena); static inline void Clear(Type** value, Arena* arena); - static inline void ClearMaybeByDefaultEnum(Type** value, Arena* arena, - int default_enum_value); - static inline void Initialize(Type** x, Arena* arena); + static constexpr TypeOnMemory Constinit(); - static inline void InitializeMaybeByDefaultEnum(Type** x, - int default_enum_value, - Arena* arena); static inline Type* EnsureMutable(Type** value, Arena* arena); // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding // those already calculate in sizeof(MapField). static inline size_t SpaceUsedInMapEntryLong(const Type* value); - // Return bytes used by value in Map. - static inline size_t SpaceUsedInMapLong(const Type& value); - // Assign default value to given instance. - static inline void AssignDefaultValue(Type** value); // Return default instance if value is not initialized when calling const // reference accessor. - static inline const Type& DefaultIfNotInitialized(const Type* value, - const Type* default_value); + static inline const Type& DefaultIfNotInitialized(const Type* value); // Check if all required fields have values set. static inline bool IsInitialized(Type* value); }; @@ -235,21 +202,12 @@ class MapTypeHandler { static inline void Merge(const MapEntryAccessorType& from, \ TypeOnMemory* to, Arena* arena); \ static inline void Clear(TypeOnMemory* value, Arena* arena); \ - static inline void ClearMaybeByDefaultEnum(TypeOnMemory* value, \ - Arena* arena, \ - int default_enum); \ static inline size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value); \ - static inline size_t SpaceUsedInMapLong(const TypeOnMemory& value); \ - static inline size_t SpaceUsedInMapLong(const std::string& value); \ - static inline void AssignDefaultValue(TypeOnMemory* value); \ static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ - const TypeOnMemory& value, const TypeOnMemory& default_value); \ + const TypeOnMemory& value); \ static inline bool IsInitialized(const TypeOnMemory& value); \ static void DeleteNoArena(TypeOnMemory& value); \ - static inline void Initialize(TypeOnMemory* value, Arena* arena); \ - static inline void InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ - int default_enum_value, \ - Arena* arena); \ + static constexpr TypeOnMemory Constinit(); \ static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ Arena* arena); \ }; @@ -546,24 +504,12 @@ inline size_t MapTypeHandlerSpaceUsedLong(); } -template -size_t MapTypeHandler::SpaceUsedInMapLong( - const Type& value) { - return value.SpaceUsedLong(); -} - template inline void MapTypeHandler::Clear( Type** value, Arena* /* arena */) { if (*value != NULL) (*value)->Clear(); } template -inline void -MapTypeHandler::ClearMaybeByDefaultEnum( - Type** value, Arena* /* arena */, int /* default_enum_value */) { - if (*value != NULL) (*value)->Clear(); -} -template inline void MapTypeHandler::Merge( const Type& from, Type** to, Arena* /* arena */) { (*to)->MergeFrom(from); @@ -576,22 +522,9 @@ void MapTypeHandler::DeleteNoArena( } template -inline void MapTypeHandler::AssignDefaultValue(Type** value) { - *value = const_cast(Type::internal_default_instance()); -} - -template -inline void MapTypeHandler::Initialize( - Type** x, Arena* /* arena */) { - *x = NULL; -} - -template -inline void MapTypeHandler:: - InitializeMaybeByDefaultEnum(Type** x, int /* default_enum_value */, - Arena* /* arena */) { - *x = NULL; +constexpr auto MapTypeHandler::Constinit() + -> TypeOnMemory { + return nullptr; } template @@ -608,8 +541,8 @@ inline Type* MapTypeHandler::EnsureMutable( template inline const Type& MapTypeHandler::DefaultIfNotInitialized( - const Type* value, const Type* default_value) { - return value != NULL ? *value : *default_value; + const Type* value) { + return value != NULL ? *value : *Type::internal_default_instance(); } template @@ -635,27 +568,9 @@ inline bool MapTypeHandler::IsInitialized( return sizeof(value); \ } \ template \ - inline size_t \ - MapTypeHandler::SpaceUsedInMapLong( \ - const TypeOnMemory& value) { \ - return sizeof(value); \ - } \ - template \ - inline size_t \ - MapTypeHandler::SpaceUsedInMapLong( \ - const std::string& value) { \ - return sizeof(value); \ - } \ - template \ inline void MapTypeHandler::Clear( \ - TypeOnMemory* value, Arena* arena) { \ - value->ClearToEmpty(&internal::GetEmptyStringAlreadyInited(), arena); \ - } \ - template \ - inline void MapTypeHandler:: \ - ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* arena, \ - int /* default_enum */) { \ - Clear(value, arena); \ + TypeOnMemory* value, Arena* /* arena */) { \ + value->ClearToEmpty(); \ } \ template \ inline void MapTypeHandler::Merge( \ @@ -668,34 +583,23 @@ inline bool MapTypeHandler::IsInitialized( value.DestroyNoArena(&internal::GetEmptyStringAlreadyInited()); \ } \ template \ - inline void \ - MapTypeHandler::AssignDefaultValue( \ - TypeOnMemory* /* value */) {} \ - template \ - inline void \ - MapTypeHandler::Initialize( \ - TypeOnMemory* value, Arena* /* arena */) { \ - value->UnsafeSetDefault(&internal::GetEmptyStringAlreadyInited()); \ - } \ - template \ - inline void MapTypeHandler:: \ - InitializeMaybeByDefaultEnum( \ - TypeOnMemory* value, int /* default_enum_value */, Arena* arena) { \ - Initialize(value, arena); \ + constexpr auto \ + MapTypeHandler::Constinit() \ + ->TypeOnMemory { \ + return TypeOnMemory(&internal::GetEmptyStringAlreadyInited()); \ } \ template \ inline typename MapTypeHandler::MapEntryAccessorType* \ MapTypeHandler::EnsureMutable( \ TypeOnMemory* value, Arena* arena) { \ - return value->Mutable(&internal::GetEmptyStringAlreadyInited(), arena); \ + return value->Mutable(ArenaStringPtr::EmptyDefault{}, arena); \ } \ template \ inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler:: \ - DefaultIfNotInitialized(const TypeOnMemory& value, \ - const TypeOnMemory& /* default_value */) { \ + MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value) { \ return value.Get(); \ } \ template \ @@ -708,81 +612,58 @@ STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING) STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) #undef STRING_OR_BYTES_HANDLER_FUNCTIONS -#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ - return value; \ - } \ - template \ - inline size_t MapTypeHandler:: \ - SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) { \ - return 0; \ - } \ - template \ - inline size_t \ - MapTypeHandler::SpaceUsedInMapLong( \ - const TypeOnMemory& /* value */) { \ - return sizeof(Type); \ - } \ - template \ - inline void MapTypeHandler::Clear( \ - TypeOnMemory* value, Arena* /* arena */) { \ - *value = 0; \ - } \ - template \ - inline void MapTypeHandler:: \ - ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* /* arena */, \ - int default_enum_value) { \ - *value = static_cast(default_enum_value); \ - } \ - template \ - inline void MapTypeHandler::Merge( \ - const MapEntryAccessorType& from, TypeOnMemory* to, \ - Arena* /* arena */) { \ - *to = from; \ - } \ - template \ - inline void MapTypeHandler::DeleteNoArena(TypeOnMemory& /* x */) {} \ - template \ - inline void \ - MapTypeHandler::AssignDefaultValue( \ - TypeOnMemory* /* value */) {} \ - template \ - inline void \ - MapTypeHandler::Initialize( \ - TypeOnMemory* value, Arena* /* arena */) { \ - *value = 0; \ - } \ - template \ - inline void MapTypeHandler:: \ - InitializeMaybeByDefaultEnum( \ - TypeOnMemory* value, int default_enum_value, Arena* /* arena */) { \ - *value = static_cast(default_enum_value); \ - } \ - template \ - inline typename MapTypeHandler::MapEntryAccessorType* \ - MapTypeHandler::EnsureMutable( \ - TypeOnMemory* value, Arena* /* arena */) { \ - return value; \ - } \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler:: \ - DefaultIfNotInitialized(const TypeOnMemory& value, \ - const TypeOnMemory& /* default_value */) { \ - return value; \ - } \ - template \ - inline bool \ - MapTypeHandler::IsInitialized( \ - const TypeOnMemory& /* value */) { \ - return true; \ +#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ + return value; \ + } \ + template \ + inline size_t MapTypeHandler:: \ + SpaceUsedInMapEntryLong(const TypeOnMemory& /* value */) { \ + return 0; \ + } \ + template \ + inline void MapTypeHandler::Clear( \ + TypeOnMemory* value, Arena* /* arena */) { \ + *value = 0; \ + } \ + template \ + inline void MapTypeHandler::Merge( \ + const MapEntryAccessorType& from, TypeOnMemory* to, \ + Arena* /* arena */) { \ + *to = from; \ + } \ + template \ + inline void MapTypeHandler::DeleteNoArena(TypeOnMemory& /* x */) {} \ + template \ + constexpr auto \ + MapTypeHandler::Constinit() \ + ->TypeOnMemory { \ + return 0; \ + } \ + template \ + inline typename MapTypeHandler::MapEntryAccessorType* \ + MapTypeHandler::EnsureMutable( \ + TypeOnMemory* value, Arena* /* arena */) { \ + return value; \ + } \ + template \ + inline const typename MapTypeHandler::MapEntryAccessorType& \ + MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value) { \ + return value; \ + } \ + template \ + inline bool \ + MapTypeHandler::IsInitialized( \ + const TypeOnMemory& /* value */) { \ + return true; \ } PRIMITIVE_HANDLER_FUNCTIONS(INT64) PRIMITIVE_HANDLER_FUNCTIONS(UINT64) diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto index 836dc10b374b..263ef61f806a 100644 --- a/src/google/protobuf/map_unittest.proto +++ b/src/google/protobuf/map_unittest.proto @@ -33,7 +33,6 @@ syntax = "proto3"; option cc_enable_arenas = true; import "google/protobuf/unittest.proto"; -import "google/protobuf/unittest_no_arena.proto"; // We don't put this in a package within proto2 because we need to make sure // that the generated code doesn't depend on being in the proto2 namespace. @@ -42,25 +41,25 @@ package protobuf_unittest; // Tests maps. message TestMap { - map map_int32_int32 = 1; - map map_int64_int64 = 2; - map map_uint32_uint32 = 3; - map map_uint64_uint64 = 4; - map map_sint32_sint32 = 5; - map map_sint64_sint64 = 6; - map map_fixed32_fixed32 = 7; - map map_fixed64_fixed64 = 8; + map map_int32_int32 = 1; + map map_int64_int64 = 2; + map map_uint32_uint32 = 3; + map map_uint64_uint64 = 4; + map map_sint32_sint32 = 5; + map map_sint64_sint64 = 6; + map map_fixed32_fixed32 = 7; + map map_fixed64_fixed64 = 8; map map_sfixed32_sfixed32 = 9; map map_sfixed64_sfixed64 = 10; - map map_int32_float = 11; - map map_int32_double = 12; - map map_bool_bool = 13; - map map_string_string = 14; - map map_int32_bytes = 15; - map map_int32_enum = 16; - map map_int32_foreign_message = 17; - map map_string_foreign_message = 18; - map map_int32_all_types = 19; + map map_int32_float = 11; + map map_int32_double = 12; + map map_bool_bool = 13; + map map_string_string = 14; + map map_int32_bytes = 15; + map map_int32_enum = 16; + map map_int32_foreign_message = 17; + map map_string_foreign_message = 18; + map map_int32_all_types = 19; } message TestMapSubmessage { @@ -90,33 +89,29 @@ message TestRequiredMessageMap { } message TestArenaMap { - map map_int32_int32 = 1; - map map_int64_int64 = 2; - map map_uint32_uint32 = 3; - map map_uint64_uint64 = 4; - map map_sint32_sint32 = 5; - map map_sint64_sint64 = 6; - map map_fixed32_fixed32 = 7; - map map_fixed64_fixed64 = 8; + map map_int32_int32 = 1; + map map_int64_int64 = 2; + map map_uint32_uint32 = 3; + map map_uint64_uint64 = 4; + map map_sint32_sint32 = 5; + map map_sint64_sint64 = 6; + map map_fixed32_fixed32 = 7; + map map_fixed64_fixed64 = 8; map map_sfixed32_sfixed32 = 9; map map_sfixed64_sfixed64 = 10; - map map_int32_float = 11; - map map_int32_double = 12; - map map_bool_bool = 13; - map map_string_string = 14; - map map_int32_bytes = 15; - map map_int32_enum = 16; - map map_int32_foreign_message = 17; - map - map_int32_foreign_message_no_arena = 18; + map map_int32_float = 11; + map map_int32_double = 12; + map map_bool_bool = 13; + map map_string_string = 14; + map map_int32_bytes = 15; + map map_int32_enum = 16; + map map_int32_foreign_message = 17; } // Previously, message containing enum called Type cannot be used as value of // map field. message MessageContainingEnumCalledType { - enum Type { - TYPE_FOO = 0; - } + enum Type { TYPE_FOO = 0; } map type = 1; } diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 650ca46c199b..259fde8010ab 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -32,13 +32,12 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include #include -#include -#include - #include #include #include @@ -48,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -136,388 +136,9 @@ void Message::DiscardUnknownFields() { return ReflectionOps::DiscardUnknownFields(this); } -namespace internal { - -class ReflectionAccessor { - public: - static void* GetOffset(void* msg, const google::protobuf::FieldDescriptor* f, - const google::protobuf::Reflection* r) { - return static_cast(msg) + r->schema_.GetFieldOffset(f); - } - - static void* GetRepeatedEnum(const Reflection* reflection, - const FieldDescriptor* field, Message* msg) { - return reflection->MutableRawRepeatedField( - msg, field, FieldDescriptor::CPPTYPE_ENUM, 0, nullptr); - } - - static InternalMetadataWithArena* MutableInternalMetadataWithArena( - const Reflection* reflection, Message* msg) { - return reflection->MutableInternalMetadataWithArena(msg); - } -}; - -} // namespace internal - -void SetField(uint64 val, const FieldDescriptor* field, Message* msg, - const Reflection* reflection) { -#define STORE_TYPE(CPPTYPE_METHOD) \ - do \ - if (field->is_repeated()) { \ - reflection->Add##CPPTYPE_METHOD(msg, field, value); \ - } else { \ - reflection->Set##CPPTYPE_METHOD(msg, field, value); \ - } \ - while (0) - - switch (field->type()) { -#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ - case FieldDescriptor::TYPE_##TYPE: { \ - CPPTYPE value = val; \ - STORE_TYPE(CPPTYPE_METHOD); \ - break; \ - } - - // Varints - HANDLE_TYPE(INT32, int32, Int32) - HANDLE_TYPE(INT64, int64, Int64) - HANDLE_TYPE(UINT32, uint32, UInt32) - HANDLE_TYPE(UINT64, uint64, UInt64) - case FieldDescriptor::TYPE_SINT32: { - int32 value = WireFormatLite::ZigZagDecode32(val); - STORE_TYPE(Int32); - break; - } - case FieldDescriptor::TYPE_SINT64: { - int64 value = WireFormatLite::ZigZagDecode64(val); - STORE_TYPE(Int64); - break; - } - HANDLE_TYPE(BOOL, bool, Bool) - - // Fixed - HANDLE_TYPE(FIXED32, uint32, UInt32) - HANDLE_TYPE(FIXED64, uint64, UInt64) - HANDLE_TYPE(SFIXED32, int32, Int32) - HANDLE_TYPE(SFIXED64, int64, Int64) - - case FieldDescriptor::TYPE_FLOAT: { - float value; - uint32 bit_rep = val; - std::memcpy(&value, &bit_rep, sizeof(value)); - STORE_TYPE(Float); - break; - } - case FieldDescriptor::TYPE_DOUBLE: { - double value; - uint64 bit_rep = val; - std::memcpy(&value, &bit_rep, sizeof(value)); - STORE_TYPE(Double); - break; - } - case FieldDescriptor::TYPE_ENUM: { - int value = val; - if (field->is_repeated()) { - reflection->AddEnumValue(msg, field, value); - } else { - reflection->SetEnumValue(msg, field, value); - } - break; - } - default: - GOOGLE_LOG(FATAL) << "Error in descriptors, primitive field with field type " - << field->type(); - } -#undef STORE_TYPE -#undef HANDLE_TYPE -} - -bool ReflectiveValidator(const void* arg, int val) { - auto d = static_cast(arg); - return d->FindValueByNumber(val) != nullptr; -} - -const char* ParsePackedField(const FieldDescriptor* field, Message* msg, - const Reflection* reflection, const char* ptr, - internal::ParseContext* ctx) { - switch (field->type()) { -#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, METHOD_NAME) \ - case FieldDescriptor::TYPE_##TYPE: \ - return internal::Packed##METHOD_NAME##Parser( \ - reflection->MutableRepeatedFieldInternal(msg, field), ptr, \ - ctx) - HANDLE_PACKED_TYPE(INT32, int32, Int32); - HANDLE_PACKED_TYPE(INT64, int64, Int64); - HANDLE_PACKED_TYPE(SINT32, int32, SInt32); - HANDLE_PACKED_TYPE(SINT64, int64, SInt64); - HANDLE_PACKED_TYPE(UINT32, uint32, UInt32); - HANDLE_PACKED_TYPE(UINT64, uint64, UInt64); - HANDLE_PACKED_TYPE(BOOL, bool, Bool); - case FieldDescriptor::TYPE_ENUM: { - auto object = - internal::ReflectionAccessor::GetRepeatedEnum(reflection, field, msg); - if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { - return internal::PackedEnumParser(object, ptr, ctx); - } else { - return internal::PackedEnumParserArg( - object, ptr, ctx, ReflectiveValidator, field->enum_type(), - internal::ReflectionAccessor::MutableInternalMetadataWithArena( - reflection, msg), - field->number()); - } - } - HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32); - HANDLE_PACKED_TYPE(FIXED64, uint64, Fixed64); - HANDLE_PACKED_TYPE(SFIXED32, int32, SFixed32); - HANDLE_PACKED_TYPE(SFIXED64, int64, SFixed64); - HANDLE_PACKED_TYPE(FLOAT, float, Float); - HANDLE_PACKED_TYPE(DOUBLE, double, Double); -#undef HANDLE_PACKED_TYPE - - default: - GOOGLE_LOG(FATAL) << "Type is not packable " << field->type(); - return nullptr; // Make compiler happy - } -} - -const char* ParseLenDelim(int field_number, const FieldDescriptor* field, - Message* msg, const Reflection* reflection, - const char* ptr, internal::ParseContext* ctx) { - if (WireFormat::WireTypeForFieldType(field->type()) != - WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - GOOGLE_DCHECK(field->is_packable()); - return ParsePackedField(field, msg, reflection, ptr, ctx); - } - enum { kNone = 0, kVerify, kStrict } utf8_level = kNone; - const char* field_name = nullptr; - auto parse_string = [ptr, ctx, &utf8_level, - &field_name](std::string* s) -> const char* { - auto res = internal::InlineGreedyStringParser(s, ptr, ctx); - if (utf8_level != kNone) { - if (!internal::VerifyUTF8(s, field_name) && utf8_level == kStrict) { - return nullptr; - } - } - return res; - }; - switch (field->type()) { - case FieldDescriptor::TYPE_STRING: { - bool enforce_utf8 = true; - bool utf8_verification = true; - if (enforce_utf8 && - field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) { - utf8_level = kStrict; - } else if (utf8_verification) { - utf8_level = kVerify; - } - field_name = field->full_name().c_str(); - PROTOBUF_FALLTHROUGH_INTENDED; - } - case FieldDescriptor::TYPE_BYTES: { - if (field->is_repeated()) { - int index = reflection->FieldSize(*msg, field); - // Add new empty value. - reflection->AddString(msg, field, ""); - if (field->options().ctype() == FieldOptions::STRING || - field->is_extension()) { - auto object = - reflection - ->MutableRepeatedPtrFieldInternal(msg, field) - ->Mutable(index); - return parse_string(object); - } else { - auto object = - reflection - ->MutableRepeatedPtrFieldInternal(msg, field) - ->Mutable(index); - return parse_string(object); - } - } else { - // Clear value and make sure it's set. - reflection->SetString(msg, field, ""); - if (field->options().ctype() == FieldOptions::STRING || - field->is_extension()) { - // HACK around inability to get mutable_string in reflection - std::string* object = &const_cast( - reflection->GetStringReference(*msg, field, nullptr)); - return parse_string(object); - } else { - // HACK around inability to get mutable_string in reflection - std::string* object = &const_cast( - reflection->GetStringReference(*msg, field, nullptr)); - return parse_string(object); - } - } - GOOGLE_LOG(FATAL) << "No other type than string supported"; - } - case FieldDescriptor::TYPE_MESSAGE: { - Message* object; - if (field->is_repeated()) { - object = reflection->AddMessage(msg, field, ctx->data().factory); - } else { - object = reflection->MutableMessage(msg, field, ctx->data().factory); - } - return ctx->ParseMessage(object, ptr); - } - default: - GOOGLE_LOG(FATAL) << "Wrong type for length delim " << field->type(); - } - return nullptr; // Make compiler happy. -} - -Message* GetGroup(int field_number, const FieldDescriptor* field, Message* msg, - const Reflection* reflection) { - if (field->is_repeated()) { - return reflection->AddMessage(msg, field, nullptr); - } else { - return reflection->MutableMessage(msg, field, nullptr); - } -} - const char* Message::_InternalParse(const char* ptr, internal::ParseContext* ctx) { - class ReflectiveFieldParser { - public: - ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx) - : ReflectiveFieldParser(msg, ctx, false) {} - - void AddVarint(uint32 num, uint64 value) { - if (is_item_ && num == 2) { - if (!payload_.empty()) { - auto field = Field(value, 2); - if (field && field->message_type()) { - auto child = reflection_->MutableMessage(msg_, field); - // TODO(gerbens) signal error - child->ParsePartialFromString(payload_); - } else { - MutableUnknown()->AddLengthDelimited(value)->swap(payload_); - } - return; - } - type_id_ = value; - return; - } - auto field = Field(num, 0); - if (field) { - SetField(value, field, msg_, reflection_); - } else { - MutableUnknown()->AddVarint(num, value); - } - } - void AddFixed64(uint32 num, uint64 value) { - auto field = Field(num, 1); - if (field) { - SetField(value, field, msg_, reflection_); - } else { - MutableUnknown()->AddFixed64(num, value); - } - } - const char* ParseLengthDelimited(uint32 num, const char* ptr, - internal::ParseContext* ctx) { - if (is_item_ && num == 3) { - if (type_id_ == 0) { - return InlineGreedyStringParser(&payload_, ptr, ctx); - } - num = type_id_; - type_id_ = 0; - } - auto field = Field(num, 2); - if (field) { - return ParseLenDelim(num, field, msg_, reflection_, ptr, ctx); - } else { - return InlineGreedyStringParser( - MutableUnknown()->AddLengthDelimited(num), ptr, ctx); - } - } - const char* ParseGroup(uint32 num, const char* ptr, - internal::ParseContext* ctx) { - if (!is_item_ && descriptor_->options().message_set_wire_format() && - num == 1) { - is_item_ = true; - ptr = ctx->ParseGroup(this, ptr, num * 8 + 3); - is_item_ = false; - type_id_ = 0; - return ptr; - } - auto field = Field(num, 3); - if (field) { - auto msg = GetGroup(num, field, msg_, reflection_); - return ctx->ParseGroup(msg, ptr, num * 8 + 3); - } else { - return UnknownFieldParse(num * 8 + 3, MutableUnknown(), ptr, ctx); - } - } - void AddFixed32(uint32 num, uint32 value) { - auto field = Field(num, 5); - if (field) { - SetField(value, field, msg_, reflection_); - } else { - MutableUnknown()->AddFixed32(num, value); - } - } - - const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) { - // We're parsing the a MessageSetItem - GOOGLE_DCHECK(is_item_); - return internal::WireFormatParser(*this, ptr, ctx); - } - - private: - Message* msg_; - const Descriptor* descriptor_; - const Reflection* reflection_; - internal::ParseContext* ctx_; - UnknownFieldSet* unknown_ = nullptr; - bool is_item_ = false; - uint32 type_id_ = 0; - std::string payload_; - - ReflectiveFieldParser(Message* msg, internal::ParseContext* ctx, - bool is_item) - : msg_(msg), - descriptor_(msg->GetDescriptor()), - reflection_(msg->GetReflection()), - ctx_(ctx), - is_item_(is_item) { - GOOGLE_CHECK(descriptor_) << msg->GetTypeName(); - GOOGLE_CHECK(reflection_) << msg->GetTypeName(); - } - - const FieldDescriptor* Field(int num, int wire_type) { - auto field = descriptor_->FindFieldByNumber(num); - - // If that failed, check if the field is an extension. - if (field == nullptr && descriptor_->IsExtensionNumber(num)) { - const DescriptorPool* pool = ctx_->data().pool; - if (pool == nullptr) { - field = reflection_->FindKnownExtensionByNumber(num); - } else { - field = pool->FindExtensionByNumber(descriptor_, num); - } - } - if (field == nullptr) return nullptr; - - if (internal::WireFormat::WireTypeForFieldType(field->type()) != - wire_type) { - if (field->is_packable()) { - if (wire_type == - internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { - return field; - } - } - return nullptr; - } - return field; - } - - UnknownFieldSet* MutableUnknown() { - if (unknown_) return unknown_; - return unknown_ = reflection_->MutableUnknownFields(msg_); - } - }; - - ReflectiveFieldParser field_parser(this, ctx); - return internal::WireFormatParser(field_parser, ptr, ctx); + return WireFormat::_InternalParse(this, ptr, ctx); } uint8* Message::_InternalSerialize(uint8* target, @@ -541,6 +162,10 @@ size_t Message::SpaceUsedLong() const { return GetReflection()->SpaceUsedLong(*this); } +uint64 Message::GetInvariantPerBuild(uint64 salt) { + return salt; +} + // ============================================================================= // MessageFactory @@ -548,6 +173,11 @@ MessageFactory::~MessageFactory() {} namespace { + +#define HASH_MAP std::unordered_map +#define STR_HASH_FXN hash<::google::protobuf::StringPiece> + + class GeneratedMessageFactory : public MessageFactory { public: static GeneratedMessageFactory* singleton(); @@ -560,8 +190,8 @@ class GeneratedMessageFactory : public MessageFactory { private: // Only written at static init time, so does not require locking. - std::unordered_map, streq> + HASH_MAP file_map_; internal::WrappedMutex mutex_; @@ -733,3 +363,5 @@ PROTOBUF_NOINLINE } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 3bd62633c79b..e20b16239304 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -145,6 +145,7 @@ class MessageFactory; class AssignDescriptorsHelper; class DynamicMessageFactory; class MapKey; +class MapValueConstRef; class MapValueRef; class MapIterator; class MapReflectionTester; @@ -170,6 +171,9 @@ class CelMapReflectionFriend; // field_backed_map_impl.cc namespace internal { class MapFieldPrinterHelper; // text_format.cc } +namespace util { +class MessageDifferencer; +} namespace internal { @@ -192,6 +196,26 @@ struct Metadata { const Reflection* reflection; }; +namespace internal { +template +inline To* GetPointerAtOffset(Message* message, uint32 offset) { + return reinterpret_cast(reinterpret_cast(message) + offset); +} + +template +const To* GetConstPointerAtOffset(const Message* message, uint32 offset) { + return reinterpret_cast(reinterpret_cast(message) + + offset); +} + +template +const To& GetConstRefAtOffset(const Message& message, uint32 offset) { + return *GetConstPointerAtOffset(&message, offset); +} + +bool CreateUnknownEnumValues(const FieldDescriptor* field); +} // namespace internal + // Abstract interface for protocol messages. // // See also MessageLite, which contains most every-day operations. Message @@ -202,10 +226,12 @@ struct Metadata { // optimized for speed will want to override these with faster implementations, // but classes optimized for code size may be happy with keeping them. See // the optimize_for option in descriptor.proto. +// +// Users must not derive from this class. Only the protocol compiler and +// the internal library are allowed to create subclasses. class PROTOBUF_EXPORT Message : public MessageLite { public: - inline Message() {} - ~Message() override {} + constexpr Message() = default; // Basic Operations ------------------------------------------------ @@ -337,6 +363,11 @@ class PROTOBUF_EXPORT Message : public MessageLite { // to implement GetDescriptor() and GetReflection() above. virtual Metadata GetMetadata() const = 0; + inline explicit Message(Arena* arena) : MessageLite(arena) {} + + + protected: + static uint64 GetInvariantPerBuild(uint64 salt); private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Message); @@ -716,8 +747,7 @@ class PROTOBUF_EXPORT Reflection final { // long as the message is not destroyed. // // Note that to use this method users need to include the header file - // "net/proto2/public/reflection.h" (which defines the RepeatedFieldRef - // class templates). + // "reflection.h" (which defines the RepeatedFieldRef class templates). template RepeatedFieldRef GetRepeatedFieldRef(const Message& message, const FieldDescriptor* field) const; @@ -729,7 +759,7 @@ class PROTOBUF_EXPORT Reflection final { Message* message, const FieldDescriptor* field) const; // DEPRECATED. Please use Get(Mutable)RepeatedFieldRef() for repeated field - // access. The following repeated field accesors will be removed in the + // access. The following repeated field accessors will be removed in the // future. // // Repeated field accessors ------------------------------------------------- @@ -888,6 +918,22 @@ class PROTOBUF_EXPORT Reflection final { const internal::RepeatedFieldAccessor* RepeatedFieldAccessor( const FieldDescriptor* field) const; + // Lists all fields of the message which are currently set, except for unknown + // fields and stripped fields. See ListFields for details. + void ListFieldsOmitStripped( + const Message& message, + std::vector* output) const; + + bool IsMessageStripped(const Descriptor* descriptor) const { + return schema_.IsMessageStripped(descriptor); + } + + friend class TextFormat; + + void ListFieldsMayFailOnStripped( + const Message& message, bool should_fail, + std::vector* output) const; + const Descriptor* const descriptor_; const internal::ReflectionSchema schema_; const DescriptorPool* const descriptor_pool_; @@ -906,6 +952,7 @@ class PROTOBUF_EXPORT Reflection final { friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper; friend class DynamicMessageFactory; friend class python::MapReflectionFriend; + friend class util::MessageDifferencer; #define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND friend class expr::CelMapReflectionFriend; friend class internal::MapFieldReflectionTest; @@ -914,7 +961,6 @@ class PROTOBUF_EXPORT Reflection final { friend class internal::ReflectionOps; // Needed for implementing text format for map. friend class internal::MapFieldPrinterHelper; - friend class internal::ReflectionAccessor; Reflection(const Descriptor* descriptor, const internal::ReflectionSchema& schema, @@ -936,10 +982,19 @@ class PROTOBUF_EXPORT Reflection final { // If key is in map field: Saves the value pointer to val and returns // false. If key in not in map field: Insert the key into map, saves - // value pointer to val and returns true. + // value pointer to val and returns true. Users are able to modify the + // map value by MapValueRef. bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field, const MapKey& key, MapValueRef* val) const; + // If key is in map field: Saves the value pointer to val and returns true. + // Returns false if key is not in map field. Users are NOT able to modify + // the value by MapValueConstRef. + bool LookupMapValue(const Message& message, const FieldDescriptor* field, + const MapKey& key, MapValueConstRef* val) const; + bool LookupMapValue(const Message&, const FieldDescriptor*, const MapKey&, + MapValueRef*) const = delete; + // Delete and returns true if key is in the map field. Returns false // otherwise. bool DeleteMapValue(Message* message, const FieldDescriptor* field, @@ -980,7 +1035,9 @@ class PROTOBUF_EXPORT Reflection final { template inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const; template - inline const Type& DefaultRaw(const FieldDescriptor* field) const; + const Type& DefaultRaw(const FieldDescriptor* field) const; + + const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const; inline const uint32* GetHasBits(const Message& message) const; inline uint32* MutableHasBits(Message* message) const; @@ -988,18 +1045,17 @@ class PROTOBUF_EXPORT Reflection final { const OneofDescriptor* oneof_descriptor) const; inline uint32* MutableOneofCase( Message* message, const OneofDescriptor* oneof_descriptor) const; - inline const internal::ExtensionSet& GetExtensionSet( - const Message& message) const; - inline internal::ExtensionSet* MutableExtensionSet(Message* message) const; + inline bool HasExtensionSet(const Message& /* message */) const { + return schema_.HasExtensionSet(); + } + const internal::ExtensionSet& GetExtensionSet(const Message& message) const; + internal::ExtensionSet* MutableExtensionSet(Message* message) const; inline Arena* GetArena(Message* message) const; - inline const internal::InternalMetadataWithArena& - GetInternalMetadataWithArena(const Message& message) const; - - internal::InternalMetadataWithArena* MutableInternalMetadataWithArena( - Message* message) const; + inline const internal::InternalMetadata& GetInternalMetadata( + const Message& message) const; - inline bool IsInlined(const FieldDescriptor* field) const; + internal::InternalMetadata* MutableInternalMetadata(Message* message) const; inline bool HasBit(const Message& message, const FieldDescriptor* field) const; @@ -1193,11 +1249,12 @@ const T* DynamicCastToGenerated(const Message* from) { const Message* unused = static_cast(nullptr); (void)unused; -#ifdef GOOGLE_PROTOBUF_NO_RTTI - bool ok = T::default_instance().GetReflection() == from->GetReflection(); - return ok ? down_cast(from) : nullptr; -#else +#if PROTOBUF_RTTI return dynamic_cast(from); +#else + bool ok = from != nullptr && + T::default_instance().GetReflection() == from->GetReflection(); + return ok ? down_cast(from) : nullptr; #endif } @@ -1287,6 +1344,11 @@ inline RepeatedPtrField* Reflection::MutableRepeatedPtrFieldInternal( MutableRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, PB::default_instance().GetDescriptor())); } + +template +const Type& Reflection::DefaultRaw(const FieldDescriptor* field) const { + return *reinterpret_cast(schema_.GetFieldDefault(field)); +} } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 4f5cc5fe917b..0cae40fbaeb8 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -117,6 +117,16 @@ inline StringPiece as_string_view(const void* data, int size) { return StringPiece(static_cast(data), size); } +// Returns true of all required fields are present / have values. +inline bool CheckFieldPresence(const internal::ParseContext& ctx, + const MessageLite& msg, + MessageLite::ParseFlags parse_flags) { + if (PROTOBUF_PREDICT_FALSE((parse_flags & MessageLite::kMergePartial) != 0)) { + return true; + } + return msg.IsInitializedWithErrors(); +} + } // namespace void MessageLite::LogInitializationErrorMessage() const { @@ -126,46 +136,62 @@ void MessageLite::LogInitializationErrorMessage() const { namespace internal { template -bool MergePartialFromImpl(StringPiece input, MessageLite* msg) { +bool MergeFromImpl(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { const char* ptr; internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(), aliasing, &ptr, input); ptr = msg->_InternalParse(ptr, &ctx); // ctx has an explicit limit set (length of string_view). - return ptr && ctx.EndedAtLimit(); + if (PROTOBUF_PREDICT_TRUE(ptr && ctx.EndedAtLimit())) { + return CheckFieldPresence(ctx, *msg, parse_flags); + } + return false; } template -bool MergePartialFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg) { +bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { const char* ptr; internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(), aliasing, &ptr, input); ptr = msg->_InternalParse(ptr, &ctx); // ctx has no explicit limit (hence we end on end of stream) - return ptr && ctx.EndedAtEndOfStream(); + if (PROTOBUF_PREDICT_TRUE(ptr && ctx.EndedAtEndOfStream())) { + return CheckFieldPresence(ctx, *msg, parse_flags); + } + return false; } template -bool MergePartialFromImpl(BoundedZCIS input, MessageLite* msg) { +bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { const char* ptr; internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(), aliasing, &ptr, input.zcis, input.limit); ptr = msg->_InternalParse(ptr, &ctx); if (PROTOBUF_PREDICT_FALSE(!ptr)) return false; ctx.BackUp(ptr); - return ctx.EndedAtLimit(); -} - -template bool MergePartialFromImpl(StringPiece input, - MessageLite* msg); -template bool MergePartialFromImpl(StringPiece input, - MessageLite* msg); -template bool MergePartialFromImpl(io::ZeroCopyInputStream* input, - MessageLite* msg); -template bool MergePartialFromImpl(io::ZeroCopyInputStream* input, - MessageLite* msg); -template bool MergePartialFromImpl(BoundedZCIS input, MessageLite* msg); -template bool MergePartialFromImpl(BoundedZCIS input, MessageLite* msg); + if (PROTOBUF_PREDICT_TRUE(ctx.EndedAtLimit())) { + return CheckFieldPresence(ctx, *msg, parse_flags); + } + return false; +} + +template bool MergeFromImpl(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +template bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); } // namespace internal @@ -195,7 +221,8 @@ class ZeroCopyCodedInputStream : public io::ZeroCopyInputStream { io::CodedInputStream* cis_; }; -bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) { +bool MessageLite::MergeFromImpl(io::CodedInputStream* input, + MessageLite::ParseFlags parse_flags) { ZeroCopyCodedInputStream zcis(input); const char* ptr; internal::ParseContext ctx(input->RecursionBudget(), zcis.aliasing_enabled(), @@ -213,24 +240,28 @@ bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) { GOOGLE_DCHECK(ctx.LastTag() != 1); // We can't end on a pushed limit. if (ctx.IsExceedingLimit(ptr)) return false; input->SetLastTag(ctx.LastTag()); - return true; + } else { + input->SetConsumed(); } - input->SetConsumed(); - return true; + return CheckFieldPresence(ctx, *this, parse_flags); +} + +bool MessageLite::MergePartialFromCodedStream(io::CodedInputStream* input) { + return MergeFromImpl(input, kMergePartial); } bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) { - return MergePartialFromCodedStream(input) && IsInitializedWithErrors(); + return MergeFromImpl(input, kMerge); } bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) { Clear(); - return MergeFromCodedStream(input); + return MergeFromImpl(input, kParse); } bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) { Clear(); - return MergePartialFromCodedStream(input); + return MergeFromImpl(input, kParsePartial); } bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) { @@ -282,11 +313,11 @@ bool MessageLite::ParsePartialFromBoundedZeroCopyStream( return ParseFrom(internal::BoundedZCIS{input, size}); } -bool MessageLite::ParseFromString(const std::string& data) { +bool MessageLite::ParseFromString(ConstStringParam data) { return ParseFrom(data); } -bool MessageLite::ParsePartialFromString(const std::string& data) { +bool MessageLite::ParsePartialFromString(ConstStringParam data) { return ParseFrom(data); } @@ -298,7 +329,7 @@ bool MessageLite::ParsePartialFromArray(const void* data, int size) { return ParseFrom(as_string_view(data, size)); } -bool MessageLite::MergeFromString(const std::string& data) { +bool MessageLite::MergeFromString(ConstStringParam data) { return ParseFrom(data); } @@ -358,7 +389,7 @@ bool MessageLite::SerializePartialToCodedStream( } int final_byte_count = output->ByteCount(); - if (final_byte_count - original_byte_count != size) { + if (final_byte_count - original_byte_count != static_cast(size)) { ByteSizeConsistencyError(size, ByteSizeLong(), final_byte_count - original_byte_count, *this); } @@ -457,7 +488,7 @@ bool MessageLite::SerializePartialToArray(void* data, int size) const { << " exceeded maximum protobuf size of 2GB: " << byte_size; return false; } - if (size < byte_size) return false; + if (size < static_cast(byte_size)) return false; uint8* start = reinterpret_cast(data); SerializeToArrayImpl(*this, start, byte_size); return true; @@ -550,3 +581,5 @@ void ShutdownProtobufLibrary() { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 31746f3e3862..87e9d2b4ccfa 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,12 @@ class ZeroCopyOutputStream; } // namespace io namespace internal { +// Tag type used to invoke the constinit constructor overload of some classes. +// Such constructors are internal implementation details of the library. +struct ConstantInitialized { + explicit ConstantInitialized() = default; +}; + // See parse_context.h for explanation class ParseContext; @@ -144,14 +151,25 @@ class ExplicitlyConstructed { } union_; }; +// We need a publicly accessible `value` object to allow constexpr +// support in C++11. +// A constexpr accessor does not work portably. +union EmptyString { + constexpr EmptyString() : dummy{} {} + ~EmptyString() {} + + // We need a dummy object for constant initialization. + std::false_type dummy; + std::string value; +}; + // Default empty string object. Don't use this directly. Instead, call // GetEmptyString() to get the reference. -PROTOBUF_EXPORT extern ExplicitlyConstructed - fixed_address_empty_string; +PROTOBUF_EXPORT extern EmptyString fixed_address_empty_string; -PROTOBUF_EXPORT inline const std::string& GetEmptyStringAlreadyInited() { - return fixed_address_empty_string.get(); +PROTOBUF_EXPORT constexpr const std::string& GetEmptyStringAlreadyInited() { + return fixed_address_empty_string.value; } PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str); @@ -181,10 +199,13 @@ PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str); // is best when you only have a small number of message types linked // into your binary, in which case the size of the protocol buffers // runtime itself is the biggest problem. +// +// Users must not derive from this class. Only the protocol compiler and +// the internal library are allowed to create subclasses. class PROTOBUF_EXPORT MessageLite { public: - inline MessageLite() {} - virtual ~MessageLite() {} + constexpr MessageLite() = default; + virtual ~MessageLite() = default; // Basic Operations ------------------------------------------------ @@ -201,10 +222,10 @@ class PROTOBUF_EXPORT MessageLite { // Get the arena, if any, associated with this message. Virtual method // required for generic operations but most arena-related operations should - // use the GetArenaNoVirtual() generated-code method. Default implementation + // use the GetArena() generated-code method. Default implementation // to reduce code size by avoiding the need for per-type implementations // when types do not implement arena support. - virtual Arena* GetArena() const { return NULL; } + Arena* GetArena() const { return _internal_metadata_.arena(); } // Get a pointer that may be equal to this message's arena, or may not be. // If the value returned by this method is equal to some arena pointer, then @@ -215,7 +236,9 @@ class PROTOBUF_EXPORT MessageLite { // store the arena pointer directly, and sometimes in a more indirect way, // and allow a fastpath comparison against the arena pointer when it's easy // to obtain. - virtual void* GetMaybeArenaPointer() const { return GetArena(); } + void* GetMaybeArenaPointer() const { + return _internal_metadata_.raw_arena_ptr(); + } // Clear all fields of the message and set them to their default values. // Clear() avoids freeing memory, assuming that any memory allocated @@ -261,28 +284,35 @@ class PROTOBUF_EXPORT MessageLite { // format. A successful return does not indicate the entire input is // consumed, ensure you call ConsumedEntireMessage() to check that if // applicable. - bool ParseFromCodedStream(io::CodedInputStream* input); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromCodedStream( + io::CodedInputStream* input); // Like ParseFromCodedStream(), but accepts messages that are missing // required fields. - bool ParsePartialFromCodedStream(io::CodedInputStream* input); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromCodedStream( + io::CodedInputStream* input); // Read a protocol buffer from the given zero-copy input stream. If // successful, the entire input will be consumed. - bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromZeroCopyStream( + io::ZeroCopyInputStream* input); // Like ParseFromZeroCopyStream(), but accepts messages that are missing // required fields. - bool ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromZeroCopyStream( + io::ZeroCopyInputStream* input); // Parse a protocol buffer from a file descriptor. If successful, the entire // input will be consumed. - bool ParseFromFileDescriptor(int file_descriptor); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromFileDescriptor( + int file_descriptor); // Like ParseFromFileDescriptor(), but accepts messages that are missing // required fields. - bool ParsePartialFromFileDescriptor(int file_descriptor); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromFileDescriptor( + int file_descriptor); // Parse a protocol buffer from a C++ istream. If successful, the entire // input will be consumed. - bool ParseFromIstream(std::istream* input); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromIstream(std::istream* input); // Like ParseFromIstream(), but accepts messages that are missing // required fields. - bool ParsePartialFromIstream(std::istream* input); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromIstream( + std::istream* input); // Read a protocol buffer from the given zero-copy input stream, expecting // the message to be exactly "size" bytes long. If successful, exactly // this many bytes will have been consumed from the input. @@ -291,25 +321,29 @@ class PROTOBUF_EXPORT MessageLite { // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are // missing required fields. bool MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); - bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size); // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are // missing required fields. - bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, - int size); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromBoundedZeroCopyStream( + io::ZeroCopyInputStream* input, int size); // Parses a protocol buffer contained in a string. Returns true on success. // This function takes a string in the (non-human-readable) binary wire // format, matching the encoding output by MessageLite::SerializeToString(). // If you'd like to convert a human-readable string into a protocol buffer // object, see google::protobuf::TextFormat::ParseFromString(). - bool ParseFromString(const std::string& data); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromString(ConstStringParam data); // Like ParseFromString(), but accepts messages that are missing // required fields. - bool ParsePartialFromString(const std::string& data); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromString( + ConstStringParam data); // Parse a protocol buffer contained in an array of bytes. - bool ParseFromArray(const void* data, int size); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromArray(const void* data, + int size); // Like ParseFromArray(), but accepts messages that are missing // required fields. - bool ParsePartialFromArray(const void* data, int size); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromArray(const void* data, + int size); // Reads a protocol buffer from the stream and merges it into this @@ -333,7 +367,7 @@ class PROTOBUF_EXPORT MessageLite { bool MergePartialFromCodedStream(io::CodedInputStream* input); // Merge a protocol buffer contained in a string. - bool MergeFromString(const std::string& data); + bool MergeFromString(ConstStringParam data); // Serialization --------------------------------------------------- @@ -444,6 +478,10 @@ class PROTOBUF_EXPORT MessageLite { return Arena::CreateMaybeMessage(arena); } + inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} + + internal::InternalMetadata _internal_metadata_; + public: enum ParseFlags { kMerge = 0, @@ -464,6 +502,13 @@ class PROTOBUF_EXPORT MessageLite { virtual uint8* _InternalSerialize(uint8* ptr, io::EpsCopyOutputStream* stream) const = 0; + // Identical to IsInitialized() except that it logs an error message. + bool IsInitializedWithErrors() const { + if (IsInitialized()) return true; + LogInitializationErrorMessage(); + return false; + } + private: // TODO(gerbens) make this a pure abstract function virtual const void* InternalGetTable() const { return NULL; } @@ -472,32 +517,34 @@ class PROTOBUF_EXPORT MessageLite { friend class Message; friend class internal::WeakFieldMap; - bool IsInitializedWithErrors() const { - if (IsInitialized()) return true; - LogInitializationErrorMessage(); - return false; - } - void LogInitializationErrorMessage() const; + bool MergeFromImpl(io::CodedInputStream* input, ParseFlags parse_flags); + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite); }; namespace internal { template -bool MergePartialFromImpl(StringPiece input, MessageLite* msg); -extern template bool MergePartialFromImpl(StringPiece input, - MessageLite* msg); -extern template bool MergePartialFromImpl(StringPiece input, - MessageLite* msg); +bool MergeFromImpl(StringPiece input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template bool MergeFromImpl(StringPiece input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template bool MergeFromImpl(StringPiece input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); template -bool MergePartialFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg); -extern template bool MergePartialFromImpl(io::ZeroCopyInputStream* input, - MessageLite* msg); -extern template bool MergePartialFromImpl(io::ZeroCopyInputStream* input, - MessageLite* msg); +bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template bool MergeFromImpl(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template bool MergeFromImpl(io::ZeroCopyInputStream* input, + MessageLite* msg, + MessageLite::ParseFlags parse_flags); struct BoundedZCIS { io::ZeroCopyInputStream* zcis; @@ -505,18 +552,20 @@ struct BoundedZCIS { }; template -bool MergePartialFromImpl(BoundedZCIS input, MessageLite* msg); -extern template bool MergePartialFromImpl(BoundedZCIS input, - MessageLite* msg); -extern template bool MergePartialFromImpl(BoundedZCIS input, - MessageLite* msg); +bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); template struct SourceWrapper; template -bool MergePartialFromImpl(const SourceWrapper& input, MessageLite* msg) { - return input.template MergePartialInto(msg); +bool MergeFromImpl(const SourceWrapper& input, MessageLite* msg, + MessageLite::ParseFlags parse_flags) { + return input.template MergeInto(msg, parse_flags); } } // namespace internal @@ -524,9 +573,8 @@ bool MergePartialFromImpl(const SourceWrapper& input, MessageLite* msg) { template bool MessageLite::ParseFrom(const T& input) { if (flags & kParse) Clear(); - constexpr bool alias = flags & kMergeWithAliasing; - bool res = internal::MergePartialFromImpl(input, this); - return res && ((flags & kMergePartial) || IsInitializedWithErrors()); + constexpr bool alias = (flags & kMergeWithAliasing) != 0; + return internal::MergeFromImpl(input, this, flags); } // =================================================================== diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index 46ae35d2ec49..4608714d1ef0 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -35,11 +35,11 @@ // This file needs to be included as .inc as it depends on certain macros being // defined prior to its inclusion. -#include - #include #include #include + +#include #ifndef _MSC_VER #include #endif @@ -48,7 +48,6 @@ #include #include -#include #include #include #include @@ -59,6 +58,7 @@ #include #include #include +#include #include @@ -235,6 +235,10 @@ TEST(MESSAGE_TEST_NAME, DynamicCastToGenerated) { test_all_types_pointer_const)); EXPECT_EQ(nullptr, DynamicCastToGenerated( test_all_types_pointer_const)); + + Message* test_all_types_pointer_nullptr = nullptr; + EXPECT_EQ(nullptr, DynamicCastToGenerated( + test_all_types_pointer_nullptr)); } #ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet. diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h index 009a7e93a6d7..4e89648ee672 100644 --- a/src/google/protobuf/metadata.h +++ b/src/google/protobuf/metadata.h @@ -28,51 +28,9 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// This header file defines an internal class that encapsulates internal message -// metadata (Unknown-field set, Arena pointer, ...) and allows its -// representation to be made more space-efficient via various optimizations. -// -// Note that this is distinct from google::protobuf::Metadata, which encapsulates -// Descriptor and Reflection pointers. - #ifndef GOOGLE_PROTOBUF_METADATA_H__ #define GOOGLE_PROTOBUF_METADATA_H__ -#include -#include - -#ifdef SWIG -#error "You cannot SWIG proto headers" -#endif - -namespace google { -namespace protobuf { -namespace internal { - -class InternalMetadataWithArena - : public InternalMetadataWithArenaBase { - public: - InternalMetadataWithArena() {} - explicit InternalMetadataWithArena(Arena* arena) - : InternalMetadataWithArenaBase(arena) {} - - void DoSwap(UnknownFieldSet* other) { mutable_unknown_fields()->Swap(other); } - - void DoMergeFrom(const UnknownFieldSet& other) { - mutable_unknown_fields()->MergeFrom(other); - } - - void DoClear() { mutable_unknown_fields()->Clear(); } - - static const UnknownFieldSet& default_instance() { - return *UnknownFieldSet::default_instance(); - } -}; - -} // namespace internal -} // namespace protobuf -} // namespace google +// TODO(b/151117630): Remove this file and all instances where it gets imported. #endif // GOOGLE_PROTOBUF_METADATA_H__ diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h index 2b762fa6b48d..ec5f92389074 100644 --- a/src/google/protobuf/metadata_lite.h +++ b/src/google/protobuf/metadata_lite.h @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include @@ -58,48 +56,54 @@ namespace internal { // The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to // indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container // pointer. -template -class InternalMetadataWithArenaBase { +class InternalMetadata { public: - InternalMetadataWithArenaBase() : ptr_(NULL) {} - explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {} + constexpr InternalMetadata() : ptr_(nullptr) {} + explicit InternalMetadata(Arena* arena) : ptr_(arena) {} - ~InternalMetadataWithArenaBase() { + template + void Delete() { + // Note that Delete<> should be called not more than once. if (have_unknown_fields() && arena() == NULL) { - delete PtrValue(); + delete PtrValue>(); } - ptr_ = NULL; } - PROTOBUF_ALWAYS_INLINE const T& unknown_fields() const { + PROTOBUF_ALWAYS_INLINE Arena* arena() const { if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) { - return PtrValue()->unknown_fields; + return PtrValue()->arena; } else { - return Derived::default_instance(); + return PtrValue(); } } - PROTOBUF_ALWAYS_INLINE T* mutable_unknown_fields() { - if (PROTOBUF_PREDICT_TRUE(have_unknown_fields())) { - return &PtrValue()->unknown_fields; - } else { - return mutable_unknown_fields_slow(); - } + PROTOBUF_ALWAYS_INLINE bool have_unknown_fields() const { + return PtrTag() == kTagContainer; } - PROTOBUF_ALWAYS_INLINE Arena* arena() const { + PROTOBUF_ALWAYS_INLINE void* raw_arena_ptr() const { return ptr_; } + + template + PROTOBUF_ALWAYS_INLINE const T& unknown_fields( + const T& (*default_instance)()) const { if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) { - return PtrValue()->arena; + return PtrValue>()->unknown_fields; } else { - return PtrValue(); + return default_instance(); } } - PROTOBUF_ALWAYS_INLINE bool have_unknown_fields() const { - return PtrTag() == kTagContainer; + template + PROTOBUF_ALWAYS_INLINE T* mutable_unknown_fields() { + if (PROTOBUF_PREDICT_TRUE(have_unknown_fields())) { + return &PtrValue>()->unknown_fields; + } else { + return mutable_unknown_fields_slow(); + } } - PROTOBUF_ALWAYS_INLINE void Swap(Derived* other) { + template + PROTOBUF_ALWAYS_INLINE void Swap(InternalMetadata* other) { // Semantics here are that we swap only the unknown fields, not the arena // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in @@ -107,24 +111,24 @@ class InternalMetadataWithArenaBase { // cannot simply swap ptr_ and then restore the arena pointers. We reuse // UFS's swap implementation instead. if (have_unknown_fields() || other->have_unknown_fields()) { - static_cast(this)->DoSwap(other->mutable_unknown_fields()); + DoSwap(other->mutable_unknown_fields()); } } - PROTOBUF_ALWAYS_INLINE void MergeFrom(const Derived& other) { + template + PROTOBUF_ALWAYS_INLINE void MergeFrom(const InternalMetadata& other) { if (other.have_unknown_fields()) { - static_cast(this)->DoMergeFrom(other.unknown_fields()); + DoMergeFrom(other.unknown_fields(nullptr)); } } + template PROTOBUF_ALWAYS_INLINE void Clear() { if (have_unknown_fields()) { - static_cast(this)->DoClear(); + DoClear(); } } - PROTOBUF_ALWAYS_INLINE void* raw_arena_ptr() const { return ptr_; } - private: void* ptr_; @@ -135,8 +139,8 @@ class InternalMetadataWithArenaBase { // ptr_ is a Container*. kTagContainer = 1, }; - static const intptr_t kPtrTagMask = 1; - static const intptr_t kPtrValueMask = ~kPtrTagMask; + static constexpr intptr_t kPtrTagMask = 1; + static constexpr intptr_t kPtrValueMask = ~kPtrTagMask; // Accessors for pointer tag and pointer value. PROTOBUF_ALWAYS_INLINE int PtrTag() const { @@ -150,14 +154,19 @@ class InternalMetadataWithArenaBase { } // If ptr_'s tag is kTagContainer, it points to an instance of this struct. - struct Container { - T unknown_fields; + struct ContainerBase { Arena* arena; }; + template + struct Container : public ContainerBase { + T unknown_fields; + }; + + template PROTOBUF_NOINLINE T* mutable_unknown_fields_slow() { Arena* my_arena = arena(); - Container* container = Arena::Create(my_arena); + Container* container = Arena::Create>(my_arena); // Two-step assignment works around a bug in clang's static analyzer: // https://bugs.llvm.org/show_bug.cgi?id=34198. ptr_ = container; @@ -166,40 +175,43 @@ class InternalMetadataWithArenaBase { container->arena = my_arena; return &(container->unknown_fields); } -}; -// We store unknown fields as a std::string right now, because there is -// currently no good interface for reading unknown fields into an ArenaString. -// We may want to revisit this to allow unknown fields to be parsed onto the -// Arena. -class InternalMetadataWithArenaLite - : public InternalMetadataWithArenaBase { - public: - InternalMetadataWithArenaLite() {} - - explicit InternalMetadataWithArenaLite(Arena* arena) - : InternalMetadataWithArenaBase(arena) {} + // Templated functions. - void DoSwap(std::string* other) { mutable_unknown_fields()->swap(*other); } - - void DoMergeFrom(const std::string& other) { - mutable_unknown_fields()->append(other); + template + void DoClear() { + mutable_unknown_fields()->Clear(); } - void DoClear() { mutable_unknown_fields()->clear(); } + template + void DoMergeFrom(const T& other) { + mutable_unknown_fields()->MergeFrom(other); + } - static const std::string& default_instance() { - // Can't use GetEmptyStringAlreadyInited() here because empty string - // may not have been initialized yet. This happens when protocol compiler - // statically determines the user can't access defaults and omits init code - // from proto constructors. However unknown fields are always part of a - // proto so it needs to be lazily initialized. See b/112613846. - return GetEmptyString(); + template + void DoSwap(T* other) { + mutable_unknown_fields()->Swap(other); } }; +// String Template specializations. + +template <> +inline void InternalMetadata::DoClear() { + mutable_unknown_fields()->clear(); +} + +template <> +inline void InternalMetadata::DoMergeFrom( + const std::string& other) { + mutable_unknown_fields()->append(other); +} + +template <> +inline void InternalMetadata::DoSwap(std::string* other) { + mutable_unknown_fields()->swap(*other); +} + // This helper RAII class is needed to efficiently parse unknown fields. We // should only call mutable_unknown_fields if there are actual unknown fields. // The obvious thing to just use a stack string and swap it at the end of @@ -210,19 +222,20 @@ class InternalMetadataWithArenaLite // guarantees that the string is only swapped after stream is destroyed. class PROTOBUF_EXPORT LiteUnknownFieldSetter { public: - explicit LiteUnknownFieldSetter(InternalMetadataWithArenaLite* metadata) + explicit LiteUnknownFieldSetter(InternalMetadata* metadata) : metadata_(metadata) { if (metadata->have_unknown_fields()) { - buffer_.swap(*metadata->mutable_unknown_fields()); + buffer_.swap(*metadata->mutable_unknown_fields()); } } ~LiteUnknownFieldSetter() { - if (!buffer_.empty()) metadata_->mutable_unknown_fields()->swap(buffer_); + if (!buffer_.empty()) + metadata_->mutable_unknown_fields()->swap(buffer_); } std::string* buffer() { return &buffer_; } private: - InternalMetadataWithArenaLite* metadata_; + InternalMetadata* metadata_; std::string buffer_; }; diff --git a/src/google/protobuf/no_field_presence_test.cc b/src/google/protobuf/no_field_presence_test.cc index ea23d28d4c67..2582cfea8e62 100644 --- a/src/google/protobuf/no_field_presence_test.cc +++ b/src/google/protobuf/no_field_presence_test.cc @@ -567,7 +567,7 @@ TEST(NoFieldPresenceTest, OneofPresence) { message.Clear(); message.set_oneof_string("test"); message.clear_oneof_string(); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); } } // namespace diff --git a/src/google/protobuf/parse_context.cc b/src/google/protobuf/parse_context.cc index 6cf63b78586a..8143af8d8bcf 100644 --- a/src/google/protobuf/parse_context.cc +++ b/src/google/protobuf/parse_context.cc @@ -48,7 +48,7 @@ namespace internal { namespace { // Only call if at start of tag. -bool ParseEndsInSlopRegion(const char* begin, int overrun, int d) { +bool ParseEndsInSlopRegion(const char* begin, int overrun, int depth) { constexpr int kSlopBytes = EpsCopyInputStream::kSlopBytes; GOOGLE_DCHECK(overrun >= 0); GOOGLE_DCHECK(overrun <= kSlopBytes); @@ -79,11 +79,11 @@ bool ParseEndsInSlopRegion(const char* begin, int overrun, int d) { break; } case 3: { // start group - d++; + depth++; break; } case 4: { // end group - if (--d < 0) return true; // We exit early + if (--depth < 0) return true; // We exit early break; } case 5: { // fixed32 @@ -99,7 +99,7 @@ bool ParseEndsInSlopRegion(const char* begin, int overrun, int d) { } // namespace -const char* EpsCopyInputStream::Next(int overrun, int d) { +const char* EpsCopyInputStream::NextBuffer(int overrun, int depth) { if (next_chunk_ == nullptr) return nullptr; // We've reached end of stream. if (next_chunk_ != buffer_) { GOOGLE_DCHECK(size_ > kSlopBytes); @@ -115,7 +115,7 @@ const char* EpsCopyInputStream::Next(int overrun, int d) { // buffer_. std::memmove(buffer_, buffer_end_, kSlopBytes); if (overall_limit_ > 0 && - (d < 0 || !ParseEndsInSlopRegion(buffer_, overrun, d))) { + (depth < 0 || !ParseEndsInSlopRegion(buffer_, overrun, depth))) { const void* data; // ZeroCopyInputStream indicates Next may return 0 size buffers. Hence // we loop. @@ -154,11 +154,22 @@ const char* EpsCopyInputStream::Next(int overrun, int d) { return buffer_; } -std::pair EpsCopyInputStream::DoneFallback(const char* ptr, - int d) { - GOOGLE_DCHECK(ptr >= limit_end_); - int overrun = ptr - buffer_end_; - GOOGLE_DCHECK(overrun <= kSlopBytes); // Guaranteed by parse loop. +const char* EpsCopyInputStream::Next() { + GOOGLE_DCHECK(limit_ > kSlopBytes); + auto p = NextBuffer(0 /* immaterial */, -1); + if (p == nullptr) { + limit_end_ = buffer_end_; + // Distinguish ending on a pushed limit or ending on end-of-stream. + SetEndOfStream(); + return nullptr; + } + limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor + limit_end_ = buffer_end_ + std::min(0, limit_); + return p; +} + +std::pair EpsCopyInputStream::DoneFallback(int overrun, + int depth) { // Did we exceeded the limit (parse error). if (PROTOBUF_PREDICT_FALSE(overrun > limit_)) return {nullptr, true}; GOOGLE_DCHECK(overrun != limit_); // Guaranteed by caller. @@ -171,25 +182,26 @@ std::pair EpsCopyInputStream::DoneFallback(const char* ptr, // At this point we know the following assertion holds. GOOGLE_DCHECK(limit_ > 0); GOOGLE_DCHECK(limit_end_ == buffer_end_); // because limit_ > 0 + const char* p; do { // We are past the end of buffer_end_, in the slop region. GOOGLE_DCHECK(overrun >= 0); - auto p = Next(overrun, d); + p = NextBuffer(overrun, depth); if (p == nullptr) { // We are at the end of the stream if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true}; GOOGLE_DCHECK(limit_ > 0); limit_end_ = buffer_end_; - // Distinquish ending on a pushed limit or ending on end-of-stream. + // Distinguish ending on a pushed limit or ending on end-of-stream. SetEndOfStream(); - return {ptr, true}; + return {buffer_end_, true}; } limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor - ptr = p + overrun; - overrun = ptr - buffer_end_; + p += overrun; + overrun = p - buffer_end_; } while (overrun >= 0); limit_end_ = buffer_end_ + std::min(0, limit_); - return {ptr, false}; + return {p, false}; } const char* EpsCopyInputStream::SkipFallback(const char* ptr, int size) { @@ -263,9 +275,11 @@ const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size, for (int i = 0; i < num; i++) dst[i] = UnalignedLoad(ptr + i * sizeof(T)); #endif - ptr += block_size; size -= block_size; - if (DoneWithCheck(&ptr, -1)) return nullptr; + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; + ptr += kSlopBytes - (nbytes - block_size); nbytes = buffer_end_ + kSlopBytes - ptr; } int num = size / sizeof(T); @@ -474,36 +488,6 @@ const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx) { return VarintParser(object, ptr, ctx); } -const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx, - bool (*is_valid)(int), - InternalMetadataWithArenaLite* metadata, - int field_num) { - return ctx->ReadPackedVarint( - ptr, [object, is_valid, metadata, field_num](uint64 val) { - if (is_valid(val)) { - static_cast*>(object)->Add(val); - } else { - WriteVarint(field_num, val, metadata->mutable_unknown_fields()); - } - }); -} - -const char* PackedEnumParserArg(void* object, const char* ptr, - ParseContext* ctx, - bool (*is_valid)(const void*, int), - const void* data, - InternalMetadataWithArenaLite* metadata, - int field_num) { - return ctx->ReadPackedVarint( - ptr, [object, is_valid, data, metadata, field_num](uint64 val) { - if (is_valid(data, val)) { - static_cast*>(object)->Add(val); - } else { - WriteVarint(field_num, val, metadata->mutable_unknown_fields()); - } - }); -} - const char* PackedBoolParser(void* object, const char* ptr, ParseContext* ctx) { return VarintParser(object, ptr, ctx); } @@ -604,12 +588,8 @@ const char* UnknownFieldParse(uint32 tag, std::string* unknown, const char* ptr, return FieldParser(tag, field_parser, ptr, ctx); } -const char* UnknownFieldParse(uint32 tag, - InternalMetadataWithArenaLite* metadata, - const char* ptr, ParseContext* ctx) { - return UnknownFieldParse(tag, metadata->mutable_unknown_fields(), ptr, ctx); -} - } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h index 9b2a473ddd84..661008589d11 100644 --- a/src/google/protobuf/parse_context.h +++ b/src/google/protobuf/parse_context.h @@ -208,9 +208,16 @@ class PROTOBUF_EXPORT EpsCopyInputStream { bool DoneWithCheck(const char** ptr, int d) { GOOGLE_DCHECK(*ptr); if (PROTOBUF_PREDICT_TRUE(*ptr < limit_end_)) return false; - // No need to fetch buffer if we ended on a limit in the slop region - if ((*ptr - buffer_end_) == limit_) return true; - auto res = DoneFallback(*ptr, d); + int overrun = *ptr - buffer_end_; + GOOGLE_DCHECK_LE(overrun, kSlopBytes); // Guaranteed by parse loop. + if (overrun == + limit_) { // No need to flip buffers if we ended on a limit. + // If we actually overrun the buffer and next_chunk_ is null. It means + // the stream ended and we passed the stream end. + if (overrun > 0 && next_chunk_ == nullptr) *ptr = nullptr; + return true; + } + auto res = DoneFallback(overrun, d); *ptr = res.first; return res.second; } @@ -239,6 +246,7 @@ class PROTOBUF_EXPORT EpsCopyInputStream { const char* InitFrom(io::ZeroCopyInputStream* zcis); const char* InitFrom(io::ZeroCopyInputStream* zcis, int limit) { + if (limit == -1) return InitFrom(zcis); overall_limit_ = limit; auto res = InitFrom(zcis); limit_ = limit - static_cast(buffer_end_ - res); @@ -275,8 +283,26 @@ class PROTOBUF_EXPORT EpsCopyInputStream { // systems. TODO(gerbens) do we need to set this as build flag? enum { kSafeStringSize = 50000000 }; - std::pair DoneFallback(const char* ptr, int d); - const char* Next(int overrun, int d); + // Advances to next buffer chunk returns a pointer to the same logical place + // in the stream as set by overrun. Overrun indicates the position in the slop + // region the parse was left (0 <= overrun <= kSlopBytes). Returns true if at + // limit, at which point the returned pointer maybe null if there was an + // error. The invariant of this function is that it's guaranteed that + // kSlopBytes bytes can be accessed from the returned ptr. This function might + // advance more buffers than one in the underlying ZeroCopyInputStream. + std::pair DoneFallback(int overrun, int depth); + // Advances to the next buffer, at most one call to Next() on the underlying + // ZeroCopyInputStream is made. This function DOES NOT match the returned + // pointer to where in the slop region the parse ends, hence no overrun + // parameter. This is useful for string operations where you always copy + // to the end of the buffer (including the slop region). + const char* Next(); + // overrun is the location in the slop region the stream currently is + // (0 <= overrun <= kSlopBytes). To prevent flipping to the next buffer of + // the ZeroCopyInputStream in the case the parse will end in the last + // kSlopBytes of the current buffer. depth is the current depth of nested + // groups (or negative if the use case does not need careful tracking). + inline const char* NextBuffer(int overrun, int depth); const char* SkipFallback(const char* ptr, int size); const char* AppendStringFallback(const char* ptr, int size, std::string* str); const char* ReadStringFallback(const char* ptr, int size, std::string* str); @@ -295,16 +321,17 @@ class PROTOBUF_EXPORT EpsCopyInputStream { int chunk_size = buffer_end_ + kSlopBytes - ptr; do { GOOGLE_DCHECK(size > chunk_size); + if (next_chunk_ == nullptr) return nullptr; append(ptr, chunk_size); ptr += chunk_size; size -= chunk_size; - // DoneFallBack asserts it isn't called when exactly on the limit. If this - // happens we fail the parse, as we are at the limit and still more bytes - // to read. - if (limit_ == kSlopBytes) return nullptr; - auto res = DoneFallback(ptr, -1); - if (res.second) return nullptr; // If done we passed the limit - ptr = res.first; + // TODO(gerbens) Next calls NextBuffer which generates buffers with + // overlap and thus incurs cost of copying the slop regions. This is not + // necessary for reading strings. We should just call Next buffers. + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; // passed the limit + ptr += kSlopBytes; chunk_size = buffer_end_ + kSlopBytes - ptr; } while (size > chunk_size); append(ptr, size); @@ -318,11 +345,19 @@ class PROTOBUF_EXPORT EpsCopyInputStream { // implicit weak messages. We keep these methods private and friend them. template const char* AppendUntilEnd(const char* ptr, const A& append) { - while (!DoneWithCheck(&ptr, -1)) { - append(ptr, limit_end_ - ptr); - ptr = limit_end_; + if (ptr - buffer_end_ > limit_) return nullptr; + while (limit_ > kSlopBytes) { + int chunk_size = buffer_end_ + kSlopBytes - ptr; + GOOGLE_DCHECK_GE(chunk_size, 0); + append(ptr, chunk_size); + ptr = Next(); + if (ptr == nullptr) return limit_end_; + ptr += kSlopBytes; } - return ptr; + auto end = buffer_end_ + limit_; + GOOGLE_DCHECK(end >= ptr); + append(ptr, end - ptr); + return end; } PROTOBUF_MUST_USE_RESULT const char* AppendString(const char* ptr, @@ -353,7 +388,6 @@ class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream { void TrackCorrectEnding() { group_depth_ = 0; } bool Done(const char** ptr) { return DoneWithCheck(ptr, group_depth_); } - bool DoneNoSlopCheck(const char** ptr) { return DoneWithCheck(ptr, -1); } int depth() const { return depth_; } @@ -618,21 +652,52 @@ PROTOBUF_MUST_USE_RESULT const char* ParseContext::ParseMessage( } template -const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add) { - int size = ReadSize(&ptr); - if (ptr == nullptr) return nullptr; - auto old = PushLimit(ptr, size); - if (old < 0) return nullptr; - while (!DoneWithCheck(&ptr, -1)) { +const char* ReadPackedVarintArray(const char* ptr, const char* end, Add add) { + while (ptr < end) { uint64 varint; ptr = VarintParse(ptr, &varint); - if (!ptr) return nullptr; + if (ptr == nullptr) return nullptr; add(varint); } - if (!PopLimit(old)) return nullptr; return ptr; } +template +const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add) { + int size = ReadSize(&ptr); + if (ptr == nullptr) return nullptr; + int chunk_size = buffer_end_ - ptr; + while (size > chunk_size) { + ptr = ReadPackedVarintArray(ptr, buffer_end_, add); + if (ptr == nullptr) return nullptr; + int overrun = ptr - buffer_end_; + GOOGLE_DCHECK(overrun >= 0 && overrun <= kSlopBytes); + if (size - chunk_size <= kSlopBytes) { + // The current buffer contains all the information needed, we don't need + // to flip buffers. However we must parse from a buffer with enough space + // so we are not prone to a buffer overflow. + char buf[kSlopBytes + 10] = {}; + std::memcpy(buf, buffer_end_, kSlopBytes); + GOOGLE_CHECK_LE(size - chunk_size, kSlopBytes); + auto end = buf + (size - chunk_size); + auto res = ReadPackedVarintArray(buf + overrun, end, add); + if (res == nullptr || res != end) return nullptr; + return buffer_end_ + (res - buf); + } + size -= overrun + chunk_size; + GOOGLE_DCHECK_GT(size, 0); + // We must flip buffers + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; + ptr += overrun; + chunk_size = buffer_end_ - ptr; + } + auto end = ptr + size; + ptr = ReadPackedVarintArray(ptr, end, add); + return end == ptr ? ptr : nullptr; +} + // Helper for verification of utf8 PROTOBUF_EXPORT bool VerifyUTF8(StringPiece s, const char* field_name); @@ -741,13 +806,35 @@ PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedSInt64Parser( void* object, const char* ptr, ParseContext* ctx); PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser( void* object, const char* ptr, ParseContext* ctx); -PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser( + +template +PROTOBUF_MUST_USE_RESULT const char* PackedEnumParser( void* object, const char* ptr, ParseContext* ctx, bool (*is_valid)(int), - InternalMetadataWithArenaLite* metadata, int field_num); -PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedEnumParserArg( + InternalMetadata* metadata, int field_num) { + return ctx->ReadPackedVarint( + ptr, [object, is_valid, metadata, field_num](uint64 val) { + if (is_valid(val)) { + static_cast*>(object)->Add(val); + } else { + WriteVarint(field_num, val, metadata->mutable_unknown_fields()); + } + }); +} + +template +PROTOBUF_MUST_USE_RESULT const char* PackedEnumParserArg( void* object, const char* ptr, ParseContext* ctx, bool (*is_valid)(const void*, int), const void* data, - InternalMetadataWithArenaLite* metadata, int field_num); + InternalMetadata* metadata, int field_num) { + return ctx->ReadPackedVarint( + ptr, [object, is_valid, data, metadata, field_num](uint64 val) { + if (is_valid(data, val)) { + static_cast*>(object)->Add(val); + } else { + WriteVarint(field_num, val, metadata->mutable_unknown_fields()); + } + }); +} PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* PackedBoolParser( void* object, const char* ptr, ParseContext* ctx); @@ -772,9 +859,6 @@ PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownGroupLiteParse( // UnknownFieldSet* to make the generated code isomorphic between full and lite. PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownFieldParse( uint32 tag, std::string* unknown, const char* ptr, ParseContext* ctx); -PROTOBUF_EXPORT PROTOBUF_MUST_USE_RESULT const char* UnknownFieldParse( - uint32 tag, InternalMetadataWithArenaLite* metadata, const char* ptr, - ParseContext* ctx); } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h index 555fd4ebc43b..aa2cfc1eb862 100644 --- a/src/google/protobuf/port.h +++ b/src/google/protobuf/port.h @@ -39,5 +39,9 @@ #include +// Protobuf intends to move into the pb:: namespace. +namespace protobuf_future_namespace_placeholder {} +namespace pb = ::protobuf_future_namespace_placeholder; + #endif // GOOGLE_PROTOBUF_PORT_H__ diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 3e39f915f64e..01d96070b08a 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -136,6 +136,24 @@ #ifdef PROTOBUF_UNUSED #error PROTOBUF_UNUSED was previously defined #endif +#ifdef PROTOBUF_FINAL +#error PROTOBUF_FINAL was previously defined +#endif +#ifdef PROTOBUF_ENABLE_MSVC_UNION_WARNING +#error PROTOBUF_ENABLE_MSVC_UNION_WARNING was previously defined +#endif +#ifdef PROTOBUF_CONSTINIT +#error PROTOBUF_CONSTINIT was previously defined +#endif +#ifdef PROTOBUF_ATTRIBUTE_NO_DESTROY +#error PROTOBUF_ATTRIBUTE_NO_DESTROY was previously defined +#endif +#ifdef PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#error PROTOBUF_ATTRIBUTE_INIT_PRIORITY was previously defined +#endif +#ifdef PROTOBUF_PRAGMA_INIT_SEG +#error PROTOBUF_PRAGMA_INIT_SEG was previously defined +#endif #define PROTOBUF_NAMESPACE "google::protobuf" @@ -235,12 +253,15 @@ #ifdef GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL #define PROTOBUF_RETURNS_NONNULL GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL #else -#ifdef __GNUC__ +#if defined(__has_attribute) +#if __has_attribute(returns_nonnull) #define PROTOBUF_RETURNS_NONNULL __attribute__((returns_nonnull)) -#else -#define PROTOBUF_RETURNS_NONNULL #endif #endif +#endif +#ifndef PROTOBUF_RETURNS_NONNULL +#define PROTOBUF_RETURNS_NONNULL +#endif #if defined(__has_cpp_attribute) #if __has_cpp_attribute(clang::reinitializes) @@ -297,17 +318,26 @@ // Shared google3/opensource definitions. ////////////////////////////////////// -#define PROTOBUF_VERSION 3011002 -#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3011000 -#define PROTOBUF_MIN_PROTOC_VERSION 3011000 +#define PROTOBUF_VERSION 3014000 +#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 3014000 +#define PROTOBUF_MIN_PROTOC_VERSION 3014000 #define PROTOBUF_VERSION_SUFFIX "" // The minimum library version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3011000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3014000 #if defined(GOOGLE_PROTOBUF_NO_RTTI) && GOOGLE_PROTOBUF_NO_RTTI #define PROTOBUF_RTTI 0 +#elif defined(__has_feature) +// https://clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension +#define PROTOBUF_RTTI __has_feature(cxx_rtti) +#elif !defined(__cxx_rtti) +// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros#C.2B.2B98 +#define PROTOBUF_RTTI 0 +#elif defined(__GNUC__) && !defined(__GXX_RTTI) +#https: // gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#define PROTOBUF_RTTI 0 #else #define PROTOBUF_RTTI 1 #endif @@ -329,7 +359,10 @@ _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ __builtin_offsetof(TYPE, FIELD) \ _Pragma("clang diagnostic pop") -#else +#elif defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +#define PROTOBUF_FIELD_OFFSET(TYPE, FIELD) __builtin_offsetof(TYPE, FIELD) +#else // defined(__clang__) // Note that we calculate relative to the pointer value 16 here since if we // just use zero, GCC complains about dereferencing a NULL pointer. We // choose 16 rather than some other number just in case the compiler would @@ -341,53 +374,67 @@ #endif #if defined(PROTOBUF_USE_DLLS) - #if defined(_MSC_VER) - #ifdef LIBPROTOBUF_EXPORTS - #define PROTOBUF_EXPORT __declspec(dllexport) - #define PROTOBUF_EXPORT_TEMPLATE_DECLARE - #define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllexport) - #else - #define PROTOBUF_EXPORT __declspec(dllimport) - #define PROTOBUF_EXPORT_TEMPLATE_DECLARE - #define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllimport) - #endif - #ifdef LIBPROTOC_EXPORTS - #define PROTOC_EXPORT __declspec(dllexport) - #else - #define PROTOC_EXPORT __declspec(dllimport) - #endif - #else // defined(_MSC_VER) - #ifdef LIBPROTOBUF_EXPORTS - #define PROTOBUF_EXPORT __attribute__((visibility("default"))) - #define PROTOBUF_EXPORT_TEMPLATE_DECLARE __attribute__((visibility("default"))) - #define PROTOBUF_EXPORT_TEMPLATE_DEFINE - #else - #define PROTOBUF_EXPORT - #define PROTOBUF_EXPORT_TEMPLATE_DECLARE - #define PROTOBUF_EXPORT_TEMPLATE_DEFINE - #endif - #ifdef LIBPROTOC_EXPORTS - #define PROTOC_EXPORT __attribute__((visibility("default"))) - #else - #define PROTOC_EXPORT - #endif - #endif +#if defined(_MSC_VER) +#ifdef LIBPROTOBUF_EXPORTS +#define PROTOBUF_EXPORT __declspec(dllexport) +#define PROTOBUF_EXPORT_TEMPLATE_DECLARE +#define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllexport) +#else +#define PROTOBUF_EXPORT __declspec(dllimport) +#define PROTOBUF_EXPORT_TEMPLATE_DECLARE +#define PROTOBUF_EXPORT_TEMPLATE_DEFINE __declspec(dllimport) +#endif +#ifdef LIBPROTOC_EXPORTS +#define PROTOC_EXPORT __declspec(dllexport) +#else +#define PROTOC_EXPORT __declspec(dllimport) +#endif +#else // defined(_MSC_VER) +#ifdef LIBPROTOBUF_EXPORTS +#define PROTOBUF_EXPORT __attribute__((visibility("default"))) +#define PROTOBUF_EXPORT_TEMPLATE_DECLARE __attribute__((visibility("default"))) +#define PROTOBUF_EXPORT_TEMPLATE_DEFINE +#else +#define PROTOBUF_EXPORT +#define PROTOBUF_EXPORT_TEMPLATE_DECLARE +#define PROTOBUF_EXPORT_TEMPLATE_DEFINE +#endif +#ifdef LIBPROTOC_EXPORTS +#define PROTOC_EXPORT __attribute__((visibility("default"))) +#else +#define PROTOC_EXPORT +#endif +#endif #else // defined(PROTOBUF_USE_DLLS) - #define PROTOBUF_EXPORT - #define PROTOC_EXPORT - #define PROTOBUF_EXPORT_TEMPLATE_DECLARE - #define PROTOBUF_EXPORT_TEMPLATE_DEFINE +#define PROTOBUF_EXPORT +#define PROTOC_EXPORT +#define PROTOBUF_EXPORT_TEMPLATE_DECLARE +#define PROTOBUF_EXPORT_TEMPLATE_DEFINE #endif // Windows declares several inconvenient macro names. We #undef them and then // restore them in port_undef.inc. #ifdef _MSC_VER +#pragma push_macro("CREATE_NEW") +#undef CREATE_NEW +#pragma push_macro("DOUBLE_CLICK") +#undef DOUBLE_CLICK +#pragma push_macro("ERROR") +#undef ERROR +#pragma push_macro("ERROR_BUSY") +#undef ERROR_BUSY +#pragma push_macro("ERROR_NOT_FOUND") +#undef ERROR_NOT_FOUND #pragma push_macro("GetMessage") #undef GetMessage #pragma push_macro("IGNORE") #undef IGNORE #pragma push_macro("IN") #undef IN +#pragma push_macro("INPUT_KEYBOARD") +#undef INPUT_KEYBOARD +#pragma push_macro("NO_ERROR") +#undef NO_ERROR #pragma push_macro("OUT") #undef OUT #pragma push_macro("OPTIONAL") @@ -396,13 +443,40 @@ #undef min #pragma push_macro("max") #undef max +#pragma push_macro("NEAR") +#undef NEAR +#pragma push_macro("NO_DATA") +#undef NO_DATA +#pragma push_macro("REASON_UNKNOWN") +#undef REASON_UNKNOWN +#pragma push_macro("SERVICE_DISABLED") +#undef SERVICE_DISABLED +#pragma push_macro("SEVERITY_ERROR") +#undef SEVERITY_ERROR +#pragma push_macro("STRICT") +#undef STRICT +#pragma push_macro("timezone") +#undef timezone #endif // _MSC_VER +#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) +// Don't let Objective-C Macros interfere with proto identifiers with the same +// name. +#pragma push_macro("DEBUG") +#undef DEBUG +#endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) + #if defined(__clang__) #pragma clang diagnostic push // TODO(gerbens) ideally we cleanup the code. But a cursory try shows many // violations. So let's ignore for now. #pragma clang diagnostic ignored "-Wshorten-64-to-32" +#elif defined(__GNUC__) +// GCC does not allow disabling diagnostics within an expression: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60875, so we disable this one +// globally even though it's only used for PROTOBUF_FIELD_OFFSET. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winvalid-offsetof" #endif // PROTOBUF_ASSUME(pred) tells the compiler that it can assume pred is true. To @@ -420,3 +494,118 @@ #else #define PROTOBUF_ASSUME(pred) GOOGLE_DCHECK(pred) #endif + +// Specify memory alignment for structs, classes, etc. +// Use like: +// class PROTOBUF_ALIGNAS(16) MyClass { ... } +// PROTOBUF_ALIGNAS(16) int array[4]; +// +// In most places you can use the C++11 keyword "alignas", which is preferred. +// +// But compilers have trouble mixing __attribute__((...)) syntax with +// alignas(...) syntax. +// +// Doesn't work in clang or gcc: +// struct alignas(16) __attribute__((packed)) S { char c; }; +// Works in clang but not gcc: +// struct __attribute__((packed)) alignas(16) S2 { char c; }; +// Works in clang and gcc: +// struct alignas(16) S3 { char c; } __attribute__((packed)); +// +// There are also some attributes that must be specified *before* a class +// definition: visibility (used for exporting functions/classes) is one of +// these attributes. This means that it is not possible to use alignas() with a +// class that is marked as exported. +#if defined(_MSC_VER) +#define PROTOBUF_ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) +#elif defined(__GNUC__) +#define PROTOBUF_ALIGNAS(byte_alignment) \ + __attribute__((aligned(byte_alignment))) +#else +#define PROTOBUF_ALIGNAS(byte_alignment) alignas(byte_alignment) +#endif + +#define PROTOBUF_FINAL final + +#if defined(_MSC_VER) +#define PROTOBUF_THREAD_LOCAL __declspec(thread) +#else +#define PROTOBUF_THREAD_LOCAL __thread +#endif + +// For enabling message owned arena, one major blocker is semantic change from +// moving to copying when there is ownership transfer (e.g., move ctor, swap, +// set allocated, release). This change not only causes performance regression +// but also breaks users code (e.g., dangling reference). For top-level +// messages, since it owns the arena, we can mitigate the issue by transferring +// ownership of arena. However, we cannot do that for nested messages. In order +// to tell how many usages of nested messages affected by message owned arena, +// we need to simulate the arena ownership. +// This experiment is purely for the purpose of gathering data. All code guarded +// by this flag is supposed to be removed after this experiment. +// #define PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT + +#if defined(__cpp_constinit) +#define PROTOBUF_CONSTINIT constinit +#elif defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::require_constant_initialization) +#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] +#endif +#endif +#ifndef PROTOBUF_CONSTINIT +#define PROTOBUF_CONSTINIT +#endif + +#if defined(__cpp_constinit) +#define PROTOBUF_CONSTINIT constinit +#elif defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::require_constant_initialization) +#define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] +#endif +#endif +#ifndef PROTOBUF_CONSTINIT +#define PROTOBUF_CONSTINIT +#endif + +// Some globals with an empty non-trivial destructor are annotated with +// no_destroy for performance reasons. It reduces the cost of these globals in +// non-opt mode and under sanitizers. +#if defined(__has_cpp_attribute) +#if __has_cpp_attribute(clang::no_destroy) +#define PROTOBUF_ATTRIBUTE_NO_DESTROY [[clang::no_destroy]] +#endif +#endif +#if !defined(PROTOBUF_ATTRIBUTE_NO_DESTROY) +#define PROTOBUF_ATTRIBUTE_NO_DESTROY +#endif + +#if defined(__GNUC__) +// Protobuf extensions and reflection require registration of the protos linked +// in the binary. Not until everything is registered does the runtime have a +// complete view on all protos. When code is using reflection or extensions +// in between registration calls this can lead to surprising behavior. By +// having the registration run first we mitigate this scenario. +// Highest priority is 101. We use 102 to allow code that really wants to +// higher priority to still beat us. +#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY __attribute__((init_priority((102)))) +#else +#define PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#endif + +#if _MSC_VER +#define PROTOBUF_PRAGMA_INIT_SEG __pragma(init_seg(lib)) +#else +#define PROTOBUF_PRAGMA_INIT_SEG +#endif + +// Silence some MSVC warnings in all our code. +#if _MSC_VER +#pragma warning(push) +// For non-trivial unions +#pragma warning(disable : 4582) +#pragma warning(disable : 4583) +// For init_seg(lib) +#pragma warning(disable : 4073) +// To silence the fact that we will pop this push from another file +#pragma warning(disable : 5031) +#endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 80822b470a9a..17cf8378a9b5 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -68,18 +68,53 @@ #undef PROTOBUF_ASSUME #undef PROTOBUF_EXPORT_TEMPLATE_DECLARE #undef PROTOBUF_EXPORT_TEMPLATE_DEFINE +#undef PROTOBUF_ALIGNAS +#undef PROTOBUF_FINAL +#undef PROTOBUF_THREAD_LOCAL +#undef PROTOBUF_MESSAGE_OWNED_ARENA_EXPERIMENT +#undef PROTOBUF_DISABLE_MSVC_UNION_WARNING +#undef PROTOBUF_ENABLE_MSVC_UNION_WARNING +#undef PROTOBUF_CONSTINIT +#undef PROTOBUF_ATTRIBUTE_NO_DESTROY +#undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY +#undef PROTOBUF_PRAGMA_INIT_SEG // Restore macro that may have been #undef'd in port_def.inc. #ifdef _MSC_VER +#pragma pop_macro("CREATE_NEW") +#pragma pop_macro("DOUBLE_CLICK") +#pragma pop_macro("ERROR") +#pragma pop_macro("ERROR_BUSY") +#pragma pop_macro("ERROR_NOT_FOUND") #pragma pop_macro("GetMessage") #pragma pop_macro("IGNORE") #pragma pop_macro("IN") +#pragma pop_macro("INPUT_KEYBOARD") #pragma pop_macro("OUT") #pragma pop_macro("OPTIONAL") #pragma pop_macro("min") #pragma pop_macro("max") +#pragma pop_macro("NEAR") +#pragma pop_macro("NO_DATA") +#pragma pop_macro("NO_ERROR") +#pragma pop_macro("REASON_UNKNOWN") +#pragma pop_macro("SERVICE_DISABLED") +#pragma pop_macro("SEVERITY_ERROR") +#pragma pop_macro("STRICT") +#pragma pop_macro("timezone") #endif +#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) +#pragma pop_macro("DEBUG") +#endif // defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) + #if defined(__clang__) #pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +// Pop the warning(push) from port_def.inc +#if _MSC_VER +#pragma warning(pop) #endif diff --git a/src/google/protobuf/preserve_unknown_enum_test.cc b/src/google/protobuf/preserve_unknown_enum_test.cc index 1ac4e13fb7b7..ed21a88b8157 100644 --- a/src/google/protobuf/preserve_unknown_enum_test.cc +++ b/src/google/protobuf/preserve_unknown_enum_test.cc @@ -137,7 +137,7 @@ TEST(PreserveUnknownEnumTest, Proto2HidesUnknownValues) { // The intermediate message has everything in its "unknown fields". proto2_preserve_unknown_enum_unittest::MyMessage message2 = message; message2.DiscardUnknownFields(); - EXPECT_EQ(0, message2.ByteSize()); + EXPECT_EQ(0, message2.ByteSizeLong()); // But when we pass it to the correct structure, all values are there. serialized.clear(); @@ -165,7 +165,7 @@ TEST(PreserveUnknownEnumTest, DynamicProto2HidesUnknownValues) { proto2_preserve_unknown_enum_unittest::MyMessage message2; message2.CopyFrom(*message); message2.DiscardUnknownFields(); - EXPECT_EQ(0, message2.ByteSize()); + EXPECT_EQ(0, message2.ByteSizeLong()); // But when we pass it to the correct structure, all values are there. serialized.clear(); diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc index 75da9eb7a27e..b253f702aad3 100644 --- a/src/google/protobuf/proto3_arena_unittest.cc +++ b/src/google/protobuf/proto3_arena_unittest.cc @@ -35,9 +35,12 @@ #include #include #include +#include #include +#include #include #include +#include using proto3_arena_unittest::TestAllTypes; @@ -135,7 +138,7 @@ TEST(Proto3ArenaTest, UnknownFields) { // We can modify this UnknownFieldSet. unknown_fields->AddVarint(1, 2); // And the unknown fields should be changed. - ASSERT_NE(original.ByteSize(), arena_message->ByteSize()); + ASSERT_NE(original.ByteSizeLong(), arena_message->ByteSizeLong()); ASSERT_FALSE( arena_message->GetReflection()->GetUnknownFields(*arena_message).empty()); } @@ -194,6 +197,331 @@ TEST(Proto3ArenaTest, MessageFieldClearViaReflection) { EXPECT_EQ(0, message->optional_nested_message().bb()); } +TEST(Proto3OptionalTest, OptionalFields) { + protobuf_unittest::TestProto3Optional msg; + EXPECT_FALSE(msg.has_optional_int32()); + msg.set_optional_int32(0); + EXPECT_TRUE(msg.has_optional_int32()); + + std::string serialized; + msg.SerializeToString(&serialized); + EXPECT_GT(serialized.size(), 0); + + msg.clear_optional_int32(); + EXPECT_FALSE(msg.has_optional_int32()); + msg.SerializeToString(&serialized); + EXPECT_EQ(serialized.size(), 0); +} + +TEST(Proto3OptionalTest, OptionalFieldDescriptor) { + const Descriptor* d = protobuf_unittest::TestProto3Optional::descriptor(); + + for (int i = 0; i < d->field_count(); i++) { + const FieldDescriptor* f = d->field(i); + if (HasPrefixString(f->name(), "singular")) { + EXPECT_FALSE(f->has_optional_keyword()) << f->full_name(); + EXPECT_FALSE(f->has_presence()) << f->full_name(); + EXPECT_FALSE(f->containing_oneof()) << f->full_name(); + } else { + EXPECT_TRUE(f->has_optional_keyword()) << f->full_name(); + EXPECT_TRUE(f->has_presence()) << f->full_name(); + EXPECT_TRUE(f->containing_oneof()) << f->full_name(); + } + } +} + +TEST(Proto3OptionalTest, OptionalField) { + protobuf_unittest::TestProto3Optional msg; + EXPECT_FALSE(msg.has_optional_int32()); + msg.set_optional_int32(0); + EXPECT_TRUE(msg.has_optional_int32()); + + std::string serialized; + msg.SerializeToString(&serialized); + EXPECT_GT(serialized.size(), 0); + + msg.clear_optional_int32(); + EXPECT_FALSE(msg.has_optional_int32()); + msg.SerializeToString(&serialized); + EXPECT_EQ(serialized.size(), 0); +} + +TEST(Proto3OptionalTest, OptionalFieldReflection) { + // Tests that oneof reflection works on synthetic oneofs. + // + // We test this more deeply elsewhere by parsing/serializing TextFormat (which + // doesn't treat synthetic oneofs specially, so reflects over them normally). + protobuf_unittest::TestProto3Optional msg; + const google::protobuf::Descriptor* d = msg.GetDescriptor(); + const google::protobuf::Reflection* r = msg.GetReflection(); + const google::protobuf::FieldDescriptor* f = d->FindFieldByName("optional_int32"); + const google::protobuf::OneofDescriptor* o = d->FindOneofByName("_optional_int32"); + GOOGLE_CHECK(f); + GOOGLE_CHECK(o); + EXPECT_TRUE(o->is_synthetic()); + + EXPECT_FALSE(r->HasField(msg, f)); + EXPECT_FALSE(r->HasOneof(msg, o)); + EXPECT_TRUE(r->GetOneofFieldDescriptor(msg, o) == nullptr); + + r->SetInt32(&msg, f, 123); + EXPECT_EQ(123, msg.optional_int32()); + EXPECT_EQ(123, r->GetInt32(msg, f)); + EXPECT_TRUE(r->HasField(msg, f)); + EXPECT_TRUE(r->HasOneof(msg, o)); + EXPECT_EQ(f, r->GetOneofFieldDescriptor(msg, o)); + + std::vector fields; + r->ListFields(msg, &fields); + EXPECT_EQ(1, fields.size()); + EXPECT_EQ(f, fields[0]); + + r->ClearOneof(&msg, o); + EXPECT_FALSE(r->HasField(msg, f)); + EXPECT_FALSE(r->HasOneof(msg, o)); + EXPECT_TRUE(r->GetOneofFieldDescriptor(msg, o) == nullptr); + + msg.set_optional_int32(123); + EXPECT_EQ(123, r->GetInt32(msg, f)); + EXPECT_TRUE(r->HasField(msg, f)); + EXPECT_TRUE(r->HasOneof(msg, o)); + EXPECT_EQ(f, r->GetOneofFieldDescriptor(msg, o)); + + r->ClearOneof(&msg, o); + EXPECT_FALSE(r->HasField(msg, f)); + EXPECT_FALSE(r->HasOneof(msg, o)); + EXPECT_TRUE(r->GetOneofFieldDescriptor(msg, o) == nullptr); +} + +// It's a regression test for b/160665543. +TEST(Proto3OptionalTest, ClearNonOptionalMessageField) { + protobuf_unittest::TestProto3OptionalMessage msg; + msg.mutable_nested_message(); + const google::protobuf::Descriptor* d = msg.GetDescriptor(); + const google::protobuf::Reflection* r = msg.GetReflection(); + const google::protobuf::FieldDescriptor* f = d->FindFieldByName("nested_message"); + r->ClearField(&msg, f); +} + +TEST(Proto3OptionalTest, ClearOptionalMessageField) { + protobuf_unittest::TestProto3OptionalMessage msg; + msg.mutable_optional_nested_message(); + const google::protobuf::Descriptor* d = msg.GetDescriptor(); + const google::protobuf::Reflection* r = msg.GetReflection(); + const google::protobuf::FieldDescriptor* f = + d->FindFieldByName("optional_nested_message"); + r->ClearField(&msg, f); +} + +TEST(Proto3OptionalTest, SwapNonOptionalMessageField) { + protobuf_unittest::TestProto3OptionalMessage msg1; + protobuf_unittest::TestProto3OptionalMessage msg2; + msg1.mutable_nested_message(); + const google::protobuf::Descriptor* d = msg1.GetDescriptor(); + const google::protobuf::Reflection* r = msg1.GetReflection(); + const google::protobuf::FieldDescriptor* f = d->FindFieldByName("nested_message"); + r->SwapFields(&msg1, &msg2, {f}); +} + +TEST(Proto3OptionalTest, SwapOptionalMessageField) { + protobuf_unittest::TestProto3OptionalMessage msg1; + protobuf_unittest::TestProto3OptionalMessage msg2; + msg1.mutable_optional_nested_message(); + const google::protobuf::Descriptor* d = msg1.GetDescriptor(); + const google::protobuf::Reflection* r = msg1.GetReflection(); + const google::protobuf::FieldDescriptor* f = + d->FindFieldByName("optional_nested_message"); + r->SwapFields(&msg1, &msg2, {f}); +} + +void SetAllFieldsZero(protobuf_unittest::TestProto3Optional* msg) { + msg->set_optional_int32(0); + msg->set_optional_int64(0); + msg->set_optional_uint32(0); + msg->set_optional_uint64(0); + msg->set_optional_sint32(0); + msg->set_optional_sint64(0); + msg->set_optional_fixed32(0); + msg->set_optional_fixed64(0); + msg->set_optional_sfixed32(0); + msg->set_optional_sfixed64(0); + msg->set_optional_float(0); + msg->set_optional_double(0); + msg->set_optional_bool(false); + msg->set_optional_string(""); + msg->set_optional_bytes(""); + msg->mutable_optional_nested_message(); + msg->mutable_lazy_nested_message(); + msg->set_optional_nested_enum( + protobuf_unittest::TestProto3Optional::UNSPECIFIED); +} + +void SetAllFieldsNonZero(protobuf_unittest::TestProto3Optional* msg) { + msg->set_optional_int32(101); + msg->set_optional_int64(102); + msg->set_optional_uint32(103); + msg->set_optional_uint64(104); + msg->set_optional_sint32(105); + msg->set_optional_sint64(106); + msg->set_optional_fixed32(107); + msg->set_optional_fixed64(108); + msg->set_optional_sfixed32(109); + msg->set_optional_sfixed64(110); + msg->set_optional_float(111); + msg->set_optional_double(112); + msg->set_optional_bool(true); + msg->set_optional_string("abc"); + msg->set_optional_bytes("def"); + msg->mutable_optional_nested_message(); + msg->mutable_lazy_nested_message(); + msg->set_optional_nested_enum(protobuf_unittest::TestProto3Optional::BAZ); +} + +void TestAllFieldsZero(const protobuf_unittest::TestProto3Optional& msg) { + EXPECT_EQ(0, msg.optional_int32()); + EXPECT_EQ(0, msg.optional_int64()); + EXPECT_EQ(0, msg.optional_uint32()); + EXPECT_EQ(0, msg.optional_uint64()); + EXPECT_EQ(0, msg.optional_sint32()); + EXPECT_EQ(0, msg.optional_sint64()); + EXPECT_EQ(0, msg.optional_fixed32()); + EXPECT_EQ(0, msg.optional_fixed64()); + EXPECT_EQ(0, msg.optional_sfixed32()); + EXPECT_EQ(0, msg.optional_sfixed64()); + EXPECT_EQ(0, msg.optional_float()); + EXPECT_EQ(0, msg.optional_double()); + EXPECT_EQ(0, msg.optional_bool()); + EXPECT_EQ("", msg.optional_string()); + EXPECT_EQ("", msg.optional_bytes()); + EXPECT_EQ(protobuf_unittest::TestProto3Optional::UNSPECIFIED, + msg.optional_nested_enum()); + + const Reflection* r = msg.GetReflection(); + const Descriptor* d = msg.GetDescriptor(); + EXPECT_EQ("", r->GetString(msg, d->FindFieldByName("optional_string"))); +} + +void TestAllFieldsNonZero(const protobuf_unittest::TestProto3Optional& msg) { + EXPECT_EQ(101, msg.optional_int32()); + EXPECT_EQ(102, msg.optional_int64()); + EXPECT_EQ(103, msg.optional_uint32()); + EXPECT_EQ(104, msg.optional_uint64()); + EXPECT_EQ(105, msg.optional_sint32()); + EXPECT_EQ(106, msg.optional_sint64()); + EXPECT_EQ(107, msg.optional_fixed32()); + EXPECT_EQ(108, msg.optional_fixed64()); + EXPECT_EQ(109, msg.optional_sfixed32()); + EXPECT_EQ(110, msg.optional_sfixed64()); + EXPECT_EQ(111, msg.optional_float()); + EXPECT_EQ(112, msg.optional_double()); + EXPECT_EQ(true, msg.optional_bool()); + EXPECT_EQ("abc", msg.optional_string()); + EXPECT_EQ("def", msg.optional_bytes()); + EXPECT_EQ(protobuf_unittest::TestProto3Optional::BAZ, + msg.optional_nested_enum()); +} + +void TestAllFieldsSet(const protobuf_unittest::TestProto3Optional& msg, + bool set) { + EXPECT_EQ(set, msg.has_optional_int32()); + EXPECT_EQ(set, msg.has_optional_int64()); + EXPECT_EQ(set, msg.has_optional_uint32()); + EXPECT_EQ(set, msg.has_optional_uint64()); + EXPECT_EQ(set, msg.has_optional_sint32()); + EXPECT_EQ(set, msg.has_optional_sint64()); + EXPECT_EQ(set, msg.has_optional_fixed32()); + EXPECT_EQ(set, msg.has_optional_fixed64()); + EXPECT_EQ(set, msg.has_optional_sfixed32()); + EXPECT_EQ(set, msg.has_optional_sfixed64()); + EXPECT_EQ(set, msg.has_optional_float()); + EXPECT_EQ(set, msg.has_optional_double()); + EXPECT_EQ(set, msg.has_optional_bool()); + EXPECT_EQ(set, msg.has_optional_string()); + EXPECT_EQ(set, msg.has_optional_bytes()); + EXPECT_EQ(set, msg.has_optional_nested_message()); + EXPECT_EQ(set, msg.has_lazy_nested_message()); + EXPECT_EQ(set, msg.has_optional_nested_enum()); +} + +TEST(Proto3OptionalTest, BinaryRoundTrip) { + protobuf_unittest::TestProto3Optional msg; + TestAllFieldsSet(msg, false); + SetAllFieldsZero(&msg); + TestAllFieldsZero(msg); + TestAllFieldsSet(msg, true); + + protobuf_unittest::TestProto3Optional msg2; + std::string serialized; + msg.SerializeToString(&serialized); + EXPECT_TRUE(msg2.ParseFromString(serialized)); + TestAllFieldsZero(msg2); + TestAllFieldsSet(msg2, true); +} + +TEST(Proto3OptionalTest, TextFormatRoundTripZeros) { + protobuf_unittest::TestProto3Optional msg; + SetAllFieldsZero(&msg); + + protobuf_unittest::TestProto3Optional msg2; + std::string text; + EXPECT_TRUE(TextFormat::PrintToString(msg, &text)); + EXPECT_TRUE(TextFormat::ParseFromString(text, &msg2)); + TestAllFieldsSet(msg2, true); + TestAllFieldsZero(msg2); +} + +TEST(Proto3OptionalTest, TextFormatRoundTripNonZeros) { + protobuf_unittest::TestProto3Optional msg; + SetAllFieldsNonZero(&msg); + + protobuf_unittest::TestProto3Optional msg2; + std::string text; + EXPECT_TRUE(TextFormat::PrintToString(msg, &text)); + EXPECT_TRUE(TextFormat::ParseFromString(text, &msg2)); + TestAllFieldsSet(msg2, true); + TestAllFieldsNonZero(msg2); +} + +TEST(Proto3OptionalTest, SwapRoundTripZero) { + protobuf_unittest::TestProto3Optional msg; + SetAllFieldsZero(&msg); + TestAllFieldsSet(msg, true); + + protobuf_unittest::TestProto3Optional msg2; + msg.Swap(&msg2); + TestAllFieldsSet(msg2, true); + TestAllFieldsZero(msg2); +} + +TEST(Proto3OptionalTest, SwapRoundTripNonZero) { + protobuf_unittest::TestProto3Optional msg; + SetAllFieldsNonZero(&msg); + TestAllFieldsSet(msg, true); + + protobuf_unittest::TestProto3Optional msg2; + msg.Swap(&msg2); + TestAllFieldsSet(msg2, true); + TestAllFieldsNonZero(msg2); +} + +TEST(Proto3OptionalTest, ReflectiveSwapRoundTrip) { + protobuf_unittest::TestProto3Optional msg; + SetAllFieldsZero(&msg); + TestAllFieldsSet(msg, true); + + protobuf_unittest::TestProto3Optional msg2; + msg2.GetReflection()->Swap(&msg, &msg2); + TestAllFieldsSet(msg2, true); + TestAllFieldsZero(msg2); +} + +TEST(Proto3OptionalTest, PlainFields) { + const Descriptor* d = TestAllTypes::descriptor(); + + EXPECT_FALSE(d->FindFieldByName("optional_int32")->has_presence()); + EXPECT_TRUE(d->FindFieldByName("oneof_nested_message")->has_presence()); +} + } // namespace } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h index 6b1e5f2edad8..af8eb00ef84c 100644 --- a/src/google/protobuf/reflection.h +++ b/src/google/protobuf/reflection.h @@ -471,7 +471,7 @@ class RepeatedFieldRefIterator // RepeatedFieldAccessor type, etc. template struct PrimitiveTraits { - static const bool is_primitive = false; + static constexpr bool is_primitive = false; }; #define DEFINE_PRIMITIVE(TYPE, type) \ template <> \ @@ -497,7 +497,8 @@ struct RefTypeTraits< typedef T AccessorValueType; typedef T IteratorValueType; typedef T* IteratorPointerType; - static const FieldDescriptor::CppType cpp_type = PrimitiveTraits::cpp_type; + static constexpr FieldDescriptor::CppType cpp_type = + PrimitiveTraits::cpp_type; static const Descriptor* GetMessageFieldDescriptor() { return NULL; } }; @@ -510,7 +511,7 @@ struct RefTypeTraits< typedef int32 AccessorValueType; typedef T IteratorValueType; typedef int32* IteratorPointerType; - static const FieldDescriptor::CppType cpp_type = + static constexpr FieldDescriptor::CppType cpp_type = FieldDescriptor::CPPTYPE_ENUM; static const Descriptor* GetMessageFieldDescriptor() { return NULL; } }; @@ -523,7 +524,7 @@ struct RefTypeTraits< typedef std::string AccessorValueType; typedef const std::string IteratorValueType; typedef const std::string* IteratorPointerType; - static const FieldDescriptor::CppType cpp_type = + static constexpr FieldDescriptor::CppType cpp_type = FieldDescriptor::CPPTYPE_STRING; static const Descriptor* GetMessageFieldDescriptor() { return NULL; } }; @@ -547,7 +548,7 @@ struct RefTypeTraits< typedef Message AccessorValueType; typedef const T& IteratorValueType; typedef const T* IteratorPointerType; - static const FieldDescriptor::CppType cpp_type = + static constexpr FieldDescriptor::CppType cpp_type = FieldDescriptor::CPPTYPE_MESSAGE; static const Descriptor* GetMessageFieldDescriptor() { return MessageDescriptorGetter::get(); diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index 077956a7bdca..9a622f4ac8a6 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -43,7 +43,6 @@ #include #include #include -#include #include @@ -85,10 +84,8 @@ void ReflectionOps::Merge(const Message& from, Message* to) { google::protobuf::MessageFactory::generated_factory()); std::vector fields; - from_reflection->ListFields(from, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; - + from_reflection->ListFieldsOmitStripped(from, &fields); + for (const FieldDescriptor* field : fields) { if (field->is_repeated()) { // Use map reflection if both are in map status and have the // same map type to avoid sync with repeated field. @@ -125,8 +122,16 @@ void ReflectionOps::Merge(const Message& from, Message* to) { #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_MESSAGE: - to_reflection->AddMessage(to, field)->MergeFrom( - from_reflection->GetRepeatedMessage(from, field, j)); + const Message& from_child = + from_reflection->GetRepeatedMessage(from, field, j); + if (from_reflection == to_reflection) { + to_reflection + ->AddMessage(to, field, + from_child.GetReflection()->GetMessageFactory()) + ->MergeFrom(from_child); + } else { + to_reflection->AddMessage(to, field)->MergeFrom(from_child); + } break; } } @@ -150,8 +155,15 @@ void ReflectionOps::Merge(const Message& from, Message* to) { #undef HANDLE_TYPE case FieldDescriptor::CPPTYPE_MESSAGE: - to_reflection->MutableMessage(to, field)->MergeFrom( - from_reflection->GetMessage(from, field)); + const Message& from_child = from_reflection->GetMessage(from, field); + if (from_reflection == to_reflection) { + to_reflection + ->MutableMessage( + to, field, from_child.GetReflection()->GetMessageFactory()) + ->MergeFrom(from_child); + } else { + to_reflection->MutableMessage(to, field)->MergeFrom(from_child); + } break; } } @@ -165,32 +177,98 @@ void ReflectionOps::Clear(Message* message) { const Reflection* reflection = GetReflectionOrDie(*message); std::vector fields; - reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - reflection->ClearField(message, fields[i]); + reflection->ListFieldsOmitStripped(*message, &fields); + for (const FieldDescriptor* field : fields) { + reflection->ClearField(message, field); } reflection->MutableUnknownFields(message)->Clear(); } +bool ReflectionOps::IsInitialized(const Message& message, bool check_fields, + bool check_descendants) { + const Descriptor* descriptor = message.GetDescriptor(); + const Reflection* reflection = GetReflectionOrDie(message); + if (const int field_count = descriptor->field_count()) { + const FieldDescriptor* begin = descriptor->field(0); + const FieldDescriptor* end = begin + field_count; + GOOGLE_DCHECK_EQ(descriptor->field(field_count - 1), end - 1); + + if (check_fields) { + // Check required fields of this message. + for (const FieldDescriptor* field = begin; field != end; ++field) { + if (field->is_required() && !reflection->HasField(message, field)) { + return false; + } + } + } + + if (check_descendants) { + for (const FieldDescriptor* field = begin; field != end; ++field) { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const Descriptor* message_type = field->message_type(); + if (PROTOBUF_PREDICT_FALSE(message_type->options().map_entry())) { + if (message_type->field(1)->cpp_type() == + FieldDescriptor::CPPTYPE_MESSAGE) { + const MapFieldBase* map_field = + reflection->GetMapData(message, field); + if (map_field->IsMapValid()) { + MapIterator it(const_cast(&message), field); + MapIterator end(const_cast(&message), field); + for (map_field->MapBegin(&it), map_field->MapEnd(&end); + it != end; ++it) { + if (!it.GetValueRef().GetMessageValue().IsInitialized()) { + return false; + } + } + } + } + } else if (field->is_repeated()) { + const int size = reflection->FieldSize(message, field); + for (int j = 0; j < size; j++) { + if (!reflection->GetRepeatedMessage(message, field, j) + .IsInitialized()) { + return false; + } + } + } else if (reflection->HasField(message, field)) { + if (!reflection->GetMessage(message, field).IsInitialized()) { + return false; + } + } + } + } + } + } + if (check_descendants && reflection->HasExtensionSet(message) && + !reflection->GetExtensionSet(message).IsInitialized()) { + return false; + } + return true; +} + bool ReflectionOps::IsInitialized(const Message& message) { const Descriptor* descriptor = message.GetDescriptor(); const Reflection* reflection = GetReflectionOrDie(message); // Check required fields of this message. - for (int i = 0; i < descriptor->field_count(); i++) { - if (descriptor->field(i)->is_required()) { - if (!reflection->HasField(message, descriptor->field(i))) { - return false; + { + const int field_count = descriptor->field_count(); + for (int i = 0; i < field_count; i++) { + if (descriptor->field(i)->is_required()) { + if (!reflection->HasField(message, descriptor->field(i))) { + return false; + } } } } // Check that sub-messages are initialized. std::vector fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + // Should be safe to skip stripped fields because required fields are not + // stripped. + reflection->ListFieldsOmitStripped(message, &fields); + for (const FieldDescriptor* field : fields) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->is_map()) { @@ -248,8 +326,7 @@ void ReflectionOps::DiscardUnknownFields(Message* message) { // messages present. std::vector fields; reflection->ListFields(*message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + for (const FieldDescriptor* field : fields) { // Skip over non-message fields. if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { continue; @@ -306,19 +383,21 @@ void ReflectionOps::FindInitializationErrors(const Message& message, const Reflection* reflection = GetReflectionOrDie(message); // Check required fields of this message. - for (int i = 0; i < descriptor->field_count(); i++) { - if (descriptor->field(i)->is_required()) { - if (!reflection->HasField(message, descriptor->field(i))) { - errors->push_back(prefix + descriptor->field(i)->name()); + { + const int field_count = descriptor->field_count(); + for (int i = 0; i < field_count; i++) { + if (descriptor->field(i)->is_required()) { + if (!reflection->HasField(message, descriptor->field(i))) { + errors->push_back(prefix + descriptor->field(i)->name()); + } } } } // Check sub-messages. std::vector fields; - reflection->ListFields(message, &fields); - for (int i = 0; i < fields.size(); i++) { - const FieldDescriptor* field = fields[i]; + reflection->ListFieldsOmitStripped(message, &fields); + for (const FieldDescriptor* field : fields) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->is_repeated()) { @@ -339,6 +418,23 @@ void ReflectionOps::FindInitializationErrors(const Message& message, } } +void GenericSwap(Message* m1, Message* m2) { + Arena* m2_arena = m2->GetArena(); + GOOGLE_DCHECK(m1->GetArena() != m2_arena); + + // Copy semantics in this case. We try to improve efficiency by placing the + // temporary on |m2|'s arena so that messages are copied twice rather than + // three times. + Message* tmp = m2->New(m2_arena); + std::unique_ptr tmp_deleter(m2_arena == nullptr ? tmp : nullptr); + tmp->CheckTypeAndMergeFrom(*m1); + m1->Clear(); + m1->CheckTypeAndMergeFrom(*m2); + m2->GetReflection()->Swap(tmp, m2); +} + } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/reflection_ops.h b/src/google/protobuf/reflection_ops.h index b30c050a75d9..fb98714defe3 100644 --- a/src/google/protobuf/reflection_ops.h +++ b/src/google/protobuf/reflection_ops.h @@ -66,6 +66,8 @@ class PROTOBUF_EXPORT ReflectionOps { static void Merge(const Message& from, Message* to); static void Clear(Message* message); static bool IsInitialized(const Message& message); + static bool IsInitialized(const Message& message, bool check_fields, + bool check_descendants); static void DiscardUnknownFields(Message* message); // Finds all unset required fields in the message and adds their full diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc index bd141933c67d..dee2af2c5d9c 100644 --- a/src/google/protobuf/reflection_ops_unittest.cc +++ b/src/google/protobuf/reflection_ops_unittest.cc @@ -340,12 +340,20 @@ TEST(ReflectionOpsTest, IsInitialized) { unittest::TestRequired message; EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); message.set_a(1); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, true, true)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); message.set_b(2); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, true, true)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); message.set_c(3); EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); } TEST(ReflectionOpsTest, ForeignIsInitialized) { @@ -354,26 +362,35 @@ TEST(ReflectionOpsTest, ForeignIsInitialized) { // Starts out initialized because the foreign message is itself an optional // field. EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); // Once we create that field, the message is no longer initialized. message.mutable_optional_message(); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true)); // Initialize it. Now we're initialized. message.mutable_optional_message()->set_a(1); message.mutable_optional_message()->set_b(2); message.mutable_optional_message()->set_c(3); EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); // Add a repeated version of the message. No longer initialized. unittest::TestRequired* sub_message = message.add_repeated_message(); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true)); // Initialize that repeated version. sub_message->set_a(1); sub_message->set_b(2); sub_message->set_c(3); EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); } TEST(ReflectionOpsTest, ExtensionIsInitialized) { @@ -382,42 +399,62 @@ TEST(ReflectionOpsTest, ExtensionIsInitialized) { // Starts out initialized because the foreign message is itself an optional // field. EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); // Once we create that field, the message is no longer initialized. message.MutableExtension(unittest::TestRequired::single); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true)); // Initialize it. Now we're initialized. message.MutableExtension(unittest::TestRequired::single)->set_a(1); message.MutableExtension(unittest::TestRequired::single)->set_b(2); message.MutableExtension(unittest::TestRequired::single)->set_c(3); EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); // Add a repeated version of the message. No longer initialized. message.AddExtension(unittest::TestRequired::multi); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true)); // Initialize that repeated version. message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1); message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2); message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3); EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); } TEST(ReflectionOpsTest, OneofIsInitialized) { unittest::TestRequiredOneof message; EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); message.mutable_foo_message(); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true)); message.set_foo_int(1); EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); message.mutable_foo_message(); EXPECT_FALSE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_FALSE(ReflectionOps::IsInitialized(message, false, true)); message.mutable_foo_message()->set_required_double(0.1); EXPECT_TRUE(ReflectionOps::IsInitialized(message)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, true, false)); + EXPECT_TRUE(ReflectionOps::IsInitialized(message, false, true)); } static std::string FindInitializationErrors(const Message& message) { @@ -473,6 +510,36 @@ TEST(ReflectionOpsTest, FindOneofInitializationErrors) { EXPECT_EQ("foo_message.required_double", FindInitializationErrors(message)); } +TEST(ReflectionOpsTest, GenericSwap) { + Arena arena; + { + unittest::TestAllTypes message; + auto* arena_message = Arena::CreateMessage(&arena); + TestUtil::SetAllFields(arena_message); + const uint64 initial_arena_size = arena.SpaceUsed(); + + GenericSwap(&message, arena_message); + + TestUtil::ExpectAllFieldsSet(message); + TestUtil::ExpectClear(*arena_message); + // The temp should be allocated on the arena in this case. + EXPECT_GT(arena.SpaceUsed(), initial_arena_size); + } + { + unittest::TestAllTypes message; + auto* arena_message = Arena::CreateMessage(&arena); + TestUtil::SetAllFields(arena_message); + const uint64 initial_arena_size = arena.SpaceUsed(); + + GenericSwap(arena_message, &message); + + TestUtil::ExpectAllFieldsSet(message); + TestUtil::ExpectClear(*arena_message); + // The temp shouldn't be allocated on the arena in this case. + EXPECT_EQ(arena.SpaceUsed(), initial_arena_size); + } +} + } // namespace } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc index fc73917c509b..f5e83ffaba91 100644 --- a/src/google/protobuf/repeated_field.cc +++ b/src/google/protobuf/repeated_field.cc @@ -55,11 +55,13 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { return &rep_->elements[current_size_]; } Rep* old_rep = rep_; - Arena* arena = GetArenaNoVirtual(); - new_size = std::max(kMinRepeatedFieldAllocationSize, + Arena* arena = GetArena(); + new_size = std::max(internal::kRepeatedFieldLowerClampLimit, std::max(total_size_ * 2, new_size)); - GOOGLE_CHECK_LE(new_size, (std::numeric_limits::max() - kRepHeaderSize) / - sizeof(old_rep->elements[0])) + GOOGLE_CHECK_LE( + static_cast(new_size), + static_cast((std::numeric_limits::max() - kRepHeaderSize) / + sizeof(old_rep->elements[0]))) << "Requested size is too large to fit into size_t."; size_t bytes = kRepHeaderSize + sizeof(old_rep->elements[0]) * new_size; if (arena == NULL) { @@ -134,3 +136,5 @@ template class PROTOBUF_EXPORT_TEMPLATE_DEFINE RepeatedPtrField; } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 73fcc74b3a02..89f1474603cf 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -66,6 +66,7 @@ #include +// Must be included last. #include #ifdef SWIG @@ -85,7 +86,16 @@ namespace internal { class MergePartialFromCodedStreamHelper; -static const int kMinRepeatedFieldAllocationSize = 4; +// kRepeatedFieldLowerClampLimit is the smallest size that will be allocated +// when growing a repeated field. +constexpr int kRepeatedFieldLowerClampLimit = 4; + +// kRepeatedFieldUpperClampLimit is the lowest signed integer value that +// overflows when multiplied by 2 (which is undefined behavior). Sizes above +// this will clamp to the maximum int value instead of following exponential +// growth when growing a repeated field. +constexpr int kRepeatedFieldUpperClampLimit = + (std::numeric_limits::max() / 2) + 1; // A utility function for logging that doesn't need any template types. void LogIndexOutOfBounds(int index, int size); @@ -106,6 +116,46 @@ inline int CalculateReserve(Iter begin, Iter end) { typedef typename std::iterator_traits::iterator_category Category; return CalculateReserve(begin, end, Category()); } + +// Swaps two blocks of memory of size sizeof(T). +template +inline void SwapBlock(char* p, char* q) { + T tmp; + memcpy(&tmp, p, sizeof(T)); + memcpy(p, q, sizeof(T)); + memcpy(q, &tmp, sizeof(T)); +} + +// Swaps two blocks of memory of size kSize: +// template void memswap(char* p, char* q); + +template +inline typename std::enable_if<(kSize == 0), void>::type memswap(char*, char*) { +} + +#define PROTO_MEMSWAP_DEF_SIZE(reg_type, max_size) \ + template \ + typename std::enable_if<(kSize >= sizeof(reg_type) && kSize < (max_size)), \ + void>::type \ + memswap(char* p, char* q) { \ + SwapBlock(p, q); \ + memswap(p + sizeof(reg_type), \ + q + sizeof(reg_type)); \ + } + +PROTO_MEMSWAP_DEF_SIZE(uint8, 2) +PROTO_MEMSWAP_DEF_SIZE(uint16, 4) +PROTO_MEMSWAP_DEF_SIZE(uint32, 8) + +#ifdef __SIZEOF_INT128__ +PROTO_MEMSWAP_DEF_SIZE(uint64, 16) +PROTO_MEMSWAP_DEF_SIZE(__uint128_t, (1u << 31)) +#else +PROTO_MEMSWAP_DEF_SIZE(uint64, (1u << 31)) +#endif + +#undef PROTO_MEMSWAP_DEF_SIZE + } // namespace internal // RepeatedField is used to represent repeated fields of a primitive type (in @@ -119,7 +169,7 @@ class RepeatedField final { "We only support types that have an alignment smaller than Arena"); public: - RepeatedField(); + constexpr RepeatedField(); explicit RepeatedField(Arena* arena); RepeatedField(const RepeatedField& other); template @@ -258,7 +308,10 @@ class RepeatedField final { iterator erase(const_iterator first, const_iterator last); // Get the Arena on which this RepeatedField stores its elements. - Arena* GetArena() const { return GetArenaNoVirtual(); } + inline Arena* GetArena() const { + return (total_size_ == 0) ? static_cast(arena_or_elements_) + : rep()->arena; + } // For internal use only. // @@ -266,7 +319,7 @@ class RepeatedField final { inline void InternalSwap(RepeatedField* other); private: - static const int kInitialSize = 0; + static constexpr int kInitialSize = 0; // A note on the representation here (see also comment below for // RepeatedPtrFieldBase's struct Rep): // @@ -281,13 +334,12 @@ class RepeatedField final { int total_size_; struct Rep { Arena* arena; - Element elements[1]; + // Here we declare a huge array as a way of approximating C's "flexible + // array member" feature without relying on undefined behavior. + Element elements[(std::numeric_limits::max() - 2 * sizeof(Arena*)) / + sizeof(Element)]; }; - // We can not use sizeof(Rep) - sizeof(Element) due to the trailing padding on - // the struct. We can not use sizeof(Arena*) as well because there might be - // a "gap" after the field arena and before the field elements (e.g., when - // Element is double and pointer is 32bit). - static const size_t kRepHeaderSize; + static constexpr size_t kRepHeaderSize = offsetof(Rep, elements); // If total_size_ == 0 this points to an Arena otherwise it points to the // elements member of a Rep struct. Using this invariant allows the storage of @@ -327,21 +379,15 @@ class RepeatedField final { // Copy the elements of |from| into |to|. void CopyArray(Element* to, const Element* from, int size); - // Internal helper expected by Arena methods. - inline Arena* GetArenaNoVirtual() const { - return (total_size_ == 0) ? static_cast(arena_or_elements_) - : rep()->arena; - } - // Internal helper to delete all elements and deallocate the storage. - // If Element has a trivial destructor (for example, if it's a fundamental - // type, like int32), the loop will be removed by the optimizer. void InternalDeallocate(Rep* rep, int size) { if (rep != NULL) { Element* e = &rep->elements[0]; - Element* limit = &rep->elements[size]; - for (; e < limit; e++) { - e->~Element(); + if (!std::is_trivial::value) { + Element* limit = &rep->elements[size]; + for (; e < limit; e++) { + e->~Element(); + } } if (rep->arena == NULL) { #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) @@ -353,11 +399,92 @@ class RepeatedField final { } } } -}; -template -const size_t RepeatedField::kRepHeaderSize = - reinterpret_cast(&reinterpret_cast(16)->elements[0]) - 16; + // This class is a performance wrapper around RepeatedField::Add(const T&) + // function. In general unless a RepeatedField is a local stack variable LLVM + // has a hard time optimizing Add. The machine code tends to be + // loop: + // mov %size, dword ptr [%repeated_field] // load + // cmp %size, dword ptr [%repeated_field + 4] + // jae fallback + // mov %buffer, qword ptr [%repeated_field + 8] + // mov dword [%buffer + %size * 4], %value + // inc %size // increment + // mov dword ptr [%repeated_field], %size // store + // jmp loop + // + // This puts a load/store in each iteration of the important loop variable + // size. It's a pretty bad compile that happens even in simple cases, but + // largely the presence of the fallback path disturbs the compilers mem-to-reg + // analysis. + // + // This class takes ownership of a repeated field for the duration of it's + // lifetime. The repeated field should not be accessed during this time, ie. + // only access through this class is allowed. This class should always be a + // function local stack variable. Intended use + // + // void AddSequence(const int* begin, const int* end, RepeatedField* out) + // { + // RepeatedFieldAdder adder(out); // Take ownership of out + // for (auto it = begin; it != end; ++it) { + // adder.Add(*it); + // } + // } + // + // Typically due to the fact adder is a local stack variable. The compiler + // will be successful in mem-to-reg transformation and the machine code will + // be loop: cmp %size, %capacity jae fallback mov dword ptr [%buffer + %size * + // 4], %val inc %size jmp loop + // + // The first version executes at 7 cycles per iteration while the second + // version near 1 or 2 cycles. + template ::value> + class FastAdderImpl { + public: + explicit FastAdderImpl(RepeatedField* rf) : repeated_field_(rf) { + index_ = repeated_field_->current_size_; + capacity_ = repeated_field_->total_size_; + buffer_ = repeated_field_->unsafe_elements(); + } + ~FastAdderImpl() { repeated_field_->current_size_ = index_; } + + void Add(Element val) { + if (index_ == capacity_) { + repeated_field_->current_size_ = index_; + repeated_field_->Reserve(index_ + 1); + capacity_ = repeated_field_->total_size_; + buffer_ = repeated_field_->unsafe_elements(); + } + buffer_[index_++] = val; + } + + private: + RepeatedField* repeated_field_; + int index_; + int capacity_; + Element* buffer_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastAdderImpl); + }; + + // FastAdder is a wrapper for adding fields. The specialization above handles + // POD types more efficiently than RepeatedField. + template + class FastAdderImpl { + public: + explicit FastAdderImpl(RepeatedField* rf) : repeated_field_(rf) {} + void Add(const Element& val) { repeated_field_->Add(val); } + + private: + RepeatedField* repeated_field_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FastAdderImpl); + }; + + using FastAdder = FastAdderImpl<>; + + friend class TestRepeatedFieldHelper; + friend class ::google::protobuf::internal::ParseContext; +}; namespace internal { template @@ -450,7 +577,7 @@ struct IsMovable // }; class PROTOBUF_EXPORT RepeatedPtrFieldBase { protected: - RepeatedPtrFieldBase(); + constexpr RepeatedPtrFieldBase(); explicit RepeatedPtrFieldBase(Arena* arena); ~RepeatedPtrFieldBase() { #ifndef NDEBUG @@ -589,10 +716,10 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { template PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other); - inline Arena* GetArenaNoVirtual() const { return arena_; } + inline Arena* GetArena() const { return arena_; } private: - static const int kInitialSize = 0; + static constexpr int kInitialSize = 0; // A few notes on internal representation: // // We use an indirected approach, with struct Rep, to keep @@ -609,9 +736,12 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { int total_size_; struct Rep { int allocated_size; - void* elements[1]; + // Here we declare a huge array as a way of approximating C's "flexible + // array member" feature without relying on undefined behavior. + void* elements[(std::numeric_limits::max() - 2 * sizeof(int)) / + sizeof(void*)]; }; - static const size_t kRepHeaderSize = sizeof(Rep) - sizeof(void*); + static constexpr size_t kRepHeaderSize = offsetof(Rep, elements); Rep* rep_; template @@ -790,7 +920,7 @@ class StringTypeHandler { template class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { public: - RepeatedPtrField(); + constexpr RepeatedPtrField(); explicit RepeatedPtrField(Arena* arena); RepeatedPtrField(const RepeatedPtrField& other); @@ -1016,7 +1146,7 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { iterator erase(const_iterator first, const_iterator last); // Gets the arena on which this RepeatedPtrField stores its elements. - Arena* GetArena() const { return GetArenaNoVirtual(); } + inline Arena* GetArena() const; // For internal use only. // @@ -1029,9 +1159,6 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // Note: RepeatedPtrField SHOULD NOT be subclassed by users. class TypeHandler; - // Internal arena accessor expected by helpers in Arena. - inline Arena* GetArenaNoVirtual() const; - // Implementations for ExtractSubrange(). The copying behavior must be // included only if the type supports the necessary operations (e.g., // MergeFrom()), so we must resolve this at compile time. ExtractSubrange() @@ -1053,7 +1180,7 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // implementation ==================================================== template -inline RepeatedField::RepeatedField() +constexpr RepeatedField::RepeatedField() : current_size_(0), total_size_(0), arena_or_elements_(nullptr) {} template @@ -1079,6 +1206,12 @@ RepeatedField::RepeatedField(Iter begin, const Iter& end) template RepeatedField::~RepeatedField() { +#ifndef NDEBUG + // Try to trigger segfault / asan failure in non-opt builds. If arena_ + // lifetime has ended before the destructor. + auto arena = GetArena(); + if (arena) (void)arena->SpaceAllocated(); +#endif if (total_size_ > 0) { InternalDeallocate(rep(), total_size_); } @@ -1097,7 +1230,7 @@ inline RepeatedField::RepeatedField(RepeatedField&& other) noexcept // We don't just call Swap(&other) here because it would perform 3 copies if // other is on an arena. This field can't be on an arena because arena // construction always uses the Arena* accepting constructor. - if (other.GetArenaNoVirtual()) { + if (other.GetArena()) { CopyFrom(other); } else { InternalSwap(&other); @@ -1110,7 +1243,7 @@ inline RepeatedField& RepeatedField::operator=( // We don't just call Swap(&other) here because it would perform 3 copies if // the two fields are on different arenas. if (this != &other) { - if (this->GetArenaNoVirtual() != other.GetArenaNoVirtual()) { + if (this->GetArena() != other.GetArena()) { CopyFrom(other); } else { InternalSwap(&other); @@ -1206,14 +1339,26 @@ inline void RepeatedField::Set(int index, const Element& value) { template inline void RepeatedField::Add(const Element& value) { - if (current_size_ == total_size_) Reserve(total_size_ + 1); - elements()[current_size_++] = value; + uint32 size = current_size_; + if (static_cast(size) == total_size_) { + // value could reference an element of the array. Reserving new space will + // invalidate the reference. So we must make a copy first. + auto tmp = value; + Reserve(total_size_ + 1); + elements()[size] = std::move(tmp); + } else { + elements()[size] = value; + } + current_size_ = size + 1; } template inline Element* RepeatedField::Add() { - if (current_size_ == total_size_) Reserve(total_size_ + 1); - return &elements()[current_size_++]; + uint32 size = current_size_; + if (static_cast(size) == total_size_) Reserve(total_size_ + 1); + auto ptr = &elements()[size]; + current_size_ = size + 1; + return ptr; } template @@ -1235,9 +1380,8 @@ inline void RepeatedField::Add(Iter begin, Iter end) { std::copy(begin, end, elements() + size()); current_size_ = reserve + size(); } else { - for (; begin != end; ++begin) { - Add(*begin); - } + FastAdder fast_adder(this); + for (; begin != end; ++begin) fast_adder.Add(*begin); } } @@ -1319,20 +1463,25 @@ inline const Element* RepeatedField::data() const { template inline void RepeatedField::InternalSwap(RepeatedField* other) { GOOGLE_DCHECK(this != other); - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); - std::swap(arena_or_elements_, other->arena_or_elements_); - std::swap(current_size_, other->current_size_); - std::swap(total_size_, other->total_size_); + // Swap all fields at once. + static_assert(std::is_standard_layout>::value, + "offsetof() requires standard layout before c++17"); + internal::memswaparena_or_elements_) - + offsetof(RepeatedField, current_size_)>( + reinterpret_cast(this) + offsetof(RepeatedField, current_size_), + reinterpret_cast(other) + offsetof(RepeatedField, current_size_)); } template void RepeatedField::Swap(RepeatedField* other) { if (this == other) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { - RepeatedField temp(other->GetArenaNoVirtual()); + RepeatedField temp(other->GetArena()); temp.MergeFrom(*this); CopyFrom(*other); other->UnsafeArenaSwap(&temp); @@ -1386,6 +1535,30 @@ inline size_t RepeatedField::SpaceUsedExcludingSelfLong() const { return total_size_ > 0 ? (total_size_ * sizeof(Element) + kRepHeaderSize) : 0; } +namespace internal { +// Returns the new size for a reserved field based on its 'total_size' and the +// requested 'new_size'. The result is clamped to the closed interval: +// [internal::kMinRepeatedFieldAllocationSize, +// std::numeric_limits::max()] +// Requires: +// new_size > total_size && +// (total_size == 0 || +// total_size >= kRepeatedFieldLowerClampLimit) +inline int CalculateReserveSize(int total_size, int new_size) { + if (new_size < kRepeatedFieldLowerClampLimit) { + // Clamp to smallest allowed size. + return kRepeatedFieldLowerClampLimit; + } + if (total_size < kRepeatedFieldUpperClampLimit) { + return std::max(total_size * 2, new_size); + } else { + // Clamp to largest allowed size. + GOOGLE_DCHECK_GT(new_size, kRepeatedFieldUpperClampLimit); + return std::numeric_limits::max(); + } +} +} // namespace internal + // Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant // amount of code bloat. template @@ -1393,9 +1566,8 @@ void RepeatedField::Reserve(int new_size) { if (total_size_ >= new_size) return; Rep* old_rep = total_size_ > 0 ? rep() : NULL; Rep* new_rep; - Arena* arena = GetArenaNoVirtual(); - new_size = std::max(internal::kMinRepeatedFieldAllocationSize, - std::max(total_size_ * 2, new_size)); + Arena* arena = GetArena(); + new_size = internal::CalculateReserveSize(total_size_, new_size); GOOGLE_DCHECK_LE( static_cast(new_size), (std::numeric_limits::max() - kRepHeaderSize) / sizeof(Element)) @@ -1409,6 +1581,10 @@ void RepeatedField::Reserve(int new_size) { } new_rep->arena = arena; int old_total_size = total_size_; + // Already known: new_size >= internal::kMinRepeatedFieldAllocationSize + // Maintain invariant: + // total_size_ == 0 || + // total_size_ >= internal::kMinRepeatedFieldAllocationSize total_size_ = new_size; arena_or_elements_ = new_rep->elements; // Invoke placement-new on newly allocated elements. We shouldn't have to do @@ -1477,7 +1653,7 @@ struct ElementCopier { namespace internal { -inline RepeatedPtrFieldBase::RepeatedPtrFieldBase() +constexpr RepeatedPtrFieldBase::RepeatedPtrFieldBase() : arena_(NULL), current_size_(0), total_size_(0), rep_(NULL) {} inline RepeatedPtrFieldBase::RepeatedPtrFieldBase(Arena* arena) @@ -1503,7 +1679,7 @@ void RepeatedPtrFieldBase::Destroy() { template inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { - if (other->GetArenaNoVirtual() == GetArenaNoVirtual()) { + if (other->GetArena() == GetArena()) { InternalSwap(other); } else { SwapFallback(other); @@ -1512,16 +1688,15 @@ inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) { template void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) { - GOOGLE_DCHECK(other->GetArenaNoVirtual() != GetArenaNoVirtual()); + GOOGLE_DCHECK(other->GetArena() != GetArena()); // Copy semantics in this case. We try to improve efficiency by placing the - // temporary on |other|'s arena so that messages are copied cross-arena only - // once, not twice. - RepeatedPtrFieldBase temp(other->GetArenaNoVirtual()); + // temporary on |other|'s arena so that messages are copied twice rather than + // three times. + RepeatedPtrFieldBase temp(other->GetArena()); temp.MergeFrom(*this); this->Clear(); this->MergeFrom(*other); - other->Clear(); other->InternalSwap(&temp); temp.Destroy(); // Frees rep_ if `other` had no arena. } @@ -1664,7 +1839,7 @@ void RepeatedPtrFieldBase::MergeFromInnerLoop(void** our_elems, reinterpret_cast(our_elems[i]); TypeHandler::Merge(*other_elem, new_elem); } - Arena* arena = GetArenaNoVirtual(); + Arena* arena = GetArena(); for (int i = already_allocated; i < length; i++) { // Not allocated: alloc a new element first, then merge it. typename TypeHandler::Type* other_elem = @@ -1741,7 +1916,7 @@ void RepeatedPtrFieldBase::AddAllocatedInternal( typename TypeHandler::Type* value, std::true_type) { Arena* element_arena = reinterpret_cast(TypeHandler::GetMaybeArenaPointer(value)); - Arena* arena = GetArenaNoVirtual(); + Arena* arena = GetArena(); if (arena == element_arena && rep_ && rep_->allocated_size < total_size_) { // Fast path: underlying arena representation (tagged pointer) is equal to // our arena pointer, and we can add to array without resizing it (at least @@ -1840,7 +2015,7 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( // First, release an element. typename TypeHandler::Type* result = UnsafeArenaReleaseLast(); // Now perform a copy if we're on an arena. - Arena* arena = GetArenaNoVirtual(); + Arena* arena = GetArena(); if (arena == NULL) { return result; } else { @@ -1858,7 +2033,7 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( template inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLastInternal( std::false_type) { - GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + GOOGLE_DCHECK(GetArena() == NULL) << "ReleaseLast() called on a RepeatedPtrField that is on an arena, " << "with a type that does not implement MergeFrom. This is unsafe; " << "please implement MergeFrom for your type."; @@ -1887,7 +2062,7 @@ inline int RepeatedPtrFieldBase::ClearedCount() const { template inline void RepeatedPtrFieldBase::AddCleared( typename TypeHandler::Type* value) { - GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + GOOGLE_DCHECK(GetArena() == NULL) << "AddCleared() can only be used on a RepeatedPtrField not on an arena."; GOOGLE_DCHECK(TypeHandler::GetArena(value) == NULL) << "AddCleared() can only accept values not on an arena."; @@ -1899,10 +2074,10 @@ inline void RepeatedPtrFieldBase::AddCleared( template inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() { - GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + GOOGLE_DCHECK(GetArena() == NULL) << "ReleaseCleared() can only be used on a RepeatedPtrField not on " << "an arena."; - GOOGLE_DCHECK(GetArenaNoVirtual() == NULL); + GOOGLE_DCHECK(GetArena() == NULL); GOOGLE_DCHECK(rep_ != NULL); GOOGLE_DCHECK_GT(rep_->allocated_size, current_size_); return cast(rep_->elements[--rep_->allocated_size]); @@ -1921,7 +2096,8 @@ class RepeatedPtrField::TypeHandler : public internal::StringTypeHandler {}; template -inline RepeatedPtrField::RepeatedPtrField() : RepeatedPtrFieldBase() {} +constexpr RepeatedPtrField::RepeatedPtrField() + : RepeatedPtrFieldBase() {} template inline RepeatedPtrField::RepeatedPtrField(Arena* arena) @@ -1966,7 +2142,7 @@ inline RepeatedPtrField::RepeatedPtrField( // We don't just call Swap(&other) here because it would perform 3 copies if // other is on an arena. This field can't be on an arena because arena // construction always uses the Arena* accepting constructor. - if (other.GetArenaNoVirtual()) { + if (other.GetArena()) { CopyFrom(other); } else { InternalSwap(&other); @@ -1979,7 +2155,7 @@ inline RepeatedPtrField& RepeatedPtrField::operator=( // We don't just call Swap(&other) here because it would perform 3 copies if // the two fields are on different arenas. if (this != &other) { - if (this->GetArenaNoVirtual() != other.GetArenaNoVirtual()) { + if (this->GetArena() != other.GetArena()) { CopyFrom(other); } else { InternalSwap(&other); @@ -2065,7 +2241,7 @@ inline void RepeatedPtrField::ExtractSubrangeInternal( if (num > 0) { // Save the values of the removed elements if requested. if (elements != NULL) { - if (GetArenaNoVirtual() != NULL) { + if (GetArena() != NULL) { // If we're on an arena, we perform a copy for each element so that the // returned elements are heap-allocated. for (int i = 0; i < num; ++i) { @@ -2095,7 +2271,7 @@ inline void RepeatedPtrField::ExtractSubrangeInternal( // ExtractSubrange() must return heap-allocated objects by contract, and we // cannot fulfill this contract if we are an on arena, we must GOOGLE_DCHECK() that // we are not on an arena. - GOOGLE_DCHECK(GetArenaNoVirtual() == NULL) + GOOGLE_DCHECK(GetArena() == NULL) << "ExtractSubrange() when arena is non-NULL is only supported when " << "the Element type supplies a MergeFrom() operation to make copies."; UnsafeArenaExtractSubrange(start, num, elements); @@ -2179,8 +2355,8 @@ inline void RepeatedPtrField::SwapElements(int index1, int index2) { } template -inline Arena* RepeatedPtrField::GetArenaNoVirtual() const { - return RepeatedPtrFieldBase::GetArenaNoVirtual(); +inline Arena* RepeatedPtrField::GetArena() const { + return RepeatedPtrFieldBase::GetArena(); } template @@ -2418,11 +2594,17 @@ class RepeatedPtrOverPtrsIterator { void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* other) { GOOGLE_DCHECK(this != other); - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); - - std::swap(rep_, other->rep_); - std::swap(current_size_, other->current_size_); - std::swap(total_size_, other->total_size_); + GOOGLE_DCHECK(GetArena() == other->GetArena()); + + // Swap all fields at once. + static_assert(std::is_standard_layout::value, + "offsetof() requires standard layout before c++17"); + internal::memswaprep_) - + offsetof(RepeatedPtrFieldBase, current_size_)>( + reinterpret_cast(this) + + offsetof(RepeatedPtrFieldBase, current_size_), + reinterpret_cast(other) + + offsetof(RepeatedPtrFieldBase, current_size_)); } } // namespace internal diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc index a04effa46caa..384d32f530df 100644 --- a/src/google/protobuf/repeated_field_reflection_unittest.cc +++ b/src/google/protobuf/repeated_field_reflection_unittest.cc @@ -52,11 +52,7 @@ namespace { static int Func(int i, int j) { return i * j; } -static std::string StrFunc(int i, int j) { - std::string str; - SStringPrintf(&str, "%d", Func(i, 4)); - return str; -} +static std::string StrFunc(int i, int j) { return StrCat(Func(i, 4)); } TEST(RepeatedFieldReflectionTest, RegularFields) { TestAllTypes message; diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index ca5452b8e902..a396b619f249 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -38,6 +38,8 @@ #include #include +#include +#include #include #include #include @@ -53,6 +55,9 @@ #include #include +// Must be included last. +#include + namespace google { namespace protobuf { namespace { @@ -60,6 +65,11 @@ namespace { using ::protobuf_unittest::TestAllTypes; using ::testing::ElementsAre; +TEST(RepeatedField, ConstInit) { + PROTOBUF_CONSTINIT static RepeatedField field{}; // NOLINT + EXPECT_TRUE(field.empty()); +} + // Test operations on a small RepeatedField. TEST(RepeatedField, Small) { RepeatedField field; @@ -268,6 +278,76 @@ TEST(RepeatedField, Resize) { EXPECT_TRUE(field.empty()); } +TEST(RepeatedField, ReserveNothing) { + RepeatedField field; + EXPECT_EQ(0, field.Capacity()); + + field.Reserve(-1); + EXPECT_EQ(0, field.Capacity()); +} + +TEST(RepeatedField, ReserveLowerClamp) { + const int clamped_value = internal::CalculateReserveSize(0, 1); + EXPECT_EQ(internal::kRepeatedFieldLowerClampLimit, clamped_value); + EXPECT_EQ(clamped_value, internal::CalculateReserveSize(clamped_value, 2)); +} + +TEST(RepeatedField, ReserveGrowth) { + // Make sure the field capacity doubles in size on repeated reservation. + for (int size = internal::kRepeatedFieldLowerClampLimit, i = 0; i < 4; + ++i, size *= 2) { + EXPECT_EQ(size * 2, internal::CalculateReserveSize(size, size + 1)); + } +} + +TEST(RepeatedField, ReserveLarge) { + const int old_size = 10; + // This is a size we won't get by doubling: + const int new_size = old_size * 3 + 1; + + // Reserving more than 2x current capacity should grow directly to that size. + EXPECT_EQ(new_size, internal::CalculateReserveSize(old_size, new_size)); +} + +TEST(RepeatedField, ReserveHuge) { + // Largest value that does not clamp to the large limit: + constexpr int non_clamping_limit = std::numeric_limits::max() / 2; + ASSERT_LT(2 * non_clamping_limit, std::numeric_limits::max()); + EXPECT_LT(internal::CalculateReserveSize(non_clamping_limit, + non_clamping_limit + 1), + std::numeric_limits::max()); + + // Smallest size that *will* clamp to the upper limit: + constexpr int min_clamping_size = std::numeric_limits::max() / 2 + 1; + EXPECT_EQ( + internal::CalculateReserveSize(min_clamping_size, min_clamping_size + 1), + std::numeric_limits::max()); + +#ifdef PROTOBUF_TEST_ALLOW_LARGE_ALLOC + // The rest of this test may allocate several GB of memory, so it is only + // built if explicitly requested. + RepeatedField huge_field; + + // Reserve a size for huge_field that will clamp. + huge_field.Reserve(min_clamping_size); + EXPECT_GE(huge_field.Capacity(), min_clamping_size); + ASSERT_LT(huge_field.Capacity(), std::numeric_limits::max() - 1); + +#ifndef ADDRESS_SANITIZER + // The array containing all the fields is, in theory, up to MAXINT-1 in size. + // However, some compilers can't handle a struct whose size is larger + // than 2GB, and the protocol buffer format doesn't handle more than 2GB of + // data at once, either. So we limit it, but the code below accesses beyond + // that limit. + + // Allocation may return more memory than we requested. However, the updated + // size must still be clamped to a valid range. + huge_field.Reserve(huge_field.Capacity() + 1); + EXPECT_EQ(huge_field.Capacity(), std::numeric_limits::max()); +#endif +#endif // PROTOBUF_TEST_ALLOW_LARGE_ALLOC +} + TEST(RepeatedField, MergeFrom) { RepeatedField source, destination; source.Add(4); @@ -740,10 +820,23 @@ TEST(RepeatedField, ClearThenReserveMore) { // strings. } +TEST(RepeatedField, TestSAddFromSelf) { + RepeatedField field; + field.Add(0); + for (int i = 0; i < 1000; i++) { + field.Add(field[0]); + } +} + // =================================================================== // RepeatedPtrField tests. These pretty much just mirror the RepeatedField // tests above. +TEST(RepeatedPtrField, ConstInit) { + PROTOBUF_CONSTINIT static RepeatedPtrField field{}; // NOLINT + EXPECT_TRUE(field.empty()); +} + TEST(RepeatedPtrField, Small) { RepeatedPtrField field; @@ -1997,3 +2090,5 @@ TEST_F(RepeatedFieldInsertionIteratorsTest, MoveProtos) { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index c8265f5e1822..fbd180477f97 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class SourceContextDefaultTypeInternal { public: @@ -28,7 +30,6 @@ static void InitDefaultsscc_info_SourceContext_google_2fprotobuf_2fsource_5fcont new (ptr) PROTOBUF_NAMESPACE_ID::SourceContext(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::SourceContext::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto = @@ -57,11 +58,10 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n$google/protobuf/source_context.proto\022\017" "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile" - "_name\030\001 \001(\tB\225\001\n\023com.google.protobufB\022Sou" - "rceContextProtoP\001ZAgoogle.golang.org/gen" - "proto/protobuf/source_context;source_con" - "text\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTy" - "pesb\006proto3" + "_name\030\001 \001(\tB\212\001\n\023com.google.protobufB\022Sou" + "rceContextProtoP\001Z6google.golang.org/pro" + "tobuf/types/known/sourcecontextpb\242\002\003GPB\252" + "\002\036Google.Protobuf.WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_deps[1] = { }; @@ -69,38 +69,36 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_SourceContext_google_2fprotobuf_2fsource_5fcontext_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto = { - &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto", 251, + false, false, descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto, "google/protobuf/source_context.proto", 240, &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once, descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_sccs, descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_deps, 1, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, file_level_service_descriptors_google_2fprotobuf_2fsource_5fcontext_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void SourceContext::InitAsDefaultInstance() { -} class SourceContext::_Internal { public: }; -SourceContext::SourceContext() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { +SourceContext::SourceContext(::PROTOBUF_NAMESPACE_ID::Arena* arena) + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.SourceContext) + RegisterArenaDtor(arena); + // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceContext) } SourceContext::SourceContext(const SourceContext& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); file_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_file_name().empty()) { - file_name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.file_name_); + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_file_name(), + GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceContext) } @@ -113,12 +111,20 @@ void SourceContext::SharedCtor() { SourceContext::~SourceContext() { // @@protoc_insertion_point(destructor:google.protobuf.SourceContext) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void SourceContext::SharedDtor() { + GOOGLE_DCHECK(GetArena() == nullptr); file_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } +void SourceContext::ArenaDtor(void* object) { + SourceContext* _this = reinterpret_cast< SourceContext* >(object); + (void)_this; +} +void SourceContext::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) { +} void SourceContext::SetCachedSize(int size) const { _cached_size_.Set(size); } @@ -134,8 +140,8 @@ void SourceContext::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - file_name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - _internal_metadata_.Clear(); + file_name_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* SourceContext::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { @@ -160,7 +166,9 @@ const char* SourceContext::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -192,7 +200,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* SourceContext::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceContext) return target; @@ -240,13 +248,12 @@ void SourceContext::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void SourceContext::MergeFrom(const SourceContext& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; if (from.file_name().size() > 0) { - - file_name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.file_name_); + _internal_set_file_name(from._internal_file_name()); } } @@ -270,9 +277,8 @@ bool SourceContext::IsInitialized() const { void SourceContext::InternalSwap(SourceContext* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - file_name_.Swap(&other->file_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + file_name_.Swap(&other->file_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } ::PROTOBUF_NAMESPACE_ID::Metadata SourceContext::GetMetadata() const { @@ -284,7 +290,7 @@ ::PROTOBUF_NAMESPACE_ID::Metadata SourceContext::GetMetadata() const { PROTOBUF_NAMESPACE_CLOSE PROTOBUF_NAMESPACE_OPEN template<> PROTOBUF_NOINLINE PROTOBUF_NAMESPACE_ID::SourceContext* Arena::CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::SourceContext >(Arena* arena) { - return Arena::CreateInternal< PROTOBUF_NAMESPACE_ID::SourceContext >(arena); + return Arena::CreateMessageInternal< PROTOBUF_NAMESPACE_ID::SourceContext >(arena); } PROTOBUF_NAMESPACE_CLOSE diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index c9c70c805226..b27ef5afcc98 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -45,7 +44,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -66,10 +65,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT SourceContext : +class PROTOBUF_EXPORT SourceContext PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ { public: - SourceContext(); + inline SourceContext() : SourceContext(nullptr) {} virtual ~SourceContext(); SourceContext(const SourceContext& from); @@ -83,7 +82,7 @@ class PROTOBUF_EXPORT SourceContext : return *this; } inline SourceContext& operator=(SourceContext&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -102,7 +101,6 @@ class PROTOBUF_EXPORT SourceContext : } static const SourceContext& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const SourceContext* internal_default_instance() { return reinterpret_cast( &_SourceContext_default_instance_); @@ -115,6 +113,15 @@ class PROTOBUF_EXPORT SourceContext : } inline void Swap(SourceContext* other) { if (other == this) return; + if (GetArena() == other->GetArena()) { + InternalSwap(other); + } else { + ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); + } + } + void UnsafeArenaSwap(SourceContext* other) { + if (other == this) return; + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -149,13 +156,11 @@ class PROTOBUF_EXPORT SourceContext : static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() { return "google.protobuf.SourceContext"; } + protected: + explicit SourceContext(::PROTOBUF_NAMESPACE_ID::Arena* arena); private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return nullptr; - } - inline void* MaybeArenaPtr() const { - return nullptr; - } + static void ArenaDtor(void* object); + inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -194,7 +199,9 @@ class PROTOBUF_EXPORT SourceContext : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; + template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr file_name_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_google_2fprotobuf_2fsource_5fcontext_2eproto; @@ -212,7 +219,7 @@ class PROTOBUF_EXPORT SourceContext : // string file_name = 1; inline void SourceContext::clear_file_name() { - file_name_.ClearToEmptyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + file_name_.ClearToEmpty(); } inline const std::string& SourceContext::file_name() const { // @@protoc_insertion_point(field_get:google.protobuf.SourceContext.file_name) @@ -227,38 +234,38 @@ inline std::string* SourceContext::mutable_file_name() { return _internal_mutable_file_name(); } inline const std::string& SourceContext::_internal_file_name() const { - return file_name_.GetNoArena(); + return file_name_.Get(); } inline void SourceContext::_internal_set_file_name(const std::string& value) { - file_name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value); + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void SourceContext::set_file_name(std::string&& value) { - file_name_.SetNoArena( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + file_name_.Set( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceContext.file_name) } inline void SourceContext::set_file_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - file_name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name) } -inline void SourceContext::set_file_name(const char* value, size_t size) { +inline void SourceContext::set_file_name(const char* value, + size_t size) { - file_name_.SetNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(reinterpret_cast(value), size)); + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceContext.file_name) } inline std::string* SourceContext::_internal_mutable_file_name() { - return file_name_.MutableNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return file_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* SourceContext::release_file_name() { // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name) - - return file_name_.ReleaseNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); + return file_name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void SourceContext::set_allocated_file_name(std::string* file_name) { if (file_name != nullptr) { @@ -266,7 +273,8 @@ inline void SourceContext::set_allocated_file_name(std::string* file_name) { } else { } - file_name_.SetAllocatedNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), file_name); + file_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), file_name, + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceContext.file_name) } diff --git a/src/google/protobuf/source_context.proto b/src/google/protobuf/source_context.proto index f3b2c966811f..06bfc43a78ec 100644 --- a/src/google/protobuf/source_context.proto +++ b/src/google/protobuf/source_context.proto @@ -37,7 +37,7 @@ option java_package = "com.google.protobuf"; option java_outer_classname = "SourceContextProto"; option java_multiple_files = true; option objc_class_prefix = "GPB"; -option go_package = "google.golang.org/genproto/protobuf/source_context;source_context"; +option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb"; // `SourceContext` represents information about the source of a // protobuf element, like the file in which it is defined. diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index 2ef6c2dc736c..396654cc1849 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fstruct_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto; PROTOBUF_NAMESPACE_OPEN class Struct_FieldsEntry_DoNotUseDefaultTypeInternal { @@ -27,12 +29,6 @@ class StructDefaultTypeInternal { class ValueDefaultTypeInternal { public: ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed _instance; - int null_value_; - double number_value_; - ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr string_value_; - bool bool_value_; - const PROTOBUF_NAMESPACE_ID::Struct* struct_value_; - const PROTOBUF_NAMESPACE_ID::ListValue* list_value_; } _Value_default_instance_; class ListValueDefaultTypeInternal { public: @@ -61,10 +57,6 @@ static void InitDefaultsscc_info_ListValue_google_2fprotobuf_2fstruct_2eproto() new (ptr) PROTOBUF_NAMESPACE_ID::ListValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Struct_FieldsEntry_DoNotUse::InitAsDefaultInstance(); - PROTOBUF_NAMESPACE_ID::Struct::InitAsDefaultInstance(); - PROTOBUF_NAMESPACE_ID::Value::InitAsDefaultInstance(); - PROTOBUF_NAMESPACE_ID::ListValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto = @@ -95,12 +87,12 @@ const ::PROTOBUF_NAMESPACE_ID::uint32 TableStruct_google_2fprotobuf_2fstruct_2ep ~0u, // no _extensions_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, _oneof_case_[0]), ~0u, // no _weak_field_map_ - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, null_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, number_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, string_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, bool_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, struct_value_), - offsetof(PROTOBUF_NAMESPACE_ID::ValueDefaultTypeInternal, list_value_), + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, + ::PROTOBUF_NAMESPACE_ID::internal::kInvalidFieldOffsetTag, PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::Value, kind_), ~0u, // no _has_bits_ PROTOBUF_FIELD_OFFSET(PROTOBUF_NAMESPACE_ID::ListValue, _internal_metadata_), @@ -136,11 +128,10 @@ const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] PROTOB "\000\0220\n\nlist_value\030\006 \001(\0132\032.google.protobuf." "ListValueH\000B\006\n\004kind\"3\n\tListValue\022&\n\006valu" "es\030\001 \003(\0132\026.google.protobuf.Value*\033\n\tNull" - "Value\022\016\n\nNULL_VALUE\020\000B\201\001\n\023com.google.pro" - "tobufB\013StructProtoP\001Z1github.com/golang/" - "protobuf/ptypes/struct;structpb\370\001\001\242\002\003GPB" - "\252\002\036Google.Protobuf.WellKnownTypesb\006proto" - "3" + "Value\022\016\n\nNULL_VALUE\020\000B\177\n\023com.google.prot" + "obufB\013StructProtoP\001Z/google.golang.org/p" + "rotobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036" + "Google.Protobuf.WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fstruct_2eproto_deps[1] = { }; @@ -148,16 +139,15 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_ListValue_google_2fprotobuf_2fstruct_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fstruct_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fstruct_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eproto = { - &descriptor_table_google_2fprotobuf_2fstruct_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto", 641, + false, false, descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto, "google/protobuf/struct.proto", 638, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, descriptor_table_google_2fprotobuf_2fstruct_2eproto_sccs, descriptor_table_google_2fprotobuf_2fstruct_2eproto_deps, 1, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fstruct_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fstruct_2eproto, 4, file_level_enum_descriptors_google_2fprotobuf_2fstruct_2eproto, file_level_service_descriptors_google_2fprotobuf_2fstruct_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto(&descriptor_table_google_2fprotobuf_2fstruct_2eproto); PROTOBUF_NAMESPACE_OPEN const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullValue_descriptor() { ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto); @@ -192,29 +182,20 @@ void Struct_FieldsEntry_DoNotUse::MergeFrom( // =================================================================== -void Struct::InitAsDefaultInstance() { -} class Struct::_Internal { public: }; -Struct::Struct() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Struct) -} Struct::Struct(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), fields_(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct) } Struct::Struct(const Struct& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); fields_.MergeFrom(from.fields_); // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct) } @@ -226,10 +207,11 @@ void Struct::SharedCtor() { Struct::~Struct() { // @@protoc_insertion_point(destructor:google.protobuf.Struct) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Struct::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void Struct::ArenaDtor(void* object) { @@ -254,12 +236,11 @@ void Struct::Clear() { (void) cached_has_bits; fields_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Struct::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -283,7 +264,9 @@ const char* Struct::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -346,7 +329,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Struct::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Struct) return target; @@ -396,7 +379,7 @@ void Struct::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Struct::MergeFrom(const Struct& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -423,7 +406,7 @@ bool Struct::IsInitialized() const { void Struct::InternalSwap(Struct* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); fields_.Swap(&other->fields_); } @@ -434,17 +417,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Struct::GetMetadata() const { // =================================================================== -void Value::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.null_value_ = 0; - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.number_value_ = 0; - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.string_value_.UnsafeSetDefault( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.bool_value_ = false; - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.struct_value_ = const_cast< PROTOBUF_NAMESPACE_ID::Struct*>( - PROTOBUF_NAMESPACE_ID::Struct::internal_default_instance()); - PROTOBUF_NAMESPACE_ID::_Value_default_instance_.list_value_ = const_cast< PROTOBUF_NAMESPACE_ID::ListValue*>( - PROTOBUF_NAMESPACE_ID::ListValue::internal_default_instance()); -} class Value::_Internal { public: static const PROTOBUF_NAMESPACE_ID::Struct& struct_value(const Value* msg); @@ -460,7 +432,7 @@ Value::_Internal::list_value(const Value* msg) { return *msg->kind_.list_value_; } void Value::set_allocated_struct_value(PROTOBUF_NAMESPACE_ID::Struct* struct_value) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); clear_kind(); if (struct_value) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = @@ -475,7 +447,7 @@ void Value::set_allocated_struct_value(PROTOBUF_NAMESPACE_ID::Struct* struct_val // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value) } void Value::set_allocated_list_value(PROTOBUF_NAMESPACE_ID::ListValue* list_value) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); clear_kind(); if (list_value) { ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = @@ -489,22 +461,15 @@ void Value::set_allocated_list_value(PROTOBUF_NAMESPACE_ID::ListValue* list_valu } // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value) } -Value::Value() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Value) -} Value::Value(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Value) } Value::Value(const Value& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); clear_has_kind(); switch (from.kind_case()) { case kNullValue: { @@ -546,10 +511,11 @@ void Value::SharedCtor() { Value::~Value() { // @@protoc_insertion_point(destructor:google.protobuf.Value) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Value::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); if (has_kind()) { clear_kind(); } @@ -582,8 +548,7 @@ void Value::clear_kind() { break; } case kStringValue: { - kind_.string_value_.Destroy(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); break; } case kBoolValue: { @@ -591,13 +556,13 @@ void Value::clear_kind() { break; } case kStructValue: { - if (GetArenaNoVirtual() == nullptr) { + if (GetArena() == nullptr) { delete kind_.struct_value_; } break; } case kListValue: { - if (GetArenaNoVirtual() == nullptr) { + if (GetArena() == nullptr) { delete kind_.list_value_; } break; @@ -617,12 +582,11 @@ void Value::Clear() { (void) cached_has_bits; clear_kind(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -679,7 +643,9 @@ const char* Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -746,7 +712,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Value::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value) return target; @@ -829,7 +795,7 @@ void Value::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Value::MergeFrom(const Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -884,7 +850,7 @@ bool Value::IsInitialized() const { void Value::InternalSwap(Value* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(kind_, other->kind_); swap(_oneof_case_[0], other->_oneof_case_[0]); } @@ -896,20 +862,12 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Value::GetMetadata() const { // =================================================================== -void ListValue::InitAsDefaultInstance() { -} class ListValue::_Internal { public: }; -ListValue::ListValue() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.ListValue) -} ListValue::ListValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), values_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -917,9 +875,8 @@ ListValue::ListValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) } ListValue::ListValue(const ListValue& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), values_(from.values_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue) } @@ -930,10 +887,11 @@ void ListValue::SharedCtor() { ListValue::~ListValue() { // @@protoc_insertion_point(destructor:google.protobuf.ListValue) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void ListValue::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void ListValue::ArenaDtor(void* object) { @@ -958,12 +916,11 @@ void ListValue::Clear() { (void) cached_has_bits; values_.Clear(); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* ListValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -987,7 +944,9 @@ const char* ListValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID:: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1017,7 +976,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* ListValue::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue) return target; @@ -1065,7 +1024,7 @@ void ListValue::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void ListValue::MergeFrom(const ListValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1092,7 +1051,7 @@ bool ListValue::IsInitialized() const { void ListValue::InternalSwap(ListValue* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); values_.InternalSwap(&other->values_); } diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 9d2ccb201627..4fda4f3d157a 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -49,7 +48,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fstruct_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[4] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -100,7 +99,7 @@ inline const std::string& NullValue_Name(T enum_t_value) { NullValue_descriptor(), enum_t_value); } inline bool NullValue_Parse( - const std::string& name, NullValue* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, NullValue* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( NullValue_descriptor(), name, value); } @@ -109,16 +108,14 @@ inline bool NullValue_Parse( class Struct_FieldsEntry_DoNotUse : public ::PROTOBUF_NAMESPACE_ID::internal::MapEntry { + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> { public: typedef ::PROTOBUF_NAMESPACE_ID::internal::MapEntry SuperType; + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> SuperType; Struct_FieldsEntry_DoNotUse(); - Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena); + explicit Struct_FieldsEntry_DoNotUse(::PROTOBUF_NAMESPACE_ID::Arena* arena); void MergeFrom(const Struct_FieldsEntry_DoNotUse& other); static const Struct_FieldsEntry_DoNotUse* internal_default_instance() { return reinterpret_cast(&_Struct_FieldsEntry_DoNotUse_default_instance_); } static bool ValidateKey(std::string* s) { @@ -138,10 +135,10 @@ class Struct_FieldsEntry_DoNotUse : public ::PROTOBUF_NAMESPACE_ID::internal::Ma // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Struct : +class PROTOBUF_EXPORT Struct PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ { public: - Struct(); + inline Struct() : Struct(nullptr) {} virtual ~Struct(); Struct(const Struct& from); @@ -155,7 +152,7 @@ class PROTOBUF_EXPORT Struct : return *this; } inline Struct& operator=(Struct&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -163,12 +160,6 @@ class PROTOBUF_EXPORT Struct : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -180,7 +171,6 @@ class PROTOBUF_EXPORT Struct : } static const Struct& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Struct* internal_default_instance() { return reinterpret_cast( &_Struct_default_instance_); @@ -193,7 +183,7 @@ class PROTOBUF_EXPORT Struct : } inline void Swap(Struct* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -201,7 +191,7 @@ class PROTOBUF_EXPORT Struct : } void UnsafeArenaSwap(Struct* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -241,13 +231,6 @@ class PROTOBUF_EXPORT Struct : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -288,7 +271,6 @@ class PROTOBUF_EXPORT Struct : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -296,17 +278,16 @@ class PROTOBUF_EXPORT Struct : Struct_FieldsEntry_DoNotUse, std::string, PROTOBUF_NAMESPACE_ID::Value, ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_STRING, - ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE, - 0 > fields_; + ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::TYPE_MESSAGE> fields_; mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_; friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Value : +class PROTOBUF_EXPORT Value PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ { public: - Value(); + inline Value() : Value(nullptr) {} virtual ~Value(); Value(const Value& from); @@ -320,7 +301,7 @@ class PROTOBUF_EXPORT Value : return *this; } inline Value& operator=(Value&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -328,12 +309,6 @@ class PROTOBUF_EXPORT Value : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -355,7 +330,6 @@ class PROTOBUF_EXPORT Value : KIND_NOT_SET = 0, }; - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Value* internal_default_instance() { return reinterpret_cast( &_Value_default_instance_); @@ -368,7 +342,7 @@ class PROTOBUF_EXPORT Value : } inline void Swap(Value* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -376,7 +350,7 @@ class PROTOBUF_EXPORT Value : } void UnsafeArenaSwap(Value* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -416,13 +390,6 @@ class PROTOBUF_EXPORT Value : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -483,15 +450,6 @@ class PROTOBUF_EXPORT Value : std::string* mutable_string_value(); std::string* release_string_value(); void set_allocated_string_value(std::string* string_value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_string_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_string_value( - std::string* string_value); private: const std::string& _internal_string_value() const; void _internal_set_string_value(const std::string& value); @@ -561,7 +519,6 @@ class PROTOBUF_EXPORT Value : inline bool has_kind() const; inline void clear_has_kind(); - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -581,10 +538,10 @@ class PROTOBUF_EXPORT Value : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT ListValue : +class PROTOBUF_EXPORT ListValue PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ { public: - ListValue(); + inline ListValue() : ListValue(nullptr) {} virtual ~ListValue(); ListValue(const ListValue& from); @@ -598,7 +555,7 @@ class PROTOBUF_EXPORT ListValue : return *this; } inline ListValue& operator=(ListValue&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -606,12 +563,6 @@ class PROTOBUF_EXPORT ListValue : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -623,7 +574,6 @@ class PROTOBUF_EXPORT ListValue : } static const ListValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const ListValue* internal_default_instance() { return reinterpret_cast( &_ListValue_default_instance_); @@ -636,7 +586,7 @@ class PROTOBUF_EXPORT ListValue : } inline void Swap(ListValue* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -644,7 +594,7 @@ class PROTOBUF_EXPORT ListValue : } void UnsafeArenaSwap(ListValue* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -684,13 +634,6 @@ class PROTOBUF_EXPORT ListValue : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -731,7 +674,6 @@ class PROTOBUF_EXPORT ListValue : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -864,8 +806,7 @@ inline void Value::set_has_string_value() { } inline void Value::clear_string_value() { if (_internal_has_string_value()) { - kind_.string_value_.Destroy(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); clear_has_kind(); } } @@ -885,7 +826,7 @@ inline const std::string& Value::_internal_string_value() const { if (_internal_has_string_value()) { return kind_.string_value_.Get(); } - return *&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(); + return ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(); } inline void Value::_internal_set_string_value(const std::string& value) { if (!_internal_has_string_value()) { @@ -893,8 +834,7 @@ inline void Value::_internal_set_string_value(const std::string& value) { set_has_string_value(); kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } - kind_.string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, - GetArenaNoVirtual()); + kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Value::set_string_value(std::string&& value) { // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) @@ -904,7 +844,7 @@ inline void Value::set_string_value(std::string&& value) { kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } kind_.string_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Value.string_value) } inline void Value::set_string_value(const char* value) { @@ -914,8 +854,8 @@ inline void Value::set_string_value(const char* value) { set_has_string_value(); kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } - kind_.string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - ::std::string(value), GetArenaNoVirtual()); + kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, + ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Value.string_value) } inline void Value::set_string_value(const char* value, @@ -926,9 +866,9 @@ inline void Value::set_string_value(const char* value, kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } kind_.string_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Value.string_value) } inline std::string* Value::_internal_mutable_string_value() { @@ -937,15 +877,14 @@ inline std::string* Value::_internal_mutable_string_value() { set_has_string_value(); kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } - return kind_.string_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + return kind_.string_value_.Mutable( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Value::release_string_value() { // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value) if (_internal_has_string_value()) { clear_has_kind(); - return kind_.string_value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + return kind_.string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } else { return nullptr; } @@ -957,32 +896,13 @@ inline void Value::set_allocated_string_value(std::string* string_value) { if (string_value != nullptr) { set_has_string_value(); kind_.string_value_.UnsafeSetDefault(string_value); + ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArena(); + if (arena != nullptr) { + arena->Own(string_value); + } } // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value) } -inline std::string* Value::unsafe_arena_release_string_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Value.string_value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (_internal_has_string_value()) { - clear_has_kind(); - return kind_.string_value_.UnsafeArenaRelease( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - } else { - return nullptr; - } -} -inline void Value::unsafe_arena_set_allocated_string_value(std::string* string_value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (!_internal_has_string_value()) { - kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - } - clear_kind(); - if (string_value) { - set_has_string_value(); - kind_.string_value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), string_value, GetArenaNoVirtual()); - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Value.string_value) -} // bool bool_value = 4; inline bool Value::_internal_has_bool_value() const { @@ -1031,7 +951,7 @@ inline void Value::set_has_struct_value() { } inline void Value::clear_struct_value() { if (_internal_has_struct_value()) { - if (GetArenaNoVirtual() == nullptr) { + if (GetArena() == nullptr) { delete kind_.struct_value_; } clear_has_kind(); @@ -1042,7 +962,7 @@ inline PROTOBUF_NAMESPACE_ID::Struct* Value::release_struct_value() { if (_internal_has_struct_value()) { clear_has_kind(); PROTOBUF_NAMESPACE_ID::Struct* temp = kind_.struct_value_; - if (GetArenaNoVirtual() != nullptr) { + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } kind_.struct_value_ = nullptr; @@ -1054,7 +974,7 @@ inline PROTOBUF_NAMESPACE_ID::Struct* Value::release_struct_value() { inline const PROTOBUF_NAMESPACE_ID::Struct& Value::_internal_struct_value() const { return _internal_has_struct_value() ? *kind_.struct_value_ - : *reinterpret_cast< PROTOBUF_NAMESPACE_ID::Struct*>(&PROTOBUF_NAMESPACE_ID::_Struct_default_instance_); + : reinterpret_cast< PROTOBUF_NAMESPACE_ID::Struct&>(PROTOBUF_NAMESPACE_ID::_Struct_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::Struct& Value::struct_value() const { // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value) @@ -1083,8 +1003,7 @@ inline PROTOBUF_NAMESPACE_ID::Struct* Value::_internal_mutable_struct_value() { if (!_internal_has_struct_value()) { clear_kind(); set_has_struct_value(); - kind_.struct_value_ = CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::Struct >( - GetArenaNoVirtual()); + kind_.struct_value_ = CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::Struct >(GetArena()); } return kind_.struct_value_; } @@ -1105,7 +1024,7 @@ inline void Value::set_has_list_value() { } inline void Value::clear_list_value() { if (_internal_has_list_value()) { - if (GetArenaNoVirtual() == nullptr) { + if (GetArena() == nullptr) { delete kind_.list_value_; } clear_has_kind(); @@ -1116,7 +1035,7 @@ inline PROTOBUF_NAMESPACE_ID::ListValue* Value::release_list_value() { if (_internal_has_list_value()) { clear_has_kind(); PROTOBUF_NAMESPACE_ID::ListValue* temp = kind_.list_value_; - if (GetArenaNoVirtual() != nullptr) { + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } kind_.list_value_ = nullptr; @@ -1128,7 +1047,7 @@ inline PROTOBUF_NAMESPACE_ID::ListValue* Value::release_list_value() { inline const PROTOBUF_NAMESPACE_ID::ListValue& Value::_internal_list_value() const { return _internal_has_list_value() ? *kind_.list_value_ - : *reinterpret_cast< PROTOBUF_NAMESPACE_ID::ListValue*>(&PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_); + : reinterpret_cast< PROTOBUF_NAMESPACE_ID::ListValue&>(PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::ListValue& Value::list_value() const { // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value) @@ -1157,8 +1076,7 @@ inline PROTOBUF_NAMESPACE_ID::ListValue* Value::_internal_mutable_list_value() { if (!_internal_has_list_value()) { clear_kind(); set_has_list_value(); - kind_.list_value_ = CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::ListValue >( - GetArenaNoVirtual()); + kind_.list_value_ = CreateMaybeMessage< PROTOBUF_NAMESPACE_ID::ListValue >(GetArena()); } return kind_.list_value_; } diff --git a/src/google/protobuf/struct.proto b/src/google/protobuf/struct.proto index ed990e31d959..545215c25276 100644 --- a/src/google/protobuf/struct.proto +++ b/src/google/protobuf/struct.proto @@ -34,7 +34,7 @@ package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes"; option cc_enable_arenas = true; -option go_package = "github.com/golang/protobuf/ptypes/struct;structpb"; +option go_package = "google.golang.org/protobuf/types/known/structpb"; option java_package = "com.google.protobuf"; option java_outer_classname = "StructProto"; option java_multiple_files = true; diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h index 0193301a225e..c7a48dea544a 100644 --- a/src/google/protobuf/stubs/bytestream.h +++ b/src/google/protobuf/stubs/bytestream.h @@ -256,11 +256,11 @@ class PROTOBUF_EXPORT GrowingArrayByteSink : public strings::ByteSink { // class PROTOBUF_EXPORT StringByteSink : public ByteSink { public: - explicit StringByteSink(string* dest) : dest_(dest) {} + explicit StringByteSink(std::string* dest) : dest_(dest) {} virtual void Append(const char* data, size_t n) override; private: - string* dest_; + std::string* dest_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringByteSink); }; diff --git a/src/google/protobuf/stubs/bytestream_unittest.cc b/src/google/protobuf/stubs/bytestream_unittest.cc index 06f114abc702..cb11825ef72e 100644 --- a/src/google/protobuf/stubs/bytestream_unittest.cc +++ b/src/google/protobuf/stubs/bytestream_unittest.cc @@ -64,7 +64,7 @@ class MockByteSource : public ByteSource { TEST(ByteSourceTest, CopyTo) { StringPiece data("Hello world!"); MockByteSource source(data, 3); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size()); @@ -75,7 +75,7 @@ TEST(ByteSourceTest, CopySubstringTo) { StringPiece data("Hello world!"); MockByteSource source(data, 3); source.Skip(1); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size() - 2); @@ -92,7 +92,7 @@ TEST(ByteSourceTest, LimitByteSource) { EXPECT_EQ(5, limit_source.Available()); { - string str; + std::string str; StringByteSink sink(&str); limit_source.CopyTo(&sink, limit_source.Available()); EXPECT_EQ("ello ", str); @@ -101,7 +101,7 @@ TEST(ByteSourceTest, LimitByteSource) { } { - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, source.Available()); EXPECT_EQ("world!", str); @@ -112,7 +112,7 @@ TEST(ByteSourceTest, LimitByteSource) { TEST(ByteSourceTest, CopyToStringByteSink) { StringPiece data("Hello world!"); MockByteSource source(data, 3); - string str; + std::string str; StringByteSink sink(&str); source.CopyTo(&sink, data.size()); EXPECT_EQ(data, str); @@ -121,7 +121,7 @@ TEST(ByteSourceTest, CopyToStringByteSink) { // Verify that ByteSink is subclassable and Flush() overridable. class FlushingByteSink : public StringByteSink { public: - explicit FlushingByteSink(string* dest) : StringByteSink(dest) {} + explicit FlushingByteSink(std::string* dest) : StringByteSink(dest) {} virtual void Flush() { Append("z", 1); } private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FlushingByteSink); @@ -134,7 +134,7 @@ void WriteAndFlush(ByteSink* s) { } TEST(ByteSinkTest, Flush) { - string str; + std::string str; FlushingByteSink f_sink(&str); WriteAndFlush(&f_sink); EXPECT_STREQ("abcz", str.c_str()); diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h index b7a3a82910e1..43d546d19987 100644 --- a/src/google/protobuf/stubs/callback.h +++ b/src/google/protobuf/stubs/callback.h @@ -62,12 +62,12 @@ namespace protobuf { // Note that NewCallback() is a bit touchy regarding argument types. Generally, // the values you provide for the parameter bindings must exactly match the // types accepted by the callback function. For example: -// void Foo(string s); +// void Foo(std::string s); // NewCallback(&Foo, "foo"); // WON'T WORK: const char* != string -// NewCallback(&Foo, string("foo")); // WORKS +// NewCallback(&Foo, std::string("foo")); // WORKS // Also note that the arguments cannot be references: -// void Foo(const string& s); -// string my_str; +// void Foo(const std::string& s); +// std::string my_str; // NewCallback(&Foo, my_str); // WON'T WORK: Can't use references. // However, correctly-typed pointers will work just fine. class PROTOBUF_EXPORT Closure { diff --git a/src/google/protobuf/stubs/casts.h b/src/google/protobuf/stubs/casts.h index b509f68cd39a..d8a49cec34b2 100644 --- a/src/google/protobuf/stubs/casts.h +++ b/src/google/protobuf/stubs/casts.h @@ -31,13 +31,15 @@ #ifndef GOOGLE_PROTOBUF_CASTS_H__ #define GOOGLE_PROTOBUF_CASTS_H__ -#include - #include +#include +#include + namespace google { namespace protobuf { namespace internal { + // Use implicit_cast as a safe version of static_cast or const_cast // for upcasting in the type hierarchy (i.e. casting a pointer to Foo // to a pointer to SuperclassOfFoo or casting a pointer to Foo to @@ -45,7 +47,7 @@ namespace internal { // When you use implicit_cast, the compiler checks that the cast is safe. // Such explicit implicit_casts are necessary in surprisingly many // situations where C++ demands an exact type match instead of an -// argument type convertable to a target type. +// argument type convertible to a target type. // // The From type can be inferred, so the preferred syntax for using // implicit_cast is the same as for static_cast etc.: @@ -88,7 +90,7 @@ inline To down_cast(From* f) { // so we only accept pointers implicit_cast(0); } -#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI) +#if !defined(NDEBUG) && PROTOBUF_RTTI assert(f == nullptr || dynamic_cast(f) != nullptr); // RTTI: debug mode only! #endif return static_cast(f); @@ -105,7 +107,7 @@ inline To down_cast(From& f) { implicit_cast(0); } -#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI) +#if !defined(NDEBUG) && PROTOBUF_RTTI // RTTI: debug mode only! assert(dynamic_cast(&f) != nullptr); #endif @@ -131,4 +133,7 @@ using internal::bit_cast; } // namespace protobuf } // namespace google + +#include + #endif // GOOGLE_PROTOBUF_CASTS_H__ diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index 4db493b70c49..f2859e94bbee 100644 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -96,7 +96,7 @@ void VerifyVersion(int headerVersion, } } -string VersionString(int version) { +std::string VersionString(int version) { int major = version / 1000000; int minor = (version / 1000) % 1000; int micro = version % 1000; @@ -127,7 +127,7 @@ namespace internal { #if defined(__ANDROID__) inline void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { return; } @@ -162,7 +162,7 @@ inline void DefaultLogHandler(LogLevel level, const char* filename, int line, #else void DefaultLogHandler(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) { return; } @@ -177,14 +177,14 @@ void DefaultLogHandler(LogLevel level, const char* filename, int line, #endif void NullLogHandler(LogLevel /* level */, const char* /* filename */, - int /* line */, const string& /* message */) { + int /* line */, const std::string& /* message */) { // Nothing. } static LogHandler* log_handler_ = &DefaultLogHandler; static std::atomic log_silencer_count_ = ATOMIC_VAR_INIT(0); -LogMessage& LogMessage::operator<<(const string& value) { +LogMessage& LogMessage::operator<<(const std::string& value) { message_ += value; return *this; } @@ -304,7 +304,7 @@ void DoNothing() {} // // TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in // google/protobuf/io/coded_stream.h and therefore can not be used here. -// Maybe move that macro definition here in the furture. +// Maybe move that macro definition here in the future. uint32 ghtonl(uint32 x) { union { uint32 result; @@ -327,3 +327,5 @@ const char* FatalException::what() const throw() { } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index ef7ace93f5e8..2d210d727c40 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -43,9 +43,10 @@ #include #include -#include #include #include +#include +#include #ifndef PROTOBUF_USE_EXCEPTIONS #if defined(_MSC_VER) && defined(_CPPUNWIND) @@ -81,7 +82,7 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 3011002 +#define GOOGLE_PROTOBUF_VERSION 3014000 // A suffix string for alpha, beta or rc releases. Empty for stable releases. #define GOOGLE_PROTOBUF_VERSION_SUFFIX "" @@ -89,15 +90,15 @@ namespace internal { // The minimum header version which works with the current version of // the library. This constant should only be used by protoc's C++ code // generator. -static const int kMinHeaderVersionForLibrary = 3011000; +static const int kMinHeaderVersionForLibrary = 3014000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3011000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3014000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 3011000; +static const int kMinHeaderVersionForProtoc = 3014000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. @@ -129,12 +130,12 @@ namespace internal { // structurally_valid.cc. PROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len); -inline bool IsStructurallyValidUTF8(const std::string& str) { +inline bool IsStructurallyValidUTF8(StringPiece str) { return IsStructurallyValidUTF8(str.data(), static_cast(str.length())); } // Returns initial number of bytes of structurally valid UTF-8. -PROTOBUF_EXPORT int UTF8SpnStructurallyValid(const StringPiece& str); +PROTOBUF_EXPORT int UTF8SpnStructurallyValid(StringPiece str); // Coerce UTF-8 byte string in src_str to be // a structurally-valid equal-length string by selectively @@ -148,8 +149,7 @@ PROTOBUF_EXPORT int UTF8SpnStructurallyValid(const StringPiece& str); // // Optimized for: all structurally valid and no byte copying is done. // -PROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid(const StringPiece& str, - char* dst, +PROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid(StringPiece str, char* dst, char replace_char); } // namespace internal diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc index 585245892299..c55e45250574 100644 --- a/src/google/protobuf/stubs/common_unittest.cc +++ b/src/google/protobuf/stubs/common_unittest.cc @@ -53,7 +53,7 @@ TEST(VersionTest, VersionMatchesConfig) { // Verify that the version string specified in config.h matches the one // in common.h. The config.h version is a string which may have a suffix // like "beta" or "rc1", so we remove that. - string version = PACKAGE_VERSION; + std::string version = PACKAGE_VERSION; int pos = 0; while (pos < version.size() && (ascii_isdigit(version[pos]) || version[pos] == '.')) { @@ -77,10 +77,10 @@ TEST(CommonTest, IntMinMaxConstants) { EXPECT_EQ(0, kuint64max + 1); } -std::vector captured_messages_; +std::vector captured_messages_; void CaptureLog(LogLevel level, const char* filename, int line, - const string& message) { + const std::string& message) { captured_messages_.push_back( strings::Substitute("$0 $1:$2: $3", implicit_cast(level), filename, line, message)); @@ -93,7 +93,7 @@ TEST(LoggingTest, DefaultLogging) { GOOGLE_LOG(WARNING) << "A warning."; GOOGLE_LOG(ERROR ) << "An error."; - string text = GetCapturedTestStderr(); + std::string text = GetCapturedTestStderr(); EXPECT_EQ( "[libprotobuf INFO " __FILE__ ":" + SimpleItoa(line + 1) + "] A message.\n" "[libprotobuf WARNING " __FILE__ ":" + SimpleItoa(line + 2) + "] A warning.\n" @@ -111,7 +111,7 @@ TEST(LoggingTest, NullLogging) { EXPECT_TRUE(SetLogHandler(old_handler) == nullptr); - string text = GetCapturedTestStderr(); + std::string text = GetCapturedTestStderr(); EXPECT_EQ("", text); } @@ -167,10 +167,10 @@ class ClosureTest : public testing::Test { static void SetA123Function() { current_instance_->a_ = 123; } void SetAMethod(int a) { a_ = a; } - void SetCMethod(string c) { c_ = c; } + void SetCMethod(std::string c) { c_ = c; } static void SetAFunction(int a) { current_instance_->a_ = a; } - static void SetCFunction(string c) { current_instance_->c_ = c; } + static void SetCFunction(std::string c) { current_instance_->c_ = c; } void SetABMethod(int a, const char* b) { a_ = a; b_ = b; } static void SetABFunction(int a, const char* b) { @@ -192,7 +192,7 @@ class ClosureTest : public testing::Test { int a_; const char* b_; - string c_; + std::string c_; Closure* permanent_closure_; static ClosureTest* current_instance_; @@ -231,15 +231,15 @@ TEST_F(ClosureTest, TestClosureMethod1) { } TEST_F(ClosureTest, TestClosureFunction1String) { - Closure* closure = NewCallback(&SetCFunction, string("test")); + Closure* closure = NewCallback(&SetCFunction, std::string("test")); EXPECT_NE("test", c_); closure->Run(); EXPECT_EQ("test", c_); } TEST_F(ClosureTest, TestClosureMethod1String) { - Closure* closure = NewCallback(current_instance_, - &ClosureTest::SetCMethod, string("test")); + Closure* closure = NewCallback(current_instance_, &ClosureTest::SetCMethod, + std::string("test")); EXPECT_NE("test", c_); closure->Run(); EXPECT_EQ("test", c_); diff --git a/src/google/protobuf/stubs/fastmem.h b/src/google/protobuf/stubs/fastmem.h deleted file mode 100644 index 76c8a3aea688..000000000000 --- a/src/google/protobuf/stubs/fastmem.h +++ /dev/null @@ -1,157 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2014 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. - -// Fast memory copying and comparison routines. -// strings::fastmemcmp_inlined() replaces memcmp() -// strings::memcpy_inlined() replaces memcpy() -// strings::memeq(a, b, n) replaces memcmp(a, b, n) == 0 -// -// strings::*_inlined() routines are inline versions of the -// routines exported by this module. Sometimes using the inlined -// versions is faster. Measure before using the inlined versions. -// -// Performance measurement: -// strings::fastmemcmp_inlined -// Analysis: memcmp, fastmemcmp_inlined, fastmemcmp -// 2012-01-30 - -#ifndef GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ -#define GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ - -#include -#include -#include - -#include - -#include - -namespace google { -namespace protobuf { -namespace internal { - -// Return true if the n bytes at a equal the n bytes at b. -// The regions are allowed to overlap. -// -// The performance is similar to the performance memcmp(), but faster for -// moderately-sized inputs, or inputs that share a common prefix and differ -// somewhere in their last 8 bytes. Further optimizations can be added later -// if it makes sense to do so.:w -inline bool memeq(const char* a, const char* b, size_t n) { - size_t n_rounded_down = n & ~static_cast(7); - if (PROTOBUF_PREDICT_FALSE(n_rounded_down == 0)) { // n <= 7 - return memcmp(a, b, n) == 0; - } - // n >= 8 - uint64 u = GOOGLE_UNALIGNED_LOAD64(a) ^ GOOGLE_UNALIGNED_LOAD64(b); - uint64 v = GOOGLE_UNALIGNED_LOAD64(a + n - 8) ^ GOOGLE_UNALIGNED_LOAD64(b + n - 8); - if ((u | v) != 0) { // The first or last 8 bytes differ. - return false; - } - a += 8; - b += 8; - n = n_rounded_down - 8; - if (n > 128) { - // As of 2012, memcmp on x86-64 uses a big unrolled loop with SSE2 - // instructions, and while we could try to do something faster, it - // doesn't seem worth pursuing. - return memcmp(a, b, n) == 0; - } - for (; n >= 16; n -= 16) { - uint64 x = GOOGLE_UNALIGNED_LOAD64(a) ^ GOOGLE_UNALIGNED_LOAD64(b); - uint64 y = GOOGLE_UNALIGNED_LOAD64(a + 8) ^ GOOGLE_UNALIGNED_LOAD64(b + 8); - if ((x | y) != 0) { - return false; - } - a += 16; - b += 16; - } - // n must be 0 or 8 now because it was a multiple of 8 at the top of the loop. - return n == 0 || GOOGLE_UNALIGNED_LOAD64(a) == GOOGLE_UNALIGNED_LOAD64(b); -} - -inline int fastmemcmp_inlined(const char *a, const char *b, size_t n) { - if (n >= 64) { - return memcmp(a, b, n); - } - const char* a_limit = a + n; - while (a + sizeof(uint64) <= a_limit && - GOOGLE_UNALIGNED_LOAD64(a) == GOOGLE_UNALIGNED_LOAD64(b)) { - a += sizeof(uint64); - b += sizeof(uint64); - } - if (a + sizeof(uint32) <= a_limit && - GOOGLE_UNALIGNED_LOAD32(a) == GOOGLE_UNALIGNED_LOAD32(b)) { - a += sizeof(uint32); - b += sizeof(uint32); - } - while (a < a_limit) { - int d = - static_cast(static_cast(*a++) - static_cast(*b++)); - if (d) return d; - } - return 0; -} - -// The standard memcpy operation is slow for variable small sizes. -// This implementation inlines the optimal realization for sizes 1 to 16. -// To avoid code bloat don't use it in case of not performance-critical spots, -// nor when you don't expect very frequent values of size <= 16. -inline void memcpy_inlined(char *dst, const char *src, size_t size) { - // Compiler inlines code with minimal amount of data movement when third - // parameter of memcpy is a constant. - switch (size) { - case 1: memcpy(dst, src, 1); break; - case 2: memcpy(dst, src, 2); break; - case 3: memcpy(dst, src, 3); break; - case 4: memcpy(dst, src, 4); break; - case 5: memcpy(dst, src, 5); break; - case 6: memcpy(dst, src, 6); break; - case 7: memcpy(dst, src, 7); break; - case 8: memcpy(dst, src, 8); break; - case 9: memcpy(dst, src, 9); break; - case 10: memcpy(dst, src, 10); break; - case 11: memcpy(dst, src, 11); break; - case 12: memcpy(dst, src, 12); break; - case 13: memcpy(dst, src, 13); break; - case 14: memcpy(dst, src, 14); break; - case 15: memcpy(dst, src, 15); break; - case 16: memcpy(dst, src, 16); break; - default: memcpy(dst, src, size); break; - } -} - -} // namespace internal -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h index a093b406cf64..a7ec06807484 100644 --- a/src/google/protobuf/stubs/hash.h +++ b/src/google/protobuf/stubs/hash.h @@ -33,9 +33,8 @@ #ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__ #define GOOGLE_PROTOBUF_STUBS_HASH_H__ -#include -#include - +#include +#include #include #include @@ -78,14 +77,14 @@ struct hash { }; template <> -struct hash { - inline size_t operator()(const string& key) const { +struct hash { + inline size_t operator()(const std::string& key) const { return hash()(key.c_str()); } static const size_t bucket_size = 4; static const size_t min_buckets = 8; - inline bool operator()(const string& a, const string& b) const { + inline bool operator()(const std::string& a, const std::string& b) const { return a < b; } }; @@ -109,14 +108,6 @@ struct hash > { } }; -// Used by GCC/SGI STL only. (Why isn't this provided by the standard -// library? :( ) -struct streq { - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) == 0; - } -}; - } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc index 2119e65505e5..7fc7dd8c5e19 100644 --- a/src/google/protobuf/stubs/int128.cc +++ b/src/google/protobuf/stubs/int128.cc @@ -190,3 +190,5 @@ std::ostream& operator<<(std::ostream& o, const uint128& b) { } // namespace protobuf } // namespace google + +#include // NOLINT diff --git a/src/google/protobuf/stubs/int128_unittest.cc b/src/google/protobuf/stubs/int128_unittest.cc index 9a8125d4887e..53dbd09ec0c4 100644 --- a/src/google/protobuf/stubs/int128_unittest.cc +++ b/src/google/protobuf/stubs/int128_unittest.cc @@ -515,3 +515,5 @@ TEST(Int128, OStream) { } } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/stubs/mutex.h b/src/google/protobuf/stubs/mutex.h index b222ff746df6..53bb25d694ba 100644 --- a/src/google/protobuf/stubs/mutex.h +++ b/src/google/protobuf/stubs/mutex.h @@ -90,12 +90,33 @@ class PROTOBUF_EXPORT CriticalSectionLock { #endif +// In MSVC std::mutex does not have a constexpr constructor. +// This wrapper makes the constructor constexpr. +template +class CallOnceInitializedMutex { + public: + constexpr CallOnceInitializedMutex() : flag_{}, buf_{} {} + ~CallOnceInitializedMutex() { get().~T(); } + + void lock() { get().lock(); } + void unlock() { get().unlock(); } + + private: + T& get() { + std::call_once(flag_, [&] { ::new (static_cast(&buf_)) T(); }); + return reinterpret_cast(buf_); + } + + std::once_flag flag_; + alignas(T) char buf_[sizeof(T)]; +}; + // Mutex is a natural type to wrap. As both google and other organization have // specialized mutexes. gRPC also provides an injection mechanism for custom // mutexes. class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex { public: - WrappedMutex() = default; + constexpr WrappedMutex() = default; void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); } void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); } // Crash if this Mutex is not held exclusively by this thread. @@ -103,11 +124,13 @@ class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex { void AssertHeld() const {} private: -#ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP +#if defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP) + CallOnceInitializedMutex mu_; +#elif defined(_MSC_VER) + CallOnceInitializedMutex mu_; +#else std::mutex mu_; -#else // ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP - CriticalSectionLock mu_; -#endif // #ifndef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP +#endif }; using Mutex = WrappedMutex; diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h index 31d2a10c07df..db8b62f6b3a4 100644 --- a/src/google/protobuf/stubs/port.h +++ b/src/google/protobuf/stubs/port.h @@ -51,11 +51,11 @@ #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) #define PROTOBUF_LITTLE_ENDIAN 1 #endif - #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) - // If MSVC has "/RTCc" set, it will complain about truncating casts at - // runtime. This file contains some intentional truncating casts. - #pragma runtime_checks("c", off) - #endif +#if defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) +// If MSVC has "/RTCc" set, it will complain about truncating casts at +// runtime. This file contains some intentional truncating casts. +#pragma runtime_checks("c", off) +#endif #else #include // __BYTE_ORDER #if defined(__OpenBSD__) @@ -117,6 +117,8 @@ namespace google { namespace protobuf { +using ConstStringParam = const std::string &; + typedef unsigned int uint; typedef int8_t int8; @@ -225,12 +227,6 @@ inline void GOOGLE_UNALIGNED_STORE64(void *p, uint64 v) { # define GOOGLE_PROTOBUF_USE_PORTABLE_LOG2 #endif -#if defined(_MSC_VER) -#define GOOGLE_THREAD_LOCAL __declspec(thread) -#else -#define GOOGLE_THREAD_LOCAL __thread -#endif - // The following guarantees declaration of the byte swap functions. #ifdef _MSC_VER #define bswap_16(x) _byteswap_ushort(x) diff --git a/src/google/protobuf/stubs/status.cc b/src/google/protobuf/stubs/status.cc index 2bfbe0b42b8e..03b37c365b83 100644 --- a/src/google/protobuf/stubs/status.cc +++ b/src/google/protobuf/stubs/status.cc @@ -38,7 +38,7 @@ namespace google { namespace protobuf { namespace util { namespace error { -inline string CodeEnumToString(error::Code code) { +inline std::string CodeEnumToString(error::Code code) { switch (code) { case OK: return "OK"; @@ -111,7 +111,7 @@ bool Status::operator==(const Status& x) const { error_message_ == x.error_message_; } -string Status::ToString() const { +std::string Status::ToString() const { if (error_code_ == error::OK) { return "OK"; } else { diff --git a/src/google/protobuf/stubs/status.h b/src/google/protobuf/stubs/status.h index 04ecc633bc9f..bededad541c5 100644 --- a/src/google/protobuf/stubs/status.h +++ b/src/google/protobuf/stubs/status.h @@ -106,11 +106,11 @@ class PROTOBUF_EXPORT Status { } // Return a combination of the error code name and message. - string ToString() const; + std::string ToString() const; private: error::Code error_code_; - string error_message_; + std::string error_message_; }; // Prints a human-readable representation of 'x' to 'os'. diff --git a/src/google/protobuf/stubs/status_test.cc b/src/google/protobuf/stubs/status_test.cc index 9a18778fba81..8f4398c9c988 100644 --- a/src/google/protobuf/stubs/status_test.cc +++ b/src/google/protobuf/stubs/status_test.cc @@ -101,7 +101,7 @@ TEST(Status, AssignEmpty) { util::Status a(util::error::UNKNOWN, "message"); util::Status b; a = b; - ASSERT_EQ(string("OK"), a.ToString()); + ASSERT_EQ(std::string("OK"), a.ToString()); ASSERT_TRUE(b.ok()); ASSERT_TRUE(a.ok()); } diff --git a/src/google/protobuf/stubs/statusor.h b/src/google/protobuf/stubs/statusor.h index e8e403a6779b..c02e89a9f0f7 100644 --- a/src/google/protobuf/stubs/statusor.h +++ b/src/google/protobuf/stubs/statusor.h @@ -153,6 +153,7 @@ class StatusOr { // If you need to initialize a T object from the stored value, // ConsumeValueOrDie() may be more efficient. const T& ValueOrDie() const; + const T& value () const; private: Status status_; @@ -254,6 +255,14 @@ inline const T& StatusOr::ValueOrDie() const { } return value_; } + +template +inline const T& StatusOr::value() const { + if (!status_.ok()) { + internal::StatusOrHelper::Crash(status_); + } + return value_; +} } // namespace util } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/stl_util.h b/src/google/protobuf/stubs/stl_util.h index aa81eb6f7234..d01f9ec944f6 100644 --- a/src/google/protobuf/stubs/stl_util.h +++ b/src/google/protobuf/stubs/stl_util.h @@ -44,7 +44,7 @@ namespace protobuf { // improve performance. However, since it's totally non-portable it has no // place in open source code. Feel free to fill this function in with your // own disgusting hack if you want the perf boost. -inline void STLStringResizeUninitialized(string* s, size_t new_size) { +inline void STLStringResizeUninitialized(std::string* s, size_t new_size) { s->resize(new_size); } @@ -60,7 +60,7 @@ inline void STLStringResizeUninitialized(string* s, size_t new_size) { // (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-active.html#530) // proposes this as the method. According to Matt Austern, this should // already work on all current implementations. -inline char* string_as_array(string* str) { +inline char* string_as_array(std::string* str) { // DO NOT USE const_cast(str->data())! See the unittest for why. return str->empty() ? nullptr : &*str->begin(); } diff --git a/src/google/protobuf/stubs/stringpiece.cc b/src/google/protobuf/stubs/stringpiece.cc index fc2f5210595d..353c78cad19b 100644 --- a/src/google/protobuf/stubs/stringpiece.cc +++ b/src/google/protobuf/stubs/stringpiece.cc @@ -64,11 +64,11 @@ StringPiece::StringPiece(StringPiece x, GOOGLE_DCHECK_GE(len, 0); } -void StringPiece::CopyToString(string* target) const { +void StringPiece::CopyToString(std::string* target) const { target->assign(ptr_, length_); } -void StringPiece::AppendToString(string* target) const { +void StringPiece::AppendToString(std::string* target) const { target->append(ptr_, length_); } diff --git a/src/google/protobuf/stubs/stringpiece.h b/src/google/protobuf/stubs/stringpiece.h index 2ae38813f627..fbcb20afc418 100644 --- a/src/google/protobuf/stubs/stringpiece.h +++ b/src/google/protobuf/stubs/stringpiece.h @@ -148,7 +148,6 @@ #include #include -#include #include #include @@ -165,7 +164,7 @@ namespace protobuf { // is 32 bits in LP32, 64 bits in LP64, 64 bits in LLP64 // future changes intended: http://go/64BitStringPiece // -typedef string::difference_type stringpiece_ssize_type; +typedef std::string::difference_type stringpiece_ssize_type; // STRINGPIECE_CHECK_SIZE protects us from 32-bit overflows. // TODO(mec): delete this after stringpiece_ssize_type goes 64 bit. @@ -302,25 +301,21 @@ class PROTOBUF_EXPORT StringPiece { return 0; } - string as_string() const { - return ToString(); - } + std::string as_string() const { return ToString(); } // We also define ToString() here, since many other string-like // interfaces name the routine that converts to a C++ string // "ToString", and it's confusing to have the method that does that // for a StringPiece be called "as_string()". We also leave the // "as_string()" method defined here for existing code. - string ToString() const { - if (ptr_ == nullptr) return string(); - return string(data(), static_cast(size())); + std::string ToString() const { + if (ptr_ == nullptr) return ""; + return std::string(data(), static_cast(size())); } - operator string() const { - return ToString(); - } + explicit operator std::string() const { return ToString(); } - void CopyToString(string* target) const; - void AppendToString(string* target) const; + void CopyToString(std::string* target) const; + void AppendToString(std::string* target) const; bool starts_with(StringPiece x) const { return (length_ >= x.length_) && @@ -466,7 +461,7 @@ struct StringPiecePod { return std::string(data_, static_cast(size_)); } - operator string() const { return ToString(); } + explicit operator std::string() const { return ToString(); } private: const char* data_; diff --git a/src/google/protobuf/stubs/stringpiece_unittest.cc b/src/google/protobuf/stubs/stringpiece_unittest.cc index d9a32d03aa68..846e1aed3d36 100644 --- a/src/google/protobuf/stubs/stringpiece_unittest.cc +++ b/src/google/protobuf/stubs/stringpiece_unittest.cc @@ -87,7 +87,7 @@ TEST(StringPiece, Ctor) { #if defined(HAS_GLOBAL_STRING) { // ::string - string bonjour = "bonjour"; + std::string bonjour = "bonjour"; StringPiece s40(bonjour); EXPECT_TRUE(s40.data() == bonjour.data()); EXPECT_EQ(7, s40.length()); @@ -100,9 +100,9 @@ TEST(StringPiece, Ctor) { } TEST(StringPiece, STLComparator) { - string s1("foo"); - string s2("bar"); - string s3("baz"); + std::string s1("foo"); + std::string s2("bar"); + std::string s3("baz"); StringPiece p1(s1); StringPiece p2(s2); @@ -207,13 +207,13 @@ TEST(StringPiece, ComparisonOperators) { COMPARE(true, >, "b", "aa"); COMPARE(true, >, "bb", "aa"); - string x; + std::string x; for (int i = 0; i < 256; i++) { x += 'a'; - string y = x; + std::string y = x; COMPARE(true, ==, x, y); for (int j = 0; j < i; j++) { - string z = x; + std::string z = x; z[j] = 'b'; // Differs in position 'j' COMPARE(false, ==, x, z); COMPARE(true, <, x, z); @@ -240,7 +240,7 @@ TEST(StringPiece, STL1) { const StringPiece c("xyz"); const StringPiece d("foobar"); const StringPiece e; - string temp("123"); + std::string temp("123"); temp += '\0'; temp += "456"; const StringPiece f(temp); @@ -315,7 +315,7 @@ TEST(StringPiece, STL2) { EXPECT_TRUE(d.data() == nullptr); EXPECT_TRUE(d.begin() == d.end()); - EXPECT_EQ(StringPiece::npos, string::npos); + EXPECT_EQ(StringPiece::npos, std::string::npos); EXPECT_EQ(a.find(b), 0); EXPECT_EQ(a.find(b, 1), StringPiece::npos); @@ -336,15 +336,15 @@ TEST(StringPiece, STL2) { EXPECT_EQ(d.find(b, 4), StringPiece::npos); EXPECT_EQ(e.find(b, 7), StringPiece::npos); - size_t empty_search_pos = string().find(string()); + size_t empty_search_pos = std::string().find(std::string()); EXPECT_EQ(d.find(d), empty_search_pos); EXPECT_EQ(d.find(e), empty_search_pos); EXPECT_EQ(e.find(d), empty_search_pos); EXPECT_EQ(e.find(e), empty_search_pos); - EXPECT_EQ(d.find(d, 4), string().find(string(), 4)); - EXPECT_EQ(d.find(e, 4), string().find(string(), 4)); - EXPECT_EQ(e.find(d, 4), string().find(string(), 4)); - EXPECT_EQ(e.find(e, 4), string().find(string(), 4)); + EXPECT_EQ(d.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(d.find(e, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(d, 4), std::string().find(std::string(), 4)); + EXPECT_EQ(e.find(e, 4), std::string().find(std::string(), 4)); EXPECT_EQ(a.find('a'), 0); EXPECT_EQ(a.find('c'), 2); @@ -376,8 +376,8 @@ TEST(StringPiece, STL2) { EXPECT_EQ(a.rfind(c, 0), StringPiece::npos); EXPECT_EQ(b.rfind(c), StringPiece::npos); EXPECT_EQ(b.rfind(c, 0), StringPiece::npos); - EXPECT_EQ(a.rfind(d), a.as_string().rfind(string())); - EXPECT_EQ(a.rfind(e), a.as_string().rfind(string())); + EXPECT_EQ(a.rfind(d), a.as_string().rfind(std::string())); + EXPECT_EQ(a.rfind(e), a.as_string().rfind(std::string())); EXPECT_EQ(a.rfind(d, 12), 12); EXPECT_EQ(a.rfind(e, 17), 17); EXPECT_EQ(a.rfind(g), StringPiece::npos); @@ -386,14 +386,14 @@ TEST(StringPiece, STL2) { EXPECT_EQ(d.rfind(b, 4), StringPiece::npos); EXPECT_EQ(e.rfind(b, 7), StringPiece::npos); // empty string nonsense - EXPECT_EQ(d.rfind(d, 4), string().rfind(string())); - EXPECT_EQ(e.rfind(d, 7), string().rfind(string())); - EXPECT_EQ(d.rfind(e, 4), string().rfind(string())); - EXPECT_EQ(e.rfind(e, 7), string().rfind(string())); - EXPECT_EQ(d.rfind(d), string().rfind(string())); - EXPECT_EQ(e.rfind(d), string().rfind(string())); - EXPECT_EQ(d.rfind(e), string().rfind(string())); - EXPECT_EQ(e.rfind(e), string().rfind(string())); + EXPECT_EQ(d.rfind(d, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e, 4), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e, 7), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(d), std::string().rfind(std::string())); + EXPECT_EQ(d.rfind(e), std::string().rfind(std::string())); + EXPECT_EQ(e.rfind(e), std::string().rfind(std::string())); EXPECT_EQ(g.rfind('o'), 8); EXPECT_EQ(g.rfind('q'), StringPiece::npos); @@ -566,7 +566,7 @@ TEST(StringPiece, STL2) { // empty string nonsense EXPECT_EQ(StringPiece(d, 0, 99), e); // Verify that they work taking an actual string, not just a StringPiece. - string a2 = a.as_string(); + std::string a2 = a.as_string(); EXPECT_EQ(StringPiece(a2, 0, 3), b); EXPECT_EQ(StringPiece(a2, 23), c); EXPECT_EQ(StringPiece(a2, 23, 3), c); @@ -577,12 +577,12 @@ TEST(StringPiece, STL2) { TEST(StringPiece, Custom) { StringPiece a("foobar"); - string s1("123"); + std::string s1("123"); s1 += '\0'; s1 += "456"; StringPiece b(s1); StringPiece e; - string s2; + std::string s2; // CopyToString a.CopyToString(&s2); @@ -666,16 +666,16 @@ TEST(StringPiece, Custom) { EXPECT_NE(c, a); // as_string - string s3(a.as_string().c_str(), 7); + std::string s3(a.as_string().c_str(), 7); EXPECT_EQ(c, s3); - string s4(e.as_string()); + std::string s4(e.as_string()); EXPECT_TRUE(s4.empty()); // ToString { - string s5(a.ToString().c_str(), 7); + std::string s5(a.ToString().c_str(), 7); EXPECT_EQ(c, s5); - string s6(e.ToString()); + std::string s6(e.ToString()); EXPECT_TRUE(s6.empty()); } @@ -747,12 +747,12 @@ TEST(StringPiece, Comparisons2) { } TEST(ComparisonOpsTest, StringCompareNotAmbiguous) { - EXPECT_EQ("hello", string("hello")); - EXPECT_LT("hello", string("world")); + EXPECT_EQ("hello", std::string("hello")); + EXPECT_LT("hello", std::string("world")); } TEST(ComparisonOpsTest, HeterogenousStringPieceEquals) { - EXPECT_EQ(StringPiece("hello"), string("hello")); + EXPECT_EQ(StringPiece("hello"), std::string("hello")); EXPECT_EQ("hello", StringPiece("hello")); } diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc index e6019fc66416..260316493647 100644 --- a/src/google/protobuf/stubs/stringprintf.cc +++ b/src/google/protobuf/stubs/stringprintf.cc @@ -54,7 +54,7 @@ enum { IS_COMPILER_MSVC = 1 }; enum { IS_COMPILER_MSVC = 0 }; #endif -void StringAppendV(string* dst, const char* format, va_list ap) { +void StringAppendV(std::string* dst, const char* format, va_list ap) { // First try with a small fixed size buffer static const int kSpaceLength = 1024; char space[kSpaceLength]; @@ -105,17 +105,16 @@ void StringAppendV(string* dst, const char* format, va_list ap) { delete[] buf; } - -string StringPrintf(const char* format, ...) { +std::string StringPrintf(const char* format, ...) { va_list ap; va_start(ap, format); - string result; + std::string result; StringAppendV(&result, format, ap); va_end(ap); return result; } -const string& SStringPrintf(string* dst, const char* format, ...) { +const std::string& SStringPrintf(std::string* dst, const char* format, ...) { va_list ap; va_start(ap, format); dst->clear(); @@ -124,7 +123,7 @@ const string& SStringPrintf(string* dst, const char* format, ...) { return *dst; } -void StringAppendF(string* dst, const char* format, ...) { +void StringAppendF(std::string* dst, const char* format, ...) { va_list ap; va_start(ap, format); StringAppendV(dst, format, ap); @@ -139,7 +138,8 @@ const int kStringPrintfVectorMaxArgs = 32; // and we can fix the problem or protect against an attack. static const char string_printf_empty_block[256] = { '\0' }; -string StringPrintfVector(const char* format, const std::vector& v) { +std::string StringPrintfVector(const char* format, + const std::vector& v) { GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs) << "StringPrintfVector currently only supports up to " << kStringPrintfVectorMaxArgs << " arguments. " diff --git a/src/google/protobuf/stubs/stringprintf.h b/src/google/protobuf/stubs/stringprintf.h index 253d736a2160..e3858be13012 100644 --- a/src/google/protobuf/stubs/stringprintf.h +++ b/src/google/protobuf/stubs/stringprintf.h @@ -52,18 +52,20 @@ namespace google { namespace protobuf { // Return a C++ string -PROTOBUF_EXPORT extern string StringPrintf(const char* format, ...); +PROTOBUF_EXPORT extern std::string StringPrintf(const char* format, ...); // Store result into a supplied string and return it -PROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, - const char* format, ...); +PROTOBUF_EXPORT extern const std::string& SStringPrintf(std::string* dst, + const char* format, + ...); // Append result to a supplied string -PROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...); +PROTOBUF_EXPORT extern void StringAppendF(std::string* dst, const char* format, + ...); // Lower-level routine that takes a va_list and appends to a specified // string. All other routines are just convenience wrappers around it. -PROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, +PROTOBUF_EXPORT extern void StringAppendV(std::string* dst, const char* format, va_list ap); // The max arguments supported by StringPrintfVector @@ -72,8 +74,8 @@ PROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs; // You can use this version when all your arguments are strings, but // you don't know how many arguments you'll have at compile time. // StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs -PROTOBUF_EXPORT extern string StringPrintfVector(const char* format, - const std::vector& v); +PROTOBUF_EXPORT extern std::string StringPrintfVector( + const char* format, const std::vector& v); } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/stringprintf_unittest.cc b/src/google/protobuf/stubs/stringprintf_unittest.cc index 7fcbf500eb7e..37172a9d9702 100644 --- a/src/google/protobuf/stubs/stringprintf_unittest.cc +++ b/src/google/protobuf/stubs/stringprintf_unittest.cc @@ -49,7 +49,7 @@ TEST(StringPrintfTest, Empty) { // so we do not allow them in google3. EXPECT_EQ("", StringPrintf("")); #endif - EXPECT_EQ("", StringPrintf("%s", string().c_str())); + EXPECT_EQ("", StringPrintf("%s", std::string().c_str())); EXPECT_EQ("", StringPrintf("%s", "")); } @@ -61,26 +61,26 @@ TEST(StringPrintfTest, Misc) { } TEST(StringAppendFTest, Empty) { - string value("Hello"); + std::string value("Hello"); const char* empty = ""; StringAppendF(&value, "%s", empty); EXPECT_EQ("Hello", value); } TEST(StringAppendFTest, EmptyString) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, "%s", ""); EXPECT_EQ("Hello", value); } TEST(StringAppendFTest, String) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, " %s", "World"); EXPECT_EQ("Hello World", value); } TEST(StringAppendFTest, Int) { - string value("Hello"); + std::string value("Hello"); StringAppendF(&value, " %d", 123); EXPECT_EQ("Hello 123", value); } @@ -96,7 +96,7 @@ TEST(StringPrintfTest, Multibyte) { setlocale(LC_CTYPE, "en_US.utf8"); const char kInvalidCodePoint[] = "\375\067s"; - string value = StringPrintf("%.*s", 3, kInvalidCodePoint); + std::string value = StringPrintf("%.*s", 3, kInvalidCodePoint); // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf // returns error given an invalid codepoint. Other versions @@ -122,7 +122,7 @@ TEST(StringPrintfTest, NoMultibyte) { // No multibyte handling, but the string contains funny chars. char* old_locale = setlocale(LC_CTYPE, nullptr); setlocale(LC_CTYPE, "POSIX"); - string value = StringPrintf("%.*s", 3, "\375\067s"); + std::string value = StringPrintf("%.*s", 3, "\375\067s"); setlocale(LC_CTYPE, old_locale); EXPECT_EQ("\375\067s", value); } @@ -132,7 +132,7 @@ TEST(StringPrintfTest, DontOverwriteErrno) { // something significantly larger than what people are normally // printing in their badly written PLOG() statements. errno = ECHILD; - string value = StringPrintf("Hello, %s!", "World"); + std::string value = StringPrintf("Hello, %s!", "World"); EXPECT_EQ(ECHILD, errno); } @@ -142,7 +142,7 @@ TEST(StringPrintfTest, LargeBuf) { char* buf = new char[n+1]; memset(buf, ' ', n); buf[n] = 0; - string value = StringPrintf("%s", buf); + std::string value = StringPrintf("%s", buf); EXPECT_EQ(buf, value); delete[] buf; } diff --git a/src/google/protobuf/stubs/structurally_valid.cc b/src/google/protobuf/stubs/structurally_valid.cc index 03f3bc07f268..9a476c3b4ca5 100644 --- a/src/google/protobuf/stubs/structurally_valid.cc +++ b/src/google/protobuf/stubs/structurally_valid.cc @@ -456,7 +456,6 @@ int UTF8GenericScan(const UTF8ScanObj* st, } //---------------------------- - // Exit possibilities: // Some exit code, !state0, back up over last char // Some exit code, state0, back up one byte exactly @@ -562,7 +561,7 @@ bool IsStructurallyValidUTF8(const char* buf, int len) { return (bytes_consumed == len); } -int UTF8SpnStructurallyValid(const StringPiece& str) { +int UTF8SpnStructurallyValid(StringPiece str) { if (!module_initialized_) return str.size(); int bytes_consumed = 0; @@ -583,8 +582,7 @@ int UTF8SpnStructurallyValid(const StringPiece& str) { // // Fast case: all is structurally valid and no byte copying is done. // -char* UTF8CoerceToStructurallyValid(const StringPiece& src_str, - char* idst, +char* UTF8CoerceToStructurallyValid(StringPiece src_str, char* idst, const char replace_char) { const char* isrc = src_str.data(); const int len = src_str.length(); diff --git a/src/google/protobuf/stubs/structurally_valid_unittest.cc b/src/google/protobuf/stubs/structurally_valid_unittest.cc index eec07a87abfa..ebd9c42306ba 100644 --- a/src/google/protobuf/stubs/structurally_valid_unittest.cc +++ b/src/google/protobuf/stubs/structurally_valid_unittest.cc @@ -43,7 +43,8 @@ TEST(StructurallyValidTest, ValidUTF8String) { // On GCC, this string can be written as: // "abcd 1234 - \u2014\u2013\u2212" // MSVC seems to interpret \u differently. - string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); + std::string valid_str( + "abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789"); EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(), valid_str.size())); // Additional check for pointer alignment @@ -54,7 +55,7 @@ TEST(StructurallyValidTest, ValidUTF8String) { } TEST(StructurallyValidTest, InvalidUTF8String) { - const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); + const std::string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789"); EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(), invalid_str.size())); // Additional check for pointer alignment diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index 4a1246bfa433..2ecdb2bf72bf 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -84,7 +84,7 @@ inline bool isprint(char c) { // Replaces any occurrence of the character 'remove' (or the characters // in 'remove') with the character 'replacewith'. // ---------------------------------------------------------------------- -void ReplaceCharacters(string *s, const char *remove, char replacewith) { +void ReplaceCharacters(std::string *s, const char *remove, char replacewith) { const char *str_start = s->c_str(); const char *str = str_start; for (str = strpbrk(str, remove); @@ -94,7 +94,7 @@ void ReplaceCharacters(string *s, const char *remove, char replacewith) { } } -void StripWhitespace(string* str) { +void StripWhitespace(std::string *str) { int str_length = str->length(); // Strip off leading whitespace. @@ -118,7 +118,7 @@ void StripWhitespace(string* str) { --last; } if (last != (str_length - 1) && last >= 0) { - str->erase(last + 1, string::npos); + str->erase(last + 1, std::string::npos); } } @@ -129,19 +129,19 @@ void StripWhitespace(string* str) { // it only replaces the first instance of "old." // ---------------------------------------------------------------------- -void StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all, - string* res) { +void StringReplace(const std::string &s, const std::string &oldsub, + const std::string &newsub, bool replace_all, + std::string *res) { if (oldsub.empty()) { res->append(s); // if empty, append the given string. return; } - string::size_type start_pos = 0; - string::size_type pos; + std::string::size_type start_pos = 0; + std::string::size_type pos; do { pos = s.find(oldsub, start_pos); - if (pos == string::npos) { + if (pos == std::string::npos) { break; } res->append(s, start_pos, pos - start_pos); @@ -160,9 +160,9 @@ void StringReplace(const string& s, const string& oldsub, // happened or not. // ---------------------------------------------------------------------- -string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all) { - string ret; +std::string StringReplace(const std::string &s, const std::string &oldsub, + const std::string &newsub, bool replace_all) { + std::string ret; StringReplace(s, oldsub, newsub, replace_all, &ret); return ret; } @@ -176,10 +176,8 @@ string StringReplace(const string& s, const string& oldsub, // the characters in the string, not the entire string as a single delimiter. // ---------------------------------------------------------------------- template -static inline -void SplitStringToIteratorUsing(const string& full, - const char* delim, - ITR& result) { +static inline void SplitStringToIteratorUsing(StringPiece full, + const char *delim, ITR &result) { // Optimize the common case where delim is a single character. if (delim[0] != '\0' && delim[1] == '\0') { char c = delim[0]; @@ -191,29 +189,29 @@ void SplitStringToIteratorUsing(const string& full, } else { const char* start = p; while (++p != end && *p != c); - *result++ = string(start, p - start); + *result++ = std::string(start, p - start); } } return; } - string::size_type begin_index, end_index; + std::string::size_type begin_index, end_index; begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { + while (begin_index != std::string::npos) { end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { - *result++ = full.substr(begin_index); + if (end_index == std::string::npos) { + *result++ = std::string(full.substr(begin_index)); return; } - *result++ = full.substr(begin_index, (end_index - begin_index)); + *result++ = + std::string(full.substr(begin_index, (end_index - begin_index))); begin_index = full.find_first_not_of(delim, end_index); } } -void SplitStringUsing(const string& full, - const char* delim, - std::vector* result) { - std::back_insert_iterator< std::vector > it(*result); +void SplitStringUsing(StringPiece full, const char *delim, + std::vector *result) { + std::back_insert_iterator > it(*result); SplitStringToIteratorUsing(full, delim, it); } @@ -228,30 +226,29 @@ void SplitStringUsing(const string& full, // // If "pieces" is negative for some reason, it returns the whole string // ---------------------------------------------------------------------- -template -static inline -void SplitStringToIteratorAllowEmpty(const StringType& full, - const char* delim, - int pieces, - ITR& result) { - string::size_type begin_index, end_index; +template +static inline void SplitStringToIteratorAllowEmpty(StringPiece full, + const char *delim, + int pieces, ITR &result) { + std::string::size_type begin_index, end_index; begin_index = 0; for (int i = 0; (i < pieces-1) || (pieces == 0); i++) { end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { - *result++ = full.substr(begin_index); + if (end_index == std::string::npos) { + *result++ = std::string(full.substr(begin_index)); return; } - *result++ = full.substr(begin_index, (end_index - begin_index)); + *result++ = + std::string(full.substr(begin_index, (end_index - begin_index))); begin_index = end_index + 1; } - *result++ = full.substr(begin_index); + *result++ = std::string(full.substr(begin_index)); } -void SplitStringAllowEmpty(const string& full, const char* delim, - std::vector* result) { - std::back_insert_iterator > it(*result); +void SplitStringAllowEmpty(StringPiece full, const char *delim, + std::vector *result) { + std::back_insert_iterator > it(*result); SplitStringToIteratorAllowEmpty(full, delim, 0, it); } @@ -262,10 +259,8 @@ void SplitStringAllowEmpty(const string& full, const char* delim, // // ---------------------------------------------------------------------- template -static void JoinStringsIterator(const ITERATOR& start, - const ITERATOR& end, - const char* delim, - string* result) { +static void JoinStringsIterator(const ITERATOR &start, const ITERATOR &end, + const char *delim, std::string *result) { GOOGLE_CHECK(result != nullptr); result->clear(); int delim_length = strlen(delim); @@ -289,9 +284,8 @@ static void JoinStringsIterator(const ITERATOR& start, } } -void JoinStrings(const std::vector& components, - const char* delim, - string * result) { +void JoinStrings(const std::vector &components, const char *delim, + std::string *result) { JoinStringsIterator(components.begin(), components.end(), delim, result); } @@ -317,8 +311,8 @@ int UnescapeCEscapeSequences(const char* source, char* dest) { return UnescapeCEscapeSequences(source, dest, nullptr); } -int UnescapeCEscapeSequences(const char* source, char* dest, - std::vector *errors) { +int UnescapeCEscapeSequences(const char *source, char *dest, + std::vector *errors) { GOOGLE_DCHECK(errors == nullptr) << "Error reporting not implemented."; char* d = dest; @@ -373,8 +367,10 @@ int UnescapeCEscapeSequences(const char* source, char* dest, while (isxdigit(p[1])) // arbitrarily many hex digits ch = (ch << 4) + hex_digit_to_int(*++p); if (ch > 0xFF) - LOG_STRING(ERROR, errors) << "Value of " << - "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits"; + LOG_STRING(ERROR, errors) + << "Value of " + << "\\" << std::string(hex_start, p + 1 - hex_start) + << " exceeds 8 bits"; *d++ = ch; break; } @@ -389,7 +385,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, } else { LOG_STRING(ERROR, errors) << "\\u must be followed by 4 hex digits: \\" - << string(hex_start, p+1-hex_start); + << std::string(hex_start, p+1-hex_start); break; } } @@ -408,7 +404,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, if (newrune > 0x10FFFF) { LOG_STRING(ERROR, errors) << "Value of \\" - << string(hex_start, p + 1 - hex_start) + << std::string(hex_start, p + 1 - hex_start) << " exceeds Unicode limit (0x10FFFF)"; break; } else { @@ -417,7 +413,7 @@ int UnescapeCEscapeSequences(const char* source, char* dest, } else { LOG_STRING(ERROR, errors) << "\\U must be followed by 8 hex digits: \\" - << string(hex_start, p+1-hex_start); + << std::string(hex_start, p+1-hex_start); break; } } @@ -449,12 +445,12 @@ int UnescapeCEscapeSequences(const char* source, char* dest, // In the first and second calls, the length of dest is returned. In the // the third call, the new string is returned. // ---------------------------------------------------------------------- -int UnescapeCEscapeString(const string& src, string* dest) { +int UnescapeCEscapeString(const std::string &src, std::string *dest) { return UnescapeCEscapeString(src, dest, nullptr); } -int UnescapeCEscapeString(const string& src, string* dest, - std::vector *errors) { +int UnescapeCEscapeString(const std::string &src, std::string *dest, + std::vector *errors) { std::unique_ptr unescaped(new char[src.size() + 1]); int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors); GOOGLE_CHECK(dest); @@ -462,10 +458,10 @@ int UnescapeCEscapeString(const string& src, string* dest, return len; } -string UnescapeCEscapeString(const string& src) { +std::string UnescapeCEscapeString(const std::string &src) { std::unique_ptr unescaped(new char[src.size() + 1]); int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), nullptr); - return string(unescaped.get(), len); + return std::string(unescaped.get(), len); } // ---------------------------------------------------------------------- @@ -562,7 +558,7 @@ static inline size_t CEscapedLength(StringPiece src) { // the required space using a lookup table, and also does not do any special // handling for Hex or UTF-8 characters. // ---------------------------------------------------------------------- -void CEscapeAndAppend(StringPiece src, string* dest) { +void CEscapeAndAppend(StringPiece src, std::string *dest) { size_t escaped_len = CEscapedLength(src); if (escaped_len == src.size()) { dest->append(src.data(), src.size()); @@ -596,30 +592,30 @@ void CEscapeAndAppend(StringPiece src, string* dest) { } } -string CEscape(const string& src) { - string dest; +std::string CEscape(const std::string &src) { + std::string dest; CEscapeAndAppend(src, &dest); return dest; } namespace strings { -string Utf8SafeCEscape(const string& src) { +std::string Utf8SafeCEscape(const std::string &src) { const int dest_length = src.size() * 4 + 1; // Maximum possible expansion std::unique_ptr dest(new char[dest_length]); const int len = CEscapeInternal(src.data(), src.size(), dest.get(), dest_length, false, true); GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); + return std::string(dest.get(), len); } -string CHexEscape(const string& src) { +std::string CHexEscape(const std::string &src) { const int dest_length = src.size() * 4 + 1; // Maximum possible expansion std::unique_ptr dest(new char[dest_length]); const int len = CEscapeInternal(src.data(), src.size(), dest.get(), dest_length, true, false); GOOGLE_DCHECK_GE(len, 0); - return string(dest.get(), len); + return std::string(dest.get(), len); } } // namespace strings @@ -667,8 +663,8 @@ uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) { return static_cast(result); } -inline bool safe_parse_sign(string* text /*inout*/, - bool* negative_ptr /*output*/) { +inline bool safe_parse_sign(std::string *text /*inout*/, + bool *negative_ptr /*output*/) { const char* start = text->data(); const char* end = start + text->size(); @@ -695,9 +691,8 @@ inline bool safe_parse_sign(string* text /*inout*/, return true; } -template -bool safe_parse_positive_int( - string text, IntType* value_p) { +template +bool safe_parse_positive_int(std::string text, IntType *value_p) { int base = 10; IntType value = 0; const IntType vmax = std::numeric_limits::max(); @@ -729,9 +724,8 @@ bool safe_parse_positive_int( return true; } -template -bool safe_parse_negative_int( - const string& text, IntType* value_p) { +template +bool safe_parse_negative_int(const std::string &text, IntType *value_p) { int base = 10; IntType value = 0; const IntType vmin = std::numeric_limits::min(); @@ -770,8 +764,8 @@ bool safe_parse_negative_int( return true; } -template -bool safe_int_internal(string text, IntType* value_p) { +template +bool safe_int_internal(std::string text, IntType *value_p) { *value_p = 0; bool negative; if (!safe_parse_sign(&text, &negative)) { @@ -784,8 +778,8 @@ bool safe_int_internal(string text, IntType* value_p) { } } -template -bool safe_uint_internal(string text, IntType* value_p) { +template +bool safe_uint_internal(std::string text, IntType *value_p) { *value_p = 0; bool negative; if (!safe_parse_sign(&text, &negative) || negative) { @@ -1119,46 +1113,46 @@ char* FastInt64ToBufferLeft(int64 i, char* buffer) { // Return value: string // ---------------------------------------------------------------------- -string SimpleItoa(int i) { +std::string SimpleItoa(int i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned int i) { +std::string SimpleItoa(unsigned int i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } -string SimpleItoa(long i) { +std::string SimpleItoa(long i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned long i) { +std::string SimpleItoa(unsigned long i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } -string SimpleItoa(long long i) { +std::string SimpleItoa(long long i) { char buffer[kFastToBufferSize]; return (sizeof(i) == 4) ? FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer); } -string SimpleItoa(unsigned long long i) { +std::string SimpleItoa(unsigned long long i) { char buffer[kFastToBufferSize]; - return string(buffer, (sizeof(i) == 4) ? - FastUInt32ToBufferLeft(i, buffer) : - FastUInt64ToBufferLeft(i, buffer)); + return std::string(buffer, (sizeof(i) == 4) + ? FastUInt32ToBufferLeft(i, buffer) + : FastUInt64ToBufferLeft(i, buffer)); } // ---------------------------------------------------------------------- @@ -1202,12 +1196,12 @@ string SimpleItoa(unsigned long long i) { // implementation. // ---------------------------------------------------------------------- -string SimpleDtoa(double value) { +std::string SimpleDtoa(double value) { char buffer[kDoubleToBufferSize]; return DoubleToBuffer(value, buffer); } -string SimpleFtoa(float value) { +std::string SimpleFtoa(float value) { char buffer[kFloatToBufferSize]; return FloatToBuffer(value, buffer); } @@ -1347,19 +1341,19 @@ bool safe_strtod(const char* str, double* value) { return *str != '\0' && *endptr == '\0'; } -bool safe_strto32(const string& str, int32* value) { +bool safe_strto32(const std::string &str, int32 *value) { return safe_int_internal(str, value); } -bool safe_strtou32(const string& str, uint32* value) { +bool safe_strtou32(const std::string &str, uint32 *value) { return safe_uint_internal(str, value); } -bool safe_strto64(const string& str, int64* value) { +bool safe_strto64(const std::string &str, int64 *value) { return safe_int_internal(str, value); } -bool safe_strtou64(const string& str, uint64* value) { +bool safe_strtou64(const std::string &str, uint64 *value) { return safe_uint_internal(str, value); } @@ -1475,8 +1469,8 @@ static char *Append4(char *out, const AlphaNum &x1, const AlphaNum &x2, return out; } -string StrCat(const AlphaNum &a, const AlphaNum &b) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b) { + std::string result; result.resize(a.size() + b.size()); char *const begin = &*result.begin(); char *out = Append2(begin, a, b); @@ -1484,8 +1478,8 @@ string StrCat(const AlphaNum &a, const AlphaNum &b) { return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { + std::string result; result.resize(a.size() + b.size() + c.size()); char *const begin = &*result.begin(); char *out = Append2(begin, a, b); @@ -1494,9 +1488,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size()); char *const begin = &*result.begin(); char *out = Append4(begin, a, b, c, d); @@ -1504,9 +1498,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size()); char *const begin = &*result.begin(); char *out = Append4(begin, a, b, c, d); @@ -1515,9 +1509,9 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size()); char *const begin = &*result.begin(); @@ -1527,10 +1521,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size()); char *const begin = &*result.begin(); @@ -1541,10 +1535,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g, const AlphaNum &h) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size() + h.size()); char *const begin = &*result.begin(); @@ -1554,10 +1548,10 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, return result; } -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) { - string result; +std::string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, + const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, + const AlphaNum &g, const AlphaNum &h, const AlphaNum &i) { + std::string result; result.resize(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() + g.size() + h.size() + i.size()); char *const begin = &*result.begin(); @@ -1576,27 +1570,27 @@ string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, GOOGLE_DCHECK_GT(uintptr_t((src).data() - (dest).data()), \ uintptr_t((dest).size())) -void StrAppend(string *result, const AlphaNum &a) { +void StrAppend(std::string *result, const AlphaNum &a) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); result->append(a.data(), a.size()); } -void StrAppend(string *result, const AlphaNum &a, const AlphaNum &b) { +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size()); char *const begin = &*result->begin(); char *out = Append2(begin + old_size, a, b); GOOGLE_DCHECK_EQ(out, begin + result->size()); } -void StrAppend(string *result, - const AlphaNum &a, const AlphaNum &b, const AlphaNum &c) { +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b, + const AlphaNum &c) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); GOOGLE_DCHECK_NO_OVERLAP(*result, c); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size() + c.size()); char *const begin = &*result->begin(); char *out = Append2(begin + old_size, a, b); @@ -1604,32 +1598,29 @@ void StrAppend(string *result, GOOGLE_DCHECK_EQ(out, begin + result->size()); } -void StrAppend(string *result, - const AlphaNum &a, const AlphaNum &b, +void StrAppend(std::string *result, const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, const AlphaNum &d) { GOOGLE_DCHECK_NO_OVERLAP(*result, a); GOOGLE_DCHECK_NO_OVERLAP(*result, b); GOOGLE_DCHECK_NO_OVERLAP(*result, c); GOOGLE_DCHECK_NO_OVERLAP(*result, d); - string::size_type old_size = result->size(); + std::string::size_type old_size = result->size(); result->resize(old_size + a.size() + b.size() + c.size() + d.size()); char *const begin = &*result->begin(); char *out = Append4(begin + old_size, a, b, c, d); GOOGLE_DCHECK_EQ(out, begin + result->size()); } -int GlobalReplaceSubstring(const string& substring, - const string& replacement, - string* s) { +int GlobalReplaceSubstring(const std::string &substring, + const std::string &replacement, std::string *s) { GOOGLE_CHECK(s != nullptr); if (s->empty() || substring.empty()) return 0; - string tmp; + std::string tmp; int num_replacements = 0; int pos = 0; for (int match_pos = s->find(substring.data(), pos, substring.length()); - match_pos != string::npos; - pos = match_pos + substring.length(), + match_pos != std::string::npos; pos = match_pos + substring.length(), match_pos = s->find(substring.data(), pos, substring.length())) { ++num_replacements; // Append the original content before the match. @@ -2060,8 +2051,8 @@ int WebSafeBase64Unescape(const char *src, int szsrc, char *dest, int szdest) { return Base64UnescapeInternal(src, szsrc, dest, szdest, kUnWebSafeBase64); } -static bool Base64UnescapeInternal(const char* src, int slen, string* dest, - const signed char* unbase64) { +static bool Base64UnescapeInternal(const char *src, int slen, std::string *dest, + const signed char *unbase64) { // Determine the size of the output string. Base64 encodes every 3 bytes into // 4 characters. any leftover chars are added directly for good measure. // This is documented in the base64 RFC: http://tools.ietf.org/html/rfc3548 @@ -2085,11 +2076,11 @@ static bool Base64UnescapeInternal(const char* src, int slen, string* dest, return true; } -bool Base64Unescape(StringPiece src, string* dest) { +bool Base64Unescape(StringPiece src, std::string *dest) { return Base64UnescapeInternal(src.data(), src.size(), dest, kUnBase64); } -bool WebSafeBase64Unescape(StringPiece src, string* dest) { +bool WebSafeBase64Unescape(StringPiece src, std::string *dest) { return Base64UnescapeInternal(src.data(), src.size(), dest, kUnWebSafeBase64); } @@ -2208,9 +2199,9 @@ int WebSafeBase64Escape(const unsigned char *src, int szsrc, char *dest, kWebSafeBase64Chars, do_padding); } -void Base64EscapeInternal(const unsigned char* src, int szsrc, - string* dest, bool do_padding, - const char* base64_chars) { +void Base64EscapeInternal(const unsigned char *src, int szsrc, + std::string *dest, bool do_padding, + const char *base64_chars) { const int calc_escaped_size = CalculateBase64EscapedLen(szsrc, do_padding); dest->resize(calc_escaped_size); @@ -2223,27 +2214,27 @@ void Base64EscapeInternal(const unsigned char* src, int szsrc, dest->erase(escaped_len); } -void Base64Escape(const unsigned char *src, int szsrc, - string* dest, bool do_padding) { +void Base64Escape(const unsigned char *src, int szsrc, std::string *dest, + bool do_padding) { Base64EscapeInternal(src, szsrc, dest, do_padding, kBase64Chars); } -void WebSafeBase64Escape(const unsigned char *src, int szsrc, - string *dest, bool do_padding) { +void WebSafeBase64Escape(const unsigned char *src, int szsrc, std::string *dest, + bool do_padding) { Base64EscapeInternal(src, szsrc, dest, do_padding, kWebSafeBase64Chars); } -void Base64Escape(StringPiece src, string* dest) { +void Base64Escape(StringPiece src, std::string *dest) { Base64Escape(reinterpret_cast(src.data()), src.size(), dest, true); } -void WebSafeBase64Escape(StringPiece src, string* dest) { +void WebSafeBase64Escape(StringPiece src, std::string *dest) { WebSafeBase64Escape(reinterpret_cast(src.data()), src.size(), dest, false); } -void WebSafeBase64EscapeWithPadding(StringPiece src, string* dest) { +void WebSafeBase64EscapeWithPadding(StringPiece src, std::string *dest) { WebSafeBase64Escape(reinterpret_cast(src.data()), src.size(), dest, true); } @@ -2284,16 +2275,19 @@ int EncodeAsUTF8Char(uint32 code_point, char* output) { // Table of UTF-8 character lengths, based on first byte static const unsigned char kUTF8LenTbl[256] = { - 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,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, - 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3, 4,4,4,4,4,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, 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, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // Return length of a single UTF-8 source character int UTF8FirstLetterNumBytes(const char* src, int len) { @@ -2336,19 +2330,19 @@ int UTF8FirstLetterNumBytes(const char* src, int len) { // (1) determines the presence of LF (first one is ok) // (2) if yes, removes any CR, else convert every CR to LF -void CleanStringLineEndings(const string &src, string *dst, +void CleanStringLineEndings(const std::string &src, std::string *dst, bool auto_end_last_line) { if (dst->empty()) { dst->append(src); CleanStringLineEndings(dst, auto_end_last_line); } else { - string tmp = src; + std::string tmp = src; CleanStringLineEndings(&tmp, auto_end_last_line); dst->append(tmp); } } -void CleanStringLineEndings(string *str, bool auto_end_last_line) { +void CleanStringLineEndings(std::string *str, bool auto_end_last_line) { ptrdiff_t output_pos = 0; bool r_seen = false; ptrdiff_t len = str->size(); @@ -2379,7 +2373,7 @@ void CleanStringLineEndings(string *str, bool auto_end_last_line) { continue; } } - string::const_reference in = p[input_pos]; + std::string::const_reference in = p[input_pos]; if (in == '\r') { if (r_seen) p[output_pos++] = '\n'; r_seen = true; diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index e688c8e83859..8ce81f28c398 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h @@ -33,12 +33,13 @@ #ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ #define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__ -#include -#include #include #include +#include +#include #include +#include namespace google { namespace protobuf { @@ -112,13 +113,13 @@ inline int hex_digit_to_int(char c) { // prefix string if the prefix matches, otherwise the original // string. // ---------------------------------------------------------------------- -inline bool HasPrefixString(const string& str, - const string& prefix) { +inline bool HasPrefixString(StringPiece str, StringPiece prefix) { return str.size() >= prefix.size() && - str.compare(0, prefix.size(), prefix) == 0; + memcmp(str.data(), prefix.data(), prefix.size()) == 0; } -inline string StripPrefixString(const string& str, const string& prefix) { +inline std::string StripPrefixString(const std::string& str, + const std::string& prefix) { if (HasPrefixString(str, prefix)) { return str.substr(prefix.size()); } else { @@ -134,13 +135,14 @@ inline string StripPrefixString(const string& str, const string& prefix) { // suffix string if the suffix matches, otherwise the original // string. // ---------------------------------------------------------------------- -inline bool HasSuffixString(const string& str, - const string& suffix) { +inline bool HasSuffixString(StringPiece str, StringPiece suffix) { return str.size() >= suffix.size() && - str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0; + memcmp(str.data() + str.size() - suffix.size(), suffix.data(), + suffix.size()) == 0; } -inline string StripSuffixString(const string& str, const string& suffix) { +inline std::string StripSuffixString(const std::string& str, + const std::string& suffix) { if (HasSuffixString(str, suffix)) { return str.substr(0, str.size() - suffix.size()); } else { @@ -157,10 +159,10 @@ inline string StripSuffixString(const string& str, const string& suffix) { // StripWhitespace // Removes whitespaces from both ends of the given string. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void ReplaceCharacters(string* s, const char* remove, +PROTOBUF_EXPORT void ReplaceCharacters(std::string* s, const char* remove, char replacewith); -PROTOBUF_EXPORT void StripWhitespace(string* s); +PROTOBUF_EXPORT void StripWhitespace(std::string* s); // ---------------------------------------------------------------------- // LowerString() @@ -172,24 +174,26 @@ PROTOBUF_EXPORT void StripWhitespace(string* s); // strings. // ---------------------------------------------------------------------- -inline void LowerString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { +inline void LowerString(std::string* s) { + std::string::iterator end = s->end(); + for (std::string::iterator i = s->begin(); i != end; ++i) { // tolower() changes based on locale. We don't want this! if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A'; } } -inline void UpperString(string * s) { - string::iterator end = s->end(); - for (string::iterator i = s->begin(); i != end; ++i) { +inline void UpperString(std::string* s) { + std::string::iterator end = s->end(); + for (std::string::iterator i = s->begin(); i != end; ++i) { // toupper() changes based on locale. We don't want this! if ('a' <= *i && *i <= 'z') *i += 'A' - 'a'; } } -inline string ToUpper(const string& s) { - string out = s; +inline void ToUpper(std::string* s) { UpperString(s); } + +inline std::string ToUpper(const std::string& s) { + std::string out = s; UpperString(&out); return out; } @@ -202,8 +206,10 @@ inline string ToUpper(const string& s) { // happened or not. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, - const string& newsub, bool replace_all); +PROTOBUF_EXPORT std::string StringReplace(const std::string& s, + const std::string& oldsub, + const std::string& newsub, + bool replace_all); // ---------------------------------------------------------------------- // SplitStringUsing() @@ -211,8 +217,8 @@ PROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub, // to 'result'. If there are consecutive delimiters, this function skips // over all of them. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim, - std::vector* res); +PROTOBUF_EXPORT void SplitStringUsing(StringPiece full, const char* delim, + std::vector* res); // Split a string using one or more byte delimiters, presented // as a nul-terminated c string. Append the components to 'result'. @@ -222,17 +228,16 @@ PROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim, // // If "full" is the empty string, yields an empty string as the only value. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void SplitStringAllowEmpty(const string& full, - const char* delim, - std::vector* result); +PROTOBUF_EXPORT void SplitStringAllowEmpty(StringPiece full, const char* delim, + std::vector* result); // ---------------------------------------------------------------------- // Split() // Split a string using a character delimiter. // ---------------------------------------------------------------------- -inline std::vector Split( - const string& full, const char* delim, bool skip_empty = true) { - std::vector result; +inline std::vector Split(StringPiece full, const char* delim, + bool skip_empty = true) { + std::vector result; if (skip_empty) { SplitStringUsing(full, delim, &result); } else { @@ -249,12 +254,12 @@ inline std::vector Split( // another takes a pointer to the target string. In the latter case the // target string is cleared and overwritten. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void JoinStrings(const std::vector& components, - const char* delim, string* result); +PROTOBUF_EXPORT void JoinStrings(const std::vector& components, + const char* delim, std::string* result); -inline string JoinStrings(const std::vector& components, - const char* delim) { - string result; +inline std::string JoinStrings(const std::vector& components, + const char* delim) { + std::string result; JoinStrings(components, delim, &result); return result; } @@ -292,7 +297,7 @@ inline string JoinStrings(const std::vector& components, PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest); PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, - std::vector* errors); + std::vector* errors); // ---------------------------------------------------------------------- // UnescapeCEscapeString() @@ -309,10 +314,12 @@ PROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest, // the third call, the new string is returned. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest); -PROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest, - std::vector* errors); -PROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); +PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src, + std::string* dest); +PROTOBUF_EXPORT int UnescapeCEscapeString(const std::string& src, + std::string* dest, + std::vector* errors); +PROTOBUF_EXPORT std::string UnescapeCEscapeString(const std::string& src); // ---------------------------------------------------------------------- // CEscape() @@ -321,21 +328,21 @@ PROTOBUF_EXPORT string UnescapeCEscapeString(const string& src); // // Escaped chars: \n, \r, \t, ", ', \, and !isprint(). // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string CEscape(const string& src); +PROTOBUF_EXPORT std::string CEscape(const std::string& src); // ---------------------------------------------------------------------- // CEscapeAndAppend() // Escapes 'src' using C-style escape sequences, and appends the escaped // string to 'dest'. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, string* dest); +PROTOBUF_EXPORT void CEscapeAndAppend(StringPiece src, std::string* dest); namespace strings { // Like CEscape() but does not escape bytes with the upper bit set. -PROTOBUF_EXPORT string Utf8SafeCEscape(const string& src); +PROTOBUF_EXPORT std::string Utf8SafeCEscape(const std::string& src); // Like CEscape() but uses hex (\x) escapes instead of octals. -PROTOBUF_EXPORT string CHexEscape(const string& src); +PROTOBUF_EXPORT std::string CHexEscape(const std::string& src); } // namespace strings // ---------------------------------------------------------------------- @@ -392,31 +399,31 @@ inline uint64 strtou64(const char *nptr, char **endptr, int base) { // ---------------------------------------------------------------------- PROTOBUF_EXPORT bool safe_strtob(StringPiece str, bool* value); -PROTOBUF_EXPORT bool safe_strto32(const string& str, int32* value); -PROTOBUF_EXPORT bool safe_strtou32(const string& str, uint32* value); +PROTOBUF_EXPORT bool safe_strto32(const std::string& str, int32* value); +PROTOBUF_EXPORT bool safe_strtou32(const std::string& str, uint32* value); inline bool safe_strto32(const char* str, int32* value) { - return safe_strto32(string(str), value); + return safe_strto32(std::string(str), value); } inline bool safe_strto32(StringPiece str, int32* value) { return safe_strto32(str.ToString(), value); } inline bool safe_strtou32(const char* str, uint32* value) { - return safe_strtou32(string(str), value); + return safe_strtou32(std::string(str), value); } inline bool safe_strtou32(StringPiece str, uint32* value) { return safe_strtou32(str.ToString(), value); } -PROTOBUF_EXPORT bool safe_strto64(const string& str, int64* value); -PROTOBUF_EXPORT bool safe_strtou64(const string& str, uint64* value); +PROTOBUF_EXPORT bool safe_strto64(const std::string& str, int64* value); +PROTOBUF_EXPORT bool safe_strtou64(const std::string& str, uint64* value); inline bool safe_strto64(const char* str, int64* value) { - return safe_strto64(string(str), value); + return safe_strto64(std::string(str), value); } inline bool safe_strto64(StringPiece str, int64* value) { return safe_strto64(str.ToString(), value); } inline bool safe_strtou64(const char* str, uint64* value) { - return safe_strtou64(string(str), value); + return safe_strtou64(std::string(str), value); } inline bool safe_strtou64(StringPiece str, uint64* value) { return safe_strtou64(str.ToString(), value); @@ -424,10 +431,10 @@ inline bool safe_strtou64(StringPiece str, uint64* value) { PROTOBUF_EXPORT bool safe_strtof(const char* str, float* value); PROTOBUF_EXPORT bool safe_strtod(const char* str, double* value); -inline bool safe_strtof(const string& str, float* value) { +inline bool safe_strtof(const std::string& str, float* value) { return safe_strtof(str.c_str(), value); } -inline bool safe_strtod(const string& str, double* value) { +inline bool safe_strtod(const std::string& str, double* value) { return safe_strtod(str.c_str(), value); } inline bool safe_strtof(StringPiece str, float* value) { @@ -520,9 +527,7 @@ inline char* FastUInt64ToBuffer(uint64 i, char* buffer) { return buffer; } -inline string SimpleBtoa(bool value) { - return value ? "true" : "false"; -} +inline std::string SimpleBtoa(bool value) { return value ? "true" : "false"; } // ---------------------------------------------------------------------- // SimpleItoa() @@ -530,12 +535,12 @@ inline string SimpleBtoa(bool value) { // // Return value: string // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string SimpleItoa(int i); -PROTOBUF_EXPORT string SimpleItoa(unsigned int i); -PROTOBUF_EXPORT string SimpleItoa(long i); -PROTOBUF_EXPORT string SimpleItoa(unsigned long i); -PROTOBUF_EXPORT string SimpleItoa(long long i); -PROTOBUF_EXPORT string SimpleItoa(unsigned long long i); +PROTOBUF_EXPORT std::string SimpleItoa(int i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned int i); +PROTOBUF_EXPORT std::string SimpleItoa(long i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned long i); +PROTOBUF_EXPORT std::string SimpleItoa(long long i); +PROTOBUF_EXPORT std::string SimpleItoa(unsigned long long i); // ---------------------------------------------------------------------- // SimpleDtoa() @@ -556,8 +561,8 @@ PROTOBUF_EXPORT string SimpleItoa(unsigned long long i); // // Return value: string // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string SimpleDtoa(double value); -PROTOBUF_EXPORT string SimpleFtoa(float value); +PROTOBUF_EXPORT std::string SimpleDtoa(double value); +PROTOBUF_EXPORT std::string SimpleFtoa(float value); PROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer); PROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer); @@ -653,7 +658,7 @@ struct PROTOBUF_EXPORT AlphaNum { // TODO: Add a string_ref constructor, eventually // AlphaNum(const StringPiece &pc) : piece(pc) {} - AlphaNum(const string& str) + AlphaNum(const std::string& str) : piece_data_(str.data()), piece_size_(str.size()) {} AlphaNum(StringPiece str) @@ -701,32 +706,34 @@ using strings::AlphaNum; // be a reference into str. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g, const AlphaNum& h); -PROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d, - const AlphaNum& e, const AlphaNum& f, - const AlphaNum& g, const AlphaNum& h, - const AlphaNum& i); - -inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h); +PROTOBUF_EXPORT std::string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g, const AlphaNum& h, + const AlphaNum& i); + +inline std::string StrCat(const AlphaNum& a) { + return std::string(a.data(), a.size()); +} // ---------------------------------------------------------------------- // StrAppend() @@ -749,12 +756,12 @@ inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } // worked around as consecutive calls to StrAppend are quite efficient. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a); +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c); -PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, +PROTOBUF_EXPORT void StrAppend(std::string* dest, const AlphaNum& a, const AlphaNum& b, const AlphaNum& c, const AlphaNum& d); @@ -764,8 +771,8 @@ PROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, // the C-string "delim" as a separator between components. // ---------------------------------------------------------------------- template -void Join(Iterator start, Iterator end, - const char* delim, string* result) { +void Join(Iterator start, Iterator end, const char* delim, + std::string* result) { for (Iterator it = start; it != end; ++it) { if (it != start) { result->append(delim); @@ -775,9 +782,8 @@ void Join(Iterator start, Iterator end, } template -string Join(const Range& components, - const char* delim) { - string result; +std::string Join(const Range& components, const char* delim) { + std::string result; Join(components.begin(), components.end(), delim, &result); return result; } @@ -786,7 +792,7 @@ string Join(const Range& components, // ToHex() // Return a lower-case hex string representation of the given integer. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT string ToHex(uint64 num); +PROTOBUF_EXPORT std::string ToHex(uint64 num); // ---------------------------------------------------------------------- // GlobalReplaceSubstring() @@ -795,9 +801,9 @@ PROTOBUF_EXPORT string ToHex(uint64 num); // // NOTE: The string pieces must not overlap s. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT int GlobalReplaceSubstring(const string& substring, - const string& replacement, - string* s); +PROTOBUF_EXPORT int GlobalReplaceSubstring(const std::string& substring, + const std::string& replacement, + std::string* s); // ---------------------------------------------------------------------- // Base64Unescape() @@ -805,7 +811,7 @@ PROTOBUF_EXPORT int GlobalReplaceSubstring(const string& substring, // writes it to "dest". If src contains invalid characters, dest is cleared // and the function returns false. Returns true on success. // ---------------------------------------------------------------------- -PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, string* dest); +PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, std::string* dest); // ---------------------------------------------------------------------- // WebSafeBase64Unescape() @@ -820,7 +826,7 @@ PROTOBUF_EXPORT bool Base64Unescape(StringPiece src, string* dest); // ---------------------------------------------------------------------- PROTOBUF_EXPORT int WebSafeBase64Unescape(const char* src, int slen, char* dest, int szdest); -PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, string* dest); +PROTOBUF_EXPORT bool WebSafeBase64Unescape(StringPiece src, std::string* dest); // Return the length to use for the output buffer given to the base64 escape // routines. Make sure to use the same value for do_padding in both. @@ -848,17 +854,17 @@ PROTOBUF_EXPORT int WebSafeBase64Escape(const unsigned char* src, int slen, char* dest, int szdest, bool do_padding); // Encode src into dest with padding. -PROTOBUF_EXPORT void Base64Escape(StringPiece src, string* dest); +PROTOBUF_EXPORT void Base64Escape(StringPiece src, std::string* dest); // Encode src into dest web-safely without padding. -PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, string* dest); +PROTOBUF_EXPORT void WebSafeBase64Escape(StringPiece src, std::string* dest); // Encode src into dest web-safely with padding. PROTOBUF_EXPORT void WebSafeBase64EscapeWithPadding(StringPiece src, - string* dest); + std::string* dest); PROTOBUF_EXPORT void Base64Escape(const unsigned char* src, int szsrc, - string* dest, bool do_padding); + std::string* dest, bool do_padding); PROTOBUF_EXPORT void WebSafeBase64Escape(const unsigned char* src, int szsrc, - string* dest, bool do_padding); + std::string* dest, bool do_padding); inline bool IsValidCodePoint(uint32 code_point) { return code_point < 0xD800 || @@ -914,11 +920,12 @@ PROTOBUF_EXPORT int UTF8FirstLetterNumBytes(const char* src, int len); // // (1) determines the presence of LF (first one is ok) // (2) if yes, removes any CR, else convert every CR to LF -PROTOBUF_EXPORT void CleanStringLineEndings(const string& src, string* dst, +PROTOBUF_EXPORT void CleanStringLineEndings(const std::string& src, + std::string* dst, bool auto_end_last_line); // Same as above, but transforms the argument in place. -PROTOBUF_EXPORT void CleanStringLineEndings(string* str, +PROTOBUF_EXPORT void CleanStringLineEndings(std::string* str, bool auto_end_last_line); namespace strings { diff --git a/src/google/protobuf/stubs/strutil_unittest.cc b/src/google/protobuf/stubs/strutil_unittest.cc index 141d263a401a..fc9a63f3f252 100644 --- a/src/google/protobuf/stubs/strutil_unittest.cc +++ b/src/google/protobuf/stubs/strutil_unittest.cc @@ -52,7 +52,7 @@ TEST(StringUtilityTest, ImmuneToLocales) { // Remember the old locale. char* old_locale_cstr = setlocale(LC_NUMERIC, nullptr); ASSERT_TRUE(old_locale_cstr != nullptr); - string old_locale = old_locale_cstr; + std::string old_locale = old_locale_cstr; // Set the locale to "C". ASSERT_TRUE(setlocale(LC_NUMERIC, "C") != nullptr); @@ -442,7 +442,7 @@ TEST(Base64, EscapeAndUnescape) { char decode_buffer[100]; int decode_length; int cypher_length; - string decode_str; + std::string decode_str; const unsigned char* unsigned_plaintext = reinterpret_cast(base64_tests[i].plaintext); @@ -491,13 +491,13 @@ TEST(Base64, EscapeAndUnescape) { EXPECT_EQ(plaintext, decode_str); // Let's try with a pre-populated string. - string encoded("this junk should be ignored"); - Base64Escape(string(base64_tests[i].plaintext, - base64_tests[i].plain_length), - &encoded); - EXPECT_EQ(encoded, string(encode_buffer, cypher_length)); + std::string encoded("this junk should be ignored"); + Base64Escape( + std::string(base64_tests[i].plaintext, base64_tests[i].plain_length), + &encoded); + EXPECT_EQ(encoded, std::string(encode_buffer, cypher_length)); - string decoded("this junk should be ignored"); + std::string decoded("this junk should be ignored"); EXPECT_TRUE(Base64Unescape( StringPiece(encode_buffer, cypher_length), &decoded)); EXPECT_EQ(decoded.size(), base64_tests[i].plain_length); @@ -514,7 +514,7 @@ TEST(Base64, EscapeAndUnescape) { // Try chopping off the equals sign(s) entirely. The decoder // should still be okay with this. - string decoded2("this junk should also be ignored"); + std::string decoded2("this junk should also be ignored"); *first_equals = '\0'; EXPECT_TRUE(Base64Unescape( StringPiece(encode_buffer, first_equals - encode_buffer), &decoded2)); @@ -730,7 +730,7 @@ TEST(Base64, EscapeAndUnescape) { EXPECT_STREQ(encode_buffer, websafe); // Let's try the (other) string version of the encoder - string plain(base64_tests[i].plaintext, base64_tests[i].plain_length); + std::string plain(base64_tests[i].plaintext, base64_tests[i].plain_length); encoded = "this junk should be ignored"; WebSafeBase64Escape(plain, &encoded); EXPECT_EQ(encoded.size(), cypher_length); @@ -798,7 +798,7 @@ TEST(Base64, EscapeAndUnescape) { // Verify the behavior when decoding bad data { const char* bad_data = "ab-/"; - string buf; + std::string buf; EXPECT_FALSE(Base64Unescape(StringPiece(bad_data), &buf)); EXPECT_TRUE(!WebSafeBase64Unescape(bad_data, &buf)); EXPECT_TRUE(buf.empty()); @@ -819,7 +819,7 @@ TEST(StrCat, Ints) { const size_t size = 10; const intptr_t intptr = -12; const uintptr_t uintptr = 13; - string answer; + std::string answer; answer = StrCat(s, us); EXPECT_EQ(answer, "-12"); answer = StrCat(i, ui); @@ -836,12 +836,13 @@ TEST(StrCat, Ints) { EXPECT_EQ(answer, "130"); } -class ReplaceChars : public ::testing::TestWithParam< - std::tuple> {}; +class ReplaceChars + : public ::testing::TestWithParam< + std::tuple> {}; TEST_P(ReplaceChars, ReplacesAllOccurencesOfAnyCharInReplaceWithAReplaceChar) { - string expected = std::get<0>(GetParam()); - string string_to_replace_in = std::get<1>(GetParam()); + std::string expected = std::get<0>(GetParam()); + std::string string_to_replace_in = std::get<1>(GetParam()); const char* what_to_replace = std::get<2>(GetParam()); char replacement = std::get<3>(GetParam()); ReplaceCharacters(&string_to_replace_in, what_to_replace, replacement); @@ -864,11 +865,12 @@ INSTANTIATE_TEST_CASE_P( std::make_tuple("qvvvvvng v T", "queueing a T", "aeiou", 'v'))); // replace all voewls -class StripWs : public ::testing::TestWithParam> {}; +class StripWs + : public ::testing::TestWithParam> {}; TEST_P(StripWs, AlwaysStripsLeadingAndTrailingWhitespace) { - string expected = std::get<0>(GetParam()); - string string_to_strip = std::get<1>(GetParam()); + std::string expected = std::get<0>(GetParam()); + std::string string_to_strip = std::get<1>(GetParam()); StripWhitespace(&string_to_strip); ASSERT_EQ(expected, string_to_strip); } diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc index a36f2f026c5e..92107416eb1b 100644 --- a/src/google/protobuf/stubs/substitute.cc +++ b/src/google/protobuf/stubs/substitute.cc @@ -52,26 +52,24 @@ static int CountSubstituteArgs(const SubstituteArg* const* args_array) { return count; } -string Substitute( - const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { - string result; +std::string Substitute(const char* format, const SubstituteArg& arg0, + const SubstituteArg& arg1, const SubstituteArg& arg2, + const SubstituteArg& arg3, const SubstituteArg& arg4, + const SubstituteArg& arg5, const SubstituteArg& arg6, + const SubstituteArg& arg7, const SubstituteArg& arg8, + const SubstituteArg& arg9) { + std::string result; SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); return result; } -void SubstituteAndAppend( - string* output, const char* format, - const SubstituteArg& arg0, const SubstituteArg& arg1, - const SubstituteArg& arg2, const SubstituteArg& arg3, - const SubstituteArg& arg4, const SubstituteArg& arg5, - const SubstituteArg& arg6, const SubstituteArg& arg7, - const SubstituteArg& arg8, const SubstituteArg& arg9) { +void SubstituteAndAppend(std::string* output, const char* format, + const SubstituteArg& arg0, const SubstituteArg& arg1, + const SubstituteArg& arg2, const SubstituteArg& arg3, + const SubstituteArg& arg4, const SubstituteArg& arg5, + const SubstituteArg& arg6, const SubstituteArg& arg7, + const SubstituteArg& arg8, const SubstituteArg& arg9) { const SubstituteArg* const args_array[] = { &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, nullptr }; diff --git a/src/google/protobuf/stubs/substitute.h b/src/google/protobuf/stubs/substitute.h index 267dead236b3..d4e72e1c5166 100644 --- a/src/google/protobuf/stubs/substitute.h +++ b/src/google/protobuf/stubs/substitute.h @@ -90,8 +90,8 @@ class SubstituteArg { public: inline SubstituteArg(const char* value) : text_(value), size_(strlen(text_)) {} - inline SubstituteArg(const string& value) - : text_(value.data()), size_(value.size()) {} + inline SubstituteArg(const std::string& value) + : text_(value.data()), size_(value.size()) {} // Indicates that no argument was given. inline explicit SubstituteArg() @@ -139,21 +139,21 @@ class SubstituteArg { } // namespace internal -PROTOBUF_EXPORT string -Substitute(const char* format, - const internal::SubstituteArg& arg0 = internal::SubstituteArg(), - const internal::SubstituteArg& arg1 = internal::SubstituteArg(), - const internal::SubstituteArg& arg2 = internal::SubstituteArg(), - const internal::SubstituteArg& arg3 = internal::SubstituteArg(), - const internal::SubstituteArg& arg4 = internal::SubstituteArg(), - const internal::SubstituteArg& arg5 = internal::SubstituteArg(), - const internal::SubstituteArg& arg6 = internal::SubstituteArg(), - const internal::SubstituteArg& arg7 = internal::SubstituteArg(), - const internal::SubstituteArg& arg8 = internal::SubstituteArg(), - const internal::SubstituteArg& arg9 = internal::SubstituteArg()); +PROTOBUF_EXPORT std::string Substitute( + const char* format, + const internal::SubstituteArg& arg0 = internal::SubstituteArg(), + const internal::SubstituteArg& arg1 = internal::SubstituteArg(), + const internal::SubstituteArg& arg2 = internal::SubstituteArg(), + const internal::SubstituteArg& arg3 = internal::SubstituteArg(), + const internal::SubstituteArg& arg4 = internal::SubstituteArg(), + const internal::SubstituteArg& arg5 = internal::SubstituteArg(), + const internal::SubstituteArg& arg6 = internal::SubstituteArg(), + const internal::SubstituteArg& arg7 = internal::SubstituteArg(), + const internal::SubstituteArg& arg8 = internal::SubstituteArg(), + const internal::SubstituteArg& arg9 = internal::SubstituteArg()); PROTOBUF_EXPORT void SubstituteAndAppend( - string* output, const char* format, + std::string* output, const char* format, const internal::SubstituteArg& arg0 = internal::SubstituteArg(), const internal::SubstituteArg& arg1 = internal::SubstituteArg(), const internal::SubstituteArg& arg2 = internal::SubstituteArg(), diff --git a/src/google/protobuf/stubs/time.cc b/src/google/protobuf/stubs/time.cc index 64f3ceb9f6fb..922be76d1ba3 100644 --- a/src/google/protobuf/stubs/time.cc +++ b/src/google/protobuf/stubs/time.cc @@ -130,7 +130,7 @@ int64 SecondsSinceCommonEra(const DateTime& time) { // Format nanoseconds with either 3, 6, or 9 digits depending on the required // precision to represent the exact value. -string FormatNanos(int32 nanos) { +std::string FormatNanos(int32 nanos) { if (nanos % kNanosPerMillisecond == 0) { return StringPrintf("%03d", nanos / kNanosPerMillisecond); } else if (nanos % kNanosPerMicrosecond == 0) { @@ -268,21 +268,21 @@ void GetCurrentTime(int64* seconds, int32* nanos) { *nanos = 0; } -string FormatTime(int64 seconds, int32 nanos) { +std::string FormatTime(int64 seconds, int32 nanos) { DateTime time; if (nanos < 0 || nanos > 999999999 || !SecondsToDateTime(seconds, &time)) { return "InvalidTime"; } - string result = StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", - time.year, time.month, time.day, - time.hour, time.minute, time.second); + std::string result = + StringPrintf("%04d-%02d-%02dT%02d:%02d:%02d", time.year, time.month, + time.day, time.hour, time.minute, time.second); if (nanos != 0) { result += "." + FormatNanos(nanos); } return result + "Z"; } -bool ParseTime(const string& value, int64* seconds, int32* nanos) { +bool ParseTime(const std::string& value, int64* seconds, int32* nanos) { DateTime time; const char* data = value.c_str(); // We only accept: diff --git a/src/google/protobuf/stubs/time.h b/src/google/protobuf/stubs/time.h index b52f3f963290..b06117689e58 100644 --- a/src/google/protobuf/stubs/time.h +++ b/src/google/protobuf/stubs/time.h @@ -65,10 +65,10 @@ void PROTOBUF_EXPORT GetCurrentTime(int64* seconds, int32* nanos); // value. // // Note that "nanos" must in the range of [0, 999999999]. -string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos); +std::string PROTOBUF_EXPORT FormatTime(int64 seconds, int32 nanos); // Parses a time string. This method accepts RFC3339 date/time string with UTC // offset. For example, "2015-05-20T13:29:35.120-08:00". -bool PROTOBUF_EXPORT ParseTime(const string& value, int64* seconds, +bool PROTOBUF_EXPORT ParseTime(const std::string& value, int64* seconds, int32* nanos); } // namespace internal diff --git a/src/google/protobuf/stubs/time_test.cc b/src/google/protobuf/stubs/time_test.cc index fc72925fa968..1ce0a1c130f7 100644 --- a/src/google/protobuf/stubs/time_test.cc +++ b/src/google/protobuf/stubs/time_test.cc @@ -38,7 +38,7 @@ namespace internal { namespace { static const int64 kSecondsPerDay = 3600 * 24; -// For DateTime, tests will mostly focuse on the date part because that's +// For DateTime, tests will mostly focus on the date part because that's // the tricky one. int64 CreateTimestamp(int year, int month, int day) { DateTime time; diff --git a/src/google/protobuf/test_messages_proto3.proto b/src/google/protobuf/test_messages_proto3.proto index a10f44d946e1..4e409dc900e3 100644 --- a/src/google/protobuf/test_messages_proto3.proto +++ b/src/google/protobuf/test_messages_proto3.proto @@ -203,6 +203,7 @@ message TestAllTypesProto3 { float oneof_float = 117; double oneof_double = 118; NestedEnum oneof_enum = 119; + google.protobuf.NullValue oneof_null_value = 120; } // Well-known types @@ -232,6 +233,7 @@ message TestAllTypesProto3 { google.protobuf.Struct optional_struct = 304; google.protobuf.Any optional_any = 305; google.protobuf.Value optional_value = 306; + google.protobuf.NullValue optional_null_value = 307; repeated google.protobuf.Duration repeated_duration = 311; repeated google.protobuf.Timestamp repeated_timestamp = 312; diff --git a/src/google/protobuf/test_util_lite.cc b/src/google/protobuf/test_util_lite.cc index a897fe26b558..e7eb60a6b7d6 100644 --- a/src/google/protobuf/test_util_lite.cc +++ b/src/google/protobuf/test_util_lite.cc @@ -1351,7 +1351,7 @@ void TestUtilLite::ExpectExtensionsClear( std::string serialized; ASSERT_TRUE(message.SerializeToString(&serialized)); EXPECT_EQ("", serialized); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); // has_blah() should initially be false for all optional fields. EXPECT_FALSE(message.HasExtension(unittest::optional_int32_extension_lite)); diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc index 7d3708e3d64d..7b628879c64e 100644 --- a/src/google/protobuf/testing/file.cc +++ b/src/google/protobuf/testing/file.cc @@ -66,11 +66,12 @@ using google::protobuf::io::win32::mkdir; using google::protobuf::io::win32::stat; #endif -bool File::Exists(const string& name) { +bool File::Exists(const std::string& name) { return access(name.c_str(), F_OK) == 0; } -bool File::ReadFileToString(const string& name, string* output, bool text_mode) { +bool File::ReadFileToString(const std::string& name, std::string* output, + bool text_mode) { char buffer[1024]; FILE* file = fopen(name.c_str(), text_mode ? "rt" : "rb"); if (file == NULL) return false; @@ -86,11 +87,12 @@ bool File::ReadFileToString(const string& name, string* output, bool text_mode) return error == 0; } -void File::ReadFileToStringOrDie(const string& name, string* output) { +void File::ReadFileToStringOrDie(const std::string& name, std::string* output) { GOOGLE_CHECK(ReadFileToString(name, output)) << "Could not read: " << name; } -bool File::WriteStringToFile(const string& contents, const string& name) { +bool File::WriteStringToFile(const std::string& contents, + const std::string& name) { FILE* file = fopen(name.c_str(), "wb"); if (file == NULL) { GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno); @@ -109,7 +111,8 @@ bool File::WriteStringToFile(const string& contents, const string& name) { return true; } -void File::WriteStringToFileOrDie(const string& contents, const string& name) { +void File::WriteStringToFileOrDie(const std::string& contents, + const std::string& name) { FILE* file = fopen(name.c_str(), "wb"); GOOGLE_CHECK(file != NULL) << "fopen(" << name << ", \"wb\"): " << strerror(errno); @@ -120,21 +123,21 @@ void File::WriteStringToFileOrDie(const string& contents, const string& name) { << "fclose(" << name << "): " << strerror(errno); } -bool File::CreateDir(const string& name, int mode) { +bool File::CreateDir(const std::string& name, int mode) { if (!name.empty()) { GOOGLE_CHECK_OK(name[name.size() - 1] != '.'); } return mkdir(name.c_str(), mode) == 0; } -bool File::RecursivelyCreateDir(const string& path, int mode) { +bool File::RecursivelyCreateDir(const std::string& path, int mode) { if (CreateDir(path, mode)) return true; if (Exists(path)) return false; // Try creating the parent. - string::size_type slashpos = path.find_last_of('/'); - if (slashpos == string::npos) { + std::string::size_type slashpos = path.find_last_of('/'); + if (slashpos == std::string::npos) { // No parent given. return false; } @@ -143,8 +146,8 @@ bool File::RecursivelyCreateDir(const string& path, int mode) { CreateDir(path, mode); } -void File::DeleteRecursively(const string& name, - void* dummy1, void* dummy2) { +void File::DeleteRecursively(const std::string& name, void* dummy1, + void* dummy2) { if (name.empty()) return; // We don't care too much about error checking here since this is only used @@ -162,9 +165,9 @@ void File::DeleteRecursively(const string& name, } do { - string entry_name = find_data.cFileName; + std::string entry_name = find_data.cFileName; if (entry_name != "." && entry_name != "..") { - string path = name + "/" + entry_name; + std::string path = name + "/" + entry_name; if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { DeleteRecursively(path, NULL, NULL); RemoveDirectoryA(path.c_str()); @@ -188,7 +191,7 @@ void File::DeleteRecursively(const string& name, while (true) { struct dirent* entry = readdir(dir); if (entry == NULL) break; - string entry_name = entry->d_name; + std::string entry_name = entry->d_name; if (entry_name != "." && entry_name != "..") { DeleteRecursively(name + "/" + entry_name, NULL, NULL); } @@ -204,7 +207,7 @@ void File::DeleteRecursively(const string& name, #endif } -bool File::ChangeWorkingDirectory(const string& new_working_directory) { +bool File::ChangeWorkingDirectory(const std::string& new_working_directory) { return chdir(new_working_directory.c_str()) == 0; } diff --git a/src/google/protobuf/testing/file.h b/src/google/protobuf/testing/file.h index 45989967c979..f18f68586521 100644 --- a/src/google/protobuf/testing/file.h +++ b/src/google/protobuf/testing/file.h @@ -46,52 +46,54 @@ const int DEFAULT_FILE_MODE = 0777; class File { public: // Check if the file exists. - static bool Exists(const string& name); + static bool Exists(const std::string& name); // Read an entire file to a string. Return true if successful, false // otherwise. - static bool ReadFileToString(const string& name, string* output, bool text_mode = false); + static bool ReadFileToString(const std::string& name, std::string* output, + bool text_mode = false); // Same as above, but crash on failure. - static void ReadFileToStringOrDie(const string& name, string* output); + static void ReadFileToStringOrDie(const std::string& name, + std::string* output); // Create a file and write a string to it. - static bool WriteStringToFile(const string& contents, - const string& name); + static bool WriteStringToFile(const std::string& contents, + const std::string& name); // Same as above, but crash on failure. - static void WriteStringToFileOrDie(const string& contents, - const string& name); + static void WriteStringToFileOrDie(const std::string& contents, + const std::string& name); // Create a directory. - static bool CreateDir(const string& name, int mode); + static bool CreateDir(const std::string& name, int mode); // Create a directory and all parent directories if necessary. - static bool RecursivelyCreateDir(const string& path, int mode); + static bool RecursivelyCreateDir(const std::string& path, int mode); // If "name" is a file, we delete it. If it is a directory, we // call DeleteRecursively() for each file or directory (other than // dot and double-dot) within it, and then delete the directory itself. // The "dummy" parameters have a meaning in the original version of this // method but they are not used anywhere in protocol buffers. - static void DeleteRecursively(const string& name, - void* dummy1, void* dummy2); + static void DeleteRecursively(const std::string& name, void* dummy1, + void* dummy2); // Change working directory to given directory. - static bool ChangeWorkingDirectory(const string& new_working_directory); + static bool ChangeWorkingDirectory(const std::string& new_working_directory); - static bool GetContents( - const string& name, string* output, bool /*is_default*/) { + static bool GetContents(const std::string& name, std::string* output, + bool /*is_default*/) { return ReadFileToString(name, output); } - static bool GetContentsAsText( - const string& name, string* output, bool /*is_default*/) { + static bool GetContentsAsText(const std::string& name, std::string* output, + bool /*is_default*/) { return ReadFileToString(name, output, true); } - static bool SetContents( - const string& name, const string& contents, bool /*is_default*/) { + static bool SetContents(const std::string& name, const std::string& contents, + bool /*is_default*/) { return WriteStringToFile(contents, name); } diff --git a/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc index 1856971cb8b3..88343f934761 100644 --- a/src/google/protobuf/testing/googletest.cc +++ b/src/google/protobuf/testing/googletest.cc @@ -70,7 +70,7 @@ using google::protobuf::io::win32::open; #endif #endif -string TestSourceDir() { +std::string TestSourceDir() { #ifndef GOOGLE_THIRD_PARTY_PROTOBUF #ifdef GOOGLE_PROTOBUF_TEST_SOURCE_PATH return GOOGLE_PROTOBUF_TEST_SOURCE_PATH; @@ -84,7 +84,7 @@ string TestSourceDir() { #endif // _MSC_VER // Look for the "src" directory. - string prefix = "."; + std::string prefix = "."; // Keep looking further up the directory tree until we find // src/.../descriptor.cc. It is important to look for a particular file, @@ -107,12 +107,12 @@ string TestSourceDir() { namespace { -string GetTemporaryDirectoryName() { +std::string GetTemporaryDirectoryName() { // Tests run under Bazel "should not" use /tmp. Bazel sets this environment // variable for tests to use instead. char *from_environment = getenv("TEST_TMPDIR"); if (from_environment != NULL && from_environment[0] != '\0') { - return string(from_environment) + "/protobuf_tmpdir"; + return std::string(from_environment) + "/protobuf_tmpdir"; } // tmpnam() is generally not considered safe but we're only using it for @@ -121,7 +121,7 @@ string GetTemporaryDirectoryName() { char b[L_tmpnam + 1]; // HPUX multithread return 0 if s is 0 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - string result = tmpnam(b); + std::string result = tmpnam(b); #pragma GCC diagnostic pop #ifdef _WIN32 // Avoid a trailing dot by changing it to an underscore. On Win32 the names of @@ -166,7 +166,7 @@ class TempDirDeleter { } } - string GetTempDir() { + std::string GetTempDir() { if (name_.empty()) { name_ = GetTemporaryDirectoryName(); GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno); @@ -179,21 +179,19 @@ class TempDirDeleter { } private: - string name_; + std::string name_; }; TempDirDeleter temp_dir_deleter_; } // namespace -string TestTempDir() { - return temp_dir_deleter_.GetTempDir(); -} +std::string TestTempDir() { return temp_dir_deleter_.GetTempDir(); } // TODO(kenton): Share duplicated code below. Too busy/lazy for now. -static string stdout_capture_filename_; -static string stderr_capture_filename_; +static std::string stdout_capture_filename_; +static std::string stderr_capture_filename_; static int original_stdout_ = -1; static int original_stderr_ = -1; @@ -227,14 +225,14 @@ void CaptureTestStderr() { close(fd); } -string GetCapturedTestStdout() { +std::string GetCapturedTestStdout() { GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing."; close(1); dup2(original_stdout_, 1); original_stdout_ = -1; - string result; + std::string result; File::ReadFileToStringOrDie(stdout_capture_filename_, &result); remove(stdout_capture_filename_.c_str()); @@ -242,14 +240,14 @@ string GetCapturedTestStdout() { return result; } -string GetCapturedTestStderr() { +std::string GetCapturedTestStderr() { GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing."; close(2); dup2(original_stderr_, 2); original_stderr_ = -1; - string result; + std::string result; File::ReadFileToStringOrDie(stderr_capture_filename_, &result); remove(stderr_capture_filename_.c_str()); @@ -270,14 +268,14 @@ ScopedMemoryLog::~ScopedMemoryLog() { active_log_ = NULL; } -const std::vector& ScopedMemoryLog::GetMessages(LogLevel level) { +const std::vector& ScopedMemoryLog::GetMessages(LogLevel level) { GOOGLE_CHECK(level == ERROR || level == WARNING); return messages_[level]; } -void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, - int line, const string& message) { +void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename, int line, + const std::string& message) { GOOGLE_CHECK(active_log_ != NULL); if (level == ERROR || level == WARNING) { active_log_->messages_[level].push_back(message); diff --git a/src/google/protobuf/testing/googletest.h b/src/google/protobuf/testing/googletest.h index 4e0cb83a8502..6a0c694e71a6 100644 --- a/src/google/protobuf/testing/googletest.h +++ b/src/google/protobuf/testing/googletest.h @@ -49,19 +49,19 @@ namespace google { namespace protobuf { // When running unittests, get the directory containing the source code. -string TestSourceDir(); +std::string TestSourceDir(); // When running unittests, get a directory where temporary files may be // placed. -string TestTempDir(); +std::string TestTempDir(); // Capture all text written to stdout or stderr. void CaptureTestStdout(); void CaptureTestStderr(); // Stop capturing stdout or stderr and return the text captured. -string GetCapturedTestStdout(); -string GetCapturedTestStderr(); +std::string GetCapturedTestStdout(); +std::string GetCapturedTestStderr(); // For use with ScopedMemoryLog::GetMessages(). Inside Google the LogLevel // constants don't have the LOGLEVEL_ prefix, so the code that used @@ -84,14 +84,14 @@ class ScopedMemoryLog { virtual ~ScopedMemoryLog(); // Fetches all messages with the given severity level. - const std::vector& GetMessages(LogLevel error); + const std::vector& GetMessages(LogLevel error); private: - std::map > messages_; + std::map > messages_; LogHandler* old_handler_; static void HandleLog(LogLevel level, const char* filename, int line, - const string& message); + const std::string& message); static ScopedMemoryLog* active_log_; diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 6b3308892764..1af250d3f52a 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -54,7 +54,6 @@ #include #include #include -#include #include #include #include @@ -63,6 +62,9 @@ #include #include +// Must be included last. +#include + namespace google { namespace protobuf { @@ -101,7 +103,7 @@ std::string Message::ShortDebugString() const { printer.PrintToString(*this, &debug_string); // Single line mode currently might have an extra space at the end. - if (debug_string.size() > 0 && debug_string[debug_string.size() - 1] == ' ') { + if (!debug_string.empty() && debug_string[debug_string.size() - 1] == ' ') { debug_string.resize(debug_string.size() - 1); } @@ -161,7 +163,7 @@ TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation( const std::vector* locations = FindOrNull(locations_, field); - if (locations == nullptr || index >= locations->size()) { + if (locations == nullptr || index >= static_cast(locations->size())) { return TextFormat::ParseLocation(); } @@ -176,7 +178,7 @@ TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( } auto it = nested_.find(field); - if (it == nested_.end() || index >= it->second.size()) { + if (it == nested_.end() || index >= static_cast(it->second.size())) { return nullptr; } @@ -258,6 +260,7 @@ class TextFormat::Parser::ParserImpl { allow_unknown_enum_(allow_unknown_enum), allow_field_number_(allow_field_number), allow_partial_(allow_partial), + initial_recursion_limit_(recursion_limit), recursion_limit_(recursion_limit), had_errors_(false) { // For backwards-compatibility with proto1, we need to allow the 'f' suffix @@ -285,6 +288,15 @@ class TextFormat::Parser::ParserImpl { // Consume fields until we cannot do so anymore. while (true) { if (LookingAtType(io::Tokenizer::TYPE_END)) { + // Ensures recursion limit properly unwinded, but only for success + // cases. This implicitly avoids the check when `Parse` returns false + // via `DO(...)`. + GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_) + << "Recursion limit at end of parse should be " + << initial_recursion_limit_ << ", but was " << recursion_limit_ + << ". Difference of " << initial_recursion_limit_ - recursion_limit_ + << " stack frames not accounted for stack unwind."; + return !had_errors_; } @@ -446,8 +458,7 @@ class TextFormat::Parser::ParserImpl { DO(ConsumeIdentifier(&field_name)); int32 field_number; - if (allow_field_number_ && - safe_strto32(field_name, &field_number)) { + if (allow_field_number_ && safe_strto32(field_name, &field_number)) { if (descriptor->IsExtensionNumber(field_number)) { field = finder_ ? finder_->FindExtensionByNumber(descriptor, field_number) @@ -636,7 +647,10 @@ class TextFormat::Parser::ParserImpl { bool ConsumeFieldMessage(Message* message, const Reflection* reflection, const FieldDescriptor* field) { if (--recursion_limit_ < 0) { - ReportError("Message is too deep"); + ReportError( + StrCat("Message is too deep, the parser exceeded the " + "configured recursion limit of ", + initial_recursion_limit_, ".")); return false; } // If the parse information tree is not nullptr, create a nested one @@ -668,12 +682,22 @@ class TextFormat::Parser::ParserImpl { // Skips the whole body of a message including the beginning delimiter and // the ending delimiter. bool SkipFieldMessage() { + if (--recursion_limit_ < 0) { + ReportError( + StrCat("Message is too deep, the parser exceeded the " + "configured recursion limit of ", + initial_recursion_limit_, ".")); + return false; + } + std::string delimiter; DO(ConsumeMessageDelimiter(&delimiter)); while (!LookingAt(">") && !LookingAt("}")) { DO(SkipField()); } DO(Consume(delimiter)); + + ++recursion_limit_; return true; } @@ -818,10 +842,19 @@ class TextFormat::Parser::ParserImpl { } bool SkipFieldValue() { + if (--recursion_limit_ < 0) { + ReportError( + StrCat("Message is too deep, the parser exceeded the " + "configured recursion limit of ", + initial_recursion_limit_, ".")); + return false; + } + if (LookingAtType(io::Tokenizer::TYPE_STRING)) { while (LookingAtType(io::Tokenizer::TYPE_STRING)) { tokenizer_.Next(); } + ++recursion_limit_; return true; } if (TryConsume("[")) { @@ -836,6 +869,7 @@ class TextFormat::Parser::ParserImpl { } DO(Consume(",")); } + ++recursion_limit_; return true; } // Possible field values other than string: @@ -865,6 +899,7 @@ class TextFormat::Parser::ParserImpl { !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { std::string text = tokenizer_.current().text; ReportError("Cannot skip field value, unexpected token: " + text); + ++recursion_limit_; return false; } // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field @@ -879,10 +914,12 @@ class TextFormat::Parser::ParserImpl { if (text != "inf" && text != "infinity" && text != "nan") { ReportError("Invalid float number: " + text); + ++recursion_limit_; return false; } } tokenizer_.Next(); + ++recursion_limit_; return true; } @@ -1192,6 +1229,7 @@ class TextFormat::Parser::ParserImpl { const bool allow_unknown_enum_; const bool allow_field_number_; const bool allow_partial_; + const int initial_recursion_limit_; int recursion_limit_; bool had_errors_; }; @@ -1285,7 +1323,7 @@ class TextFormat::Printer::TextGenerator if (failed_) return; } - while (size > buffer_size_) { + while (static_cast(size) > buffer_size_) { // Data exceeds space in the buffer. Copy what we can and request a // new buffer. if (buffer_size_ > 0) { @@ -1417,7 +1455,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, return MergeUsingImpl(input, output, &parser); } -bool TextFormat::Parser::ParseFromString(const std::string& input, +bool TextFormat::Parser::ParseFromString(ConstStringParam input, Message* output) { DO(CheckParseInputSize(input, error_collector_)); io::ArrayInputStream input_stream(input.data(), input.size()); @@ -1436,7 +1474,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, return MergeUsingImpl(input, output, &parser); } -bool TextFormat::Parser::MergeFromString(const std::string& input, +bool TextFormat::Parser::MergeFromString(ConstStringParam input, Message* output) { DO(CheckParseInputSize(input, error_collector_)); io::ArrayInputStream input_stream(input.data(), input.size()); @@ -1482,12 +1520,12 @@ bool TextFormat::Parser::ParseFieldValueFromString(const std::string& input, return Parser().Merge(input, output); } -/* static */ bool TextFormat::ParseFromString(const std::string& input, +/* static */ bool TextFormat::ParseFromString(ConstStringParam input, Message* output) { return Parser().ParseFromString(input, output); } -/* static */ bool TextFormat::MergeFromString(const std::string& input, +/* static */ bool TextFormat::MergeFromString(ConstStringParam input, Message* output) { return Parser().MergeFromString(input, output); } @@ -1510,9 +1548,9 @@ class StringBaseTextGenerator : public TextFormat::BaseTextGenerator { // Some compilers do not support ref-qualifiers even in C++11 mode. // Disable the optimization for now and revisit it later. -#if 0 // LANG_CXX11 +#if 0 // LANG_CXX11 std::string Consume() && { return std::move(output_); } -#else // !LANG_CXX11 +#else // !LANG_CXX11 const std::string& Get() { return output_; } #endif // LANG_CXX11 @@ -1670,6 +1708,11 @@ void TextFormat::FastFieldValuePrinter::PrintMessageStart( generator->PrintLiteral(" {\n"); } } +bool TextFormat::FastFieldValuePrinter::PrintMessageContent( + const Message& message, int field_index, int field_count, + bool single_line_mode, BaseTextGenerator* generator) const { + return false; // Use the default printing function. +} void TextFormat::FastFieldValuePrinter::PrintMessageEnd( const Message& message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator* generator) const { @@ -1783,6 +1826,9 @@ class FastFieldValuePrinterUtf8Escaping } // namespace +const char* const TextFormat::Printer::kDoNotParse = + "DO NOT PARSE: fields may be stripped and missing.\n"; + TextFormat::Printer::Printer() : initial_indent_level_(0), single_line_mode_(false), @@ -1886,12 +1932,16 @@ bool TextFormat::Printer::Print(const Message& message, return !generator.failed(); } +// Maximum recursion depth for heuristically printing out length-delimited +// unknown fields as messages. +static constexpr int kUnknownFieldRecursionLimit = 10; + bool TextFormat::Printer::PrintUnknownFields( const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output) const { TextGenerator generator(output, initial_indent_level_); - PrintUnknownFields(unknown_fields, &generator); + PrintUnknownFields(unknown_fields, &generator, kUnknownFieldRecursionLimit); // Output false if the generator failed internally. return !generator.failed(); @@ -1941,7 +1991,8 @@ bool TextFormat::Printer::PrintAny(const Message& message, finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name) : DefaultFinderFindAnyType(message, url_prefix, full_type_name); if (value_descriptor == nullptr) { - GOOGLE_LOG(WARNING) << "Proto type " << type_url << " not found"; + GOOGLE_LOG(WARNING) << "Can't print proto content: proto type " << type_url + << " not found"; return false; } DynamicMessageFactory factory; @@ -1976,7 +2027,7 @@ void TextFormat::Printer::Print(const Message& message, io::ArrayInputStream input(serialized.data(), serialized.size()); unknown_fields.ParseFromZeroCopyStream(&input); } - PrintUnknownFields(unknown_fields, generator); + PrintUnknownFields(unknown_fields, generator, kUnknownFieldRecursionLimit); return; } const Descriptor* descriptor = message.GetDescriptor(); @@ -1994,17 +2045,21 @@ void TextFormat::Printer::Print(const Message& message, fields.push_back(descriptor->field(0)); fields.push_back(descriptor->field(1)); } else { - reflection->ListFields(message, &fields); + reflection->ListFieldsOmitStripped(message, &fields); + if (reflection->IsMessageStripped(message.GetDescriptor())) { + generator->Print(kDoNotParse, std::strlen(kDoNotParse)); + } } if (print_message_fields_in_index_order_) { std::sort(fields.begin(), fields.end(), FieldIndexSorter()); } - for (int i = 0; i < fields.size(); i++) { - PrintField(message, reflection, fields[i], generator); + for (const FieldDescriptor* field : fields) { + PrintField(message, reflection, field, generator); } if (!hide_unknown_fields_) { - PrintUnknownFields(reflection->GetUnknownFields(message), generator); + PrintUnknownFields(reflection->GetUnknownFields(message), generator, + kUnknownFieldRecursionLimit); } } @@ -2239,7 +2294,10 @@ void TextFormat::Printer::PrintField(const Message& message, printer->PrintMessageStart(sub_message, field_index, count, single_line_mode_, generator); generator->Indent(); - Print(sub_message, generator); + if (!printer->PrintMessageContent(sub_message, field_index, count, + single_line_mode_, generator)) { + Print(sub_message, generator); + } generator->Outdent(); printer->PrintMessageEnd(sub_message, field_index, count, single_line_mode_, generator); @@ -2256,8 +2314,8 @@ void TextFormat::Printer::PrintField(const Message& message, } if (need_release) { - for (int j = 0; j < sorted_map_field.size(); ++j) { - delete sorted_map_field[j]; + for (const Message* message_to_delete : sorted_map_field) { + delete message_to_delete; } } } @@ -2337,7 +2395,8 @@ void TextFormat::Printer::PrintFieldValue(const Message& message, const std::string* value_to_print = &value; std::string truncated_value; if (truncate_string_field_longer_than_ > 0 && - truncate_string_field_longer_than_ < value.size()) { + static_cast(truncate_string_field_longer_than_) < + value.size()) { truncated_value = value.substr(0, truncate_string_field_longer_than_) + "......"; value_to_print = &truncated_value; @@ -2413,7 +2472,8 @@ void TextFormat::Printer::PrintFieldValue(const Message& message, } void TextFormat::Printer::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, TextGenerator* generator) const { + const UnknownFieldSet& unknown_fields, TextGenerator* generator, + int recursion_budget) const { for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); std::string field_number = StrCat(field.number()); @@ -2456,8 +2516,15 @@ void TextFormat::Printer::PrintUnknownFields( case UnknownField::TYPE_LENGTH_DELIMITED: { generator->PrintString(field_number); const std::string& value = field.length_delimited(); + // We create a CodedInputStream so that we can adhere to our recursion + // budget when we attempt to parse the data. UnknownFieldSet parsing is + // recursive because of groups. + io::CodedInputStream input_stream( + reinterpret_cast(value.data()), value.size()); + input_stream.SetRecursionLimit(recursion_budget); UnknownFieldSet embedded_unknown_fields; - if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) { + if (!value.empty() && recursion_budget > 0 && + embedded_unknown_fields.ParseFromCodedStream(&input_stream)) { // This field is parseable as a Message. // So it is probably an embedded message. if (single_line_mode_) { @@ -2466,7 +2533,8 @@ void TextFormat::Printer::PrintUnknownFields( generator->PrintLiteral(" {\n"); generator->Indent(); } - PrintUnknownFields(embedded_unknown_fields, generator); + PrintUnknownFields(embedded_unknown_fields, generator, + recursion_budget - 1); if (single_line_mode_) { generator->PrintLiteral("} "); } else { @@ -2474,8 +2542,8 @@ void TextFormat::Printer::PrintUnknownFields( generator->PrintLiteral("}\n"); } } else { - // This field is not parseable as a Message. - // So it is probably just a plain string. + // This field is not parseable as a Message (or we ran out of + // recursion budget). So it is probably just a plain string. generator->PrintLiteral(": \""); generator->PrintString(CEscape(value)); if (single_line_mode_) { @@ -2494,7 +2562,10 @@ void TextFormat::Printer::PrintUnknownFields( generator->PrintLiteral(" {\n"); generator->Indent(); } - PrintUnknownFields(field.group(), generator); + // For groups, we recurse without checking the budget. This is OK, + // because if the groups were too deeply nested then we would have + // already rejected the message when we originally parsed it. + PrintUnknownFields(field.group(), generator, recursion_budget - 1); if (single_line_mode_) { generator->PrintLiteral("} "); } else { @@ -2508,3 +2579,5 @@ void TextFormat::Printer::PrintUnknownFields( } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index ab34cd82bffd..3a3ee1563ab5 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -149,6 +149,14 @@ class PROTOBUF_EXPORT TextFormat { virtual void PrintMessageStart(const Message& message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator* generator) const; + // Allows to override the logic on how to print the content of a message. + // Return false to use the default printing logic. Note that it is legal for + // this function to print something and then return false to use the default + // content printing (although at that point it would behave similarly to + // PrintMessageStart). + virtual bool PrintMessageContent(const Message& message, int field_index, + int field_count, bool single_line_mode, + BaseTextGenerator* generator) const; virtual void PrintMessageEnd(const Message& message, int field_index, int field_count, bool single_line_mode, BaseTextGenerator* generator) const; @@ -361,6 +369,8 @@ class PROTOBUF_EXPORT TextFormat { // output to the OutputStream (see text_format.cc for implementation). class TextGenerator; + static const char* const kDoNotParse; + // Internal Print method, used for writing to the OutputStream via // the TextGenerator class. void Print(const Message& message, TextGenerator* generator) const; @@ -391,9 +401,10 @@ class PROTOBUF_EXPORT TextFormat { // Print the fields in an UnknownFieldSet. They are printed by tag number // only. Embedded messages are heuristically identified by attempting to - // parse them. + // parse them (subject to the recursion budget). void PrintUnknownFields(const UnknownFieldSet& unknown_fields, - TextGenerator* generator) const; + TextGenerator* generator, + int recursion_budget) const; bool PrintAny(const Message& message, TextGenerator* generator) const; @@ -443,13 +454,13 @@ class PROTOBUF_EXPORT TextFormat { // google::protobuf::MessageLite::ParseFromString(). static bool Parse(io::ZeroCopyInputStream* input, Message* output); // Like Parse(), but reads directly from a string. - static bool ParseFromString(const std::string& input, Message* output); + static bool ParseFromString(ConstStringParam input, Message* output); // Like Parse(), but the data is merged into the given message, as if // using Message::MergeFrom(). static bool Merge(io::ZeroCopyInputStream* input, Message* output); // Like Merge(), but reads directly from a string. - static bool MergeFromString(const std::string& input, Message* output); + static bool MergeFromString(ConstStringParam input, Message* output); // Parse the given text as a single field value and store it into the // given field of the given message. If the field is a repeated field, @@ -520,11 +531,11 @@ class PROTOBUF_EXPORT TextFormat { // Like TextFormat::Parse(). bool Parse(io::ZeroCopyInputStream* input, Message* output); // Like TextFormat::ParseFromString(). - bool ParseFromString(const std::string& input, Message* output); + bool ParseFromString(ConstStringParam input, Message* output); // Like TextFormat::Merge(). bool Merge(io::ZeroCopyInputStream* input, Message* output); // Like TextFormat::MergeFromString(). - bool MergeFromString(const std::string& input, Message* output); + bool MergeFromString(ConstStringParam input, Message* output); // Set where to report parse errors. If NULL (the default), errors will // be printed to stderr. @@ -558,16 +569,22 @@ class PROTOBUF_EXPORT TextFormat { const FieldDescriptor* field, Message* output); - // When an unknown extension is met, parsing will fail if this option is set - // to false (the default). If true, unknown extensions will be ignored and - // a warning message will be generated. + // When an unknown extension is met, parsing will fail if this option is + // set to false (the default). If true, unknown extensions will be ignored + // and a warning message will be generated. + // Beware! Setting this option true may hide some errors (e.g. spelling + // error on extension name). This allows data loss; unlike binary format, + // text format cannot preserve unknown extensions. Avoid using this option + // if possible. void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; } // When an unknown field is met, parsing will fail if this option is set - // to false(the default). If true, unknown fields will be ignored and + // to false (the default). If true, unknown fields will be ignored and // a warning message will be generated. - // Please aware that set this option true may hide some errors (e.g. - // spelling error on field name). Avoid to use this option if possible. + // Beware! Setting this option true may hide some errors (e.g. spelling + // error on field name). This allows data loss; unlike binary format, text + // format cannot preserve unknown fields. Avoid using this option + // if possible. void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; } diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 555976f18716..449a78c6dc2b 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -42,7 +42,6 @@ #include #include -#include #include #include #include @@ -55,9 +54,11 @@ #include #include #include -#include +#include #include #include +#include +#include #include @@ -346,14 +347,46 @@ TEST_F(TextFormatTest, PrintUnknownMessage) { UnknownFieldSet unknown_fields; EXPECT_TRUE(unknown_fields.ParseFromString(data)); EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text)); - EXPECT_EQ( - "44: \"abc\"\n" - "44: \"def\"\n" - "44: \"\"\n" - "48 {\n" - " 1: 123\n" - "}\n", - text); + // Field 44 and 48 can be printed in any order. + EXPECT_THAT(text, testing::HasSubstr("44: \"abc\"\n" + "44: \"def\"\n" + "44: \"\"\n")); + EXPECT_THAT(text, testing::HasSubstr("48 {\n" + " 1: 123\n" + "}\n")); +} + +TEST_F(TextFormatTest, PrintDeeplyNestedUnknownMessage) { + // Create a deeply nested message. + static constexpr int kNestingDepth = 25000; + static constexpr int kUnknownFieldNumber = 1; + std::vector lengths; + lengths.reserve(kNestingDepth); + lengths.push_back(0); + for (int i = 0; i < kNestingDepth - 1; ++i) { + lengths.push_back( + internal::WireFormatLite::TagSize( + kUnknownFieldNumber, internal::WireFormatLite::TYPE_BYTES) + + internal::WireFormatLite::LengthDelimitedSize(lengths.back())); + } + std::string serialized; + { + io::StringOutputStream zero_copy_stream(&serialized); + io::CodedOutputStream coded_stream(&zero_copy_stream); + for (int i = kNestingDepth - 1; i >= 0; --i) { + internal::WireFormatLite::WriteTag( + kUnknownFieldNumber, + internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &coded_stream); + coded_stream.WriteVarint32(lengths[i]); + } + } + + // Parse the data and verify that we can print it without overflowing the + // stack. + unittest::TestEmptyMessage message; + ASSERT_TRUE(message.ParseFromString(serialized)); + std::string text; + EXPECT_TRUE(TextFormat::PrintToString(message, &text)); } TEST_F(TextFormatTest, PrintMessageWithIndent) { @@ -539,6 +572,54 @@ TEST_F(TextFormatTest, CustomPrinterForComments) { text); } +class CustomMessageContentFieldValuePrinter + : public TextFormat::FastFieldValuePrinter { + public: + bool PrintMessageContent( + const Message& message, int field_index, int field_count, + bool single_line_mode, + TextFormat::BaseTextGenerator* generator) const override { + if (message.ByteSizeLong() > 0) { + generator->PrintString( + strings::Substitute("# REDACTED, $0 bytes\n", message.ByteSizeLong())); + } + return true; + } +}; + +TEST_F(TextFormatTest, CustomPrinterForMessageContent) { + protobuf_unittest::TestAllTypes message; + message.mutable_optional_nested_message(); + message.mutable_optional_import_message()->set_d(42); + message.add_repeated_nested_message(); + message.add_repeated_nested_message(); + message.add_repeated_import_message()->set_d(43); + message.add_repeated_import_message()->set_d(44); + TextFormat::Printer printer; + CustomMessageContentFieldValuePrinter my_field_printer; + printer.SetDefaultFieldValuePrinter( + new CustomMessageContentFieldValuePrinter()); + std::string text; + printer.PrintToString(message, &text); + EXPECT_EQ( + "optional_nested_message {\n" + "}\n" + "optional_import_message {\n" + " # REDACTED, 2 bytes\n" + "}\n" + "repeated_nested_message {\n" + "}\n" + "repeated_nested_message {\n" + "}\n" + "repeated_import_message {\n" + " # REDACTED, 2 bytes\n" + "}\n" + "repeated_import_message {\n" + " # REDACTED, 2 bytes\n" + "}\n", + text); +} + class CustomMultilineCommentPrinter : public TextFormat::FieldValuePrinter { public: virtual std::string PrintMessageStart(const Message& message, int field_index, @@ -637,7 +718,7 @@ TEST_F(TextFormatTest, CompactRepeatedFieldPrinter) { text); } -// Print strings into multiple line, with indention. Use this to test +// Print strings into multiple line, with indentation. Use this to test // BaseTextGenerator::Indent and BaseTextGenerator::Outdent. class MultilineStringPrinter : public TextFormat::FastFieldValuePrinter { public: @@ -726,8 +807,8 @@ TEST_F(TextFormatExtensionsTest, ParseExtensions) { TEST_F(TextFormatTest, ParseEnumFieldFromNumber) { // Create a parse string with a numerical value for an enum field. - std::string parse_string = strings::Substitute("optional_nested_enum: $0", - unittest::TestAllTypes::BAZ); + std::string parse_string = + strings::Substitute("optional_nested_enum: $0", unittest::TestAllTypes::BAZ); EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_)); EXPECT_TRUE(proto_.has_optional_nested_enum()); EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum()); @@ -1328,9 +1409,8 @@ class TextFormatParserTest : public testing::Test { parser_.RecordErrorsTo(&error_collector); EXPECT_EQ(expected_result, parser_.ParseFromString(input, proto)) << input << " -> " << proto->DebugString(); - EXPECT_EQ( - StrCat(line) + ":" + StrCat(col) + ": " + message + "\n", - error_collector.text_); + EXPECT_EQ(StrCat(line, ":", col, ": ", message, "\n"), + error_collector.text_); parser_.RecordErrorsTo(nullptr); } @@ -1365,7 +1445,7 @@ class TextFormatParserTest : public testing::Test { // implements ErrorCollector ------------------------------------- void AddError(int line, int column, const std::string& message) { strings::SubstituteAndAppend(&text_, "$0:$1: $2\n", line + 1, column + 1, - message); + message); } void AddWarning(int line, int column, const std::string& message) { @@ -1830,7 +1910,58 @@ TEST_F(TextFormatParserTest, SetRecursionLimit) { input = strings::Substitute(format, input); parser_.SetRecursionLimit(100); - ExpectMessage(input, "Message is too deep", 1, 908, &message, false); + ExpectMessage(input, + "Message is too deep, the parser exceeded the configured " + "recursion limit of 100.", + 1, 908, &message, false); + + parser_.SetRecursionLimit(101); + ExpectSuccessAndTree(input, &message, nullptr); +} + +TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldValue) { + const char* format = "[$0]"; + std::string input = "\"test_value\""; + for (int i = 0; i < 99; ++i) input = strings::Substitute(format, input); + std::string not_deep_input = StrCat("unknown_nested_array: ", input); + + parser_.AllowUnknownField(true); + parser_.SetRecursionLimit(100); + + unittest::NestedTestAllTypes message; + ExpectSuccessAndTree(not_deep_input, &message, nullptr); + + input = strings::Substitute(format, input); + std::string deep_input = StrCat("unknown_nested_array: ", input); + ExpectMessage( + deep_input, + "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no " + "field named \"unknown_nested_array\".\n1:123: Message is too deep, the " + "parser exceeded the configured recursion limit of 100.", + 1, 21, &message, false); + + parser_.SetRecursionLimit(101); + ExpectSuccessAndTree(deep_input, &message, nullptr); +} + +TEST_F(TextFormatParserTest, SetRecursionLimitUnknownFieldMessage) { + const char* format = "unknown_child: { $0 }"; + std::string input; + for (int i = 0; i < 100; ++i) input = strings::Substitute(format, input); + + parser_.AllowUnknownField(true); + parser_.SetRecursionLimit(100); + + unittest::NestedTestAllTypes message; + ExpectSuccessAndTree(input, &message, nullptr); + + input = strings::Substitute(format, input); + ExpectMessage( + input, + "WARNING:Message type \"protobuf_unittest.NestedTestAllTypes\" has no " + "field named \"unknown_child\".\n1:1716: Message is too deep, the parser " + "exceeded the configured recursion limit of 100.", + 1, 14, &message, false); parser_.SetRecursionLimit(101); ExpectSuccessAndTree(input, &message, nullptr); @@ -1924,7 +2055,7 @@ TEST(TextFormatUnknownFieldTest, TestUnknownField) { " }\n" ">", &proto)); - // Unmatched delimeters for message body + // Unmatched delimiters for message body EXPECT_FALSE(parser.ParseFromString("unknown_message: {>", &proto)); // Unknown extension EXPECT_TRUE( @@ -2029,3 +2160,5 @@ TEST(TextFormatUnknownFieldTest, TestUnknownExtension) { } // namespace text_format_unittest } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index 43de52e8b857..24b8ee9a0bc2 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class TimestampDefaultTypeInternal { public: @@ -28,7 +30,6 @@ static void InitDefaultsscc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::Timestamp(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Timestamp::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto = @@ -58,10 +59,10 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = "\n\037google/protobuf/timestamp.proto\022\017googl" "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003" - "\022\r\n\005nanos\030\002 \001(\005B~\n\023com.google.protobufB\016" - "TimestampProtoP\001Z+github.com/golang/prot" - "obuf/ptypes/timestamp\370\001\001\242\002\003GPB\252\002\036Google." - "Protobuf.WellKnownTypesb\006proto3" + "\022\r\n\005nanos\030\002 \001(\005B\205\001\n\023com.google.protobufB" + "\016TimestampProtoP\001Z2google.golang.org/pro" + "tobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002" + "\036Google.Protobuf.WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_deps[1] = { }; @@ -69,42 +70,32 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2eproto = { - &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto", 231, + false, false, descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto, "google/protobuf/timestamp.proto", 239, &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once, descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_sccs, descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_deps, 1, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftimestamp_2eproto::offsets, file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto, 1, file_level_enum_descriptors_google_2fprotobuf_2ftimestamp_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftimestamp_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void Timestamp::InitAsDefaultInstance() { -} class Timestamp::_Internal { public: }; -Timestamp::Timestamp() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Timestamp) -} Timestamp::Timestamp(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Timestamp) } Timestamp::Timestamp(const Timestamp& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::memcpy(&seconds_, &from.seconds_, static_cast(reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); @@ -112,18 +103,20 @@ Timestamp::Timestamp(const Timestamp& from) } void Timestamp::SharedCtor() { - ::memset(&seconds_, 0, static_cast( - reinterpret_cast(&nanos_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&seconds_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); } Timestamp::~Timestamp() { // @@protoc_insertion_point(destructor:google.protobuf.Timestamp) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Timestamp::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void Timestamp::ArenaDtor(void* object) { @@ -150,12 +143,11 @@ void Timestamp::Clear() { ::memset(&seconds_, 0, static_cast( reinterpret_cast(&nanos_) - reinterpret_cast(&seconds_)) + sizeof(nanos_)); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Timestamp::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -181,7 +173,9 @@ const char* Timestamp::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID:: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -215,7 +209,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Timestamp::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Timestamp) return target; @@ -270,7 +264,7 @@ void Timestamp::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Timestamp::MergeFrom(const Timestamp& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -302,9 +296,13 @@ bool Timestamp::IsInitialized() const { void Timestamp::InternalSwap(Timestamp* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - swap(seconds_, other->seconds_); - swap(nanos_, other->nanos_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Timestamp, nanos_) + + sizeof(Timestamp::nanos_) + - PROTOBUF_FIELD_OFFSET(Timestamp, seconds_)>( + reinterpret_cast(&seconds_), + reinterpret_cast(&other->seconds_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Timestamp::GetMetadata() const { diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 338a1e707b20..4d2947ab32ff 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -45,7 +44,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftimestamp_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -66,10 +65,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT Timestamp : +class PROTOBUF_EXPORT Timestamp PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ { public: - Timestamp(); + inline Timestamp() : Timestamp(nullptr) {} virtual ~Timestamp(); Timestamp(const Timestamp& from); @@ -83,7 +82,7 @@ class PROTOBUF_EXPORT Timestamp : return *this; } inline Timestamp& operator=(Timestamp&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -91,12 +90,6 @@ class PROTOBUF_EXPORT Timestamp : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -108,7 +101,6 @@ class PROTOBUF_EXPORT Timestamp : } static const Timestamp& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Timestamp* internal_default_instance() { return reinterpret_cast( &_Timestamp_default_instance_); @@ -121,7 +113,7 @@ class PROTOBUF_EXPORT Timestamp : } inline void Swap(Timestamp* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -129,7 +121,7 @@ class PROTOBUF_EXPORT Timestamp : } void UnsafeArenaSwap(Timestamp* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -169,13 +161,6 @@ class PROTOBUF_EXPORT Timestamp : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -217,7 +202,6 @@ class PROTOBUF_EXPORT Timestamp : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto index cd357864a9e4..3b2df6d91168 100644 --- a/src/google/protobuf/timestamp.proto +++ b/src/google/protobuf/timestamp.proto @@ -34,7 +34,7 @@ package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes"; option cc_enable_arenas = true; -option go_package = "github.com/golang/protobuf/ptypes/timestamp"; +option go_package = "google.golang.org/protobuf/types/known/timestamppb"; option java_package = "com.google.protobuf"; option java_outer_classname = "TimestampProto"; option java_multiple_files = true; @@ -91,7 +91,16 @@ option objc_class_prefix = "GPB"; // .setNanos((int) ((millis % 1000) * 1000000)).build(); // // -// Example 5: Compute Timestamp from current time in Python. +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// +// Example 6: Compute Timestamp from current time in Python. // // timestamp = Timestamp() // timestamp.GetCurrentTime() diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index a690acb9b6c8..5c94072592f5 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fany_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Any_google_2fprotobuf_2fany_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto; extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftype_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Field_google_2fprotobuf_2ftype_2eproto; @@ -49,7 +51,6 @@ static void InitDefaultsscc_info_Enum_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Enum(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Enum::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Enum_google_2fprotobuf_2ftype_2eproto = @@ -66,7 +67,6 @@ static void InitDefaultsscc_info_EnumValue_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::EnumValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::EnumValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_EnumValue_google_2fprotobuf_2ftype_2eproto = @@ -81,7 +81,6 @@ static void InitDefaultsscc_info_Field_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Field(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Field::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Field_google_2fprotobuf_2ftype_2eproto = @@ -96,7 +95,6 @@ static void InitDefaultsscc_info_Option_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Option(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Option::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<1> scc_info_Option_google_2fprotobuf_2ftype_2eproto = @@ -111,7 +109,6 @@ static void InitDefaultsscc_info_Type_google_2fprotobuf_2ftype_2eproto() { new (ptr) PROTOBUF_NAMESPACE_ID::Type(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Type::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<3> scc_info_Type_google_2fprotobuf_2ftype_2eproto = @@ -230,10 +227,10 @@ const char descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto[] PROTOBUF "\003 \003(\0132\027.google.protobuf.Option\";\n\006Option" "\022\014\n\004name\030\001 \001(\t\022#\n\005value\030\002 \001(\0132\024.google.p" "rotobuf.Any*.\n\006Syntax\022\021\n\rSYNTAX_PROTO2\020\000" - "\022\021\n\rSYNTAX_PROTO3\020\001B}\n\023com.google.protob" - "ufB\tTypeProtoP\001Z/google.golang.org/genpr" - "oto/protobuf/ptype;ptype\370\001\001\242\002\003GPB\252\002\036Goog" - "le.Protobuf.WellKnownTypesb\006proto3" + "\022\021\n\rSYNTAX_PROTO3\020\001B{\n\023com.google.protob" + "ufB\tTypeProtoP\001Z-google.golang.org/proto" + "buf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google" + ".Protobuf.WellKnownTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2ftype_2eproto_deps[2] = { &::descriptor_table_google_2fprotobuf_2fany_2eproto, @@ -247,16 +244,15 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_Type_google_2fprotobuf_2ftype_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2ftype_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2ftype_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto = { - &descriptor_table_google_2fprotobuf_2ftype_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto", 1594, + false, false, descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto, "google/protobuf/type.proto", 1592, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, descriptor_table_google_2fprotobuf_2ftype_2eproto_sccs, descriptor_table_google_2fprotobuf_2ftype_2eproto_deps, 5, 2, schemas, file_default_instances, TableStruct_google_2fprotobuf_2ftype_2eproto::offsets, file_level_metadata_google_2fprotobuf_2ftype_2eproto, 5, file_level_enum_descriptors_google_2fprotobuf_2ftype_2eproto, file_level_service_descriptors_google_2fprotobuf_2ftype_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto(&descriptor_table_google_2fprotobuf_2ftype_2eproto); PROTOBUF_NAMESPACE_OPEN const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* Field_Kind_descriptor() { ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto); @@ -355,10 +351,6 @@ bool Syntax_IsValid(int value) { // =================================================================== -void Type::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Type_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>( - PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance()); -} class Type::_Internal { public: static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Type* msg); @@ -368,33 +360,14 @@ const PROTOBUF_NAMESPACE_ID::SourceContext& Type::_Internal::source_context(const Type* msg) { return *msg->source_context_; } -void Type::unsafe_arena_set_allocated_source_context( - PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { - if (GetArenaNoVirtual() == nullptr) { - delete source_context_; - } - source_context_ = source_context; - if (source_context) { - - } else { - - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.source_context) -} void Type::clear_source_context() { - if (GetArenaNoVirtual() == nullptr && source_context_ != nullptr) { + if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } source_context_ = nullptr; } -Type::Type() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Type) -} Type::Type(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), fields_(arena), oneofs_(arena), options_(arena) { @@ -404,15 +377,14 @@ Type::Type(::PROTOBUF_NAMESPACE_ID::Arena* arena) } Type::Type(const Type& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), fields_(from.fields_), oneofs_(from.oneofs_), options_(from.options_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_source_context()) { source_context_ = new PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_); @@ -426,18 +398,20 @@ Type::Type(const Type& from) void Type::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Type_google_2fprotobuf_2ftype_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&source_context_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&source_context_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&source_context_)) + sizeof(syntax_)); } Type::~Type() { // @@protoc_insertion_point(destructor:google.protobuf.Type) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Type::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete source_context_; } @@ -466,18 +440,17 @@ void Type::Clear() { fields_.Clear(); oneofs_.Clear(); options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - if (GetArenaNoVirtual() == nullptr && source_context_ != nullptr) { + name_.ClearToEmpty(); + if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } source_context_ = nullptr; syntax_ = 0; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Type::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -551,7 +524,9 @@ const char* Type::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inter ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -624,7 +599,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Type::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type) return target; @@ -707,7 +682,7 @@ void Type::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Type::MergeFrom(const Type& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -745,14 +720,17 @@ bool Type::IsInitialized() const { void Type::InternalSwap(Type* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); fields_.InternalSwap(&other->fields_); oneofs_.InternalSwap(&other->oneofs_); options_.InternalSwap(&other->options_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(source_context_, other->source_context_); - swap(syntax_, other->syntax_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Type, syntax_) + + sizeof(Type::syntax_) + - PROTOBUF_FIELD_OFFSET(Type, source_context_)>( + reinterpret_cast(&source_context_), + reinterpret_cast(&other->source_context_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Type::GetMetadata() const { @@ -762,20 +740,12 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Type::GetMetadata() const { // =================================================================== -void Field::InitAsDefaultInstance() { -} class Field::_Internal { public: }; -Field::Field() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Field) -} Field::Field(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), options_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -783,28 +753,27 @@ Field::Field(::PROTOBUF_NAMESPACE_ID::Arena* arena) } Field::Field(const Field& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), options_(from.options_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_type_url().empty()) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_type_url(), - GetArenaNoVirtual()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), + GetArena()); } json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_json_name().empty()) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_json_name(), - GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(), + GetArena()); } default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_default_value().empty()) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_default_value(), - GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(), + GetArena()); } ::memcpy(&kind_, &from.kind_, static_cast(reinterpret_cast(&packed_) - @@ -818,18 +787,20 @@ void Field::SharedCtor() { type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&kind_, 0, static_cast( - reinterpret_cast(&packed_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&kind_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&packed_) - reinterpret_cast(&kind_)) + sizeof(packed_)); } Field::~Field() { // @@protoc_insertion_point(destructor:google.protobuf.Field) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Field::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); type_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); json_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); @@ -858,19 +829,18 @@ void Field::Clear() { (void) cached_has_bits; options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - json_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - default_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); + type_url_.ClearToEmpty(); + json_name_.ClearToEmpty(); + default_value_.ClearToEmpty(); ::memset(&kind_, 0, static_cast( reinterpret_cast(&packed_) - reinterpret_cast(&kind_)) + sizeof(packed_)); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Field::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -967,7 +937,9 @@ const char* Field::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inte ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1069,7 +1041,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Field::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field) return target; @@ -1176,7 +1148,7 @@ void Field::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Field::MergeFrom(const Field& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1230,21 +1202,18 @@ bool Field::IsInitialized() const { void Field::InternalSwap(Field* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); options_.InternalSwap(&other->options_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - type_url_.Swap(&other->type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - json_name_.Swap(&other->json_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - default_value_.Swap(&other->default_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(kind_, other->kind_); - swap(cardinality_, other->cardinality_); - swap(number_, other->number_); - swap(oneof_index_, other->oneof_index_); - swap(packed_, other->packed_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + type_url_.Swap(&other->type_url_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + json_name_.Swap(&other->json_name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + default_value_.Swap(&other->default_value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Field, packed_) + + sizeof(Field::packed_) + - PROTOBUF_FIELD_OFFSET(Field, kind_)>( + reinterpret_cast(&kind_), + reinterpret_cast(&other->kind_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Field::GetMetadata() const { @@ -1254,10 +1223,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Field::GetMetadata() const { // =================================================================== -void Enum::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Enum_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>( - PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance()); -} class Enum::_Internal { public: static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Enum* msg); @@ -1267,33 +1232,14 @@ const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::_Internal::source_context(const Enum* msg) { return *msg->source_context_; } -void Enum::unsafe_arena_set_allocated_source_context( - PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { - if (GetArenaNoVirtual() == nullptr) { - delete source_context_; - } - source_context_ = source_context; - if (source_context) { - - } else { - - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.source_context) -} void Enum::clear_source_context() { - if (GetArenaNoVirtual() == nullptr && source_context_ != nullptr) { + if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } source_context_ = nullptr; } -Enum::Enum() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Enum) -} Enum::Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), enumvalue_(arena), options_(arena) { SharedCtor(); @@ -1302,14 +1248,13 @@ Enum::Enum(::PROTOBUF_NAMESPACE_ID::Arena* arena) } Enum::Enum(const Enum& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), enumvalue_(from.enumvalue_), options_(from.options_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_source_context()) { source_context_ = new PROTOBUF_NAMESPACE_ID::SourceContext(*from.source_context_); @@ -1323,18 +1268,20 @@ Enum::Enum(const Enum& from) void Enum::SharedCtor() { ::PROTOBUF_NAMESPACE_ID::internal::InitSCC(&scc_info_Enum_google_2fprotobuf_2ftype_2eproto.base); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); - ::memset(&source_context_, 0, static_cast( - reinterpret_cast(&syntax_) - + ::memset(reinterpret_cast(this) + static_cast( + reinterpret_cast(&source_context_) - reinterpret_cast(this)), + 0, static_cast(reinterpret_cast(&syntax_) - reinterpret_cast(&source_context_)) + sizeof(syntax_)); } Enum::~Enum() { // @@protoc_insertion_point(destructor:google.protobuf.Enum) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Enum::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete source_context_; } @@ -1362,18 +1309,17 @@ void Enum::Clear() { enumvalue_.Clear(); options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - if (GetArenaNoVirtual() == nullptr && source_context_ != nullptr) { + name_.ClearToEmpty(); + if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } source_context_ = nullptr; syntax_ = 0; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Enum::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1433,7 +1379,9 @@ const char* Enum::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::inter ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1496,7 +1444,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Enum::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum) return target; @@ -1571,7 +1519,7 @@ void Enum::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Enum::MergeFrom(const Enum& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1608,13 +1556,16 @@ bool Enum::IsInitialized() const { void Enum::InternalSwap(Enum* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); enumvalue_.InternalSwap(&other->enumvalue_); options_.InternalSwap(&other->options_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); - swap(source_context_, other->source_context_); - swap(syntax_, other->syntax_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::memswap< + PROTOBUF_FIELD_OFFSET(Enum, syntax_) + + sizeof(Enum::syntax_) + - PROTOBUF_FIELD_OFFSET(Enum, source_context_)>( + reinterpret_cast(&source_context_), + reinterpret_cast(&other->source_context_)); } ::PROTOBUF_NAMESPACE_ID::Metadata Enum::GetMetadata() const { @@ -1624,20 +1575,12 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Enum::GetMetadata() const { // =================================================================== -void EnumValue::InitAsDefaultInstance() { -} class EnumValue::_Internal { public: }; -EnumValue::EnumValue() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.EnumValue) -} EnumValue::EnumValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena), + : ::PROTOBUF_NAMESPACE_ID::Message(arena), options_(arena) { SharedCtor(); RegisterArenaDtor(arena); @@ -1645,13 +1588,12 @@ EnumValue::EnumValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) } EnumValue::EnumValue(const EnumValue& from) : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr), options_(from.options_) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } number_ = from.number_; // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValue) @@ -1666,10 +1608,11 @@ void EnumValue::SharedCtor() { EnumValue::~EnumValue() { // @@protoc_insertion_point(destructor:google.protobuf.EnumValue) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void EnumValue::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } @@ -1695,14 +1638,13 @@ void EnumValue::Clear() { (void) cached_has_bits; options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); number_ = 0; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* EnumValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1742,7 +1684,9 @@ const char* EnumValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID:: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1788,7 +1732,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* EnumValue::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue) return target; @@ -1850,7 +1794,7 @@ void EnumValue::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void EnumValue::MergeFrom(const EnumValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1883,10 +1827,9 @@ bool EnumValue::IsInitialized() const { void EnumValue::InternalSwap(EnumValue* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); options_.InternalSwap(&other->options_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(number_, other->number_); } @@ -1897,10 +1840,6 @@ ::PROTOBUF_NAMESPACE_ID::Metadata EnumValue::GetMetadata() const { // =================================================================== -void Option::InitAsDefaultInstance() { - PROTOBUF_NAMESPACE_ID::_Option_default_instance_._instance.get_mutable()->value_ = const_cast< PROTOBUF_NAMESPACE_ID::Any*>( - PROTOBUF_NAMESPACE_ID::Any::internal_default_instance()); -} class Option::_Internal { public: static const PROTOBUF_NAMESPACE_ID::Any& value(const Option* msg); @@ -1910,45 +1849,25 @@ const PROTOBUF_NAMESPACE_ID::Any& Option::_Internal::value(const Option* msg) { return *msg->value_; } -void Option::unsafe_arena_set_allocated_value( - PROTOBUF_NAMESPACE_ID::Any* value) { - if (GetArenaNoVirtual() == nullptr) { - delete value_; - } - value_ = value; - if (value) { - - } else { - - } - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.value) -} void Option::clear_value() { - if (GetArenaNoVirtual() == nullptr && value_ != nullptr) { + if (GetArena() == nullptr && value_ != nullptr) { delete value_; } value_ = nullptr; } -Option::Option() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Option) -} Option::Option(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Option) } Option::Option(const Option& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), + GetArena()); } if (from._internal_has_value()) { value_ = new PROTOBUF_NAMESPACE_ID::Any(*from.value_); @@ -1967,10 +1886,11 @@ void Option::SharedCtor() { Option::~Option() { // @@protoc_insertion_point(destructor:google.protobuf.Option) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Option::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) delete value_; } @@ -1996,17 +1916,16 @@ void Option::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - if (GetArenaNoVirtual() == nullptr && value_ != nullptr) { + name_.ClearToEmpty(); + if (GetArena() == nullptr && value_ != nullptr) { delete value_; } value_ = nullptr; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Option::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -2034,7 +1953,9 @@ const char* Option::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::int ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -2074,7 +1995,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Option::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option) return target; @@ -2129,7 +2050,7 @@ void Option::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Option::MergeFrom(const Option& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -2161,9 +2082,8 @@ bool Option::IsInitialized() const { void Option::InternalSwap(Option* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + name_.Swap(&other->name_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); swap(value_, other->value_); } diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 40d2cd4f0fde..66b2d375f080 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -48,7 +47,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2ftype_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[5] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -121,7 +120,7 @@ inline const std::string& Field_Kind_Name(T enum_t_value) { Field_Kind_descriptor(), enum_t_value); } inline bool Field_Kind_Parse( - const std::string& name, Field_Kind* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Field_Kind* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( Field_Kind_descriptor(), name, value); } @@ -148,7 +147,7 @@ inline const std::string& Field_Cardinality_Name(T enum_t_value) { Field_Cardinality_descriptor(), enum_t_value); } inline bool Field_Cardinality_Parse( - const std::string& name, Field_Cardinality* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Field_Cardinality* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( Field_Cardinality_descriptor(), name, value); } @@ -173,16 +172,16 @@ inline const std::string& Syntax_Name(T enum_t_value) { Syntax_descriptor(), enum_t_value); } inline bool Syntax_Parse( - const std::string& name, Syntax* value) { + ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Syntax* value) { return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum( Syntax_descriptor(), name, value); } // =================================================================== -class PROTOBUF_EXPORT Type : +class PROTOBUF_EXPORT Type PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Type) */ { public: - Type(); + inline Type() : Type(nullptr) {} virtual ~Type(); Type(const Type& from); @@ -196,7 +195,7 @@ class PROTOBUF_EXPORT Type : return *this; } inline Type& operator=(Type&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -204,12 +203,6 @@ class PROTOBUF_EXPORT Type : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -221,7 +214,6 @@ class PROTOBUF_EXPORT Type : } static const Type& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Type* internal_default_instance() { return reinterpret_cast( &_Type_default_instance_); @@ -234,7 +226,7 @@ class PROTOBUF_EXPORT Type : } inline void Swap(Type* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -242,7 +234,7 @@ class PROTOBUF_EXPORT Type : } void UnsafeArenaSwap(Type* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -282,13 +274,6 @@ class PROTOBUF_EXPORT Type : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -382,15 +367,6 @@ class PROTOBUF_EXPORT Type : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -428,7 +404,6 @@ class PROTOBUF_EXPORT Type : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -443,10 +418,10 @@ class PROTOBUF_EXPORT Type : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Field : +class PROTOBUF_EXPORT Field PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Field) */ { public: - Field(); + inline Field() : Field(nullptr) {} virtual ~Field(); Field(const Field& from); @@ -460,7 +435,7 @@ class PROTOBUF_EXPORT Field : return *this; } inline Field& operator=(Field&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -468,12 +443,6 @@ class PROTOBUF_EXPORT Field : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -485,7 +454,6 @@ class PROTOBUF_EXPORT Field : } static const Field& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Field* internal_default_instance() { return reinterpret_cast( &_Field_default_instance_); @@ -498,7 +466,7 @@ class PROTOBUF_EXPORT Field : } inline void Swap(Field* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -506,7 +474,7 @@ class PROTOBUF_EXPORT Field : } void UnsafeArenaSwap(Field* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -546,13 +514,6 @@ class PROTOBUF_EXPORT Field : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -625,7 +586,7 @@ class PROTOBUF_EXPORT Field : "Incorrect type passed to function Kind_Name."); return Field_Kind_Name(enum_t_value); } - static inline bool Kind_Parse(const std::string& name, + static inline bool Kind_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Kind* value) { return Field_Kind_Parse(name, value); } @@ -659,7 +620,7 @@ class PROTOBUF_EXPORT Field : "Incorrect type passed to function Cardinality_Name."); return Field_Cardinality_Name(enum_t_value); } - static inline bool Cardinality_Parse(const std::string& name, + static inline bool Cardinality_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name, Cardinality* value) { return Field_Cardinality_Parse(name, value); } @@ -706,15 +667,6 @@ class PROTOBUF_EXPORT Field : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -731,15 +683,6 @@ class PROTOBUF_EXPORT Field : std::string* mutable_type_url(); std::string* release_type_url(); void set_allocated_type_url(std::string* type_url); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_type_url(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_type_url( - std::string* type_url); private: const std::string& _internal_type_url() const; void _internal_set_type_url(const std::string& value); @@ -756,15 +699,6 @@ class PROTOBUF_EXPORT Field : std::string* mutable_json_name(); std::string* release_json_name(); void set_allocated_json_name(std::string* json_name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_json_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_json_name( - std::string* json_name); private: const std::string& _internal_json_name() const; void _internal_set_json_name(const std::string& value); @@ -781,15 +715,6 @@ class PROTOBUF_EXPORT Field : std::string* mutable_default_value(); std::string* release_default_value(); void set_allocated_default_value(std::string* default_value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_default_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_default_value( - std::string* default_value); private: const std::string& _internal_default_value() const; void _internal_set_default_value(const std::string& value); @@ -845,7 +770,6 @@ class PROTOBUF_EXPORT Field : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -864,10 +788,10 @@ class PROTOBUF_EXPORT Field : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Enum : +class PROTOBUF_EXPORT Enum PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Enum) */ { public: - Enum(); + inline Enum() : Enum(nullptr) {} virtual ~Enum(); Enum(const Enum& from); @@ -881,7 +805,7 @@ class PROTOBUF_EXPORT Enum : return *this; } inline Enum& operator=(Enum&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -889,12 +813,6 @@ class PROTOBUF_EXPORT Enum : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -906,7 +824,6 @@ class PROTOBUF_EXPORT Enum : } static const Enum& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Enum* internal_default_instance() { return reinterpret_cast( &_Enum_default_instance_); @@ -919,7 +836,7 @@ class PROTOBUF_EXPORT Enum : } inline void Swap(Enum* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -927,7 +844,7 @@ class PROTOBUF_EXPORT Enum : } void UnsafeArenaSwap(Enum* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -967,13 +884,6 @@ class PROTOBUF_EXPORT Enum : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1042,15 +952,6 @@ class PROTOBUF_EXPORT Enum : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -1088,7 +989,6 @@ class PROTOBUF_EXPORT Enum : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1102,10 +1002,10 @@ class PROTOBUF_EXPORT Enum : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumValue : +class PROTOBUF_EXPORT EnumValue PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValue) */ { public: - EnumValue(); + inline EnumValue() : EnumValue(nullptr) {} virtual ~EnumValue(); EnumValue(const EnumValue& from); @@ -1119,7 +1019,7 @@ class PROTOBUF_EXPORT EnumValue : return *this; } inline EnumValue& operator=(EnumValue&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1127,12 +1027,6 @@ class PROTOBUF_EXPORT EnumValue : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1144,7 +1038,6 @@ class PROTOBUF_EXPORT EnumValue : } static const EnumValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const EnumValue* internal_default_instance() { return reinterpret_cast( &_EnumValue_default_instance_); @@ -1157,7 +1050,7 @@ class PROTOBUF_EXPORT EnumValue : } inline void Swap(EnumValue* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1165,7 +1058,7 @@ class PROTOBUF_EXPORT EnumValue : } void UnsafeArenaSwap(EnumValue* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1205,13 +1098,6 @@ class PROTOBUF_EXPORT EnumValue : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1260,15 +1146,6 @@ class PROTOBUF_EXPORT EnumValue : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -1288,7 +1165,6 @@ class PROTOBUF_EXPORT EnumValue : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1300,10 +1176,10 @@ class PROTOBUF_EXPORT EnumValue : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Option : +class PROTOBUF_EXPORT Option PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Option) */ { public: - Option(); + inline Option() : Option(nullptr) {} virtual ~Option(); Option(const Option& from); @@ -1317,7 +1193,7 @@ class PROTOBUF_EXPORT Option : return *this; } inline Option& operator=(Option&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1325,12 +1201,6 @@ class PROTOBUF_EXPORT Option : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1342,7 +1212,6 @@ class PROTOBUF_EXPORT Option : } static const Option& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Option* internal_default_instance() { return reinterpret_cast( &_Option_default_instance_); @@ -1355,7 +1224,7 @@ class PROTOBUF_EXPORT Option : } inline void Swap(Option* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1363,7 +1232,7 @@ class PROTOBUF_EXPORT Option : } void UnsafeArenaSwap(Option* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1403,13 +1272,6 @@ class PROTOBUF_EXPORT Option : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1439,15 +1301,6 @@ class PROTOBUF_EXPORT Option : std::string* mutable_name(); std::string* release_name(); void set_allocated_name(std::string* name); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_name(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_name( - std::string* name); private: const std::string& _internal_name() const; void _internal_set_name(const std::string& value); @@ -1476,7 +1329,6 @@ class PROTOBUF_EXPORT Option : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1498,7 +1350,7 @@ class PROTOBUF_EXPORT Option : // string name = 1; inline void Type::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); } inline const std::string& Type::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Type.name) @@ -1517,36 +1369,34 @@ inline const std::string& Type::_internal_name() const { } inline void Type::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Type::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Type.name) } inline void Type::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Type.name) } inline void Type::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.name) } inline std::string* Type::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Type::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Type.name) - - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Type::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1555,28 +1405,9 @@ inline void Type::set_allocated_name(std::string* name) { } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name) } -inline std::string* Type::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Type.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void Type::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - - } else { - - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.name) -} // repeated .google.protobuf.Field fields = 2; inline int Type::_internal_fields_size() const { @@ -1739,16 +1570,31 @@ inline bool Type::has_source_context() const { } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::_internal_source_context() const { const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Type::source_context() const { // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) return _internal_source_context(); } +inline void Type::unsafe_arena_set_allocated_source_context( + PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Type.source_context) +} inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::release_source_context() { - auto temp = unsafe_arena_release_source_context(); - if (GetArenaNoVirtual() != nullptr) { + + PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -1763,7 +1609,7 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::unsafe_arena_release_source_c inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::_internal_mutable_source_context() { if (source_context_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); source_context_ = p; } return source_context_; @@ -1773,12 +1619,13 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Type::mutable_source_context() { return _internal_mutable_source_context(); } inline void Type::set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); } if (source_context) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)->GetArena(); if (message_arena != submessage_arena) { source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, source_context, submessage_arena); @@ -1877,7 +1724,7 @@ inline void Field::set_number(::PROTOBUF_NAMESPACE_ID::int32 value) { // string name = 4; inline void Field::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); } inline const std::string& Field::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.name) @@ -1896,36 +1743,34 @@ inline const std::string& Field::_internal_name() const { } inline void Field::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.name) } inline void Field::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.name) } inline void Field::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.name) } inline std::string* Field::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Field.name) - - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Field::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -1934,32 +1779,13 @@ inline void Field::set_allocated_name(std::string* name) { } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name) } -inline std::string* Field::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void Field::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - - } else { - - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.name) -} // string type_url = 6; inline void Field::clear_type_url() { - type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + type_url_.ClearToEmpty(); } inline const std::string& Field::type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url) @@ -1978,36 +1804,34 @@ inline const std::string& Field::_internal_type_url() const { } inline void Field::_internal_set_type_url(const std::string& value) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_type_url(std::string&& value) { type_url_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.type_url) } inline void Field::set_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.type_url) } inline void Field::set_type_url(const char* value, size_t size) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.type_url) } inline std::string* Field::_internal_mutable_type_url() { - return type_url_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url) - - return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return type_url_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Field::set_allocated_type_url(std::string* type_url) { if (type_url != nullptr) { @@ -2016,28 +1840,9 @@ inline void Field::set_allocated_type_url(std::string* type_url) { } type_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type_url, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url) } -inline std::string* Field::unsafe_arena_release_type_url() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.type_url) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return type_url_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void Field::unsafe_arena_set_allocated_type_url( - std::string* type_url) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (type_url != nullptr) { - - } else { - - } - type_url_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - type_url, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.type_url) -} // int32 oneof_index = 7; inline void Field::clear_oneof_index() { @@ -2120,7 +1925,7 @@ Field::options() const { // string json_name = 10; inline void Field::clear_json_name() { - json_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + json_name_.ClearToEmpty(); } inline const std::string& Field::json_name() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name) @@ -2139,36 +1944,34 @@ inline const std::string& Field::_internal_json_name() const { } inline void Field::_internal_set_json_name(const std::string& value) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_json_name(std::string&& value) { json_name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.json_name) } inline void Field::set_json_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name) } inline void Field::set_json_name(const char* value, size_t size) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name) } inline std::string* Field::_internal_mutable_json_name() { - return json_name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_json_name() { // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name) - - return json_name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return json_name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Field::set_allocated_json_name(std::string* json_name) { if (json_name != nullptr) { @@ -2177,32 +1980,13 @@ inline void Field::set_allocated_json_name(std::string* json_name) { } json_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), json_name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name) } -inline std::string* Field::unsafe_arena_release_json_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.json_name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return json_name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void Field::unsafe_arena_set_allocated_json_name( - std::string* json_name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (json_name != nullptr) { - - } else { - - } - json_name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - json_name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.json_name) -} // string default_value = 11; inline void Field::clear_default_value() { - default_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + default_value_.ClearToEmpty(); } inline const std::string& Field::default_value() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value) @@ -2221,36 +2005,34 @@ inline const std::string& Field::_internal_default_value() const { } inline void Field::_internal_set_default_value(const std::string& value) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_default_value(std::string&& value) { default_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.default_value) } inline void Field::set_default_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.default_value) } inline void Field::set_default_value(const char* value, size_t size) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.default_value) } inline std::string* Field::_internal_mutable_default_value() { - return default_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_default_value() { // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value) - - return default_value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return default_value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Field::set_allocated_default_value(std::string* default_value) { if (default_value != nullptr) { @@ -2259,28 +2041,9 @@ inline void Field::set_allocated_default_value(std::string* default_value) { } default_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_value, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.default_value) } -inline std::string* Field::unsafe_arena_release_default_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Field.default_value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return default_value_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void Field::unsafe_arena_set_allocated_default_value( - std::string* default_value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (default_value != nullptr) { - - } else { - - } - default_value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - default_value, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Field.default_value) -} // ------------------------------------------------------------------- @@ -2288,7 +2051,7 @@ inline void Field::unsafe_arena_set_allocated_default_value( // string name = 1; inline void Enum::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); } inline const std::string& Enum::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Enum.name) @@ -2307,36 +2070,34 @@ inline const std::string& Enum::_internal_name() const { } inline void Enum::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Enum::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Enum.name) } inline void Enum::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Enum.name) } inline void Enum::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Enum.name) } inline std::string* Enum::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Enum::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Enum.name) - - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Enum::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -2345,28 +2106,9 @@ inline void Enum::set_allocated_name(std::string* name) { } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name) } -inline std::string* Enum::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Enum.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void Enum::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - - } else { - - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.name) -} // repeated .google.protobuf.EnumValue enumvalue = 2; inline int Enum::_internal_enumvalue_size() const { @@ -2455,16 +2197,31 @@ inline bool Enum::has_source_context() const { } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::_internal_source_context() const { const PROTOBUF_NAMESPACE_ID::SourceContext* p = source_context_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::SourceContext& Enum::source_context() const { // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) return _internal_source_context(); } +inline void Enum::unsafe_arena_set_allocated_source_context( + PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); + } + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Enum.source_context) +} inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::release_source_context() { - auto temp = unsafe_arena_release_source_context(); - if (GetArenaNoVirtual() != nullptr) { + + PROTOBUF_NAMESPACE_ID::SourceContext* temp = source_context_; + source_context_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -2479,7 +2236,7 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::unsafe_arena_release_source_c inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::_internal_mutable_source_context() { if (source_context_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); source_context_ = p; } return source_context_; @@ -2489,12 +2246,13 @@ inline PROTOBUF_NAMESPACE_ID::SourceContext* Enum::mutable_source_context() { return _internal_mutable_source_context(); } inline void Enum::set_allocated_source_context(PROTOBUF_NAMESPACE_ID::SourceContext* source_context) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context_); } if (source_context) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(source_context)->GetArena(); if (message_arena != submessage_arena) { source_context = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, source_context, submessage_arena); @@ -2533,7 +2291,7 @@ inline void Enum::set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void EnumValue::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); } inline const std::string& EnumValue::name() const { // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name) @@ -2552,36 +2310,34 @@ inline const std::string& EnumValue::_internal_name() const { } inline void EnumValue::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void EnumValue::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumValue.name) } inline void EnumValue::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValue.name) } inline void EnumValue::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValue.name) } inline std::string* EnumValue::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* EnumValue::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name) - - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void EnumValue::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -2590,28 +2346,9 @@ inline void EnumValue::set_allocated_name(std::string* name) { } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name) } -inline std::string* EnumValue::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.EnumValue.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void EnumValue::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - - } else { - - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.EnumValue.name) -} // int32 number = 2; inline void EnumValue::clear_number() { @@ -2678,7 +2415,7 @@ EnumValue::options() const { // string name = 1; inline void Option::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + name_.ClearToEmpty(); } inline const std::string& Option::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Option.name) @@ -2697,36 +2434,34 @@ inline const std::string& Option::_internal_name() const { } inline void Option::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Option::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Option.name) } inline void Option::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Option.name) } inline void Option::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Option.name) } inline std::string* Option::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Option::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Option.name) - - return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return name_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void Option::set_allocated_name(std::string* name) { if (name != nullptr) { @@ -2735,28 +2470,9 @@ inline void Option::set_allocated_name(std::string* name) { } name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name) } -inline std::string* Option::unsafe_arena_release_name() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.Option.name) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return name_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void Option::unsafe_arena_set_allocated_name( - std::string* name) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (name != nullptr) { - - } else { - - } - name_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - name, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.name) -} // .google.protobuf.Any value = 2; inline bool Option::_internal_has_value() const { @@ -2767,16 +2483,31 @@ inline bool Option::has_value() const { } inline const PROTOBUF_NAMESPACE_ID::Any& Option::_internal_value() const { const PROTOBUF_NAMESPACE_ID::Any* p = value_; - return p != nullptr ? *p : *reinterpret_cast( - &PROTOBUF_NAMESPACE_ID::_Any_default_instance_); + return p != nullptr ? *p : reinterpret_cast( + PROTOBUF_NAMESPACE_ID::_Any_default_instance_); } inline const PROTOBUF_NAMESPACE_ID::Any& Option::value() const { // @@protoc_insertion_point(field_get:google.protobuf.Option.value) return _internal_value(); } +inline void Option::unsafe_arena_set_allocated_value( + PROTOBUF_NAMESPACE_ID::Any* value) { + if (GetArena() == nullptr) { + delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_); + } + value_ = value; + if (value) { + + } else { + + } + // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.Option.value) +} inline PROTOBUF_NAMESPACE_ID::Any* Option::release_value() { - auto temp = unsafe_arena_release_value(); - if (GetArenaNoVirtual() != nullptr) { + + PROTOBUF_NAMESPACE_ID::Any* temp = value_; + value_ = nullptr; + if (GetArena() != nullptr) { temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp); } return temp; @@ -2791,7 +2522,7 @@ inline PROTOBUF_NAMESPACE_ID::Any* Option::unsafe_arena_release_value() { inline PROTOBUF_NAMESPACE_ID::Any* Option::_internal_mutable_value() { if (value_ == nullptr) { - auto* p = CreateMaybeMessage(GetArenaNoVirtual()); + auto* p = CreateMaybeMessage(GetArena()); value_ = p; } return value_; @@ -2801,12 +2532,13 @@ inline PROTOBUF_NAMESPACE_ID::Any* Option::mutable_value() { return _internal_mutable_value(); } inline void Option::set_allocated_value(PROTOBUF_NAMESPACE_ID::Any* value) { - ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaNoVirtual(); + ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena(); if (message_arena == nullptr) { delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(value_); } if (value) { - ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = nullptr; + ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena = + reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(value)->GetArena(); if (message_arena != submessage_arena) { value = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage( message_arena, value, submessage_arena); diff --git a/src/google/protobuf/type.proto b/src/google/protobuf/type.proto index e4b1d3a4abff..d3f6a68b8398 100644 --- a/src/google/protobuf/type.proto +++ b/src/google/protobuf/type.proto @@ -41,7 +41,7 @@ option java_package = "com.google.protobuf"; option java_outer_classname = "TypeProto"; option java_multiple_files = true; option objc_class_prefix = "GPB"; -option go_package = "google.golang.org/genproto/protobuf/ptype;ptype"; +option go_package = "google.golang.org/protobuf/types/known/typepb"; // A protocol buffer message type. message Type { @@ -113,7 +113,7 @@ message Field { CARDINALITY_REQUIRED = 2; // For repeated fields. CARDINALITY_REPEATED = 3; - }; + } // The field type. Kind kind = 1; diff --git a/src/google/protobuf/unittest_arena.proto b/src/google/protobuf/unittest_arena.proto index cd7e437e163e..7b3173996e28 100644 --- a/src/google/protobuf/unittest_arena.proto +++ b/src/google/protobuf/unittest_arena.proto @@ -30,8 +30,6 @@ syntax = "proto2"; -import "google/protobuf/unittest_no_arena_import.proto"; - package proto2_arena_unittest; option cc_enable_arenas = true; @@ -41,6 +39,5 @@ message NestedMessage { } message ArenaMessage { - repeated NestedMessage repeated_nested_message = 1; - repeated ImportNoArenaNestedMessage repeated_import_no_arena_message = 2; -}; + repeated NestedMessage repeated_nested_message = 1; +} diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto index c4aad2edf686..f774c766e31b 100644 --- a/src/google/protobuf/unittest_custom_options.proto +++ b/src/google/protobuf/unittest_custom_options.proto @@ -38,20 +38,20 @@ syntax = "proto2"; // Some generic_services option(s) added automatically. // See: http://go/proto2-generic-services-default -option cc_generic_services = true; // auto-added -option java_generic_services = true; // auto-added +option cc_generic_services = true; // auto-added +option java_generic_services = true; // auto-added option py_generic_services = true; // A custom file option (defined below). option (file_opt1) = 9876543210; +import "google/protobuf/any.proto"; import "google/protobuf/descriptor.proto"; // We don't put this in a package within proto2 because we need to make sure // that the generated code doesn't depend on being in the proto2 namespace. package protobuf_unittest; - // Some simple test custom options of various types. extend google.protobuf.FileOptions { @@ -66,7 +66,7 @@ extend google.protobuf.FieldOptions { optional fixed64 field_opt1 = 7740936; // This is useful for testing that we correctly register default values for // extension options. - optional int32 field_opt2 = 7753913 [default=42]; + optional int32 field_opt2 = 7753913 [default = 42]; } extend google.protobuf.OneofOptions { @@ -98,14 +98,13 @@ extend google.protobuf.MethodOptions { // regular options, to make sure they interact nicely). message TestMessageWithCustomOptions { option message_set_wire_format = false; - option (message_opt1) = -56; - optional string field1 = 1 [ctype=CORD, - (field_opt1)=8765432109]; + optional string field1 = 1 [ctype = CORD, (field_opt1) = 8765432109]; oneof AnOneof { option (oneof_opt1) = -99; + int32 oneof_field = 2; } @@ -117,20 +116,15 @@ message TestMessageWithCustomOptions { } } - // A test RPC service with custom options at all possible locations (and also // some regular options, to make sure they interact nicely). -message CustomOptionFooRequest { -} +message CustomOptionFooRequest {} -message CustomOptionFooResponse { -} +message CustomOptionFooResponse {} -message CustomOptionFooClientMessage { -} +message CustomOptionFooClientMessage {} -message CustomOptionFooServerMessage { -} +message CustomOptionFooServerMessage {} service TestServiceWithCustomOptions { option (service_opt1) = -9876543210; @@ -140,8 +134,6 @@ service TestServiceWithCustomOptions { } } - - // Options of every possible field type, so we can test them all exhaustively. message DummyMessageContainingEnum { @@ -151,74 +143,73 @@ message DummyMessageContainingEnum { } } -message DummyMessageInvalidAsOptionType { -} +message DummyMessageInvalidAsOptionType {} extend google.protobuf.MessageOptions { - optional bool bool_opt = 7706090; - optional int32 int32_opt = 7705709; - optional int64 int64_opt = 7705542; - optional uint32 uint32_opt = 7704880; - optional uint64 uint64_opt = 7702367; - optional sint32 sint32_opt = 7701568; - optional sint64 sint64_opt = 7700863; - optional fixed32 fixed32_opt = 7700307; - optional fixed64 fixed64_opt = 7700194; - optional sfixed32 sfixed32_opt = 7698645; - optional sfixed64 sfixed64_opt = 7685475; - optional float float_opt = 7675390; - optional double double_opt = 7673293; - optional string string_opt = 7673285; - optional bytes bytes_opt = 7673238; + optional bool bool_opt = 7706090; + optional int32 int32_opt = 7705709; + optional int64 int64_opt = 7705542; + optional uint32 uint32_opt = 7704880; + optional uint64 uint64_opt = 7702367; + optional sint32 sint32_opt = 7701568; + optional sint64 sint64_opt = 7700863; + optional fixed32 fixed32_opt = 7700307; + optional fixed64 fixed64_opt = 7700194; + optional sfixed32 sfixed32_opt = 7698645; + optional sfixed64 sfixed64_opt = 7685475; + optional float float_opt = 7675390; + optional double double_opt = 7673293; + optional string string_opt = 7673285; + optional bytes bytes_opt = 7673238; optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233; optional DummyMessageInvalidAsOptionType message_type_opt = 7665967; } message CustomOptionMinIntegerValues { - option (bool_opt) = false; - option (int32_opt) = -0x80000000; - option (int64_opt) = -0x8000000000000000; - option (uint32_opt) = 0; - option (uint64_opt) = 0; - option (sint32_opt) = -0x80000000; - option (sint64_opt) = -0x8000000000000000; - option (fixed32_opt) = 0; - option (fixed64_opt) = 0; + option (bool_opt) = false; + option (int32_opt) = -0x80000000; + option (int64_opt) = -0x8000000000000000; + option (uint32_opt) = 0; + option (uint64_opt) = 0; + option (sint32_opt) = -0x80000000; + option (sint64_opt) = -0x8000000000000000; + option (fixed32_opt) = 0; + option (fixed64_opt) = 0; option (sfixed32_opt) = -0x80000000; option (sfixed64_opt) = -0x8000000000000000; } message CustomOptionMaxIntegerValues { - option (bool_opt) = true; - option (int32_opt) = 0x7FFFFFFF; - option (int64_opt) = 0x7FFFFFFFFFFFFFFF; - option (uint32_opt) = 0xFFFFFFFF; - option (uint64_opt) = 0xFFFFFFFFFFFFFFFF; - option (sint32_opt) = 0x7FFFFFFF; - option (sint64_opt) = 0x7FFFFFFFFFFFFFFF; - option (fixed32_opt) = 0xFFFFFFFF; - option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF; + option (bool_opt) = true; + option (int32_opt) = 0x7FFFFFFF; + option (int64_opt) = 0x7FFFFFFFFFFFFFFF; + option (uint32_opt) = 0xFFFFFFFF; + option (uint64_opt) = 0xFFFFFFFFFFFFFFFF; + option (sint32_opt) = 0x7FFFFFFF; + option (sint64_opt) = 0x7FFFFFFFFFFFFFFF; + option (fixed32_opt) = 0xFFFFFFFF; + option (fixed64_opt) = 0xFFFFFFFFFFFFFFFF; option (sfixed32_opt) = 0x7FFFFFFF; option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF; } message CustomOptionOtherValues { - option (int32_opt) = -100; // To test sign-extension. - option (float_opt) = 12.3456789; + option (int32_opt) = -100; // To test sign-extension. + option (float_opt) = 12.3456789; option (double_opt) = 1.234567890123456789; option (string_opt) = "Hello, \"World\""; - option (bytes_opt) = "Hello\0World"; - option (enum_opt) = TEST_OPTION_ENUM_TYPE2; + option (bytes_opt) = "Hello\0World"; + option (enum_opt) = TEST_OPTION_ENUM_TYPE2; } message SettingRealsFromPositiveInts { - option (float_opt) = 12; + option (float_opt) = 12; option (double_opt) = 154; } message SettingRealsFromNegativeInts { - option (float_opt) = -12; - option (double_opt) = -154; + option (float_opt) = -12; + option (double_opt) = -154; } // Options of complex message types, themselves combined and extended in @@ -295,8 +286,12 @@ message VariousComplexOptions { option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121; option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971; option (complex_opt2).fred.waldo = 321; - option (complex_opt2).barney = { waldo: 101 }; - option (complex_opt2).barney = { waldo: 212 }; + option (complex_opt2).barney = { + waldo: 101 + }; + option (complex_opt2).barney = { + waldo: 212 + }; option (protobuf_unittest.complex_opt3).qux = 9; option (complex_opt3).complexoptiontype5.plugh = 22; option (complexopt6).xyzzy = 24; @@ -308,6 +303,7 @@ message VariousComplexOptions { message AggregateMessageSet { option message_set_wire_format = true; + extensions 4 to max; } @@ -334,32 +330,48 @@ message Aggregate { // An embedded message set optional AggregateMessageSet mset = 5; + + // An any + optional google.protobuf.Any any = 6; } // Allow Aggregate to be used as an option at all possible locations // in the .proto grammar. -extend google.protobuf.FileOptions { optional Aggregate fileopt = 15478479; } -extend google.protobuf.MessageOptions { optional Aggregate msgopt = 15480088; } -extend google.protobuf.FieldOptions { optional Aggregate fieldopt = 15481374; } -extend google.protobuf.EnumOptions { optional Aggregate enumopt = 15483218; } -extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; } -extend google.protobuf.ServiceOptions { optional Aggregate serviceopt = 15497145; } -extend google.protobuf.MethodOptions { optional Aggregate methodopt = 15512713; } +extend google.protobuf.FileOptions { + optional Aggregate fileopt = 15478479; +} +extend google.protobuf.MessageOptions { + optional Aggregate msgopt = 15480088; +} +extend google.protobuf.FieldOptions { + optional Aggregate fieldopt = 15481374; +} +extend google.protobuf.EnumOptions { + optional Aggregate enumopt = 15483218; +} +extend google.protobuf.EnumValueOptions { + optional Aggregate enumvalopt = 15486921; +} +extend google.protobuf.ServiceOptions { + optional Aggregate serviceopt = 15497145; +} +extend google.protobuf.MethodOptions { + optional Aggregate methodopt = 15512713; +} // Try using AggregateOption at different points in the proto grammar option (fileopt) = { s: 'FileAnnotation' // Also test the handling of comments - /* of both types */ i: 100 + /* of both types */ + i: 100 sub { s: 'NestedFileAnnotation' } // Include a google.protobuf.FileOptions and recursively extend it with // another fileopt. file { - [protobuf_unittest.fileopt] { - s:'FileExtensionAnnotation' - } + [protobuf_unittest.fileopt] { s: 'FileExtensionAnnotation' } } // A message set inside an option value @@ -368,33 +380,53 @@ option (fileopt) = { s: 'EmbeddedMessageSetElement' } } + + any { + [type.googleapis.com/protobuf_unittest.AggregateMessageSetElement] { + s: 'EmbeddedMessageSetElement' + } + } }; message AggregateMessage { - option (msgopt) = { i:101 s:'MessageAnnotation' }; - optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }]; + option (msgopt) = { + i: 101 + s: 'MessageAnnotation' + }; + + optional int32 fieldname = 1 [(fieldopt) = { s: 'FieldAnnotation' }]; } service AggregateService { - option (serviceopt) = { s:'ServiceAnnotation' }; - rpc Method (AggregateMessage) returns (AggregateMessage) { - option (methodopt) = { s:'MethodAnnotation' }; + option (serviceopt) = { + s: 'ServiceAnnotation' + }; + + rpc Method(AggregateMessage) returns (AggregateMessage) { + option (methodopt) = { + s: 'MethodAnnotation' + }; } } enum AggregateEnum { - option (enumopt) = { s:'EnumAnnotation' }; - VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }]; + option (enumopt) = { + s: 'EnumAnnotation' + }; + + VALUE = 1 [(enumvalopt) = { s: 'EnumValueAnnotation' }]; } // Test custom options for nested type. message NestedOptionType { message NestedMessage { option (message_opt1) = 1001; + optional int32 nested_field = 1 [(field_opt1) = 1002]; } enum NestedEnum { option (enum_opt1) = 1003; + NESTED_ENUM_VALUE = 1 [(enum_value_opt1) = 1004]; } extend google.protobuf.FileOptions { @@ -405,9 +437,7 @@ message NestedOptionType { // Custom message option that has a required enum field. // WARNING: this is strongly discouraged! message OldOptionType { - enum TestEnum { - OLD_VALUE = 0; - } + enum TestEnum { OLD_VALUE = 0; } required TestEnum value = 1; } @@ -426,5 +456,7 @@ extend google.protobuf.MessageOptions { // Test message using the "required_enum_opt" option defined above. message TestMessageWithRequiredEnumOption { - option (required_enum_opt) = { value: OLD_VALUE }; + option (required_enum_opt) = { + value: OLD_VALUE + }; } diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto index 979c8416b470..f501f509d1f5 100644 --- a/src/google/protobuf/unittest_lite.proto +++ b/src/google/protobuf/unittest_lite.proto @@ -38,6 +38,7 @@ package protobuf_unittest; import "google/protobuf/unittest_import_lite.proto"; +option cc_enable_arenas = true; option optimize_for = LITE_RUNTIME; option java_package = "com.google.protobuf"; @@ -48,6 +49,10 @@ message TestAllTypesLite { optional int64 cc = 2; } + message NestedMessage2 { + optional int32 dd = 1; + } + enum NestedEnum { FOO = 1; BAR = 2; @@ -162,6 +167,7 @@ message TestAllTypesLite { string oneof_string = 113; bytes oneof_bytes = 114; NestedMessage oneof_lazy_nested_message = 115 [lazy = true]; + NestedMessage2 oneof_nested_message2 = 117; } // Tests toString for non-repeated fields with a list suffix diff --git a/src/google/protobuf/unittest_no_arena.proto b/src/google/protobuf/unittest_no_arena.proto deleted file mode 100644 index adc8656f7324..000000000000 --- a/src/google/protobuf/unittest_no_arena.proto +++ /dev/null @@ -1,206 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// 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 its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS 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. - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This proto file contains copies of TestAllTypes and friends, but with arena -// support disabled in code generation. It allows us to test the performance -// impact against baseline (non-arena) google.protobuf. - -syntax = "proto2"; - -// Some generic_services option(s) added automatically. -// See: http://go/proto2-generic-services-default -option cc_generic_services = true; // auto-added -option java_generic_services = true; // auto-added -option py_generic_services = true; // auto-added -option cc_enable_arenas = false; -option objc_class_prefix = "NOARN"; - -import "google/protobuf/unittest_import.proto"; -import "google/protobuf/unittest_arena.proto"; - -// We don't put this in a package within proto2 because we need to make sure -// that the generated code doesn't depend on being in the proto2 namespace. -// In test_util.h we do "using namespace unittest = protobuf_unittest". -package protobuf_unittest_no_arena; - -// Protos optimized for SPEED use a strict superset of the generated code -// of equivalent ones optimized for CODE_SIZE, so we should optimize all our -// tests for speed unless explicitly testing code size optimization. -option optimize_for = SPEED; - -option java_outer_classname = "UnittestProto"; - -// This proto includes every type of field in both singular and repeated -// forms. -message TestAllTypes { - message NestedMessage { - // The field name "b" fails to compile in proto1 because it conflicts with - // a local variable named "b" in one of the generated methods. Doh. - // This file needs to compile in proto1 to test backwards-compatibility. - optional int32 bb = 1; - } - - enum NestedEnum { - FOO = 1; - BAR = 2; - BAZ = 3; - NEG = -1; // Intentionally negative. - } - - // Singular - optional int32 optional_int32 = 1; - optional int64 optional_int64 = 2; - optional uint32 optional_uint32 = 3; - optional uint64 optional_uint64 = 4; - optional sint32 optional_sint32 = 5; - optional sint64 optional_sint64 = 6; - optional fixed32 optional_fixed32 = 7; - optional fixed64 optional_fixed64 = 8; - optional sfixed32 optional_sfixed32 = 9; - optional sfixed64 optional_sfixed64 = 10; - optional float optional_float = 11; - optional double optional_double = 12; - optional bool optional_bool = 13; - optional string optional_string = 14; - optional bytes optional_bytes = 15; - - optional group OptionalGroup = 16 { - optional int32 a = 17; - } - - optional NestedMessage optional_nested_message = 18; - optional ForeignMessage optional_foreign_message = 19; - optional protobuf_unittest_import.ImportMessage optional_import_message = 20; - - optional NestedEnum optional_nested_enum = 21; - optional ForeignEnum optional_foreign_enum = 22; - optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; - - // Defined in unittest_import_public.proto - optional protobuf_unittest_import.PublicImportMessage - optional_public_import_message = 26; - - optional NestedMessage optional_message = 27 [lazy=true]; - - // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; - repeated sfixed32 repeated_sfixed32 = 39; - repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; - - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } - - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; - repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; - - repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; - - // Singular with defaults - optional int32 default_int32 = 61 [default = 41 ]; - optional int64 default_int64 = 62 [default = 42 ]; - optional uint32 default_uint32 = 63 [default = 43 ]; - optional uint64 default_uint64 = 64 [default = 44 ]; - optional sint32 default_sint32 = 65 [default = -45 ]; - optional sint64 default_sint64 = 66 [default = 46 ]; - optional fixed32 default_fixed32 = 67 [default = 47 ]; - optional fixed64 default_fixed64 = 68 [default = 48 ]; - optional sfixed32 default_sfixed32 = 69 [default = 49 ]; - optional sfixed64 default_sfixed64 = 70 [default = -50 ]; - optional float default_float = 71 [default = 51.5 ]; - optional double default_double = 72 [default = 52e3 ]; - optional bool default_bool = 73 [default = true ]; - optional string default_string = 74 [default = "hello"]; - optional bytes default_bytes = 75 [default = "world"]; - - optional NestedEnum default_nested_enum = 81 [default = BAR ]; - optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR]; - optional protobuf_unittest_import.ImportEnum - default_import_enum = 83 [default = IMPORT_BAR]; - - optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"]; - optional string default_cord = 85 [ctype=CORD,default="123"]; - - // For oneof test - oneof oneof_field { - uint32 oneof_uint32 = 111; - NestedMessage oneof_nested_message = 112; - string oneof_string = 113; - bytes oneof_bytes = 114; - NestedMessage lazy_oneof_nested_message = 115 [lazy=true]; - } -} - -// Define these after TestAllTypes to make sure the compiler can handle -// that. -message ForeignMessage { - optional int32 c = 1; -} - -enum ForeignEnum { - FOREIGN_FOO = 4; - FOREIGN_BAR = 5; - FOREIGN_BAZ = 6; -} - -message TestNoArenaMessage { - optional proto2_arena_unittest.ArenaMessage arena_message = 1; -}; - -message OneString { - optional string data = 1; -} diff --git a/src/google/protobuf/unittest_proto3_arena_lite.proto b/src/google/protobuf/unittest_proto3_arena_lite.proto index b3c91f570efb..0d4218b97fc5 100644 --- a/src/google/protobuf/unittest_proto3_arena_lite.proto +++ b/src/google/protobuf/unittest_proto3_arena_lite.proto @@ -30,12 +30,12 @@ syntax = "proto3"; -option cc_enable_arenas = true; -option optimize_for = LITE_RUNTIME; +package proto3_arena_lite_unittest; import "google/protobuf/unittest_import.proto"; -package proto3_arena_lite_unittest; +option cc_enable_arenas = true; +option optimize_for = LITE_RUNTIME; // This proto includes every type of field in both singular and repeated // forms. @@ -56,86 +56,86 @@ message TestAllTypes { } // Singular - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - sint32 optional_sint32 = 5; - sint64 optional_sint64 = 6; - fixed32 optional_fixed32 = 7; - fixed64 optional_fixed64 = 8; - sfixed32 optional_sfixed32 = 9; + int32 optional_int32 = 1; + int64 optional_int64 = 2; + uint32 optional_uint32 = 3; + uint64 optional_uint64 = 4; + sint32 optional_sint32 = 5; + sint64 optional_sint64 = 6; + fixed32 optional_fixed32 = 7; + fixed64 optional_fixed64 = 8; + sfixed32 optional_sfixed32 = 9; sfixed64 optional_sfixed64 = 10; - float optional_float = 11; - double optional_double = 12; - bool optional_bool = 13; - string optional_string = 14; - bytes optional_bytes = 15; + float optional_float = 11; + double optional_double = 12; + bool optional_bool = 13; + string optional_string = 14; + bytes optional_bytes = 15; // Groups are not allowed in proto3. // optional group OptionalGroup = 16 { // optional int32 a = 17; // } - NestedMessage optional_nested_message = 18; - ForeignMessage optional_foreign_message = 19; - protobuf_unittest_import.ImportMessage optional_import_message = 20; + NestedMessage optional_nested_message = 18; + ForeignMessage optional_foreign_message = 19; + protobuf_unittest_import.ImportMessage optional_import_message = 20; - NestedEnum optional_nested_enum = 21; - ForeignEnum optional_foreign_enum = 22; + NestedEnum optional_nested_enum = 21; + ForeignEnum optional_foreign_enum = 22; // Omitted (compared to unittest.proto) because proto2 enums are not allowed // inside proto2 messages. // // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - string optional_string_piece = 24 [ctype=STRING_PIECE]; - string optional_cord = 25 [ctype=CORD]; + string optional_string_piece = 24 [ctype = STRING_PIECE]; + string optional_cord = 25 [ctype = CORD]; // Defined in unittest_import_public.proto - protobuf_unittest_import.PublicImportMessage - optional_public_import_message = 26; + protobuf_unittest_import.PublicImportMessage optional_public_import_message = + 26; - NestedMessage optional_lazy_message = 27 [lazy=true]; + NestedMessage optional_lazy_message = 27 [lazy = true]; // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; repeated sfixed32 repeated_sfixed32 = 39; repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; // Groups are not allowed in proto3. // repeated group RepeatedGroup = 46 { // optional int32 a = 47; // } - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; + repeated NestedMessage repeated_nested_message = 48; + repeated ForeignMessage repeated_foreign_message = 49; + repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; + repeated NestedEnum repeated_nested_enum = 51; + repeated ForeignEnum repeated_foreign_enum = 52; // Omitted (compared to unittest.proto) because proto2 enums are not allowed // inside proto2 messages. // // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; + repeated string repeated_string_piece = 54 [ctype = STRING_PIECE]; + repeated string repeated_cord = 55 [ctype = CORD]; - repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; + repeated NestedMessage repeated_lazy_message = 57 [lazy = true]; oneof oneof_field { uint32 oneof_uint32 = 111; @@ -148,37 +148,37 @@ message TestAllTypes { // Test messages for packed fields message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; + repeated int32 packed_int32 = 90 [packed = true]; + repeated int64 packed_int64 = 91 [packed = true]; + repeated uint32 packed_uint32 = 92 [packed = true]; + repeated uint64 packed_uint64 = 93 [packed = true]; + repeated sint32 packed_sint32 = 94 [packed = true]; + repeated sint64 packed_sint64 = 95 [packed = true]; + repeated fixed32 packed_fixed32 = 96 [packed = true]; + repeated fixed64 packed_fixed64 = 97 [packed = true]; + repeated sfixed32 packed_sfixed32 = 98 [packed = true]; + repeated sfixed64 packed_sfixed64 = 99 [packed = true]; + repeated float packed_float = 100 [packed = true]; + repeated double packed_double = 101 [packed = true]; + repeated bool packed_bool = 102 [packed = true]; + repeated ForeignEnum packed_enum = 103 [packed = true]; } // Explicitly set packed to false message TestUnpackedTypes { - repeated int32 repeated_int32 = 1 [packed = false]; - repeated int64 repeated_int64 = 2 [packed = false]; - repeated uint32 repeated_uint32 = 3 [packed = false]; - repeated uint64 repeated_uint64 = 4 [packed = false]; - repeated sint32 repeated_sint32 = 5 [packed = false]; - repeated sint64 repeated_sint64 = 6 [packed = false]; - repeated fixed32 repeated_fixed32 = 7 [packed = false]; - repeated fixed64 repeated_fixed64 = 8 [packed = false]; - repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; + repeated int32 repeated_int32 = 1 [packed = false]; + repeated int64 repeated_int64 = 2 [packed = false]; + repeated uint32 repeated_uint32 = 3 [packed = false]; + repeated uint64 repeated_uint64 = 4 [packed = false]; + repeated sint32 repeated_sint32 = 5 [packed = false]; + repeated sint64 repeated_sint64 = 6 [packed = false]; + repeated fixed32 repeated_fixed32 = 7 [packed = false]; + repeated fixed64 repeated_fixed64 = 8 [packed = false]; + repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; repeated sfixed64 repeated_sfixed64 = 10 [packed = false]; - repeated float repeated_float = 11 [packed = false]; - repeated double repeated_double = 12 [packed = false]; - repeated bool repeated_bool = 13 [packed = false]; + repeated float repeated_float = 11 [packed = false]; + repeated double repeated_double = 12 [packed = false]; + repeated bool repeated_bool = 13 [packed = false]; repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false]; } @@ -202,6 +202,4 @@ enum ForeignEnum { } // TestEmptyMessage is used to test behavior of unknown fields. -message TestEmptyMessage { -} - +message TestEmptyMessage {} diff --git a/src/google/protobuf/unittest_proto3_lite.proto b/src/google/protobuf/unittest_proto3_lite.proto index 6ee8bc8085bc..837bb03c5f1f 100644 --- a/src/google/protobuf/unittest_proto3_lite.proto +++ b/src/google/protobuf/unittest_proto3_lite.proto @@ -30,11 +30,11 @@ syntax = "proto3"; -option optimize_for = LITE_RUNTIME; +package proto3_lite_unittest; import "google/protobuf/unittest_import.proto"; -package proto3_lite_unittest; +option optimize_for = LITE_RUNTIME; // This proto includes every type of field in both singular and repeated // forms. @@ -55,86 +55,86 @@ message TestAllTypes { } // Singular - int32 optional_int32 = 1; - int64 optional_int64 = 2; - uint32 optional_uint32 = 3; - uint64 optional_uint64 = 4; - sint32 optional_sint32 = 5; - sint64 optional_sint64 = 6; - fixed32 optional_fixed32 = 7; - fixed64 optional_fixed64 = 8; - sfixed32 optional_sfixed32 = 9; + int32 optional_int32 = 1; + int64 optional_int64 = 2; + uint32 optional_uint32 = 3; + uint64 optional_uint64 = 4; + sint32 optional_sint32 = 5; + sint64 optional_sint64 = 6; + fixed32 optional_fixed32 = 7; + fixed64 optional_fixed64 = 8; + sfixed32 optional_sfixed32 = 9; sfixed64 optional_sfixed64 = 10; - float optional_float = 11; - double optional_double = 12; - bool optional_bool = 13; - string optional_string = 14; - bytes optional_bytes = 15; + float optional_float = 11; + double optional_double = 12; + bool optional_bool = 13; + string optional_string = 14; + bytes optional_bytes = 15; // Groups are not allowed in proto3. // optional group OptionalGroup = 16 { // optional int32 a = 17; // } - NestedMessage optional_nested_message = 18; - ForeignMessage optional_foreign_message = 19; - protobuf_unittest_import.ImportMessage optional_import_message = 20; + NestedMessage optional_nested_message = 18; + ForeignMessage optional_foreign_message = 19; + protobuf_unittest_import.ImportMessage optional_import_message = 20; - NestedEnum optional_nested_enum = 21; - ForeignEnum optional_foreign_enum = 22; + NestedEnum optional_nested_enum = 21; + ForeignEnum optional_foreign_enum = 22; // Omitted (compared to unittest.proto) because proto2 enums are not allowed // inside proto2 messages. // // optional protobuf_unittest_import.ImportEnum optional_import_enum = 23; - string optional_string_piece = 24 [ctype=STRING_PIECE]; - string optional_cord = 25 [ctype=CORD]; + string optional_string_piece = 24 [ctype = STRING_PIECE]; + string optional_cord = 25 [ctype = CORD]; // Defined in unittest_import_public.proto - protobuf_unittest_import.PublicImportMessage - optional_public_import_message = 26; + protobuf_unittest_import.PublicImportMessage optional_public_import_message = + 26; - NestedMessage optional_lazy_message = 27 [lazy=true]; + NestedMessage optional_lazy_message = 27 [lazy = true]; // Repeated - repeated int32 repeated_int32 = 31; - repeated int64 repeated_int64 = 32; - repeated uint32 repeated_uint32 = 33; - repeated uint64 repeated_uint64 = 34; - repeated sint32 repeated_sint32 = 35; - repeated sint64 repeated_sint64 = 36; - repeated fixed32 repeated_fixed32 = 37; - repeated fixed64 repeated_fixed64 = 38; + repeated int32 repeated_int32 = 31; + repeated int64 repeated_int64 = 32; + repeated uint32 repeated_uint32 = 33; + repeated uint64 repeated_uint64 = 34; + repeated sint32 repeated_sint32 = 35; + repeated sint64 repeated_sint64 = 36; + repeated fixed32 repeated_fixed32 = 37; + repeated fixed64 repeated_fixed64 = 38; repeated sfixed32 repeated_sfixed32 = 39; repeated sfixed64 repeated_sfixed64 = 40; - repeated float repeated_float = 41; - repeated double repeated_double = 42; - repeated bool repeated_bool = 43; - repeated string repeated_string = 44; - repeated bytes repeated_bytes = 45; + repeated float repeated_float = 41; + repeated double repeated_double = 42; + repeated bool repeated_bool = 43; + repeated string repeated_string = 44; + repeated bytes repeated_bytes = 45; // Groups are not allowed in proto3. // repeated group RepeatedGroup = 46 { // optional int32 a = 47; // } - repeated NestedMessage repeated_nested_message = 48; - repeated ForeignMessage repeated_foreign_message = 49; - repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; + repeated NestedMessage repeated_nested_message = 48; + repeated ForeignMessage repeated_foreign_message = 49; + repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50; - repeated NestedEnum repeated_nested_enum = 51; - repeated ForeignEnum repeated_foreign_enum = 52; + repeated NestedEnum repeated_nested_enum = 51; + repeated ForeignEnum repeated_foreign_enum = 52; // Omitted (compared to unittest.proto) because proto2 enums are not allowed // inside proto2 messages. // // repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53; - repeated string repeated_string_piece = 54 [ctype=STRING_PIECE]; - repeated string repeated_cord = 55 [ctype=CORD]; + repeated string repeated_string_piece = 54 [ctype = STRING_PIECE]; + repeated string repeated_cord = 55 [ctype = CORD]; - repeated NestedMessage repeated_lazy_message = 57 [lazy=true]; + repeated NestedMessage repeated_lazy_message = 57 [lazy = true]; oneof oneof_field { uint32 oneof_uint32 = 111; @@ -147,37 +147,37 @@ message TestAllTypes { // Test messages for packed fields message TestPackedTypes { - repeated int32 packed_int32 = 90 [packed = true]; - repeated int64 packed_int64 = 91 [packed = true]; - repeated uint32 packed_uint32 = 92 [packed = true]; - repeated uint64 packed_uint64 = 93 [packed = true]; - repeated sint32 packed_sint32 = 94 [packed = true]; - repeated sint64 packed_sint64 = 95 [packed = true]; - repeated fixed32 packed_fixed32 = 96 [packed = true]; - repeated fixed64 packed_fixed64 = 97 [packed = true]; - repeated sfixed32 packed_sfixed32 = 98 [packed = true]; - repeated sfixed64 packed_sfixed64 = 99 [packed = true]; - repeated float packed_float = 100 [packed = true]; - repeated double packed_double = 101 [packed = true]; - repeated bool packed_bool = 102 [packed = true]; - repeated ForeignEnum packed_enum = 103 [packed = true]; + repeated int32 packed_int32 = 90 [packed = true]; + repeated int64 packed_int64 = 91 [packed = true]; + repeated uint32 packed_uint32 = 92 [packed = true]; + repeated uint64 packed_uint64 = 93 [packed = true]; + repeated sint32 packed_sint32 = 94 [packed = true]; + repeated sint64 packed_sint64 = 95 [packed = true]; + repeated fixed32 packed_fixed32 = 96 [packed = true]; + repeated fixed64 packed_fixed64 = 97 [packed = true]; + repeated sfixed32 packed_sfixed32 = 98 [packed = true]; + repeated sfixed64 packed_sfixed64 = 99 [packed = true]; + repeated float packed_float = 100 [packed = true]; + repeated double packed_double = 101 [packed = true]; + repeated bool packed_bool = 102 [packed = true]; + repeated ForeignEnum packed_enum = 103 [packed = true]; } // Explicitly set packed to false message TestUnpackedTypes { - repeated int32 repeated_int32 = 1 [packed = false]; - repeated int64 repeated_int64 = 2 [packed = false]; - repeated uint32 repeated_uint32 = 3 [packed = false]; - repeated uint64 repeated_uint64 = 4 [packed = false]; - repeated sint32 repeated_sint32 = 5 [packed = false]; - repeated sint64 repeated_sint64 = 6 [packed = false]; - repeated fixed32 repeated_fixed32 = 7 [packed = false]; - repeated fixed64 repeated_fixed64 = 8 [packed = false]; - repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; + repeated int32 repeated_int32 = 1 [packed = false]; + repeated int64 repeated_int64 = 2 [packed = false]; + repeated uint32 repeated_uint32 = 3 [packed = false]; + repeated uint64 repeated_uint64 = 4 [packed = false]; + repeated sint32 repeated_sint32 = 5 [packed = false]; + repeated sint64 repeated_sint64 = 6 [packed = false]; + repeated fixed32 repeated_fixed32 = 7 [packed = false]; + repeated fixed64 repeated_fixed64 = 8 [packed = false]; + repeated sfixed32 repeated_sfixed32 = 9 [packed = false]; repeated sfixed64 repeated_sfixed64 = 10 [packed = false]; - repeated float repeated_float = 11 [packed = false]; - repeated double repeated_double = 12 [packed = false]; - repeated bool repeated_bool = 13 [packed = false]; + repeated float repeated_float = 11 [packed = false]; + repeated double repeated_double = 12 [packed = false]; + repeated bool repeated_bool = 13 [packed = false]; repeated TestAllTypes.NestedEnum repeated_nested_enum = 14 [packed = false]; } @@ -201,6 +201,4 @@ enum ForeignEnum { } // TestEmptyMessage is used to test behavior of unknown fields. -message TestEmptyMessage { -} - +message TestEmptyMessage {} diff --git a/src/google/protobuf/unittest_proto3_optional.proto b/src/google/protobuf/unittest_proto3_optional.proto new file mode 100644 index 000000000000..e760021f3bc5 --- /dev/null +++ b/src/google/protobuf/unittest_proto3_optional.proto @@ -0,0 +1,88 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS 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. + +syntax = "proto3"; + +package protobuf_unittest; + +option java_multiple_files = true; +option java_package = "com.google.protobuf.testing.proto"; + +message TestProto3Optional { + message NestedMessage { + // The field name "b" fails to compile in proto1 because it conflicts with + // a local variable named "b" in one of the generated methods. Doh. + // This file needs to compile in proto1 to test backwards-compatibility. + optional int32 bb = 1; + } + + enum NestedEnum { + UNSPECIFIED = 0; + FOO = 1; + BAR = 2; + BAZ = 3; + NEG = -1; // Intentionally negative. + } + + // Singular + optional int32 optional_int32 = 1; + optional int64 optional_int64 = 2; + optional uint32 optional_uint32 = 3; + optional uint64 optional_uint64 = 4; + optional sint32 optional_sint32 = 5; + optional sint64 optional_sint64 = 6; + optional fixed32 optional_fixed32 = 7; + optional fixed64 optional_fixed64 = 8; + optional sfixed32 optional_sfixed32 = 9; + optional sfixed64 optional_sfixed64 = 10; + optional float optional_float = 11; + optional double optional_double = 12; + optional bool optional_bool = 13; + optional string optional_string = 14; + optional bytes optional_bytes = 15; + optional string optional_cord = 16 [ctype = CORD]; + + optional NestedMessage optional_nested_message = 18; + optional NestedMessage lazy_nested_message = 19 [lazy = true]; + optional NestedEnum optional_nested_enum = 21; + + // Add some non-optional fields to verify we can mix them. + int32 singular_int32 = 22; + int64 singular_int64 = 23; +} + +message TestProto3OptionalMessage { + message NestedMessage { + string s = 1; + } + + NestedMessage nested_message = 1; + optional NestedMessage optional_nested_message = 2; +} diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index fcffe85fcd6d..8ab4a1a19982 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -50,9 +49,9 @@ namespace google { namespace protobuf { -const UnknownFieldSet* UnknownFieldSet::default_instance() { +const UnknownFieldSet& UnknownFieldSet::default_instance() { static auto instance = internal::OnShutdownDelete(new UnknownFieldSet()); - return instance; + return *instance; } void UnknownFieldSet::ClearFallback() { @@ -99,10 +98,9 @@ void UnknownFieldSet::MergeFromAndDestroy(UnknownFieldSet* other) { other->fields_.clear(); } -void UnknownFieldSet::MergeToInternalMetdata( - const UnknownFieldSet& other, - internal::InternalMetadataWithArena* metadata) { - metadata->mutable_unknown_fields()->MergeFrom(other); +void UnknownFieldSet::MergeToInternalMetadata( + const UnknownFieldSet& other, internal::InternalMetadata* metadata) { + metadata->mutable_unknown_fields()->MergeFrom(other); } size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const { @@ -110,8 +108,7 @@ size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const { size_t total_size = sizeof(fields_) + sizeof(UnknownField) * fields_.size(); - for (int i = 0; i < fields_.size(); i++) { - const UnknownField& field = (fields_)[i]; + for (const UnknownField& field : fields_) { switch (field.type()) { case UnknownField::TYPE_LENGTH_DELIMITED: total_size += sizeof(*field.data_.length_delimited_.string_value) + @@ -186,7 +183,7 @@ void UnknownFieldSet::DeleteSubrange(int start, int num) { (fields_)[i + start].Delete(); } // Slide down the remaining fields. - for (int i = start + num; i < fields_.size(); ++i) { + for (size_t i = start + num; i < fields_.size(); ++i) { (fields_)[i - num] = (fields_)[i]; } // Pop off the # of deleted fields. @@ -196,8 +193,8 @@ void UnknownFieldSet::DeleteSubrange(int start, int num) { } void UnknownFieldSet::DeleteByNumber(int number) { - int left = 0; // The number of fields left after deletion. - for (int i = 0; i < fields_.size(); ++i) { + size_t left = 0; // The number of fields left after deletion. + for (size_t i = 0; i < fields_.size(); ++i) { UnknownField* field = &(fields_)[i]; if (field->number() == number) { field->Delete(); @@ -279,34 +276,6 @@ uint8* UnknownField::InternalSerializeLengthDelimitedNoTag( } namespace internal { -const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx, - bool (*is_valid)(int), - InternalMetadataWithArena* metadata, - int field_num) { - return ctx->ReadPackedVarint( - ptr, [object, is_valid, metadata, field_num](uint64 val) { - if (is_valid(val)) { - static_cast*>(object)->Add(val); - } else { - WriteVarint(field_num, val, metadata->mutable_unknown_fields()); - } - }); -} -const char* PackedEnumParserArg(void* object, const char* ptr, - ParseContext* ctx, - bool (*is_valid)(const void*, int), - const void* data, - InternalMetadataWithArena* metadata, - int field_num) { - return ctx->ReadPackedVarint( - ptr, [object, is_valid, data, metadata, field_num](uint64 val) { - if (is_valid(data, val)) { - static_cast*>(object)->Add(val); - } else { - WriteVarint(field_num, val, metadata->mutable_unknown_fields()); - } - }); -} class UnknownFieldParserHelper { public: @@ -352,11 +321,8 @@ const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown, return FieldParser(tag, field_parser, ptr, ctx); } -const char* UnknownFieldParse(uint32 tag, InternalMetadataWithArena* metadata, - const char* ptr, ParseContext* ctx) { - return UnknownFieldParse(tag, metadata->mutable_unknown_fields(), ptr, ctx); -} - } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h index b6134691b19e..ab3633daddd8 100644 --- a/src/google/protobuf/unknown_field_set.h +++ b/src/google/protobuf/unknown_field_set.h @@ -60,7 +60,7 @@ namespace google { namespace protobuf { namespace internal { -class InternalMetadataWithArena; // metadata.h +class InternalMetadata; // metadata_lite.h class WireFormat; // wire_format.h class MessageSetFieldSkipperUsingCord; // extension_set_heavy.cc @@ -104,9 +104,8 @@ class PROTOBUF_EXPORT UnknownFieldSet { // Merge the contents an UnknownFieldSet with the UnknownFieldSet in // *metadata, if there is one. If *metadata doesn't have an UnknownFieldSet // then add one to it and make it be a copy of the first arg. - static void MergeToInternalMetdata( - const UnknownFieldSet& other, - internal::InternalMetadataWithArena* metadata); + static void MergeToInternalMetadata(const UnknownFieldSet& other, + internal::InternalMetadata* metadata); // Swaps the contents of some other UnknownFieldSet with this one. inline void Swap(UnknownFieldSet* x); @@ -173,7 +172,7 @@ class PROTOBUF_EXPORT UnknownFieldSet { template bool MergeFromMessage(const MessageType& message); - static const UnknownFieldSet* default_instance(); + static const UnknownFieldSet& default_instance(); private: // For InternalMergeFrom @@ -218,27 +217,12 @@ inline void WriteLengthDelimited(uint32 num, StringPiece val, unknown->AddLengthDelimited(num)->assign(val.data(), val.size()); } -PROTOBUF_EXPORT -const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx, - bool (*is_valid)(int), - InternalMetadataWithArena* unknown, int field_num); -PROTOBUF_EXPORT -const char* PackedEnumParserArg(void* object, const char* ptr, - ParseContext* ctx, - bool (*is_valid)(const void*, int), - const void* data, - InternalMetadataWithArena* unknown, - int field_num); - PROTOBUF_EXPORT const char* UnknownGroupParse(UnknownFieldSet* unknown, const char* ptr, ParseContext* ctx); PROTOBUF_EXPORT const char* UnknownFieldParse(uint64 tag, UnknownFieldSet* unknown, const char* ptr, ParseContext* ctx); -PROTOBUF_EXPORT -const char* UnknownFieldParse(uint32 tag, InternalMetadataWithArena* metadata, - const char* ptr, ParseContext* ctx); } // namespace internal diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc index b1ccb5c5a1e4..bc8db5f514f6 100644 --- a/src/google/protobuf/unknown_field_set_unittest.cc +++ b/src/google/protobuf/unknown_field_set_unittest.cc @@ -37,6 +37,8 @@ #include +#include + #include #include #include @@ -50,6 +52,7 @@ #include #include #include +#include #include namespace google { @@ -112,30 +115,32 @@ class UnknownFieldSetTest : public testing::Test { namespace { TEST_F(UnknownFieldSetTest, AllFieldsPresent) { - // All fields of TestAllTypes should be present, in numeric order (because - // that's the order we parsed them in). Fields that are not valid field - // numbers of TestAllTypes should NOT be present. - - int pos = 0; - - for (int i = 0; i < 1000; i++) { - const FieldDescriptor* field = descriptor_->FindFieldByNumber(i); - if (field != NULL) { - ASSERT_LT(pos, unknown_fields_->field_count()); - // Do not check oneof field if it is not set. - if (field->containing_oneof() == NULL) { - EXPECT_EQ(i, unknown_fields_->field(pos++).number()); - } else if (i == unknown_fields_->field(pos).number()) { - pos++; - } - if (field->is_repeated()) { - // Should have a second instance. - ASSERT_LT(pos, unknown_fields_->field_count()); - EXPECT_EQ(i, unknown_fields_->field(pos++).number()); - } + // Verifies the following: + // --all unknown tags belong to TestAllTypes. + // --all fields in TestAllTypes is present in UnknownFieldSet except unset + // oneof fields. + // + // Should handle repeated fields that may appear multiple times in + // UnknownFieldSet. + + int non_oneof_count = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + non_oneof_count++; } } - EXPECT_EQ(unknown_fields_->field_count(), pos); + + std::unordered_set unknown_tags; + for (int i = 0; i < unknown_fields_->field_count(); i++) { + unknown_tags.insert(unknown_fields_->field(i).number()); + } + + for (uint32 t : unknown_tags) { + EXPECT_NE(descriptor_->FindFieldByNumber(t), nullptr); + } + + EXPECT_EQ(non_oneof_count + descriptor_->oneof_decl_count(), + unknown_tags.size()); } TEST_F(UnknownFieldSetTest, Varint) { @@ -245,7 +250,7 @@ TEST_F(UnknownFieldSetTest, SerializeViaReflection) { { io::StringOutputStream raw_output(&data); io::CodedOutputStream output(&raw_output); - int size = WireFormat::ByteSize(empty_message_); + size_t size = WireFormat::ByteSize(empty_message_); WireFormat::SerializeWithCachedSizes(empty_message_, size, &output); ASSERT_FALSE(output.HadError()); } @@ -535,29 +540,29 @@ TEST_F(UnknownFieldSetTest, SpaceUsed) { // Make sure an unknown field set has zero space used until a field is // actually added. - int base_size = empty_message.SpaceUsed(); + size_t base_size = empty_message.SpaceUsedLong(); UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields(); - EXPECT_EQ(base_size, empty_message.SpaceUsed()); + EXPECT_EQ(base_size, empty_message.SpaceUsedLong()); - // Make sure each thing we add to the set increases the SpaceUsed(). + // Make sure each thing we add to the set increases the SpaceUsedLong(). unknown_fields->AddVarint(1, 0); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); + EXPECT_LT(base_size, empty_message.SpaceUsedLong()); + base_size = empty_message.SpaceUsedLong(); std::string* str = unknown_fields->AddLengthDelimited(1); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); + EXPECT_LT(base_size, empty_message.SpaceUsedLong()); + base_size = empty_message.SpaceUsedLong(); str->assign(sizeof(std::string) + 1, 'x'); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); + EXPECT_LT(base_size, empty_message.SpaceUsedLong()); + base_size = empty_message.SpaceUsedLong(); UnknownFieldSet* group = unknown_fields->AddGroup(1); - EXPECT_LT(base_size, empty_message.SpaceUsed()); - base_size = empty_message.SpaceUsed(); + EXPECT_LT(base_size, empty_message.SpaceUsedLong()); + base_size = empty_message.SpaceUsedLong(); group->AddVarint(1, 0); - EXPECT_LT(base_size, empty_message.SpaceUsed()); + EXPECT_LT(base_size, empty_message.SpaceUsedLong()); } diff --git a/src/google/protobuf/util/delimited_message_util.cc b/src/google/protobuf/util/delimited_message_util.cc index 425dc2cfdff8..80cab309be3d 100644 --- a/src/google/protobuf/util/delimited_message_util.cc +++ b/src/google/protobuf/util/delimited_message_util.cc @@ -74,12 +74,18 @@ bool ParseDelimitedFromCodedStream(MessageLite* message, return false; } + // Get the position after any size bytes have been read (and only the message + // itself remains). + int position_after_size = input->CurrentPosition(); + // Tell the stream not to read beyond that size. io::CodedInputStream::Limit limit = input->PushLimit(size); // Parse the message. if (!message->MergeFromCodedStream(input)) return false; if (!input->ConsumedEntireMessage()) return false; + if (input->CurrentPosition() - position_after_size != static_cast(size)) + return false; // Release the limit. input->PopLimit(limit); diff --git a/src/google/protobuf/util/delimited_message_util_test.cc b/src/google/protobuf/util/delimited_message_util_test.cc index 9ed67784ee1c..9483a646e738 100644 --- a/src/google/protobuf/util/delimited_message_util_test.cc +++ b/src/google/protobuf/util/delimited_message_util_test.cc @@ -82,6 +82,35 @@ TEST(DelimitedMessageUtilTest, DelimitedMessages) { } } +TEST(DelimitedMessageUtilTest, FailsAtEndOfStream) { + std::stringstream full_stream; + std::stringstream partial_stream; + + { + protobuf_unittest::ForeignMessage message; + message.set_c(42); + message.set_d(24); + EXPECT_TRUE(SerializeDelimitedToOstream(message, &full_stream)); + + std::string full_output = full_stream.str(); + ASSERT_GT(full_output.size(), size_t{2}); + ASSERT_EQ(full_output[0], 4); + + partial_stream << full_output[0] << full_output[1] << full_output[2]; + } + + { + bool clean_eof; + io::IstreamInputStream zstream(&partial_stream); + + protobuf_unittest::ForeignMessage message; + clean_eof = true; + EXPECT_FALSE(ParseDelimitedFromZeroCopyStream(&message, + &zstream, &clean_eof)); + EXPECT_FALSE(clean_eof); + } +} + } // namespace util } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/util/field_comparator.h b/src/google/protobuf/util/field_comparator.h index 7b5ce52b8210..9058bbef15a7 100644 --- a/src/google/protobuf/util/field_comparator.h +++ b/src/google/protobuf/util/field_comparator.h @@ -170,6 +170,7 @@ class PROTOBUF_EXPORT DefaultFieldComparator : public FieldComparator { // Defines the map to store the tolerances for floating point comparison. typedef std::map ToleranceMap; + friend class MessageDifferencer; // The following methods get executed when CompareFields is called for the // basic types (instead of submessages). They return true on success. One // can use ResultFromBoolean() to convert that boolean to a ComparisonResult diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc index d3f347ed32b6..23800181b446 100644 --- a/src/google/protobuf/util/field_mask_util.cc +++ b/src/google/protobuf/util/field_mask_util.cc @@ -30,6 +30,7 @@ #include +#include #include #include @@ -198,7 +199,7 @@ class FieldMaskTree { // Remove a path from the tree. // If the path is a sub-path of an existing field path in the tree, it means - // we need remove the existing fied path and add all sub-paths except + // we need remove the existing field path and add all sub-paths except // specified path. If the path matches an existing node in the tree, this node // will be moved. void RemovePath(const std::string& path, const Descriptor* descriptor); @@ -331,7 +332,7 @@ void FieldMaskTree::AddPath(const std::string& path) { for (int i = 0; i < parts.size(); ++i) { if (!new_branch && node != &root_ && node->children.empty()) { // Path matches an existing leaf node. This means the path is already - // coverred by this tree (for example, adding "foo.bar.baz" to a tree + // covered by this tree (for example, adding "foo.bar.baz" to a tree // which already contains "foo.bar"). return; } @@ -706,7 +707,7 @@ bool FieldMaskUtil::TrimMessage(const FieldMask& mask, Message* message, // fields. FieldMaskTree tree; tree.MergeFromFieldMask(mask); - // If keep_required_fields is true, implicitely add required fields of + // If keep_required_fields is true, implicitly add required fields of // a message present in the tree to prevent from trimming. if (options.keep_required_fields()) { tree.AddRequiredFieldPath(GOOGLE_CHECK_NOTNULL(message->GetDescriptor())); diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h index 75ea5206426a..3ca93597c94f 100644 --- a/src/google/protobuf/util/field_mask_util.h +++ b/src/google/protobuf/util/field_mask_util.h @@ -55,6 +55,21 @@ class PROTOBUF_EXPORT FieldMaskUtil { static std::string ToString(const FieldMask& mask); static void FromString(StringPiece str, FieldMask* out); + // Populates the FieldMask with the paths corresponding to the fields with the + // given numbers, after checking that all field numbers are valid. + template + static void FromFieldNumbers(const std::vector& field_numbers, + FieldMask* out) { + for (const auto field_number : field_numbers) { + const FieldDescriptor* field_desc = + T::descriptor()->FindFieldByNumber(field_number); + GOOGLE_CHECK(field_desc != nullptr) + << "Invalid field number for " << T::descriptor()->full_name() << ": " + << field_number; + AddPathToFieldMask(field_desc->lowercase_name(), out); + } + } + // Converts FieldMask to/from string, formatted according to proto3 JSON // spec for FieldMask (e.g., "fooBar,baz.quz"). If the field name is not // style conforming (i.e., not snake_case when converted to string, or not @@ -90,8 +105,8 @@ class PROTOBUF_EXPORT FieldMaskUtil { // This method check-fails if the path is not a valid path for type T. template static void AddPathToFieldMask(StringPiece path, FieldMask* mask) { - GOOGLE_CHECK(IsValidPath(path)); - mask->add_paths(path); + GOOGLE_CHECK(IsValidPath(path)) << path; + mask->add_paths(std::string(path)); } // Creates a FieldMask with all fields of type T. This FieldMask only @@ -180,8 +195,8 @@ class PROTOBUF_EXPORT FieldMaskUtil { static bool SnakeCaseToCamelCase(StringPiece input, std::string* output); // Converts a field name from camelCase to snake_case: - // 1. Every uppercase letter is converted to lowercase with a additional - // preceding "-". + // 1. Every uppercase letter is converted to lowercase with an additional + // preceding "_". // The conversion will fail if: // 1. The field name contains "_"s. // If the conversion succeeds, it's guaranteed that the resulted diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc index 22fe329a5653..f639b3267864 100644 --- a/src/google/protobuf/util/field_mask_util_test.cc +++ b/src/google/protobuf/util/field_mask_util_test.cc @@ -31,13 +31,14 @@ #include #include +#include -#include -#include #include #include #include #include +#include +#include namespace google { namespace protobuf { @@ -45,7 +46,7 @@ namespace util { class SnakeCaseCamelCaseTest : public ::testing::Test { protected: - string SnakeCaseToCamelCase(const std::string& input) { + std::string SnakeCaseToCamelCase(const std::string& input) { std::string output; if (FieldMaskUtil::SnakeCaseToCamelCase(input, &output)) { return output; @@ -54,7 +55,7 @@ class SnakeCaseCamelCaseTest : public ::testing::Test { } } - string CamelCaseToSnakeCase(const std::string& input) { + std::string CamelCaseToSnakeCase(const std::string& input) { std::string output; if (FieldMaskUtil::CamelCaseToSnakeCase(input, &output)) { return output; @@ -161,6 +162,20 @@ TEST(FieldMaskUtilTest, JsonStringFormat) { EXPECT_EQ("baz_quz", mask.paths(1)); } +TEST(FieldMaskUtilTest, FromFieldNumbers) { + FieldMask mask; + std::vector field_numbers = { + TestAllTypes::kOptionalInt64FieldNumber, + TestAllTypes::kOptionalBoolFieldNumber, + TestAllTypes::kRepeatedStringFieldNumber, + }; + FieldMaskUtil::FromFieldNumbers(field_numbers, &mask); + ASSERT_EQ(3, mask.paths_size()); + EXPECT_EQ("optional_int64", mask.paths(0)); + EXPECT_EQ("optional_bool", mask.paths(1)); + EXPECT_EQ("repeated_string", mask.paths(2)); +} + TEST(FieldMaskUtilTest, GetFieldDescriptors) { std::vector field_descriptors; EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors( diff --git a/src/google/protobuf/util/internal/constants.h b/src/google/protobuf/util/internal/constants.h index 6acf970e96bc..adaf0300fe76 100644 --- a/src/google/protobuf/util/internal/constants.h +++ b/src/google/protobuf/util/internal/constants.h @@ -49,7 +49,7 @@ const char kRfc3339TimeFormat[] = "%E4Y-%m-%dT%H:%M:%S"; // timestamps like "1-01-0001T23:59:59Z" instead of "0001-01-0001T23:59:59Z". const char kRfc3339TimeFormatNoPadding[] = "%Y-%m-%dT%H:%M:%S"; -// Minimun seconds allowed in a google.protobuf.Timestamp value. +// Minimum seconds allowed in a google.protobuf.Timestamp value. const int64 kTimestampMinSeconds = -62135596800LL; // Maximum seconds allowed in a google.protobuf.Timestamp value. diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc index 041ff7b74dce..4246956f5599 100644 --- a/src/google/protobuf/util/internal/datapiece.cc +++ b/src/google/protobuf/util/internal/datapiece.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,6 @@ namespace util { namespace converter { using util::Status; -using util::StatusOr; using util::error::Code; namespace { @@ -56,7 +56,7 @@ inline Status InvalidArgument(StringPiece value_str) { } template -StatusOr ValidateNumberConversion(To after, From before) { +util::StatusOr ValidateNumberConversion(To after, From before) { if (after == before && MathUtil::Sign(before) == MathUtil::Sign(after)) { return after; @@ -73,7 +73,7 @@ StatusOr ValidateNumberConversion(To after, From before) { // int32, int64, uint32, uint64, double and float // except conversion between double and float. template -StatusOr NumberConvertAndCheck(From before) { +util::StatusOr NumberConvertAndCheck(From before) { if (std::is_same::value) return before; To after = static_cast(before); @@ -83,7 +83,7 @@ StatusOr NumberConvertAndCheck(From before) { // For conversion to integer types (int32, int64, uint32, uint64) from floating // point types (double, float) only. template -StatusOr FloatingPointToIntConvertAndCheck(From before) { +util::StatusOr FloatingPointToIntConvertAndCheck(From before) { if (std::is_same::value) return before; To after = static_cast(before); @@ -91,13 +91,13 @@ StatusOr FloatingPointToIntConvertAndCheck(From before) { } // For conversion between double and float only. -StatusOr FloatToDouble(float before) { +util::StatusOr FloatToDouble(float before) { // Casting float to double should just work as double has more precision // than float. return static_cast(before); } -StatusOr DoubleToFloat(double before) { +util::StatusOr DoubleToFloat(double before) { if (std::isnan(before)) { return std::numeric_limits::quiet_NaN(); } else if (!std::isfinite(before)) { @@ -114,7 +114,7 @@ StatusOr DoubleToFloat(double before) { } // namespace -StatusOr DataPiece::ToInt32() const { +util::StatusOr DataPiece::ToInt32() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strto32); if (type_ == TYPE_DOUBLE) @@ -126,7 +126,7 @@ StatusOr DataPiece::ToInt32() const { return GenericConvert(); } -StatusOr DataPiece::ToUint32() const { +util::StatusOr DataPiece::ToUint32() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strtou32); @@ -139,7 +139,7 @@ StatusOr DataPiece::ToUint32() const { return GenericConvert(); } -StatusOr DataPiece::ToInt64() const { +util::StatusOr DataPiece::ToInt64() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strto64); if (type_ == TYPE_DOUBLE) @@ -151,7 +151,7 @@ StatusOr DataPiece::ToInt64() const { return GenericConvert(); } -StatusOr DataPiece::ToUint64() const { +util::StatusOr DataPiece::ToUint64() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strtou64); @@ -164,7 +164,7 @@ StatusOr DataPiece::ToUint64() const { return GenericConvert(); } -StatusOr DataPiece::ToDouble() const { +util::StatusOr DataPiece::ToDouble() const { if (type_ == TYPE_FLOAT) { return FloatToDouble(float_); } @@ -172,8 +172,8 @@ StatusOr DataPiece::ToDouble() const { if (str_ == "Infinity") return std::numeric_limits::infinity(); if (str_ == "-Infinity") return -std::numeric_limits::infinity(); if (str_ == "NaN") return std::numeric_limits::quiet_NaN(); - StatusOr value = StringToNumber(safe_strtod); - if (value.ok() && !std::isfinite(value.ValueOrDie())) { + util::StatusOr value = StringToNumber(safe_strtod); + if (value.ok() && !std::isfinite(value.value())) { // safe_strtod converts out-of-range values to +inf/-inf, but we want // to report them as errors. return InvalidArgument(StrCat("\"", str_, "\"")); @@ -184,7 +184,7 @@ StatusOr DataPiece::ToDouble() const { return GenericConvert(); } -StatusOr DataPiece::ToFloat() const { +util::StatusOr DataPiece::ToFloat() const { if (type_ == TYPE_DOUBLE) { return DoubleToFloat(double_); } @@ -199,7 +199,7 @@ StatusOr DataPiece::ToFloat() const { return GenericConvert(); } -StatusOr DataPiece::ToBool() const { +util::StatusOr DataPiece::ToBool() const { switch (type_) { case TYPE_BOOL: return bool_; @@ -211,7 +211,7 @@ StatusOr DataPiece::ToBool() const { } } -StatusOr DataPiece::ToString() const { +util::StatusOr DataPiece::ToString() const { switch (type_) { case TYPE_STRING: return std::string(str_); @@ -257,7 +257,7 @@ std::string DataPiece::ValueAsStringOrDefault( } } -StatusOr DataPiece::ToBytes() const { +util::StatusOr DataPiece::ToBytes() const { if (type_ == TYPE_BYTES) return str_.ToString(); if (type_ == TYPE_STRING) { std::string decoded; @@ -271,11 +271,11 @@ StatusOr DataPiece::ToBytes() const { } } -StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, - bool use_lower_camel_for_enums, - bool case_insensitive_enum_parsing, - bool ignore_unknown_enum_values, - bool* is_unknown_enum_value) const { +util::StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_enum_values, + bool* is_unknown_enum_value) const { if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE; if (type_ == TYPE_STRING) { @@ -286,10 +286,10 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, if (value != nullptr) return value->number(); // Check if int version of enum is sent as string. - StatusOr int_value = ToInt32(); + util::StatusOr int_value = ToInt32(); if (int_value.ok()) { if (const google::protobuf::EnumValue* enum_value = - FindEnumValueByNumberOrNull(enum_type, int_value.ValueOrDie())) { + FindEnumValueByNumberOrNull(enum_type, int_value.value())) { return enum_value->number(); } } @@ -317,7 +317,9 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, // If ignore_unknown_enum_values is true an unknown enum value is ignored. if (ignore_unknown_enum_values) { *is_unknown_enum_value = true; - return enum_type->enumvalue(0).number(); + if (enum_type->enumvalue_size() > 0) { + return enum_type->enumvalue(0).number(); + } } } else { // We don't need to check whether the value is actually declared in the @@ -329,7 +331,7 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, } template -StatusOr DataPiece::GenericConvert() const { +util::StatusOr DataPiece::GenericConvert() const { switch (type_) { case TYPE_INT32: return NumberConvertAndCheck(i32_); @@ -351,8 +353,8 @@ StatusOr DataPiece::GenericConvert() const { } template -StatusOr DataPiece::StringToNumber(bool (*func)(StringPiece, - To*)) const { +util::StatusOr DataPiece::StringToNumber(bool (*func)(StringPiece, + To*)) const { if (str_.size() > 0 && (str_[0] == ' ' || str_[str_.size() - 1] == ' ')) { return InvalidArgument(StrCat("\"", str_, "\"")); } @@ -382,9 +384,8 @@ bool DataPiece::DecodeBase64(StringPiece src, std::string* dest) const { if (Base64Unescape(src, dest)) { if (use_strict_base64_decoding_) { std::string encoded; - Base64Escape( - reinterpret_cast(dest->data()), dest->length(), - &encoded, false); + Base64Escape(reinterpret_cast(dest->data()), + dest->length(), &encoded, false); StringPiece src_no_padding = StringPiece(src).substr( 0, HasSuffixString(src, "=") ? src.find_last_not_of('=') + 1 : src.length()); diff --git a/src/google/protobuf/util/internal/datapiece.h b/src/google/protobuf/util/internal/datapiece.h index 1b0ccfa24481..38ced1727796 100644 --- a/src/google/protobuf/util/internal/datapiece.h +++ b/src/google/protobuf/util/internal/datapiece.h @@ -167,10 +167,10 @@ class PROTOBUF_EXPORT DataPiece { // Same as the ToEnum() method above but with additional flag to ignore // unknown enum values. util::StatusOr ToEnum(const google::protobuf::Enum* enum_type, - bool use_lower_camel_for_enums, - bool case_insensitive_enum_parsing, - bool ignore_unknown_enum_values, - bool* is_unknown_enum_value) const; + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_enum_values, + bool* is_unknown_enum_value) const; // For numeric conversion between // int32, int64, uint32, uint64, double, float and bool @@ -180,8 +180,7 @@ class PROTOBUF_EXPORT DataPiece { // For conversion from string to // int32, int64, uint32, uint64, double, float and bool template - util::StatusOr StringToNumber(bool (*func)(StringPiece, - To*)) const; + util::StatusOr StringToNumber(bool (*func)(StringPiece, To*)) const; // Decodes a base64 string. Returns true on success. bool DecodeBase64(StringPiece src, std::string* dest) const; diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index 828c86887e89..60a44dbe525e 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -40,7 +40,6 @@ namespace google { namespace protobuf { namespace util { using util::Status; -using util::StatusOr; namespace converter { namespace { @@ -49,10 +48,11 @@ namespace { // If value is empty or if conversion fails, the default_value is returned. template T ConvertTo(StringPiece value, - StatusOr (DataPiece::*converter_fn)() const, T default_value) { + util::StatusOr (DataPiece::*converter_fn)() const, + T default_value) { if (value.empty()) return default_value; - StatusOr result = (DataPiece(value, true).*converter_fn)(); - return result.ok() ? result.ValueOrDie() : default_value; + util::StatusOr result = (DataPiece(value, true).*converter_fn)(); + return result.ok() ? result.value() : default_value; } } // namespace @@ -290,7 +290,7 @@ const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType( if (!sub_type.ok()) { GOOGLE_LOG(WARNING) << "Cannot resolve type '" << sub_field.type_url() << "'."; } else { - return sub_type.ValueOrDie(); + return sub_type.value(); } break; } @@ -354,7 +354,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren( // "field" is of an unknown type. GOOGLE_LOG(WARNING) << "Cannot resolve type '" << field.type_url() << "'."; } else { - const google::protobuf::Type* found_type = found_result.ValueOrDie(); + const google::protobuf::Type* found_type = found_result.value(); is_map = IsMap(field, *found_type); if (!is_map) { @@ -587,7 +587,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, name == "@type") { util::StatusOr data_string = data.ToString(); if (data_string.ok()) { - const std::string& string_value = data_string.ValueOrDie(); + const std::string& string_value = data_string.value(); // If the type of current_ is "Any" and its "@type" field is being set // here, sets the type of current_ to be the type specified by the // "@type". @@ -596,7 +596,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, if (!found_type.ok()) { GOOGLE_LOG(WARNING) << "Failed to resolve type '" << string_value << "'."; } else { - current_->set_type(found_type.ValueOrDie()); + current_->set_type(found_type.value()); } current_->set_is_any(true); // If the "@type" field is placed after other fields, we should populate diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index 30c03043fffa..08793fc9bd75 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -201,7 +201,7 @@ class PROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // Returns the Value Type of a map given the Type of the map entry and a // TypeInfo instance. const google::protobuf::Type* GetMapValueType( - const google::protobuf::Type& entry_type, const TypeInfo* typeinfo); + const google::protobuf::Type& found_type, const TypeInfo* typeinfo); // Calls WriteTo() on every child in children_. void WriteChildren(ObjectWriter* ow); diff --git a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc index 032d112fed07..7af357995448 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc @@ -29,6 +29,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include + #include #include #include diff --git a/src/google/protobuf/util/internal/expecting_objectwriter.h b/src/google/protobuf/util/internal/expecting_objectwriter.h index 65961adee559..2cb7f69740dc 100644 --- a/src/google/protobuf/util/internal/expecting_objectwriter.h +++ b/src/google/protobuf/util/internal/expecting_objectwriter.h @@ -60,6 +60,7 @@ namespace protobuf { namespace util { namespace converter { +using testing::Eq; using testing::IsEmpty; using testing::NanSensitiveDoubleEq; using testing::NanSensitiveFloatEq; @@ -71,21 +72,27 @@ class MockObjectWriter : public ObjectWriter { public: MockObjectWriter() {} - MOCK_METHOD1(StartObject, ObjectWriter*(StringPiece)); - MOCK_METHOD0(EndObject, ObjectWriter*()); - MOCK_METHOD1(StartList, ObjectWriter*(StringPiece)); - MOCK_METHOD0(EndList, ObjectWriter*()); - MOCK_METHOD2(RenderBool, ObjectWriter*(StringPiece, bool)); - MOCK_METHOD2(RenderInt32, ObjectWriter*(StringPiece, int32)); - MOCK_METHOD2(RenderUint32, ObjectWriter*(StringPiece, uint32)); - MOCK_METHOD2(RenderInt64, ObjectWriter*(StringPiece, int64)); - MOCK_METHOD2(RenderUint64, ObjectWriter*(StringPiece, uint64)); - MOCK_METHOD2(RenderDouble, ObjectWriter*(StringPiece, double)); - MOCK_METHOD2(RenderFloat, ObjectWriter*(StringPiece, float)); - MOCK_METHOD2(RenderString, - ObjectWriter*(StringPiece, StringPiece)); - MOCK_METHOD2(RenderBytes, ObjectWriter*(StringPiece, StringPiece)); - MOCK_METHOD1(RenderNull, ObjectWriter*(StringPiece)); + MOCK_METHOD(ObjectWriter*, StartObject, (StringPiece), (override)); + MOCK_METHOD(ObjectWriter*, EndObject, (), (override)); + MOCK_METHOD(ObjectWriter*, StartList, (StringPiece), (override)); + MOCK_METHOD(ObjectWriter*, EndList, (), (override)); + MOCK_METHOD(ObjectWriter*, RenderBool, (StringPiece, bool), (override)); + MOCK_METHOD(ObjectWriter*, RenderInt32, (StringPiece, int32), + (override)); + MOCK_METHOD(ObjectWriter*, RenderUint32, (StringPiece, uint32), + (override)); + MOCK_METHOD(ObjectWriter*, RenderInt64, (StringPiece, int64), + (override)); + MOCK_METHOD(ObjectWriter*, RenderUint64, (StringPiece, uint64), + (override)); + MOCK_METHOD(ObjectWriter*, RenderDouble, (StringPiece, double), + (override)); + MOCK_METHOD(ObjectWriter*, RenderFloat, (StringPiece, float), + (override)); + MOCK_METHOD(ObjectWriter*, RenderString, + (StringPiece, StringPiece), (override)); + MOCK_METHOD(ObjectWriter*, RenderBytes, (StringPiece, StringPiece)); + MOCK_METHOD(ObjectWriter*, RenderNull, (StringPiece), (override)); }; class ExpectingObjectWriter : public ObjectWriter { @@ -94,7 +101,7 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* StartObject(StringPiece name) { (name.empty() ? EXPECT_CALL(*mock_, StartObject(IsEmpty())) - : EXPECT_CALL(*mock_, StartObject(StrEq(std::string(name))))) + : EXPECT_CALL(*mock_, StartObject(Eq(std::string(name))))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); return this; @@ -109,7 +116,7 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* StartList(StringPiece name) { (name.empty() ? EXPECT_CALL(*mock_, StartList(IsEmpty())) - : EXPECT_CALL(*mock_, StartList(StrEq(std::string(name))))) + : EXPECT_CALL(*mock_, StartList(Eq(std::string(name))))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); return this; @@ -125,8 +132,8 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* RenderBool(StringPiece name, bool value) { (name.empty() ? EXPECT_CALL(*mock_, RenderBool(IsEmpty(), TypedEq(value))) - : EXPECT_CALL(*mock_, RenderBool(StrEq(std::string(name)), - TypedEq(value)))) + : EXPECT_CALL(*mock_, + RenderBool(Eq(std::string(name)), TypedEq(value)))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); return this; @@ -135,7 +142,7 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* RenderInt32(StringPiece name, int32 value) { (name.empty() ? EXPECT_CALL(*mock_, RenderInt32(IsEmpty(), TypedEq(value))) - : EXPECT_CALL(*mock_, RenderInt32(StrEq(std::string(name)), + : EXPECT_CALL(*mock_, RenderInt32(Eq(std::string(name)), TypedEq(value)))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); @@ -145,7 +152,7 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* RenderUint32(StringPiece name, uint32 value) { (name.empty() ? EXPECT_CALL(*mock_, RenderUint32(IsEmpty(), TypedEq(value))) - : EXPECT_CALL(*mock_, RenderUint32(StrEq(std::string(name)), + : EXPECT_CALL(*mock_, RenderUint32(Eq(std::string(name)), TypedEq(value)))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); @@ -155,7 +162,7 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* RenderInt64(StringPiece name, int64 value) { (name.empty() ? EXPECT_CALL(*mock_, RenderInt64(IsEmpty(), TypedEq(value))) - : EXPECT_CALL(*mock_, RenderInt64(StrEq(std::string(name)), + : EXPECT_CALL(*mock_, RenderInt64(Eq(std::string(name)), TypedEq(value)))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); @@ -165,7 +172,7 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* RenderUint64(StringPiece name, uint64 value) { (name.empty() ? EXPECT_CALL(*mock_, RenderUint64(IsEmpty(), TypedEq(value))) - : EXPECT_CALL(*mock_, RenderUint64(StrEq(std::string(name)), + : EXPECT_CALL(*mock_, RenderUint64(Eq(std::string(name)), TypedEq(value)))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); @@ -176,7 +183,7 @@ class ExpectingObjectWriter : public ObjectWriter { (name.empty() ? EXPECT_CALL(*mock_, RenderDouble(IsEmpty(), NanSensitiveDoubleEq(value))) - : EXPECT_CALL(*mock_, RenderDouble(StrEq(std::string(name)), + : EXPECT_CALL(*mock_, RenderDouble(Eq(std::string(name)), NanSensitiveDoubleEq(value)))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); @@ -187,7 +194,7 @@ class ExpectingObjectWriter : public ObjectWriter { (name.empty() ? EXPECT_CALL(*mock_, RenderFloat(IsEmpty(), NanSensitiveFloatEq(value))) - : EXPECT_CALL(*mock_, RenderFloat(StrEq(std::string(name)), + : EXPECT_CALL(*mock_, RenderFloat(Eq(std::string(name)), NanSensitiveFloatEq(value)))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); @@ -199,7 +206,7 @@ class ExpectingObjectWriter : public ObjectWriter { (name.empty() ? EXPECT_CALL(*mock_, RenderString(IsEmpty(), TypedEq( std::string(value)))) - : EXPECT_CALL(*mock_, RenderString(StrEq(std::string(name)), + : EXPECT_CALL(*mock_, RenderString(Eq(std::string(name)), TypedEq( std::string(value))))) .WillOnce(Return(mock_)) @@ -211,7 +218,7 @@ class ExpectingObjectWriter : public ObjectWriter { ? EXPECT_CALL(*mock_, RenderBytes(IsEmpty(), TypedEq( value.ToString()))) : EXPECT_CALL(*mock_, - RenderBytes(StrEq(name.ToString()), + RenderBytes(Eq(std::string(name)), TypedEq(value.ToString())))) .WillOnce(Return(mock_)) .RetiresOnSaturation(); @@ -220,7 +227,7 @@ class ExpectingObjectWriter : public ObjectWriter { virtual ObjectWriter* RenderNull(StringPiece name) { (name.empty() ? EXPECT_CALL(*mock_, RenderNull(IsEmpty())) - : EXPECT_CALL(*mock_, RenderNull(StrEq(std::string(name)))) + : EXPECT_CALL(*mock_, RenderNull(Eq(std::string(name)))) .WillOnce(Return(mock_)) .RetiresOnSaturation()); return this; diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc index 40e193e59317..0beff996a688 100644 --- a/src/google/protobuf/util/internal/field_mask_utility.cc +++ b/src/google/protobuf/util/internal/field_mask_utility.cc @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -107,7 +108,7 @@ std::string ConvertFieldMaskPath(const StringPiece path, } util::Status DecodeCompactFieldMaskPaths(StringPiece paths, - PathSinkCallback path_sink) { + PathSinkCallback path_sink) { std::stack prefix; int length = paths.length(); int previous_position = 0; diff --git a/src/google/protobuf/util/internal/field_mask_utility.h b/src/google/protobuf/util/internal/field_mask_utility.h index 7335af506bfe..bc413212207e 100644 --- a/src/google/protobuf/util/internal/field_mask_utility.h +++ b/src/google/protobuf/util/internal/field_mask_utility.h @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -63,7 +64,7 @@ std::string ConvertFieldMaskPath(const StringPiece path, // Note that we also support Apiary style FieldMask form. The above example in // the Apiary style will look like "a.b,a.c(d,e)". util::Status DecodeCompactFieldMaskPaths(StringPiece paths, - PathSinkCallback path_sink); + PathSinkCallback path_sink); } // namespace converter } // namespace util diff --git a/src/google/protobuf/util/internal/json_escaping.h b/src/google/protobuf/util/internal/json_escaping.h index 4ba765c699a8..d05c335976f5 100644 --- a/src/google/protobuf/util/internal/json_escaping.h +++ b/src/google/protobuf/util/internal/json_escaping.h @@ -44,34 +44,34 @@ class JsonEscaping { // The minimum value of a unicode high-surrogate code unit in the utf-16 // encoding. A high-surrogate is also known as a leading-surrogate. // See http://www.unicode.org/glossary/#high_surrogate_code_unit - static const uint16 kMinHighSurrogate = 0xd800; + static constexpr uint16 kMinHighSurrogate = 0xd800; // The maximum value of a unicide high-surrogate code unit in the utf-16 // encoding. A high-surrogate is also known as a leading-surrogate. // See http://www.unicode.org/glossary/#high_surrogate_code_unit - static const uint16 kMaxHighSurrogate = 0xdbff; + static constexpr uint16 kMaxHighSurrogate = 0xdbff; // The minimum value of a unicode low-surrogate code unit in the utf-16 // encoding. A low-surrogate is also known as a trailing-surrogate. // See http://www.unicode.org/glossary/#low_surrogate_code_unit - static const uint16 kMinLowSurrogate = 0xdc00; + static constexpr uint16 kMinLowSurrogate = 0xdc00; // The maximum value of a unicode low-surrogate code unit in the utf-16 // encoding. A low-surrogate is also known as a trailing surrogate. // See http://www.unicode.org/glossary/#low_surrogate_code_unit - static const uint16 kMaxLowSurrogate = 0xdfff; + static constexpr uint16 kMaxLowSurrogate = 0xdfff; // The minimum value of a unicode supplementary code point. // See http://www.unicode.org/glossary/#supplementary_code_point - static const uint32 kMinSupplementaryCodePoint = 0x010000; + static constexpr uint32 kMinSupplementaryCodePoint = 0x010000; // The minimum value of a unicode code point. // See http://www.unicode.org/glossary/#code_point - static const uint32 kMinCodePoint = 0x000000; + static constexpr uint32 kMinCodePoint = 0x000000; // The maximum value of a unicode code point. // See http://www.unicode.org/glossary/#code_point - static const uint32 kMaxCodePoint = 0x10ffff; + static constexpr uint32 kMaxCodePoint = 0x10ffff; JsonEscaping() {} virtual ~JsonEscaping() {} diff --git a/src/google/protobuf/util/internal/json_objectwriter.cc b/src/google/protobuf/util/internal/json_objectwriter.cc index a98e7bad5cb2..32ce2dcd1c22 100644 --- a/src/google/protobuf/util/internal/json_objectwriter.cc +++ b/src/google/protobuf/util/internal/json_objectwriter.cc @@ -148,7 +148,7 @@ JsonObjectWriter* JsonObjectWriter::RenderBytes(StringPiece name, std::string base64; if (use_websafe_base64_for_bytes_) - WebSafeBase64EscapeWithPadding(value.ToString(), &base64); + WebSafeBase64EscapeWithPadding(std::string(value), &base64); else Base64Escape(value, &base64); diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h index 9e00712389fe..ab372abd8702 100644 --- a/src/google/protobuf/util/internal/json_objectwriter.h +++ b/src/google/protobuf/util/internal/json_objectwriter.h @@ -152,7 +152,7 @@ class PROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter { return false; } - // Whether we are currently renderring inside a JSON object (i.e., between + // Whether we are currently rendering inside a JSON object (i.e., between // StartObject() and EndObject()). bool is_json_object() const { return is_json_object_; } diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc index a221b98c3133..0a321386a15b 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.cc +++ b/src/google/protobuf/util/internal/json_stream_parser.cc @@ -82,8 +82,28 @@ inline bool IsAlphanumeric(char c) { // Indicates a character may not be part of an unquoted key. inline bool IsKeySeparator(char c) { - return (ascii_isspace(c) || c == '"' || c == '\'' || c == '{' || c == '}' || - c == '[' || c == ']' || c == ':' || c == ','); + return (ascii_isspace(c) || c == '"' || c == '\'' || c == '{' || + c == '}' || c == '[' || c == ']' || c == ':' || c == ','); +} + +inline void ReplaceInvalidCodePoints(StringPiece str, + const std::string& replacement, + std::string* dst) { + while (!str.empty()) { + int n_valid_bytes = internal::UTF8SpnStructurallyValid(str); + StringPiece valid_part = str.substr(0, n_valid_bytes); + StrAppend(dst, valid_part); + + if (n_valid_bytes == str.size()) { + break; + } + + // Append replacement value. + StrAppend(dst, replacement); + + // Move past valid bytes + one invalid byte. + str.remove_prefix(n_valid_bytes + 1); + } } static bool ConsumeKey(StringPiece* input, StringPiece* key) { @@ -132,6 +152,7 @@ JsonStreamParser::JsonStreamParser(ObjectWriter* ow) string_open_(0), chunk_storage_(), coerce_to_utf8_(false), + utf8_replacement_character_(" "), allow_empty_null_(false), allow_permissive_key_naming_(false), loose_float_number_conversion_(false), @@ -180,15 +201,20 @@ util::Status JsonStreamParser::FinishParse() { return util::Status(); } - // Storage for UTF8-coerced string. - std::unique_ptr utf8; - if (coerce_to_utf8_) { - utf8.reset(new char[leftover_.size()]); - char* coerced = internal::UTF8CoerceToStructurallyValid(leftover_, utf8.get(), ' '); - p_ = json_ = StringPiece(coerced, leftover_.size()); + // Lifetime needs to last until RunParser returns, so keep this variable + // outside of the coerce_to_utf8 block. + std::unique_ptr scratch; + + bool is_valid_utf8 = internal::IsStructurallyValidUTF8(leftover_); + if (coerce_to_utf8_ && !is_valid_utf8) { + scratch.reset(new std::string); + scratch->reserve(leftover_.size() * utf8_replacement_character_.size()); + ReplaceInvalidCodePoints(leftover_, utf8_replacement_character_, + scratch.get()); + p_ = json_ = *scratch; } else { p_ = json_ = leftover_; - if (!internal::IsStructurallyValidUTF8(leftover_)) { + if (!is_valid_utf8) { return ReportFailure("Encountered non UTF-8 code points."); } } @@ -827,7 +853,7 @@ util::Status JsonStreamParser::ReportUnknown(StringPiece message) { util::Status JsonStreamParser::IncrementRecursionDepth( StringPiece key) const { if (++recursion_depth_ > max_recursion_depth_) { - return Status( + return util::Status( util::error::INVALID_ARGUMENT, StrCat("Message too deep. Max recursion depth reached for key '", key, "'")); diff --git a/src/google/protobuf/util/internal/json_stream_parser.h b/src/google/protobuf/util/internal/json_stream_parser.h index 0292bf26c0f9..2eb3532ca2a4 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.h +++ b/src/google/protobuf/util/internal/json_stream_parser.h @@ -130,7 +130,7 @@ class PROTOBUF_EXPORT JsonStreamParser { }; // Parses a single chunk of JSON, returning an error if the JSON was invalid. - util::Status ParseChunk(StringPiece json); + util::Status ParseChunk(StringPiece chunk); // Runs the parser based on stack_ and p_, until the stack is empty or p_ runs // out of data. If we unexpectedly run out of p_ we push the latest back onto @@ -269,6 +269,9 @@ class PROTOBUF_EXPORT JsonStreamParser { // Whether to allow non UTF-8 encoded input and replace invalid code points. bool coerce_to_utf8_; + // Replacement character for invalid UTF-8 code points. + std::string utf8_replacement_character_; + // Whether allows empty string represented null array value or object entry // value. bool allow_empty_null_; diff --git a/src/google/protobuf/util/internal/json_stream_parser_test.cc b/src/google/protobuf/util/internal/json_stream_parser_test.cc index 6bb22a6c0efe..aa4751d80b14 100644 --- a/src/google/protobuf/util/internal/json_stream_parser_test.cc +++ b/src/google/protobuf/util/internal/json_stream_parser_test.cc @@ -32,10 +32,10 @@ #include #include -#include #include #include #include +#include #include @@ -146,7 +146,7 @@ class JsonStreamParserTest : public ::testing::Test { #ifndef _MSC_VER // TODO(xiaofeng): We have to disable InSequence check for MSVC because it - // causes stack overflow due to its use of a linked list that is desctructed + // causes stack overflow due to its use of a linked list that is destructed // recursively. ::testing::InSequence in_sequence_; #endif // !_MSC_VER @@ -235,7 +235,7 @@ TEST_F(JsonStreamParserTest, SimpleInt) { TEST_F(JsonStreamParserTest, SimpleNegativeInt) { StringPiece str = "-79497823553162765"; for (int i = 0; i <= str.length(); ++i) { - ow_.RenderInt64("", -79497823553162765LL); + ow_.RenderInt64("", int64{-79497823553162765}); DoTest(str, i); } } @@ -243,7 +243,7 @@ TEST_F(JsonStreamParserTest, SimpleNegativeInt) { TEST_F(JsonStreamParserTest, SimpleUnsignedInt) { StringPiece str = "11779497823553162765"; for (int i = 0; i <= str.length(); ++i) { - ow_.RenderUint64("", 11779497823553162765ULL); + ow_.RenderUint64("", uint64{11779497823553162765u}); DoTest(str, i); } } @@ -378,7 +378,7 @@ TEST_F(JsonStreamParserTest, ArrayComplexValues) { ->RenderInt64("", -127) ->RenderDouble("", 45.3) ->RenderDouble("", -1056.4) - ->RenderUint64("", 11779497823553162765ULL) + ->RenderUint64("", uint64{11779497823553162765u}) ->EndList() ->StartObject("") ->RenderBool("key", true) @@ -406,7 +406,7 @@ TEST_F(JsonStreamParserTest, ObjectValues) { ->RenderInt64("ni", -127) ->RenderDouble("pd", 45.3) ->RenderDouble("nd", -1056.4) - ->RenderUint64("pl", 11779497823553162765ULL) + ->RenderUint64("pl", uint64{11779497823553162765u}) ->StartList("l") ->StartList("") ->EndList() diff --git a/src/google/protobuf/util/internal/mock_error_listener.h b/src/google/protobuf/util/internal/mock_error_listener.h index 53e58768bfbf..4f5b0a22d9bc 100644 --- a/src/google/protobuf/util/internal/mock_error_listener.h +++ b/src/google/protobuf/util/internal/mock_error_listener.h @@ -46,14 +46,18 @@ class MockErrorListener : public ErrorListener { MockErrorListener() {} virtual ~MockErrorListener() {} - MOCK_METHOD3(InvalidName, - void(const LocationTrackerInterface& loc, - StringPiece unknown_name, StringPiece message)); - MOCK_METHOD3(InvalidValue, - void(const LocationTrackerInterface& loc, - StringPiece type_name, StringPiece value)); - MOCK_METHOD2(MissingField, void(const LocationTrackerInterface& loc, - StringPiece missing_name)); + MOCK_METHOD(void, InvalidName, + (const LocationTrackerInterface& loc, + StringPiece unknown_name, StringPiece message), + (override)); + MOCK_METHOD(void, InvalidValue, + (const LocationTrackerInterface& loc, StringPiece type_name, + StringPiece value), + (override)); + MOCK_METHOD(void, MissingField, + (const LocationTrackerInterface& loc, + StringPiece missing_name), + (override)); }; } // namespace converter diff --git a/src/google/protobuf/util/internal/object_writer.cc b/src/google/protobuf/util/internal/object_writer.cc index bb1b3e5710b0..b7667b6b163c 100644 --- a/src/google/protobuf/util/internal/object_writer.cc +++ b/src/google/protobuf/util/internal/object_writer.cc @@ -42,35 +42,35 @@ void ObjectWriter::RenderDataPieceTo(const DataPiece& data, StringPiece name, ObjectWriter* ow) { switch (data.type()) { case DataPiece::TYPE_INT32: { - ow->RenderInt32(name, data.ToInt32().ValueOrDie()); + ow->RenderInt32(name, data.ToInt32().value()); break; } case DataPiece::TYPE_INT64: { - ow->RenderInt64(name, data.ToInt64().ValueOrDie()); + ow->RenderInt64(name, data.ToInt64().value()); break; } case DataPiece::TYPE_UINT32: { - ow->RenderUint32(name, data.ToUint32().ValueOrDie()); + ow->RenderUint32(name, data.ToUint32().value()); break; } case DataPiece::TYPE_UINT64: { - ow->RenderUint64(name, data.ToUint64().ValueOrDie()); + ow->RenderUint64(name, data.ToUint64().value()); break; } case DataPiece::TYPE_DOUBLE: { - ow->RenderDouble(name, data.ToDouble().ValueOrDie()); + ow->RenderDouble(name, data.ToDouble().value()); break; } case DataPiece::TYPE_FLOAT: { - ow->RenderFloat(name, data.ToFloat().ValueOrDie()); + ow->RenderFloat(name, data.ToFloat().value()); break; } case DataPiece::TYPE_BOOL: { - ow->RenderBool(name, data.ToBool().ValueOrDie()); + ow->RenderBool(name, data.ToBool().value()); break; } case DataPiece::TYPE_STRING: { - ow->RenderString(name, data.ToString().ValueOrDie()); + ow->RenderString(name, data.ToString().value()); break; } case DataPiece::TYPE_BYTES: { @@ -86,6 +86,7 @@ void ObjectWriter::RenderDataPieceTo(const DataPiece& data, } } + } // namespace converter } // namespace util } // namespace protobuf diff --git a/src/google/protobuf/util/internal/object_writer.h b/src/google/protobuf/util/internal/object_writer.h index 856d77d074fc..29b05c166822 100644 --- a/src/google/protobuf/util/internal/object_writer.h +++ b/src/google/protobuf/util/internal/object_writer.h @@ -42,6 +42,7 @@ namespace protobuf { namespace util { namespace converter { + class DataPiece; // An ObjectWriter is an interface for writing a stream of events @@ -92,7 +93,6 @@ class PROTOBUF_EXPORT ObjectWriter { // Renders a double value. virtual ObjectWriter* RenderDouble(StringPiece name, double value) = 0; - // Renders a float value. virtual ObjectWriter* RenderFloat(StringPiece name, float value) = 0; @@ -111,6 +111,7 @@ class PROTOBUF_EXPORT ObjectWriter { static void RenderDataPieceTo(const DataPiece& data, StringPiece name, ObjectWriter* ow); + // Indicates whether this ObjectWriter has completed writing the root message, // usually this means writing of one complete object. Subclasses must override // this behavior appropriately. diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index 31288b351e4f..24a71425cafe 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -34,13 +34,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include #include @@ -55,7 +55,6 @@ namespace converter { using io::CodedOutputStream; using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; using util::Status; -using util::StatusOr; using util::error::INVALID_ARGUMENT; @@ -70,6 +69,7 @@ ProtoWriter::ProtoWriter(TypeResolver* type_resolver, ignore_unknown_enum_values_(false), use_lower_camel_for_enums_(false), case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), element_(nullptr), size_insert_(), output_(output), @@ -91,6 +91,7 @@ ProtoWriter::ProtoWriter(const TypeInfo* typeinfo, ignore_unknown_enum_values_(false), use_lower_camel_for_enums_(false), case_insensitive_enum_parsing_(true), + use_json_name_in_missing_fields_(false), element_(nullptr), size_insert_(), output_(output), @@ -120,139 +121,139 @@ ProtoWriter::~ProtoWriter() { namespace { // Writes an INT32 field, including tag to the stream. -inline Status WriteInt32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i32 = data.ToInt32(); +inline util::Status WriteInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i32 = data.ToInt32(); if (i32.ok()) { - WireFormatLite::WriteInt32(field_number, i32.ValueOrDie(), stream); + WireFormatLite::WriteInt32(field_number, i32.value(), stream); } return i32.status(); } // writes an SFIXED32 field, including tag, to the stream. -inline Status WriteSFixed32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i32 = data.ToInt32(); +inline util::Status WriteSFixed32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i32 = data.ToInt32(); if (i32.ok()) { - WireFormatLite::WriteSFixed32(field_number, i32.ValueOrDie(), stream); + WireFormatLite::WriteSFixed32(field_number, i32.value(), stream); } return i32.status(); } // Writes an SINT32 field, including tag, to the stream. -inline Status WriteSInt32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i32 = data.ToInt32(); +inline util::Status WriteSInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i32 = data.ToInt32(); if (i32.ok()) { - WireFormatLite::WriteSInt32(field_number, i32.ValueOrDie(), stream); + WireFormatLite::WriteSInt32(field_number, i32.value(), stream); } return i32.status(); } // Writes a FIXED32 field, including tag, to the stream. -inline Status WriteFixed32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u32 = data.ToUint32(); +inline util::Status WriteFixed32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u32 = data.ToUint32(); if (u32.ok()) { - WireFormatLite::WriteFixed32(field_number, u32.ValueOrDie(), stream); + WireFormatLite::WriteFixed32(field_number, u32.value(), stream); } return u32.status(); } // Writes a UINT32 field, including tag, to the stream. -inline Status WriteUInt32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u32 = data.ToUint32(); +inline util::Status WriteUInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u32 = data.ToUint32(); if (u32.ok()) { - WireFormatLite::WriteUInt32(field_number, u32.ValueOrDie(), stream); + WireFormatLite::WriteUInt32(field_number, u32.value(), stream); } return u32.status(); } // Writes an INT64 field, including tag, to the stream. -inline Status WriteInt64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i64 = data.ToInt64(); +inline util::Status WriteInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i64 = data.ToInt64(); if (i64.ok()) { - WireFormatLite::WriteInt64(field_number, i64.ValueOrDie(), stream); + WireFormatLite::WriteInt64(field_number, i64.value(), stream); } return i64.status(); } // Writes an SFIXED64 field, including tag, to the stream. -inline Status WriteSFixed64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i64 = data.ToInt64(); +inline util::Status WriteSFixed64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i64 = data.ToInt64(); if (i64.ok()) { - WireFormatLite::WriteSFixed64(field_number, i64.ValueOrDie(), stream); + WireFormatLite::WriteSFixed64(field_number, i64.value(), stream); } return i64.status(); } // Writes an SINT64 field, including tag, to the stream. -inline Status WriteSInt64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i64 = data.ToInt64(); +inline util::Status WriteSInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i64 = data.ToInt64(); if (i64.ok()) { - WireFormatLite::WriteSInt64(field_number, i64.ValueOrDie(), stream); + WireFormatLite::WriteSInt64(field_number, i64.value(), stream); } return i64.status(); } // Writes a FIXED64 field, including tag, to the stream. -inline Status WriteFixed64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u64 = data.ToUint64(); +inline util::Status WriteFixed64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u64 = data.ToUint64(); if (u64.ok()) { - WireFormatLite::WriteFixed64(field_number, u64.ValueOrDie(), stream); + WireFormatLite::WriteFixed64(field_number, u64.value(), stream); } return u64.status(); } // Writes a UINT64 field, including tag, to the stream. -inline Status WriteUInt64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u64 = data.ToUint64(); +inline util::Status WriteUInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u64 = data.ToUint64(); if (u64.ok()) { - WireFormatLite::WriteUInt64(field_number, u64.ValueOrDie(), stream); + WireFormatLite::WriteUInt64(field_number, u64.value(), stream); } return u64.status(); } // Writes a DOUBLE field, including tag, to the stream. -inline Status WriteDouble(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr d = data.ToDouble(); +inline util::Status WriteDouble(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr d = data.ToDouble(); if (d.ok()) { - WireFormatLite::WriteDouble(field_number, d.ValueOrDie(), stream); + WireFormatLite::WriteDouble(field_number, d.value(), stream); } return d.status(); } // Writes a FLOAT field, including tag, to the stream. -inline Status WriteFloat(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr f = data.ToFloat(); +inline util::Status WriteFloat(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr f = data.ToFloat(); if (f.ok()) { - WireFormatLite::WriteFloat(field_number, f.ValueOrDie(), stream); + WireFormatLite::WriteFloat(field_number, f.value(), stream); } return f.status(); } // Writes a BOOL field, including tag, to the stream. -inline Status WriteBool(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr b = data.ToBool(); +inline util::Status WriteBool(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr b = data.ToBool(); if (b.ok()) { - WireFormatLite::WriteBool(field_number, b.ValueOrDie(), stream); + WireFormatLite::WriteBool(field_number, b.value(), stream); } return b.status(); } // Writes a BYTES field, including tag, to the stream. -inline Status WriteBytes(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr c = data.ToBytes(); +inline util::Status WriteBytes(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr c = data.ToBytes(); if (c.ok()) { WireFormatLite::WriteBytes(field_number, c.ValueOrDie(), stream); } @@ -260,11 +261,11 @@ inline Status WriteBytes(int field_number, const DataPiece& data, } // Writes a STRING field, including tag, to the stream. -inline Status WriteString(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr s = data.ToString(); +inline util::Status WriteString(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr s = data.ToString(); if (s.ok()) { - WireFormatLite::WriteString(field_number, s.ValueOrDie(), stream); + WireFormatLite::WriteString(field_number, s.value(), stream); } return s.status(); } @@ -350,7 +351,9 @@ ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() { for (std::set::iterator it = required_fields_.begin(); it != required_fields_.end(); ++it) { - ow_->MissingField((*it)->name()); + ow_->MissingField(ow_->use_json_name_in_missing_fields_ + ? (*it)->json_name() + : (*it)->name()); } } // Computes the total number of proto bytes used by a message, also adjusts @@ -406,7 +409,9 @@ std::string ProtoWriter::ProtoElement::ToString() const { now->parent()->parent_field_ != now->parent_field_) { std::string name = now->parent_field_->name(); int i = 0; - while (i < name.size() && (ascii_isalnum(name[i]) || name[i] == '_')) ++i; + while (i < name.size() && + (ascii_isalnum(name[i]) || name[i] == '_')) + ++i; if (i > 0 && i == name.size()) { // safe field name if (loc.empty()) { loc = name; @@ -449,7 +454,8 @@ void ProtoWriter::MissingField(StringPiece missing_name) { listener_->MissingField(location(), missing_name); } -ProtoWriter* ProtoWriter::StartObject(StringPiece name) { +ProtoWriter* ProtoWriter::StartObject( + StringPiece name) { // Starting the root message. Create the root ProtoElement and return. if (element_ == nullptr) { if (!name.empty()) { @@ -459,8 +465,8 @@ ProtoWriter* ProtoWriter::StartObject(StringPiece name) { return this; } - const google::protobuf::Field* field = nullptr; - field = BeginNamed(name, false); + const google::protobuf::Field* field = BeginNamed(name, false); + if (field == nullptr) return this; // Check to see if this field is a oneof and that no oneof in that group has @@ -481,6 +487,7 @@ ProtoWriter* ProtoWriter::StartObject(StringPiece name) { return StartObjectField(*field, *type); } + ProtoWriter* ProtoWriter::EndObject() { if (invalid_depth_ > 0) { --invalid_depth_; @@ -500,8 +507,11 @@ ProtoWriter* ProtoWriter::EndObject() { return this; } -ProtoWriter* ProtoWriter::StartList(StringPiece name) { +ProtoWriter* ProtoWriter::StartList( + StringPiece name) { + const google::protobuf::Field* field = BeginNamed(name, true); + if (field == nullptr) return this; if (!ValidOneof(*field, name)) { @@ -520,6 +530,7 @@ ProtoWriter* ProtoWriter::StartList(StringPiece name) { return StartListField(*field, *type); } + ProtoWriter* ProtoWriter::EndList() { if (invalid_depth_ > 0) { --invalid_depth_; @@ -529,12 +540,13 @@ ProtoWriter* ProtoWriter::EndList() { return this; } -ProtoWriter* ProtoWriter::RenderDataPiece(StringPiece name, - const DataPiece& data) { - Status status; +ProtoWriter* ProtoWriter::RenderDataPiece( + StringPiece name, const DataPiece& data) { + util::Status status; if (invalid_depth_ > 0) return this; const google::protobuf::Field* field = Lookup(name); + if (field == nullptr) return this; if (!ValidOneof(*field, name)) return this; @@ -584,18 +596,18 @@ ProtoWriter* ProtoWriter::StartListField(const google::protobuf::Field& field, return this; } -Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, - const google::protobuf::Enum* enum_type, - CodedOutputStream* stream, - bool use_lower_camel_for_enums, - bool case_insensitive_enum_parsing, - bool ignore_unknown_values) { +util::Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, + const google::protobuf::Enum* enum_type, + CodedOutputStream* stream, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_values) { bool is_unknown_enum_value = false; - StatusOr e = data.ToEnum(enum_type, use_lower_camel_for_enums, - case_insensitive_enum_parsing, - ignore_unknown_values, &is_unknown_enum_value); + util::StatusOr e = data.ToEnum( + enum_type, use_lower_camel_for_enums, case_insensitive_enum_parsing, + ignore_unknown_values, &is_unknown_enum_value); if (e.ok() && !is_unknown_enum_value) { - WireFormatLite::WriteEnum(field_number, e.ValueOrDie(), stream); + WireFormatLite::WriteEnum(field_number, e.value(), stream); } return e.status(); } @@ -603,31 +615,17 @@ Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, ProtoWriter* ProtoWriter::RenderPrimitiveField( const google::protobuf::Field& field, const google::protobuf::Type& type, const DataPiece& data) { - Status status; + util::Status status; // Pushing a ProtoElement and then pop it off at the end for 2 purposes: // error location reporting and required field accounting. // - // For proto3, since there is no required field tracking, we only need to push - // ProtoElement for error cases. + // For proto3, since there is no required field tracking, we only need to + // push ProtoElement for error cases. if (!element_->proto3()) { element_.reset(new ProtoElement(element_.release(), &field, type, false)); } - if (field.kind() == google::protobuf::Field::TYPE_UNKNOWN || - field.kind() == google::protobuf::Field::TYPE_MESSAGE) { - // Push a ProtoElement for location reporting purposes. - if (element_->proto3()) { - element_.reset(new ProtoElement(element_.release(), &field, type, false)); - } - InvalidValue(field.type_url().empty() - ? google::protobuf::Field_Kind_Name(field.kind()) - : field.type_url(), - data.ValueAsStringOrDefault("")); - element_.reset(element()->pop()); - return this; - } - switch (field.kind()) { case google::protobuf::Field::TYPE_INT32: { status = WriteInt32(field.number(), data, stream_.get()); @@ -696,9 +694,9 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( case_insensitive_enum_parsing_, ignore_unknown_enum_values_); break; } - default: // TYPE_GROUP or TYPE_MESSAGE - status = Status(util::error::INVALID_ARGUMENT, - data.ToString().ValueOrDie()); + default: // TYPE_GROUP, TYPE_MESSAGE, TYPE_UNKNOWN. + status = util::Status(util::error::INVALID_ARGUMENT, + data.ValueAsStringOrDefault("")); } if (!status.ok()) { @@ -706,7 +704,9 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( if (element_->proto3()) { element_.reset(new ProtoElement(element_.release(), &field, type, false)); } - InvalidValue(google::protobuf::Field_Kind_Name(field.kind()), + InvalidValue(field.type_url().empty() + ? google::protobuf::Field_Kind_Name(field.kind()) + : field.type_url(), status.message()); element_.reset(element()->pop()); return this; diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h index f81117364adf..8149ed3624d8 100644 --- a/src/google/protobuf/util/internal/proto_writer.h +++ b/src/google/protobuf/util/internal/proto_writer.h @@ -49,6 +49,7 @@ #include #include +// Must be included last. #include namespace google { @@ -56,6 +57,7 @@ namespace protobuf { namespace util { namespace converter { + class ObjectLocationTracker; // An ObjectWriter that can write protobuf bytes directly from writer events. @@ -102,10 +104,12 @@ class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { return RenderDataPiece(name, DataPiece(value, use_strict_base64_decoding())); } + ProtoWriter* RenderBytes(StringPiece name, StringPiece value) override { return RenderDataPiece( name, DataPiece(value, false, use_strict_base64_decoding())); } + ProtoWriter* RenderNull(StringPiece name) override { return RenderDataPiece(name, DataPiece::NullData()); } @@ -114,7 +118,8 @@ class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // Renders a DataPiece 'value' into a field whose wire type is determined // from the given field 'name'. virtual ProtoWriter* RenderDataPiece(StringPiece name, - const DataPiece& value); + const DataPiece& data); + // Returns the location tracker to use for tracking locations for errors. const LocationTrackerInterface& location() { @@ -154,6 +159,11 @@ class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { case_insensitive_enum_parsing_ = case_insensitive_enum_parsing; } + void set_use_json_name_in_missing_fields( + bool use_json_name_in_missing_fields) { + use_json_name_in_missing_fields_ = use_json_name_in_missing_fields; + } + protected: class PROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTrackerInterface { @@ -299,7 +309,7 @@ class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // Renders a primitive field given the field and the enclosing type. ProtoWriter* RenderPrimitiveField(const google::protobuf::Field& field, const google::protobuf::Type& type, - const DataPiece& value); + const DataPiece& data); private: // Writes an ENUM field, including tag, to the stream. @@ -334,6 +344,9 @@ class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // If true, check if enum name in UPPER_CASE matches the field name. bool case_insensitive_enum_parsing_; + // If true, use the json name in missing fields errors. + bool use_json_name_in_missing_fields_; + // Variable for internal state processing: // element_ : the current element. // size_insert_: sizes of nested messages. diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 4fc026fa81b0..a941aa0988df 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -49,6 +48,8 @@ #include #include #include +#include +#include #include #include @@ -59,7 +60,6 @@ namespace google { namespace protobuf { namespace util { using util::Status; -using util::StatusOr; namespace error { using util::error::Code; using util::error::INTERNAL; @@ -68,7 +68,6 @@ namespace converter { using ::PROTOBUF_NAMESPACE_ID::internal::WireFormat; using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; using util::Status; -using util::StatusOr; namespace { @@ -88,7 +87,7 @@ const google::protobuf::EnumValue* FindEnumValueByNumber( // Utility function to format nanos. const std::string FormatNanos(uint32 nanos, bool with_trailing_zeros); -StatusOr MapKeyDefaultValueAsString( +util::StatusOr MapKeyDefaultValueAsString( const google::protobuf::Field& field) { switch (field.kind()) { case google::protobuf::Field::TYPE_BOOL: @@ -107,7 +106,7 @@ StatusOr MapKeyDefaultValueAsString( case google::protobuf::Field::TYPE_STRING: return std::string(); default: - return Status(util::error::INTERNAL, "Invalid map key type."); + return util::Status(util::error::INTERNAL, "Invalid map key type."); } } } // namespace @@ -159,8 +158,8 @@ ProtoStreamObjectSource::~ProtoStreamObjectSource() { } } -Status ProtoStreamObjectSource::NamedWriteTo(StringPiece name, - ObjectWriter* ow) const { +util::Status ProtoStreamObjectSource::NamedWriteTo(StringPiece name, + ObjectWriter* ow) const { return WriteMessage(type_, name, 0, true, ow); } @@ -184,11 +183,9 @@ const google::protobuf::Field* ProtoStreamObjectSource::FindAndVerifyField( return field; } -Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, - StringPiece name, - const uint32 end_tag, - bool include_start_and_end, - ObjectWriter* ow) const { +util::Status ProtoStreamObjectSource::WriteMessage( + const google::protobuf::Type& type, StringPiece name, + const uint32 end_tag, bool include_start_and_end, ObjectWriter* ow) const { const TypeRenderer* type_renderer = FindTypeRenderer(type.name()); if (type_renderer != nullptr) { @@ -201,14 +198,14 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, uint32 tag = stream_->ReadTag(), last_tag = tag + 1; UnknownFieldSet unknown_fields; - if (tag == end_tag && suppress_empty_object_) { + if (!name.empty() && tag == end_tag && suppress_empty_object_) { return util::Status(); } if (include_start_and_end) { ow->StartObject(name); } - while (tag != end_tag) { + while (tag != end_tag && tag != 0) { if (tag != last_tag) { // Update field only if tag is changed. last_tag = tag; field = FindAndVerifyField(type, tag); @@ -251,7 +248,7 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, return util::Status(); } -StatusOr ProtoStreamObjectSource::RenderList( +util::StatusOr ProtoStreamObjectSource::RenderList( const google::protobuf::Field* field, StringPiece name, uint32 list_tag, ObjectWriter* ow) const { uint32 tag_to_return = 0; @@ -273,7 +270,7 @@ StatusOr ProtoStreamObjectSource::RenderList( return tag_to_return; } -StatusOr ProtoStreamObjectSource::RenderMap( +util::StatusOr ProtoStreamObjectSource::RenderMap( const google::protobuf::Field* field, StringPiece name, uint32 list_tag, ObjectWriter* ow) const { const google::protobuf::Type* field_type = @@ -303,7 +300,8 @@ StatusOr ProtoStreamObjectSource::RenderMap( if (key_field == nullptr) { // The Type info for this map entry is incorrect. It should always // have a field named "key" and with field number 1. - return Status(util::error::INTERNAL, "Invalid map entry."); + return util::Status(util::error::INTERNAL, + "Invalid map entry."); } ASSIGN_OR_RETURN(map_key, MapKeyDefaultValueAsString(*key_field)); } @@ -311,7 +309,7 @@ StatusOr ProtoStreamObjectSource::RenderMap( } else { // The Type info for this map entry is incorrect. It should contain // exactly two fields with field number 1 and 2. - return Status(util::error::INTERNAL, "Invalid map entry."); + return util::Status(util::error::INTERNAL, "Invalid map entry."); } } stream_->PopLimit(old_limit); @@ -319,7 +317,7 @@ StatusOr ProtoStreamObjectSource::RenderMap( return tag_to_return; } -Status ProtoStreamObjectSource::RenderPacked( +util::Status ProtoStreamObjectSource::RenderPacked( const google::protobuf::Field* field, ObjectWriter* ow) const { uint32 length; stream_->ReadVarint32(&length); @@ -331,20 +329,21 @@ Status ProtoStreamObjectSource::RenderPacked( return util::Status(); } -Status ProtoStreamObjectSource::RenderTimestamp( +util::Status ProtoStreamObjectSource::RenderTimestamp( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { std::pair p = os->ReadSecondsAndNanos(type); int64 seconds = p.first; int32 nanos = p.second; if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) { - return Status(util::error::INTERNAL, - StrCat("Timestamp seconds exceeds limit for field: ", - field_name)); + return util::Status( + util::error::INTERNAL, + StrCat("Timestamp seconds exceeds limit for field: ", + field_name)); } if (nanos < 0 || nanos >= kNanosPerSecond) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Timestamp nanos exceeds limit for field: ", field_name)); } @@ -355,20 +354,20 @@ Status ProtoStreamObjectSource::RenderTimestamp( return util::Status(); } -Status ProtoStreamObjectSource::RenderDuration( +util::Status ProtoStreamObjectSource::RenderDuration( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { std::pair p = os->ReadSecondsAndNanos(type); int64 seconds = p.first; int32 nanos = p.second; if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Duration seconds exceeds limit for field: ", field_name)); } if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Duration nanos exceeds limit for field: ", field_name)); } @@ -376,7 +375,7 @@ Status ProtoStreamObjectSource::RenderDuration( std::string sign = ""; if (seconds < 0) { if (nanos > 0) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Duration nanos is non-negative, but seconds is " "negative for field: ", @@ -397,10 +396,9 @@ Status ProtoStreamObjectSource::RenderDuration( return util::Status(); } -Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderDouble( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // default value of Double wrapper value if (tag != 0) { @@ -411,10 +409,9 @@ Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderFloat( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32 = 0; // default value of Float wrapper value if (tag != 0) { @@ -425,10 +422,9 @@ Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderInt64( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // default value of Int64 wrapper value if (tag != 0) { @@ -439,10 +435,9 @@ Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderUInt64( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // default value of UInt64 wrapper value if (tag != 0) { @@ -453,10 +448,9 @@ Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderInt32( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32 = 0; // default value of Int32 wrapper value if (tag != 0) { @@ -467,10 +461,9 @@ Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderUInt32( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32 = 0; // default value of UInt32 wrapper value if (tag != 0) { @@ -481,10 +474,9 @@ Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderBool( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // results in 'false' value as default, which is the // default value of Bool wrapper @@ -496,10 +488,9 @@ Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderString( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32; std::string str; // default value of empty for String wrapper @@ -512,10 +503,9 @@ Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderBytes( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32; std::string str; @@ -528,15 +518,19 @@ Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderStruct( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { const google::protobuf::Field* field = nullptr; uint32 tag = os->stream_->ReadTag(); ow->StartObject(field_name); while (tag != 0) { field = os->FindAndVerifyField(type, tag); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); + tag = os->stream_->ReadTag(); + continue; + } // google.protobuf.Struct has only one field that is a map. Hence we use // RenderMap to render that field. if (os->IsMap(*field)) { @@ -547,7 +541,7 @@ Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderStructValue( +util::Status ProtoStreamObjectSource::RenderStructValue( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { const google::protobuf::Field* field = nullptr; @@ -564,7 +558,7 @@ Status ProtoStreamObjectSource::RenderStructValue( } // TODO(skarvaje): Avoid code duplication of for loops and SkipField logic. -Status ProtoStreamObjectSource::RenderStructListValue( +util::Status ProtoStreamObjectSource::RenderStructListValue( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); @@ -588,10 +582,9 @@ Status ProtoStreamObjectSource::RenderStructListValue( return util::Status(); } -Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderAny( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { // An Any is of the form { string type_url = 1; bytes value = 2; } uint32 tag; std::string type_url; @@ -647,7 +640,7 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, resolved_type.status().message()); } // nested_type cannot be null at this time. - const google::protobuf::Type* nested_type = resolved_type.ValueOrDie(); + const google::protobuf::Type* nested_type = resolved_type.value(); io::ArrayInputStream zero_copy_stream(value.data(), value.size()); io::CodedInputStream in_stream(&zero_copy_stream); @@ -671,7 +664,7 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, return result; } -Status ProtoStreamObjectSource::RenderFieldMask( +util::Status ProtoStreamObjectSource::RenderFieldMask( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { std::string combined; @@ -704,7 +697,7 @@ Status ProtoStreamObjectSource::RenderFieldMask( std::unordered_map* - ProtoStreamObjectSource::renderers_ = NULL; + ProtoStreamObjectSource::renderers_ = nullptr; PROTOBUF_NAMESPACE_ID::internal::once_flag source_renderers_init_; @@ -747,7 +740,7 @@ void ProtoStreamObjectSource::InitRendererMap() { void ProtoStreamObjectSource::DeleteRendererMap() { delete ProtoStreamObjectSource::renderers_; - renderers_ = NULL; + renderers_ = nullptr; } // static @@ -758,7 +751,7 @@ ProtoStreamObjectSource::FindTypeRenderer(const std::string& type_url) { return FindOrNull(*renderers_, type_url); } -Status ProtoStreamObjectSource::RenderField( +util::Status ProtoStreamObjectSource::RenderField( const google::protobuf::Field* field, StringPiece field_name, ObjectWriter* ow) const { // Short-circuit message types as it tends to call WriteMessage recursively @@ -772,7 +765,7 @@ Status ProtoStreamObjectSource::RenderField( const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(field->type_url()); if (type == nullptr) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Invalid configuration. Could not find the type: ", field->type_url())); @@ -790,8 +783,9 @@ Status ProtoStreamObjectSource::RenderField( --recursion_depth_; if (!stream_->ConsumedEntireMessage()) { - return Status(util::error::INVALID_ARGUMENT, - "Nested protocol message not parsed in its entirety."); + return util::Status( + util::error::INVALID_ARGUMENT, + "Nested protocol message not parsed in its entirety."); } stream_->PopLimit(old_limit); } else { @@ -801,12 +795,12 @@ Status ProtoStreamObjectSource::RenderField( return util::Status(); } -Status ProtoStreamObjectSource::RenderNonMessageField( +util::Status ProtoStreamObjectSource::RenderNonMessageField( const google::protobuf::Field* field, StringPiece field_name, ObjectWriter* ow) const { // Temporary buffers of different types. - uint32 buffer32; - uint64 buffer64; + uint32 buffer32 = 0; + uint64 buffer64 = 0; std::string strbuffer; switch (field->kind()) { case google::protobuf::Field::TYPE_BOOL: { @@ -1086,10 +1080,10 @@ std::pair ProtoStreamObjectSource::ReadSecondsAndNanos( return std::pair(signed_seconds, signed_nanos); } -Status ProtoStreamObjectSource::IncrementRecursionDepth( +util::Status ProtoStreamObjectSource::IncrementRecursionDepth( StringPiece type_name, StringPiece field_name) const { if (++recursion_depth_ > max_recursion_depth_) { - return Status( + return util::Status( util::error::INVALID_ARGUMENT, StrCat("Message too deep. Max recursion depth reached for type '", type_name, "', field '", field_name, "'")); diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index a83031d17c45..9dce1187e081 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -131,7 +131,7 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // nested messages (end with 0) and nested groups (end with group end tag). // The include_start_and_end parameter allows this method to be called when // already inside of an object, and skip calling StartObject and EndObject. - virtual util::Status WriteMessage(const google::protobuf::Type& descriptor, + virtual util::Status WriteMessage(const google::protobuf::Type& type, StringPiece name, const uint32 end_tag, bool include_start_and_end, @@ -160,6 +160,9 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { const google::protobuf::Field& field) const; + // Returns the input stream. + io::CodedInputStream* stream() const { return stream_; } + private: ProtoStreamObjectSource(io::CodedInputStream* stream, const TypeInfo* typeinfo, @@ -176,8 +179,8 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Returns the next tag after reading all map entries. The caller should use // this tag before reading more tags from the stream. util::StatusOr RenderMap(const google::protobuf::Field* field, - StringPiece name, uint32 list_tag, - ObjectWriter* ow) const; + StringPiece name, uint32 list_tag, + ObjectWriter* ow) const; // Renders a packed repeating field. A packed field is stored as: // {tag length item1 item2 item3} instead of the less efficient @@ -281,7 +284,7 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { StringPiece field_name) const; // Input stream to read from. Ownership rests with the caller. - io::CodedInputStream* stream_; + mutable io::CodedInputStream* stream_; // Type information for all the types used in the descriptor. Used to find // google::protobuf::Type of nested messages/enums. diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index 22fc3f62df3b..4c0caed3565d 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -49,6 +49,7 @@ #include #include #include +#include namespace google { @@ -105,11 +106,11 @@ class ProtostreamObjectSourceTest virtual ~ProtostreamObjectSourceTest() {} void DoTest(const Message& msg, const Descriptor* descriptor) { - Status status = ExecuteTest(msg, descriptor); + util::Status status = ExecuteTest(msg, descriptor); EXPECT_EQ(util::Status(), status); } - Status ExecuteTest(const Message& msg, const Descriptor* descriptor) { + util::Status ExecuteTest(const Message& msg, const Descriptor* descriptor) { std::ostringstream oss; msg.SerializePartialToOstream(&oss); std::string proto = oss.str(); @@ -152,13 +153,13 @@ class ProtostreamObjectSourceTest ->RenderInt32("", 3208) ->EndList() ->StartList("repFix64") - ->RenderUint64("", bit_cast(6401LL)) - ->RenderUint64("", bit_cast(0LL)) + ->RenderUint64("", bit_cast(int64{6401})) + ->RenderUint64("", bit_cast(int64{0})) ->EndList() ->StartList("repU64") - ->RenderUint64("", bit_cast(0LL)) - ->RenderUint64("", bit_cast(6402LL)) - ->RenderUint64("", bit_cast(6403LL)) + ->RenderUint64("", bit_cast(int64{0})) + ->RenderUint64("", bit_cast(int64{6402})) + ->RenderUint64("", bit_cast(int64{6403})) ->EndList() ->StartList("repI64") ->RenderInt64("", 6404L) @@ -325,8 +326,8 @@ TEST_P(ProtostreamObjectSourceTest, Primitives) { ->RenderInt32("i32", 3203) ->RenderInt32("sf32", 3204) ->RenderInt32("s32", 3205) - ->RenderUint64("fix64", bit_cast(6401LL)) - ->RenderUint64("u64", bit_cast(6402LL)) + ->RenderUint64("fix64", bit_cast(int64{6401})) + ->RenderUint64("u64", bit_cast(int64{6402})) ->RenderInt64("i64", 6403L) ->RenderInt64("sf64", 6404L) ->RenderInt64("s64", 6405L) @@ -595,7 +596,7 @@ TEST_P(ProtostreamObjectSourceTest, CyclicMessageDepthTest) { current = next; } - Status status = ExecuteTest(cyclic, Cyclic::descriptor()); + util::Status status = ExecuteTest(cyclic, Cyclic::descriptor()); EXPECT_EQ(util::error::INVALID_ARGUMENT, status.code()); } @@ -941,7 +942,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, MissingTypeUrlError) { // We start the "AnyOut" part and then fail when we hit the Any object. ow_.StartObject(""); - Status status = ExecuteTest(out, AnyOut::descriptor()); + util::Status status = ExecuteTest(out, AnyOut::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -957,7 +958,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeServiceError) { // We start the "AnyOut" part and then fail when we hit the Any object. ow_.StartObject(""); - Status status = ExecuteTest(out, AnyOut::descriptor()); + util::Status status = ExecuteTest(out, AnyOut::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -973,7 +974,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeError) { // We start the "AnyOut" part and then fail when we hit the Any object. ow_.StartObject(""); - Status status = ExecuteTest(out, AnyOut::descriptor()); + util::Status status = ExecuteTest(out, AnyOut::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1106,7 +1107,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampBelowMinTest) { ts->set_seconds(kTimestampMinSeconds - 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1117,7 +1118,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampAboveMaxTest) { ts->set_seconds(kTimestampMaxSeconds + 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1128,7 +1129,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationBelowMinTest) { dur->set_seconds(kDurationMinSeconds - 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1139,7 +1140,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationAboveMaxTest) { dur->set_seconds(kDurationMaxSeconds + 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 0b89ae297247..ace209ab277d 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -35,7 +35,6 @@ #include #include -#include #include #include #include @@ -43,6 +42,8 @@ #include #include #include +#include +#include #include #include @@ -57,7 +58,6 @@ namespace converter { using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; using std::placeholders::_1; using util::Status; -using util::StatusOr; using util::error::INVALID_ARGUMENT; @@ -73,6 +73,7 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter( set_ignore_unknown_enum_values(options_.ignore_unknown_enum_values); set_use_lower_camel_for_enums(options_.use_lower_camel_for_enums); set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing); + set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields); } ProtoStreamObjectWriter::ProtoStreamObjectWriter( @@ -86,6 +87,7 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter( set_ignore_unknown_fields(options_.ignore_unknown_fields); set_use_lower_camel_for_enums(options.use_lower_camel_for_enums); set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing); + set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields); } ProtoStreamObjectWriter::ProtoStreamObjectWriter( @@ -328,16 +330,16 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { if (value.type() == DataPiece::TYPE_STRING) { type_url_ = std::string(value.str()); } else { - StatusOr s = value.ToString(); + util::StatusOr s = value.ToString(); if (!s.ok()) { parent_->InvalidValue("String", s.status().message()); invalid_ = true; return; } - type_url_ = s.ValueOrDie(); + type_url_ = s.value(); } // Resolve the type url, and report an error if we failed to resolve it. - StatusOr resolved_type = + util::StatusOr resolved_type = parent_->typeinfo()->ResolveTypeUrl(type_url_); if (!resolved_type.ok()) { parent_->InvalidValue("Any", resolved_type.status().message()); @@ -345,7 +347,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { return; } // At this point, type is never null. - const google::protobuf::Type* type = resolved_type.ValueOrDie(); + const google::protobuf::Type* type = resolved_type.value(); well_known_type_render_ = FindTypeRenderer(type_url_); if (well_known_type_render_ != nullptr || @@ -480,6 +482,7 @@ bool ProtoStreamObjectWriter::Item::InsertMapKeyIfNotPresent( return InsertIfNotPresent(map_keys_.get(), std::string(map_key)); } + ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( StringPiece name) { if (invalid_depth() > 0) { @@ -583,8 +586,41 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( } const google::protobuf::Field* field = BeginNamed(name, false); + if (field == nullptr) return this; + // Legacy JSON map is a list of key value pairs. Starts a map entry object. + if (options_.use_legacy_json_map_format && name.empty()) { + Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false); + return this; + } + + if (IsMap(*field)) { + // Begin a map. A map is triggered by a StartObject() call if the current + // field has a map type. + // A map type is always repeated, hence set is_list to true. + // Render + // "": [ + Push(name, Item::MAP, false, true); + return this; + } + + if (options_.disable_implicit_message_list) { + // If the incoming object is repeated, the top-level object on stack should + // be list. Report an error otherwise. + if (IsRepeated(*field) && !current_->is_list()) { + IncrementInvalidDepth(); + + if (!options_.suppress_implicit_message_list_error) { + InvalidValue( + field->name(), + "Starting an object in a repeated field but the parent object " + "is not a list"); + } + return this; + } + } + if (IsStruct(*field)) { // Start a struct object. // Render @@ -608,19 +644,13 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( return this; } - // Legacy JSON map is a list of key value pairs. Starts a map entry object. - if (options_.use_legacy_json_map_format && name.empty()) { - Push(name, IsAny(*field) ? Item::ANY : Item::MESSAGE, false, false); - return this; - } + if (field->kind() != google::protobuf::Field::TYPE_GROUP && + field->kind() != google::protobuf::Field::TYPE_MESSAGE) { + IncrementInvalidDepth(); + if (!options_.suppress_object_to_scalar_error) { + InvalidValue(field->name(), "Starting an object on a scalar field"); + } - if (IsMap(*field)) { - // Begin a map. A map is triggered by a StartObject() call if the current - // field has a map type. - // A map type is always repeated, hence set is_list to true. - // Render - // "": [ - Push(name, Item::MAP, false, true); return this; } @@ -648,6 +678,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndObject() { return this; } + ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList( StringPiece name) { if (invalid_depth() > 0) { @@ -796,6 +827,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList( // name is not empty const google::protobuf::Field* field = Lookup(name); + if (field == nullptr) { IncrementInvalidDepth(); return this; @@ -889,11 +921,11 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, switch (data.type()) { case DataPiece::TYPE_INT32: { if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToInt32(); + util::StatusOr int_value = data.ToInt32(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(int_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(int_value.value()), true)); return Status(); } } @@ -902,11 +934,11 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } case DataPiece::TYPE_UINT32: { if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToUint32(); + util::StatusOr int_value = data.ToUint32(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(int_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(int_value.value()), true)); return Status(); } } @@ -917,11 +949,10 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, // If the option to treat integers as strings is set, then render them as // strings. Otherwise, fallback to rendering them as double. if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToInt64(); + util::StatusOr int_value = data.ToInt64(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( - "string_value", - DataPiece(StrCat(int_value.ValueOrDie()), true)); + "string_value", DataPiece(StrCat(int_value.value()), true)); return Status(); } } @@ -932,11 +963,10 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, // If the option to treat integers as strings is set, then render them as // strings. Otherwise, fallback to rendering them as double. if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToUint64(); + util::StatusOr int_value = data.ToUint64(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( - "string_value", - DataPiece(StrCat(int_value.ValueOrDie()), true)); + "string_value", DataPiece(StrCat(int_value.value()), true)); return Status(); } } @@ -945,11 +975,11 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } case DataPiece::TYPE_FLOAT: { if (ow->options_.struct_integers_as_strings) { - StatusOr float_value = data.ToFloat(); + util::StatusOr float_value = data.ToFloat(); if (float_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(float_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(float_value.value()), true)); return Status(); } } @@ -958,11 +988,11 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } case DataPiece::TYPE_DOUBLE: { if (ow->options_.struct_integers_as_strings) { - StatusOr double_value = data.ToDouble(); + util::StatusOr double_value = data.ToDouble(); if (double_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", - DataPiece(SimpleDtoa(double_value.ValueOrDie()), true)); + DataPiece(SimpleDtoa(double_value.value()), true)); return Status(); } } @@ -1016,7 +1046,7 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, } static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow, - StringPiece path) { + StringPiece path) { ow->ProtoWriter::RenderDataPiece( "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true)); return Status(); @@ -1217,7 +1247,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( // Map of functions that are responsible for rendering well known type // represented by the key. std::unordered_map* - ProtoStreamObjectWriter::renderers_ = NULL; + ProtoStreamObjectWriter::renderers_ = nullptr; PROTOBUF_NAMESPACE_ID::internal::once_flag writer_renderers_init_; void ProtoStreamObjectWriter::InitRendererMap() { @@ -1272,7 +1302,7 @@ void ProtoStreamObjectWriter::InitRendererMap() { void ProtoStreamObjectWriter::DeleteRendererMap() { delete ProtoStreamObjectWriter::renderers_; - renderers_ = NULL; + renderers_ = nullptr; } ProtoStreamObjectWriter::TypeRenderer* @@ -1296,9 +1326,9 @@ bool ProtoStreamObjectWriter::ValidMapKey(StringPiece unnormalized_name) { return true; } -void ProtoStreamObjectWriter::Push(StringPiece name, - Item::ItemType item_type, - bool is_placeholder, bool is_list) { +void ProtoStreamObjectWriter::Push( + StringPiece name, Item::ItemType item_type, bool is_placeholder, + bool is_list) { is_list ? ProtoWriter::StartList(name) : ProtoWriter::StartObject(name); // invalid_depth == 0 means it is a successful StartObject or StartList. diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index 5fb23a993de5..a5bea409d19b 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -100,6 +100,20 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { // If true, accepts repeated key/value pair for a map proto field. bool use_legacy_json_map_format; + // If true, disable implicitly creating message list. + bool disable_implicit_message_list; + + // If true, suppress the error of implicitly creating message list when it + // is disabled. + bool suppress_implicit_message_list_error; + + // If true, suppress the error of rendering scalar field if the source is an + // object. + bool suppress_object_to_scalar_error; + + // If true, use the json name in missing fields errors. + bool use_json_name_in_missing_fields; + Options() : struct_integers_as_strings(false), ignore_unknown_fields(false), @@ -107,7 +121,11 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { use_lower_camel_for_enums(false), case_insensitive_enum_parsing(false), ignore_null_value_map_entry(false), - use_legacy_json_map_format(false) {} + use_legacy_json_map_format(false), + disable_implicit_message_list(false), + suppress_implicit_message_list_error(false), + suppress_object_to_scalar_error(false), + use_json_name_in_missing_fields(false) {} // Default instance of Options with all options set to defaults. static const Options& Defaults() { @@ -116,7 +134,7 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { } }; -// Constructor. Does not take ownership of any parameter passed in. + // Constructor. Does not take ownership of any parameter passed in. ProtoStreamObjectWriter(TypeResolver* type_resolver, const google::protobuf::Type& type, strings::ByteSink* output, ErrorListener* listener, @@ -241,7 +259,7 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { int depth_; // True if the type is a well-known type. Well-known types in Any - // has a special formating: + // has a special formatting: // { // "@type": "type.googleapis.com/google.protobuf.XXX", // "value": , @@ -347,24 +365,24 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { // Renders google.protobuf.Value in struct.proto. It picks the right oneof // type based on value's type. static util::Status RenderStructValue(ProtoStreamObjectWriter* ow, - const DataPiece& value); + const DataPiece& data); // Renders google.protobuf.Timestamp value. static util::Status RenderTimestamp(ProtoStreamObjectWriter* ow, - const DataPiece& value); + const DataPiece& data); // Renders google.protobuf.FieldMask value. static util::Status RenderFieldMask(ProtoStreamObjectWriter* ow, - const DataPiece& value); + const DataPiece& data); // Renders google.protobuf.Duration value. static util::Status RenderDuration(ProtoStreamObjectWriter* ow, - const DataPiece& value); + const DataPiece& data); // Renders wrapper message types for primitive types in // google/protobuf/wrappers.proto. static util::Status RenderWrapperType(ProtoStreamObjectWriter* ow, - const DataPiece& value); + const DataPiece& data); static void InitRendererMap(); static void DeleteRendererMap(); @@ -387,6 +405,7 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { void Push(StringPiece name, Item::ItemType item_type, bool is_placeholder, bool is_list); + // Pops items from the stack. All placeholder items are popped until a // non-placeholder item is found. void Pop(); diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 6b22b5286709..211b7bcbf8f5 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +65,7 @@ namespace protobuf { namespace util { namespace converter { + using proto_util_converter::testing::AnyM; using proto_util_converter::testing::AnyOut; using proto_util_converter::testing::Author; @@ -90,12 +93,6 @@ std::string GetTypeUrl(const Descriptor* descriptor) { } } // namespace -#if __cplusplus >= 201103L -using std::get; -#else -using std::tr1::get; -#endif - class BaseProtoStreamObjectWriterTest : public ::testing::TestWithParam { protected: @@ -168,8 +165,8 @@ class BaseProtoStreamObjectWriterTest MATCHER_P(HasObjectLocation, expected, "Verifies the expected object location") { - std::string actual = get<0>(arg).ToString(); - if (actual.compare(expected) == 0) return true; + std::string actual = std::get<0>(arg).ToString(); + if (actual == expected) return true; *result_listener << "actual location is: " << actual; return false; } @@ -278,6 +275,7 @@ TEST_P(ProtoStreamObjectWriterTest, ConflictingJsonName) { CheckOutput(message2); } + TEST_P(ProtoStreamObjectWriterTest, IntEnumValuesAreAccepted) { Book book; book.set_title("Some Book"); @@ -1002,7 +1000,10 @@ TEST_P(ProtoStreamObjectWriterTest, Proto3Message expected; EXPECT_CALL( listener_, - InvalidValue(_, StringPiece("TYPE_ENUM"), + InvalidValue(_, + StringPiece( + "type.googleapis.com/" + "proto_util_converter.testing.Proto3Message.NestedEnum"), StringPiece("\"someunknownvalueyouwillneverknow\""))) .With(Args<0>(HasObjectLocation("enum_value"))); ow_->StartObject("") @@ -2537,7 +2538,7 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest, SimpleFieldMaskTest) { CheckOutput(expected); } -TEST_P(ProtoStreamObjectWriterFieldMaskTest, MutipleMasksInCompactForm) { +TEST_P(ProtoStreamObjectWriterFieldMaskTest, MultipleMasksInCompactForm) { FieldMaskTest expected; expected.set_id("1"); expected.mutable_single_mask()->add_paths("camel_case1"); diff --git a/src/google/protobuf/util/internal/structured_objectwriter.h b/src/google/protobuf/util/internal/structured_objectwriter.h index bccea718c467..01cbb9e1aca0 100644 --- a/src/google/protobuf/util/internal/structured_objectwriter.h +++ b/src/google/protobuf/util/internal/structured_objectwriter.h @@ -69,7 +69,8 @@ class PROTOBUF_EXPORT StructuredObjectWriter : public ObjectWriter { public: // Takes ownership of the parent Element. explicit BaseElement(BaseElement* parent) - : parent_(parent), level_(parent == NULL ? 0 : parent->level() + 1) {} + : parent_(parent), + level_(parent == nullptr ? 0 : parent->level() + 1) {} virtual ~BaseElement() {} // Releases ownership of the parent and returns a pointer to it. diff --git a/src/google/protobuf/util/internal/testdata/books.proto b/src/google/protobuf/util/internal/testdata/books.proto index 4f02ae1444c8..328c5ce0d74a 100644 --- a/src/google/protobuf/util/internal/testdata/books.proto +++ b/src/google/protobuf/util/internal/testdata/books.proto @@ -34,6 +34,7 @@ // Some of the older enums don't use CAPITALS_WITH_UNDERSCORES for testing. // LINT: LEGACY_NAMES +// LINT: ALLOW_GROUPS syntax = "proto2"; @@ -212,3 +213,39 @@ message TestJsonName1 { message TestJsonName2 { optional int32 another_value = 1 [json_name = "value"]; } + +message TestPrimitiveFieldsWithSameJsonName { + optional string val_str1 = 1; + optional string val_str_1 = 2; + + optional int32 val_int321 = 3; + optional int32 val_int32_1 = 4; + + optional uint32 val_uint321 = 5; + optional uint32 val_uint32_1 = 6; + + optional int64 val_int641 = 7; + optional int64 val_int64_1 = 8; + + optional uint64 val_uint641 = 9; + optional uint64 val_uint64_1 = 10; + + optional bool val_bool1 = 11; + optional bool val_bool_1 = 12; + + optional double val_double1 = 13; + optional double val_double_1 = 14; + + optional float val_float1 = 15; + optional float val_float_1 = 16; +} + +message TestRepeatedFieldsWithSameJsonName { + repeated string rep_str1 = 1; + repeated string rep_str_1 = 2; +} + +message TestMessageFieldsWithSameJsonName { + optional Primitive prim1 = 1; + optional Primitive prim_1 = 2; +} diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index 818df6417204..e91afa027e19 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ class TypeInfoForTypeResolver : public TypeInfo { const google::protobuf::Type* GetTypeByTypeUrl( StringPiece type_url) const override { StatusOrType result = ResolveTypeUrl(type_url); - return result.ok() ? result.ValueOrDie() : NULL; + return result.ok() ? result.value() : NULL; } const google::protobuf::Enum* GetEnumByTypeUrl( @@ -89,7 +90,7 @@ class TypeInfoForTypeResolver : public TypeInfo { std::map::iterator it = cached_enums_.find(type_url); if (it != cached_enums_.end()) { - return it->second.ok() ? it->second.ValueOrDie() : NULL; + return it->second.ok() ? it->second.value() : NULL; } // Stores the string value so it can be referenced using StringPiece in the // cached_enums_ map. @@ -102,7 +103,7 @@ class TypeInfoForTypeResolver : public TypeInfo { StatusOrEnum result = status.ok() ? StatusOrEnum(enum_type.release()) : StatusOrEnum(status); cached_enums_[string_type_url] = result; - return result.ok() ? result.ValueOrDie() : NULL; + return result.ok() ? result.value() : NULL; } const google::protobuf::Field* FindField( @@ -134,7 +135,7 @@ class TypeInfoForTypeResolver : public TypeInfo { cached_types->begin(); it != cached_types->end(); ++it) { if (it->second.ok()) { - delete it->second.ValueOrDie(); + delete it->second.value(); } } } diff --git a/src/google/protobuf/util/internal/type_info_test_helper.cc b/src/google/protobuf/util/internal/type_info_test_helper.cc index cc2dcd73cb3f..ccf6fbd836d1 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.cc +++ b/src/google/protobuf/util/internal/type_info_test_helper.cc @@ -95,7 +95,7 @@ ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource( } } GOOGLE_LOG(FATAL) << "Can not reach here."; - return NULL; + return nullptr; } ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter( @@ -109,7 +109,7 @@ ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter( } } GOOGLE_LOG(FATAL) << "Can not reach here."; - return NULL; + return nullptr; } DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter( @@ -121,7 +121,7 @@ DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter( } } GOOGLE_LOG(FATAL) << "Can not reach here."; - return NULL; + return nullptr; } } // namespace testing diff --git a/src/google/protobuf/util/internal/type_info_test_helper.h b/src/google/protobuf/util/internal/type_info_test_helper.h index 3cafbceb371d..923050d8b751 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.h +++ b/src/google/protobuf/util/internal/type_info_test_helper.h @@ -63,7 +63,7 @@ class TypeInfoTestHelper { // Creates a TypeInfo object for the given set of descriptors. void ResetTypeInfo(const std::vector& descriptors); - // Convinent overloads. + // Convenient overloads. void ResetTypeInfo(const Descriptor* descriptor); void ResetTypeInfo(const Descriptor* descriptor1, const Descriptor* descriptor2); diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index e3cdbcb12853..1816b6843f7d 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -270,7 +270,8 @@ std::string ToCamelCase(StringPiece input) { // 1) following a lowercase: "...aB..." // 2) followed by a lowercase: "...ABc..." if (!result.empty() && is_cap && - (!was_cap || (i + 1 < input.size() && ascii_islower(input[i + 1])))) { + (!was_cap || + (i + 1 < input.size() && ascii_islower(input[i + 1])))) { first_word = false; result.push_back(input[i]); } else { @@ -310,9 +311,9 @@ std::string ToSnakeCase(StringPiece input) { // (e.g. "GoogleLAB" => "google_lab") // 4) Followed by a lowercase: "...ABc..." => "...a_bc..." // (e.g. "GBike" => "g_bike") - if (was_not_underscore && // case 1 out - (was_not_cap || // case 2 in, case 3 out - (i + 1 < input.size() && // case 3 out + if (was_not_underscore && // case 1 out + (was_not_cap || // case 2 in, case 3 out + (i + 1 < input.size() && // case 3 out ascii_islower(input[i + 1])))) { // case 4 in // We add an underscore for case 2 and case 4. result.push_back('_'); @@ -329,7 +330,7 @@ std::string ToSnakeCase(StringPiece input) { return result; } -std::set* well_known_types_ = NULL; +std::set* well_known_types_ = nullptr; PROTOBUF_NAMESPACE_ID::internal::once_flag well_known_types_init_; const char* well_known_types_name_array_[] = { "google.protobuf.Timestamp", "google.protobuf.Duration", diff --git a/src/google/protobuf/util/internal/utility.h b/src/google/protobuf/util/internal/utility.h index 6ce9023d6a6e..d92e41e70cff 100644 --- a/src/google/protobuf/util/internal/utility.h +++ b/src/google/protobuf/util/internal/utility.h @@ -82,8 +82,8 @@ PROTOBUF_EXPORT std::string GetStringOptionOrDefault( // Returns a boolean value contained in Any type. // TODO(skarvaje): Make these utilities dealing with Any types more generic, -// add more error checking and move to a more public/sharable location so others -// can use. +// add more error checking and move to a more public/shareable location so +// others can use. PROTOBUF_EXPORT bool GetBoolFromAny(const google::protobuf::Any& any); // Returns int64 value contained in Any type. diff --git a/src/google/protobuf/util/json_format_proto3.proto b/src/google/protobuf/util/json_format_proto3.proto index b62487a5789f..0eec9da319c8 100644 --- a/src/google/protobuf/util/json_format_proto3.proto +++ b/src/google/protobuf/util/json_format_proto3.proto @@ -91,6 +91,7 @@ message TestOneof { bytes oneof_bytes_value = 3; EnumType oneof_enum_value = 4; MessageType oneof_message_value = 5; + google.protobuf.NullValue oneof_null_value = 6; } } diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc index 2f3e6c6ba5a0..6ced27c46502 100644 --- a/src/google/protobuf/util/json_util.cc +++ b/src/google/protobuf/util/json_util.cc @@ -145,8 +145,8 @@ class StatusErrorListener : public converter::ErrorListener { StringPiece value) override { status_ = util::Status( util::error::INVALID_ARGUMENT, - StrCat(GetLocString(loc), ": invalid value ", string(value), - " for type ", string(type_name))); + StrCat(GetLocString(loc), ": invalid value ", std::string(value), + " for type ", std::string(type_name))); } void MissingField(const converter::LocationTrackerInterface& loc, diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 26fb8999f363..68af4d17ba24 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -111,8 +112,8 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator : message_differencer_(message_differencer), key_field_paths_(key_field_paths) { GOOGLE_CHECK(!key_field_paths_.empty()); - for (int i = 0; i < key_field_paths_.size(); ++i) { - GOOGLE_CHECK(!key_field_paths_[i].empty()); + for (const auto& path : key_field_paths_) { + GOOGLE_CHECK(!path.empty()); } } MultipleFieldsMapKeyComparator(MessageDifferencer* message_differencer, @@ -124,9 +125,8 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator } bool IsMatch(const Message& message1, const Message& message2, const std::vector& parent_fields) const override { - for (int i = 0; i < key_field_paths_.size(); ++i) { - if (!IsMatchInternal(message1, message2, parent_fields, - key_field_paths_[i], 0)) { + for (const auto& path : key_field_paths_) { + if (!IsMatchInternal(message1, message2, parent_fields, path, 0)) { return false; } } @@ -141,7 +141,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator int path_index) const { const FieldDescriptor* field = key_field_path[path_index]; std::vector current_parent_fields(parent_fields); - if (path_index == key_field_path.size() - 1) { + if (path_index == static_cast(key_field_path.size() - 1)) { if (field->is_repeated()) { if (!message_differencer_->CompareRepeatedField( message1, message2, field, ¤t_parent_fields)) { @@ -187,7 +187,7 @@ class MessageDifferencer::MultipleFieldsMapKeyComparator void MatchIndicesPostProcessorForSmartList( std::vector* match_list1, std::vector* match_list2) { int last_matched_index = -1; - for (int i = 0; i < match_list1->size(); ++i) { + for (size_t i = 0; i < match_list1->size(); ++i) { if (match_list1->at(i) < 0) { continue; } @@ -275,11 +275,11 @@ MessageDifferencer::MessageDifferencer() MatchIndicesPostProcessorForSmartList) {} MessageDifferencer::~MessageDifferencer() { - for (int i = 0; i < owned_key_comparators_.size(); ++i) { - delete owned_key_comparators_[i]; + for (MapKeyComparator* comparator : owned_key_comparators_) { + delete comparator; } - for (int i = 0; i < ignore_criteria_.size(); ++i) { - delete ignore_criteria_[i]; + for (IgnoreCriteria* criteria : ignore_criteria_) { + delete criteria; } } @@ -379,9 +379,9 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldsAsKey( const FieldDescriptor* field, const std::vector& key_fields) { std::vector > key_field_paths; - for (int i = 0; i < key_fields.size(); ++i) { + for (const FieldDescriptor* key_filed : key_fields) { std::vector key_field_path; - key_field_path.push_back(key_fields[i]); + key_field_path.push_back(key_filed); key_field_paths.push_back(key_field_path); } TreatAsMapWithMultipleFieldPathsAsKey(field, key_field_paths); @@ -394,10 +394,8 @@ void MessageDifferencer::TreatAsMapWithMultipleFieldPathsAsKey( << "Field must be repeated: " << field->full_name(); GOOGLE_CHECK_EQ(FieldDescriptor::CPPTYPE_MESSAGE, field->cpp_type()) << "Field has to be message type. Field name is: " << field->full_name(); - for (int i = 0; i < key_field_paths.size(); ++i) { - const std::vector& key_field_path = - key_field_paths[i]; - for (int j = 0; j < key_field_path.size(); ++j) { + for (const auto& key_field_path : key_field_paths) { + for (size_t j = 0; j < key_field_path.size(); ++j) { const FieldDescriptor* parent_field = j == 0 ? field : key_field_path[j - 1]; const FieldDescriptor* child_field = key_field_path[j]; @@ -576,12 +574,12 @@ bool MessageDifferencer::Compare(const Message& message1, bool unknown_compare_result = true; // Ignore unknown fields in EQUIVALENT mode if (message_field_comparison_ != EQUIVALENT) { - const UnknownFieldSet* unknown_field_set1 = - &reflection1->GetUnknownFields(message1); - const UnknownFieldSet* unknown_field_set2 = - &reflection2->GetUnknownFields(message2); - if (!CompareUnknownFields(message1, message2, *unknown_field_set1, - *unknown_field_set2, parent_fields)) { + const UnknownFieldSet& unknown_field_set1 = + reflection1->GetUnknownFields(message1); + const UnknownFieldSet& unknown_field_set2 = + reflection2->GetUnknownFields(message2); + if (!CompareUnknownFields(message1, message2, unknown_field_set1, + unknown_field_set2, parent_fields)) { if (reporter_ == NULL) { return false; } @@ -671,8 +669,8 @@ bool MessageDifferencer::CompareRequestedFieldsUsingSettings( FieldDescriptorArray MessageDifferencer::CombineFields( const FieldDescriptorArray& fields1, Scope fields1_scope, const FieldDescriptorArray& fields2, Scope fields2_scope) { - int index1 = 0; - int index2 = 0; + size_t index1 = 0; + size_t index2 = 0; tmp_message_fields_.clear(); @@ -916,6 +914,82 @@ bool MessageDifferencer::IsMatch( return match; } +bool MessageDifferencer::CompareMapFieldByMapReflection( + const Message& message1, const Message& message2, + const FieldDescriptor* map_field, std::vector* parent_fields, + DefaultFieldComparator* comparator) { + const Reflection* reflection1 = message1.GetReflection(); + const Reflection* reflection2 = message2.GetReflection(); + const int count1 = reflection1->MapSize(message1, map_field); + const int count2 = reflection2->MapSize(message2, map_field); + const bool treated_as_subset = IsTreatedAsSubset(map_field); + if (count1 != count2 && !treated_as_subset) { + return false; + } + if (count1 > count2) { + return false; + } + const FieldDescriptor* val_des = map_field->message_type()->map_value(); + switch (val_des->cpp_type()) { +#define HANDLE_TYPE(CPPTYPE, METHOD, COMPAREMETHOD) \ + case FieldDescriptor::CPPTYPE_##CPPTYPE: { \ + for (MapIterator it = reflection1->MapBegin( \ + const_cast(&message1), map_field); \ + it != \ + reflection1->MapEnd(const_cast(&message1), map_field); \ + ++it) { \ + if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { \ + return false; \ + } \ + MapValueConstRef value2; \ + reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2); \ + if (!comparator->Compare##COMPAREMETHOD(*val_des, \ + it.GetValueRef().Get##METHOD(), \ + value2.Get##METHOD())) { \ + return false; \ + } \ + } \ + break; \ + } + HANDLE_TYPE(INT32, Int32Value, Int32); + HANDLE_TYPE(INT64, Int64Value, Int64); + HANDLE_TYPE(UINT32, UInt32Value, UInt32); + HANDLE_TYPE(UINT64, UInt64Value, UInt64); + HANDLE_TYPE(DOUBLE, DoubleValue, Double); + HANDLE_TYPE(FLOAT, FloatValue, Float); + HANDLE_TYPE(BOOL, BoolValue, Bool); + HANDLE_TYPE(STRING, StringValue, String); + HANDLE_TYPE(ENUM, EnumValue, Int32); +#undef HANDLE_TYPE + case FieldDescriptor::CPPTYPE_MESSAGE: { + for (MapIterator it = reflection1->MapBegin( + const_cast(&message1), map_field); + it != + reflection1->MapEnd(const_cast(&message1), map_field); + ++it) { + if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { + return false; + } + bool compare_result; + MapValueConstRef value2; + reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2); + // Append currently compared field to the end of parent_fields. + SpecificField specific_value_field; + specific_value_field.field = val_des; + parent_fields->push_back(specific_value_field); + compare_result = Compare(it.GetValueRef().GetMessageValue(), + value2.GetMessageValue(), parent_fields); + parent_fields->pop_back(); + if (!compare_result) { + return false; + } + } + break; + } + } + return true; +} + bool MessageDifferencer::CompareRepeatedField( const Message& message1, const Message& message2, const FieldDescriptor* repeated_field, @@ -923,6 +997,49 @@ bool MessageDifferencer::CompareRepeatedField( // the input FieldDescriptor is guaranteed to be repeated field. const Reflection* reflection1 = message1.GetReflection(); const Reflection* reflection2 = message2.GetReflection(); + + // When both map fields are on map, do not sync to repeated field. + // TODO(jieluo): Add support for reporter + if (repeated_field->is_map() && reporter_ == nullptr && + // Users didn't set custom map field key comparator + map_field_key_comparator_.find(repeated_field) == + map_field_key_comparator_.end() && + // Users didn't set repeated field comparison + repeated_field_comparison_ == AS_LIST) { + DefaultFieldComparator* map_field_comparator = + field_comparator_ ? nullptr : &default_field_comparator_; +#if PROTOBUF_RTTI + // Inherit class from DefaultFieldComparator can not get the benefit + // because DefaultFieldComparator::Compare() method might be overwrote. + if (field_comparator_ && + typeid(*field_comparator_) == typeid(default_field_comparator_)) { + map_field_comparator = + static_cast(field_comparator_); + } +#endif + if (map_field_comparator) { + const FieldDescriptor* key_des = + repeated_field->message_type()->map_key(); + const FieldDescriptor* val_des = + repeated_field->message_type()->map_value(); + const internal::MapFieldBase* map_field1 = + reflection1->GetMapData(message1, repeated_field); + const internal::MapFieldBase* map_field2 = + reflection2->GetMapData(message2, repeated_field); + std::vector current_parent_fields(*parent_fields); + SpecificField specific_field; + specific_field.field = repeated_field; + current_parent_fields.push_back(specific_field); + if (map_field1->IsMapValid() && map_field2->IsMapValid() && + !IsIgnored(message1, message2, key_des, current_parent_fields) && + !IsIgnored(message1, message2, val_des, current_parent_fields)) { + return CompareMapFieldByMapReflection( + message1, message2, repeated_field, ¤t_parent_fields, + map_field_comparator); + } + } + } + const int count1 = reflection1->FieldSize(message1, repeated_field); const int count2 = reflection2->FieldSize(message2, repeated_field); const bool treated_as_subset = IsTreatedAsSubset(repeated_field); @@ -1116,10 +1233,11 @@ bool MessageDifferencer::CompareFieldValueUsingParentFields( bool MessageDifferencer::CheckPathChanged( const std::vector& field_path) { - for (int i = 0; i < field_path.size(); ++i) { + for (const SpecificField& specific_field : field_path) { // Don't check indexes for map entries -- maps are unordered. - if (field_path[i].field != NULL && field_path[i].field->is_map()) continue; - if (field_path[i].index != field_path[i].new_index) return true; + if (specific_field.field != nullptr && specific_field.field->is_map()) + continue; + if (specific_field.index != specific_field.new_index) return true; } return false; } @@ -1130,7 +1248,8 @@ bool MessageDifferencer::IsTreatedAsSet(const FieldDescriptor* field) { repeated_field_comparisons_.end()) { return repeated_field_comparisons_[field] == AS_SET; } - return repeated_field_comparison_ == AS_SET; + return GetMapKeyComparator(field) == nullptr && + repeated_field_comparison_ == AS_SET; } bool MessageDifferencer::IsTreatedAsSmartSet(const FieldDescriptor* field) { @@ -1139,7 +1258,8 @@ bool MessageDifferencer::IsTreatedAsSmartSet(const FieldDescriptor* field) { repeated_field_comparisons_.end()) { return repeated_field_comparisons_[field] == AS_SMART_SET; } - return repeated_field_comparison_ == AS_SMART_SET; + return GetMapKeyComparator(field) == nullptr && + repeated_field_comparison_ == AS_SMART_SET; } bool MessageDifferencer::IsTreatedAsSmartList(const FieldDescriptor* field) { @@ -1148,7 +1268,8 @@ bool MessageDifferencer::IsTreatedAsSmartList(const FieldDescriptor* field) { repeated_field_comparisons_.end()) { return repeated_field_comparisons_[field] == AS_SMART_LIST; } - return repeated_field_comparison_ == AS_SMART_LIST; + return GetMapKeyComparator(field) == nullptr && + repeated_field_comparison_ == AS_SMART_LIST; } bool MessageDifferencer::IsTreatedAsSubset(const FieldDescriptor* field) { @@ -1163,9 +1284,8 @@ bool MessageDifferencer::IsIgnored( if (ignored_fields_.find(field) != ignored_fields_.end()) { return true; } - for (int i = 0; i < ignore_criteria_.size(); ++i) { - if (ignore_criteria_[i]->IsIgnored(message1, message2, field, - parent_fields)) { + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsIgnored(message1, message2, field, parent_fields)) { return true; } } @@ -1176,9 +1296,9 @@ bool MessageDifferencer::IsUnknownFieldIgnored( const Message& message1, const Message& message2, const SpecificField& field, const std::vector& parent_fields) { - for (int i = 0; i < ignore_criteria_.size(); ++i) { - if (ignore_criteria_[i]->IsUnknownFieldIgnored(message1, message2, field, - parent_fields)) { + for (IgnoreCriteria* criteria : ignore_criteria_) { + if (criteria->IsUnknownFieldIgnored(message1, message2, field, + parent_fields)) { return true; } } @@ -1243,7 +1363,7 @@ bool MessageDifferencer::UnpackAny(const Message& any, } data->reset(dynamic_message_factory_->GetPrototype(desc)->New()); std::string serialized_value = reflection->GetString(any, value_field); - if (!(*data)->ParseFromString(serialized_value)) { + if (!(*data)->ParsePartialFromString(serialized_value)) { GOOGLE_DLOG(ERROR) << "Failed to parse value for " << full_type_name; return false; } @@ -1297,8 +1417,8 @@ bool MessageDifferencer::CompareUnknownFields( // Now that we have two sorted lists, we can detect fields which appear only // in one list or the other by traversing them simultaneously. - int index1 = 0; - int index2 = 0; + size_t index1 = 0; + size_t index2 = 0; while (index1 < fields1.size() || index2 < fields2.size()) { enum { ADDITION, @@ -1403,12 +1523,14 @@ bool MessageDifferencer::CompareUnknownFields( if (IsUnknownFieldIgnored(message1, message2, specific_field, *parent_field)) { - if (reporter_ != NULL) { + if (report_ignores_ && reporter_ != NULL) { parent_field->push_back(specific_field); reporter_->ReportUnknownFieldIgnored(message1, message2, *parent_field); parent_field->pop_back(); } - return true; + if (change_type != ADDITION) ++index1; + if (change_type != DELETION) ++index2; + continue; } if (change_type == ADDITION || change_type == DELETION || @@ -1526,7 +1648,7 @@ int MaximumMatcher::FindMaximumMatch(bool early_return) { } } // Backfill match_list1_ as we only filled match_list2_ when finding - // argumenting pathes. + // argumenting paths. for (int i = 0; i < count2_; ++i) { if ((*match_list2_)[i] != -1) { (*match_list1_)[(*match_list2_)[i]] = i; @@ -1761,7 +1883,7 @@ MessageDifferencer::StreamReporter::~StreamReporter() { void MessageDifferencer::StreamReporter::PrintPath( const std::vector& field_path, bool left_side) { - for (int i = 0; i < field_path.size(); ++i) { + for (size_t i = 0; i < field_path.size(); ++i) { if (i > 0) { printer_->Print("."); } diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index 21cf374dd0e7..2384e51d3966 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -177,43 +177,33 @@ class PROTOBUF_EXPORT MessageDifferencer { // For known fields, "field" is filled in and "unknown_field_number" is -1. // For unknown fields, "field" is NULL, "unknown_field_number" is the field // number, and "unknown_field_type" is its type. - const FieldDescriptor* field; - int unknown_field_number; - UnknownField::Type unknown_field_type; + const FieldDescriptor* field = nullptr; + int unknown_field_number = -1; + UnknownField::Type unknown_field_type = UnknownField::Type::TYPE_VARINT; // If this a repeated field, "index" is the index within it. For unknown // fields, this is the index of the field among all unknown fields of the // same field number and type. - int index; + int index = -1; // If "field" is a repeated field which is being treated as a map or // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates // the index the position to which the element has moved. If the element // has not moved, "new_index" will have the same value as "index". - int new_index; + int new_index = -1; // For unknown fields, these are the pointers to the UnknownFieldSet // containing the unknown fields. In certain cases (e.g. proto1's // MessageSet, or nested groups of unknown fields), these may differ from // the messages' internal UnknownFieldSets. - const UnknownFieldSet* unknown_field_set1; - const UnknownFieldSet* unknown_field_set2; + const UnknownFieldSet* unknown_field_set1 = nullptr; + const UnknownFieldSet* unknown_field_set2 = nullptr; // For unknown fields, these are the index of the field within the // UnknownFieldSets. One or the other will be -1 when // reporting an addition or deletion. - int unknown_field_index1; - int unknown_field_index2; - - SpecificField() - : field(NULL), - unknown_field_number(-1), - index(-1), - new_index(-1), - unknown_field_set1(NULL), - unknown_field_set2(NULL), - unknown_field_index1(-1), - unknown_field_index2(-1) {} + int unknown_field_index1 = -1; + int unknown_field_index2 = -1; }; // Abstract base class from which all MessageDifferencer @@ -225,6 +215,19 @@ class PROTOBUF_EXPORT MessageDifferencer { // FieldDescriptors. The first will be the field of the embedded message // itself and the second will be the actual field in the embedded message // that was added/deleted/modified. + // Fields will be reported in PostTraversalOrder. + // For example, given following proto, if both baz and quux are changed. + // foo { + // bar { + // baz: 1 + // quux: 2 + // } + // } + // ReportModified will be invoked with following order: + // 1. foo.bar.baz or foo.bar.quux + // 2. foo.bar.quux or foo.bar.baz + // 2. foo.bar + // 3. foo class PROTOBUF_EXPORT Reporter { public: Reporter(); @@ -315,7 +318,7 @@ class PROTOBUF_EXPORT MessageDifferencer { // Abstract base class from which all IgnoreCriteria derive. // By adding IgnoreCriteria more complex ignore logic can be implemented. - // IgnoreCriteria are registed with AddIgnoreCriteria. For each compared + // IgnoreCriteria are registered with AddIgnoreCriteria. For each compared // field IsIgnored is called on each added IgnoreCriteria until one returns // true or all return false. // IsIgnored is called for fields where at least one side has a value. @@ -754,6 +757,13 @@ class PROTOBUF_EXPORT MessageDifferencer { const FieldDescriptor* field, std::vector* parent_fields); + // Compare the map fields using map reflection instead of sync to repeated. + bool CompareMapFieldByMapReflection(const Message& message1, + const Message& message2, + const FieldDescriptor* field, + std::vector* parent_fields, + DefaultFieldComparator* comparator); + // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields. bool CompareFieldValue(const Message& message1, const Message& message2, const FieldDescriptor* field, int index1, int index2); diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index b57062ad6227..3d36e8593c26 100644 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc @@ -160,6 +160,29 @@ TEST(MessageDifferencerTest, MapFieldEqualityTest) { // Compare EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Get map entries by index will sync map to repeated field + MapTestUtil::GetMapEntries(msg1, 0); + EXPECT_TRUE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Compare values not match + (*msg1.mutable_map_int32_int32())[1] = 2; + (*msg2.mutable_map_int32_int32())[1] = 3; + EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Compare keys not match + msg1.Clear(); + msg2.Clear(); + (*msg1.mutable_map_string_string())["1"] = ""; + (*msg2.mutable_map_string_string())["2"] = ""; + EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2)); + + // Compare message values not match + msg1.Clear(); + msg2.Clear(); + (*msg1.mutable_map_int32_foreign_message())[1].set_c(1); + (*msg2.mutable_map_int32_foreign_message())[1].set_c(2); + EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2)); } TEST(MessageDifferencerTest, BasicPartialEqualityTest) { @@ -1205,7 +1228,7 @@ TEST(MessageDifferencerTest, RepeatedFieldSmartSetTest_PreviouslyMatch) { *msg2.add_rm() = elem1_2; *msg2.add_rm() = elem2_2; - string diff_report; + std::string diff_report; util::MessageDifferencer differencer; differencer.ReportDifferencesToString(&diff_report); differencer.set_repeated_field_comparison( @@ -2385,7 +2408,7 @@ class ComparisonTest : public testing::Test { void field_as_set(const std::string& field) { set_field_ = field; } - void field_as_map(const string& field, const std::string& key) { + void field_as_map(const std::string& field, const std::string& key) { map_field_ = field; map_key_ = key; } @@ -3198,11 +3221,13 @@ TEST_F(ComparisonTest, EquivalentIgnoresUnknown) { } TEST_F(ComparisonTest, MapTest) { - Map& map1 = *map_proto1_.mutable_map_string_string(); + Map& map1 = + *map_proto1_.mutable_map_string_string(); map1["key1"] = "1"; map1["key2"] = "2"; map1["key3"] = "3"; - Map& map2 = *map_proto2_.mutable_map_string_string(); + Map& map2 = + *map_proto2_.mutable_map_string_string(); map2["key3"] = "0"; map2["key2"] = "2"; map2["key1"] = "1"; @@ -3212,11 +3237,13 @@ TEST_F(ComparisonTest, MapTest) { } TEST_F(ComparisonTest, MapIgnoreKeyTest) { - Map& map1 = *map_proto1_.mutable_map_string_string(); + Map& map1 = + *map_proto1_.mutable_map_string_string(); map1["key1"] = "1"; map1["key2"] = "2"; map1["key3"] = "3"; - Map& map2 = *map_proto2_.mutable_map_string_string(); + Map& map2 = + *map_proto2_.mutable_map_string_string(); map2["key4"] = "2"; map2["key5"] = "3"; map2["key6"] = "1"; @@ -3444,6 +3471,7 @@ TEST_F(MatchingTest, ReportMatchedForMovedFields) { RunWithResult(&differencer, msg1, msg2, true)); } + TEST_F(MatchingTest, MatchesAppearInPostTraversalOrderForMovedFields) { protobuf_unittest::TestDiffMessage msg1, msg2; protobuf_unittest::TestDiffMessage::Item* item; diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc index e61562733de9..4b80e7ca66d0 100644 --- a/src/google/protobuf/util/time_util.cc +++ b/src/google/protobuf/util/time_util.cc @@ -30,13 +30,14 @@ #include -#include #include #include -#include #include #include +#include +#include +// Must go after other includes. #include namespace google { diff --git a/src/google/protobuf/util/time_util_test.cc b/src/google/protobuf/util/time_util_test.cc index 9f0d17fc5011..b6d381326418 100644 --- a/src/google/protobuf/util/time_util_test.cc +++ b/src/google/protobuf/util/time_util_test.cc @@ -119,10 +119,10 @@ TEST(TimeUtilTest, DurationStringFormat) { // Duration must support range from -315,576,000,000s to +315576000000s // which includes negative values. EXPECT_TRUE(TimeUtil::FromString("315576000000.999999999s", &d)); - EXPECT_EQ(315576000000LL, d.seconds()); + EXPECT_EQ(int64{315576000000}, d.seconds()); EXPECT_EQ(999999999, d.nanos()); EXPECT_TRUE(TimeUtil::FromString("-315576000000.999999999s", &d)); - EXPECT_EQ(-315576000000LL, d.seconds()); + EXPECT_EQ(int64{-315576000000}, d.seconds()); EXPECT_EQ(-999999999, d.nanos()); } @@ -278,20 +278,22 @@ TEST(TimeUtilTest, DurationOperators) { // Multiplication should not overflow if the result fits into the supported // range of Duration (intermediate result may be larger than int64). EXPECT_EQ("315575999684.424s", - TimeUtil::ToString((one_second - one_nano) * 315576000000LL)); + TimeUtil::ToString((one_second - one_nano) * int64{315576000000})); EXPECT_EQ("-315575999684.424s", - TimeUtil::ToString((one_nano - one_second) * 315576000000LL)); - EXPECT_EQ("-315575999684.424s", - TimeUtil::ToString((one_second - one_nano) * (-315576000000LL))); + TimeUtil::ToString((one_nano - one_second) * int64{315576000000})); + EXPECT_EQ("-315575999684.424s", TimeUtil::ToString((one_second - one_nano) * + (int64{-315576000000}))); // Test / and % EXPECT_EQ("0.999999999s", TimeUtil::ToString(a / 2)); EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b / 2)); - Duration large = TimeUtil::SecondsToDuration(315576000000LL) - one_nano; + Duration large = TimeUtil::SecondsToDuration(int64{315576000000}) - one_nano; // We have to handle division with values beyond 64 bits. - EXPECT_EQ("0.999999999s", TimeUtil::ToString(large / 315576000000LL)); - EXPECT_EQ("-0.999999999s", TimeUtil::ToString((-large) / 315576000000LL)); - EXPECT_EQ("-0.999999999s", TimeUtil::ToString(large / (-315576000000LL))); + EXPECT_EQ("0.999999999s", TimeUtil::ToString(large / int64{315576000000})); + EXPECT_EQ("-0.999999999s", + TimeUtil::ToString((-large) / int64{315576000000})); + EXPECT_EQ("-0.999999999s", + TimeUtil::ToString(large / (int64{-315576000000}))); Duration large2 = large + one_nano; EXPECT_EQ(large, large % large2); EXPECT_EQ(-large, (-large) % large2); diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc index 35736f10078a..e906d58d7079 100644 --- a/src/google/protobuf/util/type_resolver_util.cc +++ b/src/google/protobuf/util/type_resolver_util.cc @@ -305,7 +305,7 @@ class DescriptorPoolTypeResolver : public TypeResolver { return url_prefix_ + "/" + descriptor->full_name(); } - Status ParseTypeUrl(const string& type_url, std::string* type_name) { + Status ParseTypeUrl(const std::string& type_url, std::string* type_name) { if (type_url.substr(0, url_prefix_.size() + 1) != url_prefix_ + "/") { return Status( util::error::INVALID_ARGUMENT, diff --git a/src/google/protobuf/util/type_resolver_util_test.cc b/src/google/protobuf/util/type_resolver_util_test.cc index f9b9ad65a1f6..d90fdffd9e27 100644 --- a/src/google/protobuf/util/type_resolver_util_test.cc +++ b/src/google/protobuf/util/type_resolver_util_test.cc @@ -158,7 +158,7 @@ class DescriptorPoolTypeResolverTest : public testing::Test { return false; } - string GetTypeUrl(std::string full_name) { + std::string GetTypeUrl(std::string full_name) { return kUrlPrefix + std::string("/") + full_name; } diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index f60b774f3bf7..a3f0fd5dc6e9 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include #include +#include #include #include @@ -65,7 +67,7 @@ namespace internal { static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, const MapKey& value); static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, - const MapValueRef& value); + const MapValueConstRef& value); // =================================================================== @@ -653,6 +655,381 @@ bool WireFormat::ParseAndMergeMessageSetItem(io::CodedInputStream* input, input, MSReflective{message->GetReflection(), message}); } +struct WireFormat::MessageSetParser { + const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) { + // Parse a MessageSetItem + auto metadata = reflection->MutableInternalMetadata(msg); + std::string payload; + uint32 type_id = 0; + bool payload_read = false; + while (!ctx->Done(&ptr)) { + // We use 64 bit tags in order to allow typeid's that span the whole + // range of 32 bit numbers. + uint32 tag = static_cast(*ptr++); + if (tag == WireFormatLite::kMessageSetTypeIdTag) { + uint64 tmp; + ptr = ParseBigVarint(ptr, &tmp); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + type_id = tmp; + if (payload_read) { + const FieldDescriptor* field; + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(type_id); + } else { + field = + ctx->data().pool->FindExtensionByNumber(descriptor, type_id); + } + if (field == nullptr || field->message_type() == nullptr) { + WriteLengthDelimited( + type_id, payload, + metadata->mutable_unknown_fields()); + } else { + Message* value = + field->is_repeated() + ? reflection->AddMessage(msg, field, ctx->data().factory) + : reflection->MutableMessage(msg, field, + ctx->data().factory); + const char* p; + // We can't use regular parse from string as we have to track + // proper recursion depth and descriptor pools. + ParseContext tmp_ctx(ctx->depth(), false, &p, payload); + tmp_ctx.data().pool = ctx->data().pool; + tmp_ctx.data().factory = ctx->data().factory; + GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) && + tmp_ctx.EndedAtLimit()); + } + type_id = 0; + } + continue; + } else if (tag == WireFormatLite::kMessageSetMessageTag) { + if (type_id == 0) { + int32 size = ReadSize(&ptr); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + ptr = ctx->ReadString(ptr, size, &payload); + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + payload_read = true; + } else { + // We're now parsing the payload + const FieldDescriptor* field = nullptr; + if (descriptor->IsExtensionNumber(type_id)) { + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(type_id); + } else { + field = + ctx->data().pool->FindExtensionByNumber(descriptor, type_id); + } + } + ptr = WireFormat::_InternalParseAndMergeField( + msg, ptr, ctx, static_cast(type_id) * 8 + 2, reflection, + field); + type_id = 0; + } + } else { + // An unknown field in MessageSetItem. + ptr = ReadTag(ptr - 1, &tag); + if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { + ctx->SetLastTag(tag); + return ptr; + } + // Skip field. + ptr = internal::UnknownFieldParse( + tag, static_cast(nullptr), ptr, ctx); + } + GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); + } + return ptr; + } + + const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) { + while (!ctx->Done(&ptr)) { + uint32 tag; + ptr = ReadTag(ptr, &tag); + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { + ctx->SetLastTag(tag); + break; + } + if (tag == WireFormatLite::kMessageSetItemStartTag) { + // A message set item starts + ptr = ctx->ParseGroup(this, ptr, tag); + } else { + // Parse other fields as normal extensions. + int field_number = WireFormatLite::GetTagFieldNumber(tag); + const FieldDescriptor* field = nullptr; + if (descriptor->IsExtensionNumber(field_number)) { + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(field_number); + } else { + field = ctx->data().pool->FindExtensionByNumber(descriptor, + field_number); + } + } + ptr = WireFormat::_InternalParseAndMergeField(msg, ptr, ctx, tag, + reflection, field); + } + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + } + return ptr; + } + + Message* msg; + const Descriptor* descriptor; + const Reflection* reflection; +}; + +const char* WireFormat::_InternalParse(Message* msg, const char* ptr, + internal::ParseContext* ctx) { + const Descriptor* descriptor = msg->GetDescriptor(); + const Reflection* reflection = msg->GetReflection(); + GOOGLE_DCHECK(descriptor); + GOOGLE_DCHECK(reflection); + if (descriptor->options().message_set_wire_format()) { + MessageSetParser message_set{msg, descriptor, reflection}; + return message_set.ParseMessageSet(ptr, ctx); + } + while (!ctx->Done(&ptr)) { + uint32 tag; + ptr = ReadTag(ptr, &tag); + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { + ctx->SetLastTag(tag); + break; + } + const FieldDescriptor* field = nullptr; + + int field_number = WireFormatLite::GetTagFieldNumber(tag); + field = descriptor->FindFieldByNumber(field_number); + + // If that failed, check if the field is an extension. + if (field == nullptr && descriptor->IsExtensionNumber(field_number)) { + if (ctx->data().pool == nullptr) { + field = reflection->FindKnownExtensionByNumber(field_number); + } else { + field = + ctx->data().pool->FindExtensionByNumber(descriptor, field_number); + } + } + + ptr = _InternalParseAndMergeField(msg, ptr, ctx, tag, reflection, field); + if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; + } + return ptr; +} + +const char* WireFormat::_InternalParseAndMergeField( + Message* msg, const char* ptr, internal::ParseContext* ctx, uint64 tag, + const Reflection* reflection, const FieldDescriptor* field) { + if (field == nullptr) { + // unknown field set parser takes 64bit tags, because message set type ids + // span the full 32 bit range making the tag span [0, 2^35) range. + return internal::UnknownFieldParse( + tag, reflection->MutableUnknownFields(msg), ptr, ctx); + } + if (WireFormatLite::GetTagWireType(tag) != + WireTypeForFieldType(field->type())) { + if (field->is_packable() && WireFormatLite::GetTagWireType(tag) == + WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + switch (field->type()) { +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + ptr = internal::Packed##CPPTYPE_METHOD##Parser( \ + reflection->MutableRepeatedFieldInternal(msg, field), ptr, \ + ctx); \ + return ptr; \ + } + + HANDLE_PACKED_TYPE(INT32, int32, Int32) + HANDLE_PACKED_TYPE(INT64, int64, Int64) + HANDLE_PACKED_TYPE(SINT32, int32, SInt32) + HANDLE_PACKED_TYPE(SINT64, int64, SInt64) + HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) + HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) + + HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32) + HANDLE_PACKED_TYPE(FIXED64, uint64, Fixed64) + HANDLE_PACKED_TYPE(SFIXED32, int32, SFixed32) + HANDLE_PACKED_TYPE(SFIXED64, int64, SFixed64) + + HANDLE_PACKED_TYPE(FLOAT, float, Float) + HANDLE_PACKED_TYPE(DOUBLE, double, Double) + + HANDLE_PACKED_TYPE(BOOL, bool, Bool) +#undef HANDLE_PACKED_TYPE + + case FieldDescriptor::TYPE_ENUM: { + auto rep_enum = + reflection->MutableRepeatedFieldInternal(msg, field); + bool open_enum = false; + if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || + open_enum) { + ptr = internal::PackedEnumParser(rep_enum, ptr, ctx); + } else { + return ctx->ReadPackedVarint( + ptr, [rep_enum, field, reflection, msg](uint64 val) { + if (field->enum_type()->FindValueByNumber(val) != nullptr) { + rep_enum->Add(val); + } else { + WriteVarint(field->number(), val, + reflection->MutableUnknownFields(msg)); + } + }); + } + return ptr; + } + + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + GOOGLE_LOG(FATAL) << "Can't reach"; + return nullptr; + } + } else { + // mismatched wiretype; + return internal::UnknownFieldParse( + tag, reflection->MutableUnknownFields(msg), ptr, ctx); + } + } + + // Non-packed value + bool utf8_check = false; + bool strict_utf8_check = false; + switch (field->type()) { +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + CPPTYPE value; \ + ptr = VarintParse(ptr, &value); \ + if (ptr == nullptr) return nullptr; \ + if (field->is_repeated()) { \ + reflection->Add##CPPTYPE_METHOD(msg, field, value); \ + } else { \ + reflection->Set##CPPTYPE_METHOD(msg, field, value); \ + } \ + return ptr; \ + } + + HANDLE_TYPE(BOOL, uint64, Bool) + HANDLE_TYPE(INT32, uint32, Int32) + HANDLE_TYPE(INT64, uint64, Int64) + HANDLE_TYPE(UINT32, uint32, UInt32) + HANDLE_TYPE(UINT64, uint64, UInt64) + + case FieldDescriptor::TYPE_SINT32: { + int32 value = ReadVarintZigZag32(&ptr); + if (ptr == nullptr) return nullptr; + if (field->is_repeated()) { + reflection->AddInt32(msg, field, value); + } else { + reflection->SetInt32(msg, field, value); + } + return ptr; + } + case FieldDescriptor::TYPE_SINT64: { + int64 value = ReadVarintZigZag64(&ptr); + if (ptr == nullptr) return nullptr; + if (field->is_repeated()) { + reflection->AddInt64(msg, field, value); + } else { + reflection->SetInt64(msg, field, value); + } + return ptr; + } +#undef HANDLE_TYPE +#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case FieldDescriptor::TYPE_##TYPE: { \ + CPPTYPE value; \ + value = UnalignedLoad(ptr); \ + ptr += sizeof(CPPTYPE); \ + if (field->is_repeated()) { \ + reflection->Add##CPPTYPE_METHOD(msg, field, value); \ + } else { \ + reflection->Set##CPPTYPE_METHOD(msg, field, value); \ + } \ + return ptr; \ + } + + HANDLE_TYPE(FIXED32, uint32, UInt32) + HANDLE_TYPE(FIXED64, uint64, UInt64) + HANDLE_TYPE(SFIXED32, int32, Int32) + HANDLE_TYPE(SFIXED64, int64, Int64) + + HANDLE_TYPE(FLOAT, float, Float) + HANDLE_TYPE(DOUBLE, double, Double) + +#undef HANDLE_TYPE + + case FieldDescriptor::TYPE_ENUM: { + uint32 value; + ptr = VarintParse(ptr, &value); + if (ptr == nullptr) return nullptr; + if (field->is_repeated()) { + reflection->AddEnumValue(msg, field, value); + } else { + reflection->SetEnumValue(msg, field, value); + } + return ptr; + } + + // Handle strings separately so that we can optimize the ctype=CORD case. + case FieldDescriptor::TYPE_STRING: + utf8_check = true; + strict_utf8_check = StrictUtf8Check(field); + PROTOBUF_FALLTHROUGH_INTENDED; + case FieldDescriptor::TYPE_BYTES: { + int size = ReadSize(&ptr); + if (ptr == nullptr) return nullptr; + std::string value; + ptr = ctx->ReadString(ptr, size, &value); + if (ptr == nullptr) return nullptr; + if (utf8_check) { + if (strict_utf8_check) { + if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(), + WireFormatLite::PARSE, + field->full_name().c_str())) { + return nullptr; + } + } else { + VerifyUTF8StringNamedField(value.data(), value.length(), PARSE, + field->full_name().c_str()); + } + } + if (field->is_repeated()) { + reflection->AddString(msg, field, value); + } else { + reflection->SetString(msg, field, value); + } + return ptr; + } + + case FieldDescriptor::TYPE_GROUP: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = reflection->AddMessage(msg, field, ctx->data().factory); + } else { + sub_message = + reflection->MutableMessage(msg, field, ctx->data().factory); + } + + return ctx->ParseGroup(sub_message, ptr, tag); + } + + case FieldDescriptor::TYPE_MESSAGE: { + Message* sub_message; + if (field->is_repeated()) { + sub_message = reflection->AddMessage(msg, field, ctx->data().factory); + } else { + sub_message = + reflection->MutableMessage(msg, field, ctx->data().factory); + } + return ctx->ParseMessage(sub_message, ptr); + } + } + + // GCC 8 complains about control reaching end of non-void function here. + // Let's keep it happy by returning a nullptr. + return nullptr; +} + // =================================================================== uint8* WireFormat::_InternalSerialize(const Message& message, uint8* target, @@ -722,7 +1099,7 @@ static uint8* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, } static uint8* SerializeMapValueRefWithCachedSizes( - const FieldDescriptor* field, const MapValueRef& value, uint8* target, + const FieldDescriptor* field, const MapValueConstRef& value, uint8* target, io::EpsCopyOutputStream* stream) { target = stream->EnsureSpace(target); switch (field->type()) { @@ -807,7 +1184,8 @@ class MapKeySorter { static uint8* InternalSerializeMapEntry(const FieldDescriptor* field, const MapKey& key, - const MapValueRef& value, uint8* target, + const MapValueConstRef& value, + uint8* target, io::EpsCopyOutputStream* stream) { const FieldDescriptor* key_field = field->message_type()->field(0); const FieldDescriptor* value_field = field->message_type()->field(1); @@ -860,9 +1238,8 @@ uint8* WireFormat::InternalSerializeField(const FieldDescriptor* field, MapKeySorter::SortKey(message, message_reflection, field); for (std::vector::iterator it = sorted_key_list.begin(); it != sorted_key_list.end(); ++it) { - MapValueRef map_value; - message_reflection->InsertOrLookupMapValue( - const_cast(&message), field, *it, &map_value); + MapValueConstRef map_value; + message_reflection->LookupMapValue(message, field, *it, &map_value); target = InternalSerializeMapEntry(field, *it, map_value, target, stream); } @@ -1085,8 +1462,8 @@ size_t WireFormat::ByteSize(const Message& message) { message_reflection->ListFields(message, &fields); } - for (int i = 0; i < fields.size(); i++) { - our_size += FieldByteSize(fields[i], message); + for (const FieldDescriptor* field : fields) { + our_size += FieldByteSize(field, message); } if (descriptor->options().message_set_wire_format()) { @@ -1189,7 +1566,7 @@ static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, } static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, - const MapValueRef& value) { + const MapValueConstRef& value) { switch (field->type()) { case FieldDescriptor::TYPE_GROUP: GOOGLE_LOG(FATAL) << "Unsupported"; @@ -1268,7 +1645,7 @@ size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: \ if (field->is_repeated()) { \ - for (int j = 0; j < count; j++) { \ + for (size_t j = 0; j < count; j++) { \ data_size += WireFormatLite::TYPE_METHOD##Size( \ message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ j)); \ @@ -1308,7 +1685,7 @@ size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, case FieldDescriptor::TYPE_ENUM: { if (field->is_repeated()) { - for (int j = 0; j < count; j++) { + for (size_t j = 0; j < count; j++) { data_size += WireFormatLite::EnumSize( message_reflection->GetRepeatedEnum(message, field, j)->number()); } @@ -1323,7 +1700,7 @@ size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, // instead of copying. case FieldDescriptor::TYPE_STRING: case FieldDescriptor::TYPE_BYTES: { - for (int j = 0; j < count; j++) { + for (size_t j = 0; j < count; j++) { std::string scratch; const std::string& value = field->is_repeated() @@ -1359,9 +1736,11 @@ size_t WireFormat::MessageSetItemByteSize(const FieldDescriptor* field, } // Compute the size of the UnknownFieldSet on the wire. -size_t ComputeUnknownFieldsSize(const InternalMetadataWithArena& metadata, +size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata, size_t total_size, CachedSize* cached_size) { - total_size += WireFormat::ComputeUnknownFieldsSize(metadata.unknown_fields()); + total_size += WireFormat::ComputeUnknownFieldsSize( + metadata.unknown_fields( + UnknownFieldSet::default_instance)); cached_size->Set(ToCachedSize(total_size)); return total_size; } @@ -1369,3 +1748,5 @@ size_t ComputeUnknownFieldsSize(const InternalMetadataWithArena& metadata, } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h index c88f3dae0c91..d42cefb65c28 100644 --- a/src/google/protobuf/wire_format.h +++ b/src/google/protobuf/wire_format.h @@ -42,9 +42,12 @@ #include #include +#include #include #include +#include #include +#include #include #include @@ -106,6 +109,11 @@ class PROTOBUF_EXPORT WireFormat { static bool ParseAndMergePartial(io::CodedInputStream* input, Message* message); + // This is meant for internal protobuf use (WireFormat is an internal class). + // This is the reflective implementation of the _InternalParse functionality. + static const char* _InternalParse(Message* msg, const char* ptr, + internal::ParseContext* ctx); + // Serialize a message in protocol buffer wire format. // // Any embedded messages within the message must have their correct sizes @@ -275,6 +283,7 @@ class PROTOBUF_EXPORT WireFormat { Operation op, const char* field_name); private: + struct MessageSetParser; // Skip a MessageSet field. static bool SkipMessageSetField(io::CodedInputStream* input, uint32 field_number, @@ -285,6 +294,12 @@ class PROTOBUF_EXPORT WireFormat { const FieldDescriptor* field, Message* message, io::CodedInputStream* input); + // Parses the value from the wire that belongs to tag. + static const char* _InternalParseAndMergeField(Message* msg, const char* ptr, + internal::ParseContext* ctx, + uint64 tag, + const Reflection* reflection, + const FieldDescriptor* field); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat); }; @@ -380,8 +395,8 @@ inline size_t ComputeUnknownMessageSetItemsSize( // Compute the size of the UnknownFieldSet on the wire. PROTOBUF_EXPORT -size_t ComputeUnknownFieldsSize(const InternalMetadataWithArena& metadata, - size_t size, CachedSize* cached_size); +size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata, size_t size, + CachedSize* cached_size); } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index 47ad0f1e8bb2..d07f903584d8 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc @@ -479,7 +479,7 @@ void WireFormatLite::WriteString(int field_number, const std::string& value, io::CodedOutputStream* output) { // String is for UTF-8 text only WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteString(value); } @@ -488,14 +488,14 @@ void WireFormatLite::WriteStringMaybeAliased(int field_number, io::CodedOutputStream* output) { // String is for UTF-8 text only WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteRawMaybeAliased(value.data(), value.size()); } void WireFormatLite::WriteBytes(int field_number, const std::string& value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteString(value); } @@ -503,7 +503,7 @@ void WireFormatLite::WriteBytesMaybeAliased(int field_number, const std::string& value, io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - GOOGLE_CHECK_LE(value.size(), kint32max); + GOOGLE_CHECK_LE(value.size(), static_cast(kint32max)); output->WriteVarint32(value.size()); output->WriteRawMaybeAliased(value.data(), value.size()); } @@ -603,7 +603,6 @@ bool WireFormatLite::VerifyUtf8String(const char* data, int size, Operation op, // efficient SSE code. template static size_t VarintSize(const T* data, const int n) { -#if __cplusplus >= 201103L static_assert(sizeof(T) == 4, "This routine only works for 32 bit integers"); // is_unsigned => !ZigZag static_assert( @@ -615,7 +614,6 @@ static size_t VarintSize(const T* data, const int n) { "Cannot SignExtended unsigned types"); static_assert(!(SignExtended && ZigZag), "Cannot SignExtended and ZigZag on the same type"); -#endif uint32 sum = n; uint32 msb_sum = 0; for (int i = 0; i < n; i++) { @@ -640,12 +638,10 @@ static size_t VarintSize(const T* data, const int n) { template static size_t VarintSize64(const T* data, const int n) { -#if __cplusplus >= 201103L static_assert(sizeof(T) == 8, "This routine only works for 64 bit integers"); // is_unsigned => !ZigZag static_assert(!ZigZag || !std::is_unsigned::value, "Cannot ZigZag encode unsigned types"); -#endif uint64 sum = n; for (int i = 0; i < n; i++) { uint64 x = data[i]; @@ -780,3 +776,5 @@ size_t WireFormatLite::SInt64Size(const RepeatedField& value) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index aa2a1adbd44e..c742fe869e84 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -49,6 +49,7 @@ #include #include #include +#include // Do UTF-8 validation on string type in Debug build only #ifndef NDEBUG @@ -155,9 +156,9 @@ class PROTOBUF_EXPORT WireFormatLite { } // Number of bits in a tag which identify the wire type. - static const int kTagTypeBits = 3; + static constexpr int kTagTypeBits = 3; // Mask for those bits. - static const uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; + static constexpr uint32 kTagTypeMask = (1 << kTagTypeBits) - 1; // Helper functions for encoding and decoding tags. (Inlined below and in // _inl.h) @@ -209,9 +210,9 @@ class PROTOBUF_EXPORT WireFormatLite { // required string message = 3; // } // } - static const int kMessageSetItemNumber = 1; - static const int kMessageSetTypeIdNumber = 2; - static const int kMessageSetMessageNumber = 3; + static constexpr int kMessageSetItemNumber = 1; + static constexpr int kMessageSetTypeIdNumber = 2; + static constexpr int kMessageSetMessageNumber = 3; static const int kMessageSetItemStartTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( kMessageSetItemNumber, WireFormatLite::WIRETYPE_START_GROUP); static const int kMessageSetItemEndTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG( @@ -684,13 +685,13 @@ class PROTOBUF_EXPORT WireFormatLite { static size_t EnumSize(const RepeatedField& value); // These types always have the same size. - static const size_t kFixed32Size = 4; - static const size_t kFixed64Size = 8; - static const size_t kSFixed32Size = 4; - static const size_t kSFixed64Size = 8; - static const size_t kFloatSize = 4; - static const size_t kDoubleSize = 8; - static const size_t kBoolSize = 1; + static constexpr size_t kFixed32Size = 4; + static constexpr size_t kFixed64Size = 8; + static constexpr size_t kSFixed32Size = 4; + static constexpr size_t kSFixed64Size = 8; + static constexpr size_t kFloatSize = 4; + static constexpr size_t kDoubleSize = 8; + static constexpr size_t kBoolSize = 1; static inline size_t StringSize(const std::string& value); static inline size_t BytesSize(const std::string& value); @@ -806,39 +807,19 @@ inline size_t WireFormatLite::TagSize(int field_number, } inline uint32 WireFormatLite::EncodeFloat(float value) { - union { - float f; - uint32 i; - }; - f = value; - return i; + return bit_cast(value); } inline float WireFormatLite::DecodeFloat(uint32 value) { - union { - float f; - uint32 i; - }; - i = value; - return f; + return bit_cast(value); } inline uint64 WireFormatLite::EncodeDouble(double value) { - union { - double f; - uint64 i; - }; - f = value; - return i; + return bit_cast(value); } inline double WireFormatLite::DecodeDouble(uint64 value) { - union { - double f; - uint64 i; - }; - i = value; - return f; + return bit_cast(value); } // ZigZag Transform: Encodes signed integers so that they can be diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index ff502d6ddf34..e75fc316f875 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -33,25 +33,31 @@ // Sanjay Ghemawat, Jeff Dean, and others. #include + +#include +#include #include +#include #include #include #include #include #include #include +#include #include - -#include -#include -#include +#include #include +#include +#include #include #include #include #include +// clang-format off #include +// clang-format on namespace google { namespace protobuf { @@ -207,8 +213,16 @@ TEST(WireFormatTest, OneofOnlySetLast) { source.set_foo_int(100); source.set_foo_string("101"); - // Serialize and parse to oneof message. - source.SerializeToString(&data); + // Serialize and parse to oneof message. Generated serializer may not order + // fields in tag order. Use WireFormat::SerializeWithCachedSizes instead as + // it sorts fields beforehand. + { + io::StringOutputStream raw_output(&data); + io::CodedOutputStream output(&raw_output); + WireFormat::SerializeWithCachedSizes(source, source.ByteSizeLong(), + &output); + ASSERT_FALSE(output.HadError()); + } io::ArrayInputStream raw_input(data.data(), data.size()); io::CodedInputStream input(&raw_input); WireFormat::ParseAndMergePartial(&input, &oneof_dest); @@ -222,9 +236,9 @@ TEST(WireFormatTest, ByteSize) { unittest::TestAllTypes message; TestUtil::SetAllFields(&message); - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); message.Clear(); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); EXPECT_EQ(0, WireFormat::ByteSize(message)); } @@ -232,9 +246,9 @@ TEST(WireFormatTest, ByteSizeExtensions) { unittest::TestAllExtensions message; TestUtil::SetAllExtensions(&message); - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); message.Clear(); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); EXPECT_EQ(0, WireFormat::ByteSize(message)); } @@ -242,9 +256,9 @@ TEST(WireFormatTest, ByteSizePacked) { unittest::TestPackedTypes message; TestUtil::SetPackedFields(&message); - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); message.Clear(); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); EXPECT_EQ(0, WireFormat::ByteSize(message)); } @@ -252,9 +266,9 @@ TEST(WireFormatTest, ByteSizePackedExtensions) { unittest::TestPackedExtensions message; TestUtil::SetPackedExtensions(&message); - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); message.Clear(); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); EXPECT_EQ(0, WireFormat::ByteSize(message)); } @@ -262,10 +276,10 @@ TEST(WireFormatTest, ByteSizeOneof) { unittest::TestOneof2 message; TestUtil::SetOneof1(&message); - EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message)); + EXPECT_EQ(message.ByteSizeLong(), WireFormat::ByteSize(message)); message.Clear(); - EXPECT_EQ(0, message.ByteSize()); + EXPECT_EQ(0, message.ByteSizeLong()); EXPECT_EQ(0, WireFormat::ByteSize(message)); } @@ -275,7 +289,7 @@ TEST(WireFormatTest, Serialize) { std::string dynamic_data; TestUtil::SetAllFields(&message); - int size = message.ByteSize(); + size_t size = message.ByteSizeLong(); // Serialize using the generated code. { @@ -293,10 +307,9 @@ TEST(WireFormatTest, Serialize) { ASSERT_FALSE(output.HadError()); } - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); } TEST(WireFormatTest, SerializeExtensions) { @@ -305,7 +318,7 @@ TEST(WireFormatTest, SerializeExtensions) { std::string dynamic_data; TestUtil::SetAllExtensions(&message); - int size = message.ByteSize(); + size_t size = message.ByteSizeLong(); // Serialize using the generated code. { @@ -323,10 +336,9 @@ TEST(WireFormatTest, SerializeExtensions) { ASSERT_FALSE(output.HadError()); } - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); } TEST(WireFormatTest, SerializeFieldsAndExtensions) { @@ -335,7 +347,7 @@ TEST(WireFormatTest, SerializeFieldsAndExtensions) { std::string dynamic_data; TestUtil::SetAllFieldsAndExtensions(&message); - int size = message.ByteSize(); + size_t size = message.ByteSizeLong(); // Serialize using the generated code. { @@ -353,14 +365,9 @@ TEST(WireFormatTest, SerializeFieldsAndExtensions) { ASSERT_FALSE(output.HadError()); } - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); - - // Should output in canonical order. - TestUtil::ExpectAllFieldsAndExtensionsInOrder(dynamic_data); - TestUtil::ExpectAllFieldsAndExtensionsInOrder(generated_data); + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); } TEST(WireFormatTest, SerializeOneof) { @@ -369,7 +376,7 @@ TEST(WireFormatTest, SerializeOneof) { std::string dynamic_data; TestUtil::SetOneof1(&message); - int size = message.ByteSize(); + size_t size = message.ByteSizeLong(); // Serialize using the generated code. { @@ -387,10 +394,9 @@ TEST(WireFormatTest, SerializeOneof) { ASSERT_FALSE(output.HadError()); } - // Should be the same. - // Don't use EXPECT_EQ here because we're comparing raw binary data and - // we really don't want it dumped to stdout on failure. - EXPECT_TRUE(dynamic_data == generated_data); + // Should parse to the same message. + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, generated_data)); + EXPECT_TRUE(TestUtil::EqualsToSerialized(message, dynamic_data)); } TEST(WireFormatTest, ParseMultipleExtensionRanges) { @@ -480,7 +486,7 @@ TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) { message_set.mutable_unknown_fields()->AddLengthDelimited(kUnknownTypeId, "bar"); - int size = message_set.ByteSize(); + size_t size = message_set.ByteSizeLong(); EXPECT_EQ(size, message_set.GetCachedSize()); ASSERT_EQ(size, WireFormat::ByteSize(message_set)); @@ -593,7 +599,7 @@ TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) { WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber, WireFormatLite::WIRETYPE_LENGTH_DELIMITED, &coded_output); - coded_output.WriteVarint32(message.ByteSize()); + coded_output.WriteVarint32(message.ByteSizeLong()); message.SerializeWithCachedSizes(&coded_output); // Write the type id. uint32 type_id = message.GetDescriptor()->extension(0)->number(); @@ -987,7 +993,7 @@ class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test { void TestSerialization(Proto* message, const std::string& expected) { SetProto3PrimitiveRepeatedFields(message); - int size = message->ByteSize(); + size_t size = message->ByteSizeLong(); // Serialize using the generated code. std::string generated_data; @@ -997,7 +1003,7 @@ class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test { message->SerializeWithCachedSizes(&output); ASSERT_FALSE(output.HadError()); } - EXPECT_TRUE(expected == generated_data); + EXPECT_TRUE(TestUtil::EqualsToSerialized(*message, generated_data)); // Serialize using the dynamic code. std::string dynamic_data; @@ -1520,3 +1526,5 @@ TEST(RepeatedVarint, Enum) { } // namespace internal } // namespace protobuf } // namespace google + +#include diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index abb68fae7903..8274cec9f404 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -14,6 +14,8 @@ #include // @@protoc_insertion_point(includes) #include + +PROTOBUF_PRAGMA_INIT_SEG PROTOBUF_NAMESPACE_OPEN class DoubleValueDefaultTypeInternal { public: @@ -60,7 +62,6 @@ static void InitDefaultsscc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto( new (ptr) PROTOBUF_NAMESPACE_ID::BoolValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::BoolValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BoolValue_google_2fprotobuf_2fwrappers_2eproto = @@ -74,7 +75,6 @@ static void InitDefaultsscc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::BytesValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::BytesValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_BytesValue_google_2fprotobuf_2fwrappers_2eproto = @@ -88,7 +88,6 @@ static void InitDefaultsscc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::DoubleValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::DoubleValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_DoubleValue_google_2fprotobuf_2fwrappers_2eproto = @@ -102,7 +101,6 @@ static void InitDefaultsscc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::FloatValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::FloatValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_FloatValue_google_2fprotobuf_2fwrappers_2eproto = @@ -116,7 +114,6 @@ static void InitDefaultsscc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::Int32Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Int32Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Int32Value_google_2fprotobuf_2fwrappers_2eproto = @@ -130,7 +127,6 @@ static void InitDefaultsscc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto new (ptr) PROTOBUF_NAMESPACE_ID::Int64Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::Int64Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_Int64Value_google_2fprotobuf_2fwrappers_2eproto = @@ -144,7 +140,6 @@ static void InitDefaultsscc_info_StringValue_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::StringValue(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::StringValue::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_StringValue_google_2fprotobuf_2fwrappers_2eproto = @@ -158,7 +153,6 @@ static void InitDefaultsscc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::UInt32Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UInt32Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UInt32Value_google_2fprotobuf_2fwrappers_2eproto = @@ -172,7 +166,6 @@ static void InitDefaultsscc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eprot new (ptr) PROTOBUF_NAMESPACE_ID::UInt64Value(); ::PROTOBUF_NAMESPACE_ID::internal::OnShutdownDestroyMessage(ptr); } - PROTOBUF_NAMESPACE_ID::UInt64Value::InitAsDefaultInstance(); } PROTOBUF_EXPORT ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo<0> scc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eproto = @@ -270,11 +263,11 @@ const char descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto[] PROT "e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013" "UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022" "\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001" - " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B|\n\023com" - ".google.protobufB\rWrappersProtoP\001Z*githu" - "b.com/golang/protobuf/ptypes/wrappers\370\001\001" - "\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypesb" - "\006proto3" + " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014B\203\001\n\023co" + "m.google.protobufB\rWrappersProtoP\001Z1goog" + "le.golang.org/protobuf/types/known/wrapp" + "erspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKno" + "wnTypesb\006proto3" ; static const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable*const descriptor_table_google_2fprotobuf_2fwrappers_2eproto_deps[1] = { }; @@ -290,42 +283,32 @@ static ::PROTOBUF_NAMESPACE_ID::internal::SCCInfoBase*const descriptor_table_goo &scc_info_UInt64Value_google_2fprotobuf_2fwrappers_2eproto.base, }; static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once; -static bool descriptor_table_google_2fprotobuf_2fwrappers_2eproto_initialized = false; const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fwrappers_2eproto = { - &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_initialized, descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto", 447, + false, false, descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto, "google/protobuf/wrappers.proto", 455, &descriptor_table_google_2fprotobuf_2fwrappers_2eproto_once, descriptor_table_google_2fprotobuf_2fwrappers_2eproto_sccs, descriptor_table_google_2fprotobuf_2fwrappers_2eproto_deps, 9, 0, schemas, file_default_instances, TableStruct_google_2fprotobuf_2fwrappers_2eproto::offsets, file_level_metadata_google_2fprotobuf_2fwrappers_2eproto, 9, file_level_enum_descriptors_google_2fprotobuf_2fwrappers_2eproto, file_level_service_descriptors_google_2fprotobuf_2fwrappers_2eproto, }; // Force running AddDescriptors() at dynamic initialization time. -static bool dynamic_init_dummy_google_2fprotobuf_2fwrappers_2eproto = (static_cast(::PROTOBUF_NAMESPACE_ID::internal::AddDescriptors(&descriptor_table_google_2fprotobuf_2fwrappers_2eproto)), true); +PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fwrappers_2eproto(&descriptor_table_google_2fprotobuf_2fwrappers_2eproto); PROTOBUF_NAMESPACE_OPEN // =================================================================== -void DoubleValue::InitAsDefaultInstance() { -} class DoubleValue::_Internal { public: }; -DoubleValue::DoubleValue() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.DoubleValue) -} DoubleValue::DoubleValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.DoubleValue) } DoubleValue::DoubleValue(const DoubleValue& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_ = from.value_; // @@protoc_insertion_point(copy_constructor:google.protobuf.DoubleValue) } @@ -337,10 +320,11 @@ void DoubleValue::SharedCtor() { DoubleValue::~DoubleValue() { // @@protoc_insertion_point(destructor:google.protobuf.DoubleValue) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void DoubleValue::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void DoubleValue::ArenaDtor(void* object) { @@ -365,12 +349,11 @@ void DoubleValue::Clear() { (void) cached_has_bits; value_ = 0; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* DoubleValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -389,7 +372,9 @@ const char* DoubleValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -417,7 +402,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* DoubleValue::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DoubleValue) return target; @@ -463,7 +448,7 @@ void DoubleValue::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void DoubleValue::MergeFrom(const DoubleValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -492,7 +477,7 @@ bool DoubleValue::IsInitialized() const { void DoubleValue::InternalSwap(DoubleValue* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(value_, other->value_); } @@ -503,28 +488,19 @@ ::PROTOBUF_NAMESPACE_ID::Metadata DoubleValue::GetMetadata() const { // =================================================================== -void FloatValue::InitAsDefaultInstance() { -} class FloatValue::_Internal { public: }; -FloatValue::FloatValue() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.FloatValue) -} FloatValue::FloatValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FloatValue) } FloatValue::FloatValue(const FloatValue& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_ = from.value_; // @@protoc_insertion_point(copy_constructor:google.protobuf.FloatValue) } @@ -536,10 +512,11 @@ void FloatValue::SharedCtor() { FloatValue::~FloatValue() { // @@protoc_insertion_point(destructor:google.protobuf.FloatValue) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void FloatValue::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void FloatValue::ArenaDtor(void* object) { @@ -564,12 +541,11 @@ void FloatValue::Clear() { (void) cached_has_bits; value_ = 0; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* FloatValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -588,7 +564,9 @@ const char* FloatValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -616,7 +594,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* FloatValue::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FloatValue) return target; @@ -662,7 +640,7 @@ void FloatValue::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void FloatValue::MergeFrom(const FloatValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -691,7 +669,7 @@ bool FloatValue::IsInitialized() const { void FloatValue::InternalSwap(FloatValue* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(value_, other->value_); } @@ -702,28 +680,19 @@ ::PROTOBUF_NAMESPACE_ID::Metadata FloatValue::GetMetadata() const { // =================================================================== -void Int64Value::InitAsDefaultInstance() { -} class Int64Value::_Internal { public: }; -Int64Value::Int64Value() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Int64Value) -} Int64Value::Int64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Int64Value) } Int64Value::Int64Value(const Int64Value& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_ = from.value_; // @@protoc_insertion_point(copy_constructor:google.protobuf.Int64Value) } @@ -735,10 +704,11 @@ void Int64Value::SharedCtor() { Int64Value::~Int64Value() { // @@protoc_insertion_point(destructor:google.protobuf.Int64Value) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Int64Value::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void Int64Value::ArenaDtor(void* object) { @@ -763,12 +733,11 @@ void Int64Value::Clear() { (void) cached_has_bits; value_ = PROTOBUF_LONGLONG(0); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Int64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -787,7 +756,9 @@ const char* Int64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -815,7 +786,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Int64Value::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int64Value) return target; @@ -863,7 +834,7 @@ void Int64Value::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Int64Value::MergeFrom(const Int64Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -892,7 +863,7 @@ bool Int64Value::IsInitialized() const { void Int64Value::InternalSwap(Int64Value* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(value_, other->value_); } @@ -903,28 +874,19 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Int64Value::GetMetadata() const { // =================================================================== -void UInt64Value::InitAsDefaultInstance() { -} class UInt64Value::_Internal { public: }; -UInt64Value::UInt64Value() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.UInt64Value) -} UInt64Value::UInt64Value(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt64Value) } UInt64Value::UInt64Value(const UInt64Value& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_ = from.value_; // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt64Value) } @@ -936,10 +898,11 @@ void UInt64Value::SharedCtor() { UInt64Value::~UInt64Value() { // @@protoc_insertion_point(destructor:google.protobuf.UInt64Value) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void UInt64Value::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void UInt64Value::ArenaDtor(void* object) { @@ -964,12 +927,11 @@ void UInt64Value::Clear() { (void) cached_has_bits; value_ = PROTOBUF_ULONGLONG(0); - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* UInt64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -988,7 +950,9 @@ const char* UInt64Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1016,7 +980,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* UInt64Value::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt64Value) return target; @@ -1064,7 +1028,7 @@ void UInt64Value::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void UInt64Value::MergeFrom(const UInt64Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1093,7 +1057,7 @@ bool UInt64Value::IsInitialized() const { void UInt64Value::InternalSwap(UInt64Value* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(value_, other->value_); } @@ -1104,28 +1068,19 @@ ::PROTOBUF_NAMESPACE_ID::Metadata UInt64Value::GetMetadata() const { // =================================================================== -void Int32Value::InitAsDefaultInstance() { -} class Int32Value::_Internal { public: }; -Int32Value::Int32Value() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.Int32Value) -} Int32Value::Int32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Int32Value) } Int32Value::Int32Value(const Int32Value& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_ = from.value_; // @@protoc_insertion_point(copy_constructor:google.protobuf.Int32Value) } @@ -1137,10 +1092,11 @@ void Int32Value::SharedCtor() { Int32Value::~Int32Value() { // @@protoc_insertion_point(destructor:google.protobuf.Int32Value) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void Int32Value::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void Int32Value::ArenaDtor(void* object) { @@ -1165,12 +1121,11 @@ void Int32Value::Clear() { (void) cached_has_bits; value_ = 0; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* Int32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1189,7 +1144,9 @@ const char* Int32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1217,7 +1174,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* Int32Value::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int32Value) return target; @@ -1265,7 +1222,7 @@ void Int32Value::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void Int32Value::MergeFrom(const Int32Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1294,7 +1251,7 @@ bool Int32Value::IsInitialized() const { void Int32Value::InternalSwap(Int32Value* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(value_, other->value_); } @@ -1305,28 +1262,19 @@ ::PROTOBUF_NAMESPACE_ID::Metadata Int32Value::GetMetadata() const { // =================================================================== -void UInt32Value::InitAsDefaultInstance() { -} class UInt32Value::_Internal { public: }; -UInt32Value::UInt32Value() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.UInt32Value) -} UInt32Value::UInt32Value(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.UInt32Value) } UInt32Value::UInt32Value(const UInt32Value& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_ = from.value_; // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt32Value) } @@ -1338,10 +1286,11 @@ void UInt32Value::SharedCtor() { UInt32Value::~UInt32Value() { // @@protoc_insertion_point(destructor:google.protobuf.UInt32Value) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void UInt32Value::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void UInt32Value::ArenaDtor(void* object) { @@ -1366,12 +1315,11 @@ void UInt32Value::Clear() { (void) cached_has_bits; value_ = 0u; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* UInt32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1390,7 +1338,9 @@ const char* UInt32Value::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1418,7 +1368,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* UInt32Value::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt32Value) return target; @@ -1466,7 +1416,7 @@ void UInt32Value::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void UInt32Value::MergeFrom(const UInt32Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1495,7 +1445,7 @@ bool UInt32Value::IsInitialized() const { void UInt32Value::InternalSwap(UInt32Value* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(value_, other->value_); } @@ -1506,28 +1456,19 @@ ::PROTOBUF_NAMESPACE_ID::Metadata UInt32Value::GetMetadata() const { // =================================================================== -void BoolValue::InitAsDefaultInstance() { -} class BoolValue::_Internal { public: }; -BoolValue::BoolValue() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.BoolValue) -} BoolValue::BoolValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.BoolValue) } BoolValue::BoolValue(const BoolValue& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_ = from.value_; // @@protoc_insertion_point(copy_constructor:google.protobuf.BoolValue) } @@ -1539,10 +1480,11 @@ void BoolValue::SharedCtor() { BoolValue::~BoolValue() { // @@protoc_insertion_point(destructor:google.protobuf.BoolValue) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void BoolValue::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); } void BoolValue::ArenaDtor(void* object) { @@ -1567,12 +1509,11 @@ void BoolValue::Clear() { (void) cached_has_bits; value_ = false; - _internal_metadata_.Clear(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* BoolValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1591,7 +1532,9 @@ const char* BoolValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID:: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1619,7 +1562,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* BoolValue::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BoolValue) return target; @@ -1665,7 +1608,7 @@ void BoolValue::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void BoolValue::MergeFrom(const BoolValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1694,7 +1637,7 @@ bool BoolValue::IsInitialized() const { void BoolValue::InternalSwap(BoolValue* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); swap(value_, other->value_); } @@ -1705,32 +1648,23 @@ ::PROTOBUF_NAMESPACE_ID::Metadata BoolValue::GetMetadata() const { // =================================================================== -void StringValue::InitAsDefaultInstance() { -} class StringValue::_Internal { public: }; -StringValue::StringValue() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.StringValue) -} StringValue::StringValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.StringValue) } StringValue::StringValue(const StringValue& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_value().empty()) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_value(), - GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), + GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.StringValue) } @@ -1743,10 +1677,11 @@ void StringValue::SharedCtor() { StringValue::~StringValue() { // @@protoc_insertion_point(destructor:google.protobuf.StringValue) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void StringValue::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } @@ -1771,13 +1706,12 @@ void StringValue::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - _internal_metadata_.Clear(); + value_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* StringValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -1798,7 +1732,9 @@ const char* StringValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -1830,7 +1766,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* StringValue::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.StringValue) return target; @@ -1878,7 +1814,7 @@ void StringValue::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void StringValue::MergeFrom(const StringValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -1907,9 +1843,8 @@ bool StringValue::IsInitialized() const { void StringValue::InternalSwap(StringValue* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - value_.Swap(&other->value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + value_.Swap(&other->value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } ::PROTOBUF_NAMESPACE_ID::Metadata StringValue::GetMetadata() const { @@ -1919,32 +1854,23 @@ ::PROTOBUF_NAMESPACE_ID::Metadata StringValue::GetMetadata() const { // =================================================================== -void BytesValue::InitAsDefaultInstance() { -} class BytesValue::_Internal { public: }; -BytesValue::BytesValue() - : ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) { - SharedCtor(); - // @@protoc_insertion_point(constructor:google.protobuf.BytesValue) -} BytesValue::BytesValue(::PROTOBUF_NAMESPACE_ID::Arena* arena) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(arena) { + : ::PROTOBUF_NAMESPACE_ID::Message(arena) { SharedCtor(); RegisterArenaDtor(arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.BytesValue) } BytesValue::BytesValue(const BytesValue& from) - : ::PROTOBUF_NAMESPACE_ID::Message(), - _internal_metadata_(nullptr) { - _internal_metadata_.MergeFrom(from._internal_metadata_); + : ::PROTOBUF_NAMESPACE_ID::Message() { + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_value().empty()) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_value(), - GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), + GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.BytesValue) } @@ -1957,10 +1883,11 @@ void BytesValue::SharedCtor() { BytesValue::~BytesValue() { // @@protoc_insertion_point(destructor:google.protobuf.BytesValue) SharedDtor(); + _internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } void BytesValue::SharedDtor() { - GOOGLE_DCHECK(GetArenaNoVirtual() == nullptr); + GOOGLE_DCHECK(GetArena() == nullptr); value_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } @@ -1985,13 +1912,12 @@ void BytesValue::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); - _internal_metadata_.Clear(); + value_.ClearToEmpty(); + _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } const char* BytesValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) { #define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure - ::PROTOBUF_NAMESPACE_ID::Arena* arena = GetArenaNoVirtual(); (void)arena; while (!ctx->Done(&ptr)) { ::PROTOBUF_NAMESPACE_ID::uint32 tag; ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag); @@ -2011,7 +1937,9 @@ const char* BytesValue::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID: ctx->SetLastTag(tag); goto success; } - ptr = UnknownFieldParse(tag, &_internal_metadata_, ptr, ctx); + ptr = UnknownFieldParse(tag, + _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(), + ptr, ctx); CHK_(ptr != nullptr); continue; } @@ -2039,7 +1967,7 @@ ::PROTOBUF_NAMESPACE_ID::uint8* BytesValue::_InternalSerialize( if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray( - _internal_metadata_.unknown_fields(), target, stream); + _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BytesValue) return target; @@ -2087,7 +2015,7 @@ void BytesValue::MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) { void BytesValue::MergeFrom(const BytesValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue) GOOGLE_DCHECK_NE(&from, this); - _internal_metadata_.MergeFrom(from._internal_metadata_); + _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); ::PROTOBUF_NAMESPACE_ID::uint32 cached_has_bits = 0; (void) cached_has_bits; @@ -2116,9 +2044,8 @@ bool BytesValue::IsInitialized() const { void BytesValue::InternalSwap(BytesValue* other) { using std::swap; - _internal_metadata_.Swap(&other->_internal_metadata_); - value_.Swap(&other->value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); + _internal_metadata_.Swap<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(&other->_internal_metadata_); + value_.Swap(&other->value_, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } ::PROTOBUF_NAMESPACE_ID::Metadata BytesValue::GetMetadata() const { diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index ebde03a63f8a..0edfe878c435 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -8,12 +8,12 @@ #include #include -#if PROTOBUF_VERSION < 3011000 +#if PROTOBUF_VERSION < 3014000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3011002 < PROTOBUF_MIN_PROTOC_VERSION +#if 3014000 < PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -25,8 +25,7 @@ #include #include #include -#include -#include +#include #include #include #include // IWYU pragma: export @@ -45,7 +44,7 @@ PROTOBUF_NAMESPACE_CLOSE struct PROTOBUF_EXPORT TableStruct_google_2fprotobuf_2fwrappers_2eproto { static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); - static const ::PROTOBUF_NAMESPACE_ID::internal::AuxillaryParseTableField aux[] + static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[] PROTOBUF_SECTION_VARIABLE(protodesc_cold); static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[9] PROTOBUF_SECTION_VARIABLE(protodesc_cold); @@ -98,10 +97,10 @@ PROTOBUF_NAMESPACE_OPEN // =================================================================== -class PROTOBUF_EXPORT DoubleValue : +class PROTOBUF_EXPORT DoubleValue PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DoubleValue) */ { public: - DoubleValue(); + inline DoubleValue() : DoubleValue(nullptr) {} virtual ~DoubleValue(); DoubleValue(const DoubleValue& from); @@ -115,7 +114,7 @@ class PROTOBUF_EXPORT DoubleValue : return *this; } inline DoubleValue& operator=(DoubleValue&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -123,12 +122,6 @@ class PROTOBUF_EXPORT DoubleValue : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -140,7 +133,6 @@ class PROTOBUF_EXPORT DoubleValue : } static const DoubleValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const DoubleValue* internal_default_instance() { return reinterpret_cast( &_DoubleValue_default_instance_); @@ -153,7 +145,7 @@ class PROTOBUF_EXPORT DoubleValue : } inline void Swap(DoubleValue* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -161,7 +153,7 @@ class PROTOBUF_EXPORT DoubleValue : } void UnsafeArenaSwap(DoubleValue* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -201,13 +193,6 @@ class PROTOBUF_EXPORT DoubleValue : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -239,7 +224,6 @@ class PROTOBUF_EXPORT DoubleValue : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -249,10 +233,10 @@ class PROTOBUF_EXPORT DoubleValue : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT FloatValue : +class PROTOBUF_EXPORT FloatValue PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FloatValue) */ { public: - FloatValue(); + inline FloatValue() : FloatValue(nullptr) {} virtual ~FloatValue(); FloatValue(const FloatValue& from); @@ -266,7 +250,7 @@ class PROTOBUF_EXPORT FloatValue : return *this; } inline FloatValue& operator=(FloatValue&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -274,12 +258,6 @@ class PROTOBUF_EXPORT FloatValue : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -291,7 +269,6 @@ class PROTOBUF_EXPORT FloatValue : } static const FloatValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const FloatValue* internal_default_instance() { return reinterpret_cast( &_FloatValue_default_instance_); @@ -304,7 +281,7 @@ class PROTOBUF_EXPORT FloatValue : } inline void Swap(FloatValue* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -312,7 +289,7 @@ class PROTOBUF_EXPORT FloatValue : } void UnsafeArenaSwap(FloatValue* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -352,13 +329,6 @@ class PROTOBUF_EXPORT FloatValue : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -390,7 +360,6 @@ class PROTOBUF_EXPORT FloatValue : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -400,10 +369,10 @@ class PROTOBUF_EXPORT FloatValue : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Int64Value : +class PROTOBUF_EXPORT Int64Value PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int64Value) */ { public: - Int64Value(); + inline Int64Value() : Int64Value(nullptr) {} virtual ~Int64Value(); Int64Value(const Int64Value& from); @@ -417,7 +386,7 @@ class PROTOBUF_EXPORT Int64Value : return *this; } inline Int64Value& operator=(Int64Value&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -425,12 +394,6 @@ class PROTOBUF_EXPORT Int64Value : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -442,7 +405,6 @@ class PROTOBUF_EXPORT Int64Value : } static const Int64Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Int64Value* internal_default_instance() { return reinterpret_cast( &_Int64Value_default_instance_); @@ -455,7 +417,7 @@ class PROTOBUF_EXPORT Int64Value : } inline void Swap(Int64Value* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -463,7 +425,7 @@ class PROTOBUF_EXPORT Int64Value : } void UnsafeArenaSwap(Int64Value* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -503,13 +465,6 @@ class PROTOBUF_EXPORT Int64Value : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -541,7 +496,6 @@ class PROTOBUF_EXPORT Int64Value : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -551,10 +505,10 @@ class PROTOBUF_EXPORT Int64Value : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT UInt64Value : +class PROTOBUF_EXPORT UInt64Value PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt64Value) */ { public: - UInt64Value(); + inline UInt64Value() : UInt64Value(nullptr) {} virtual ~UInt64Value(); UInt64Value(const UInt64Value& from); @@ -568,7 +522,7 @@ class PROTOBUF_EXPORT UInt64Value : return *this; } inline UInt64Value& operator=(UInt64Value&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -576,12 +530,6 @@ class PROTOBUF_EXPORT UInt64Value : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -593,7 +541,6 @@ class PROTOBUF_EXPORT UInt64Value : } static const UInt64Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UInt64Value* internal_default_instance() { return reinterpret_cast( &_UInt64Value_default_instance_); @@ -606,7 +553,7 @@ class PROTOBUF_EXPORT UInt64Value : } inline void Swap(UInt64Value* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -614,7 +561,7 @@ class PROTOBUF_EXPORT UInt64Value : } void UnsafeArenaSwap(UInt64Value* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -654,13 +601,6 @@ class PROTOBUF_EXPORT UInt64Value : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -692,7 +632,6 @@ class PROTOBUF_EXPORT UInt64Value : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -702,10 +641,10 @@ class PROTOBUF_EXPORT UInt64Value : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Int32Value : +class PROTOBUF_EXPORT Int32Value PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Int32Value) */ { public: - Int32Value(); + inline Int32Value() : Int32Value(nullptr) {} virtual ~Int32Value(); Int32Value(const Int32Value& from); @@ -719,7 +658,7 @@ class PROTOBUF_EXPORT Int32Value : return *this; } inline Int32Value& operator=(Int32Value&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -727,12 +666,6 @@ class PROTOBUF_EXPORT Int32Value : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -744,7 +677,6 @@ class PROTOBUF_EXPORT Int32Value : } static const Int32Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const Int32Value* internal_default_instance() { return reinterpret_cast( &_Int32Value_default_instance_); @@ -757,7 +689,7 @@ class PROTOBUF_EXPORT Int32Value : } inline void Swap(Int32Value* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -765,7 +697,7 @@ class PROTOBUF_EXPORT Int32Value : } void UnsafeArenaSwap(Int32Value* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -805,13 +737,6 @@ class PROTOBUF_EXPORT Int32Value : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -843,7 +768,6 @@ class PROTOBUF_EXPORT Int32Value : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -853,10 +777,10 @@ class PROTOBUF_EXPORT Int32Value : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT UInt32Value : +class PROTOBUF_EXPORT UInt32Value PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UInt32Value) */ { public: - UInt32Value(); + inline UInt32Value() : UInt32Value(nullptr) {} virtual ~UInt32Value(); UInt32Value(const UInt32Value& from); @@ -870,7 +794,7 @@ class PROTOBUF_EXPORT UInt32Value : return *this; } inline UInt32Value& operator=(UInt32Value&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -878,12 +802,6 @@ class PROTOBUF_EXPORT UInt32Value : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -895,7 +813,6 @@ class PROTOBUF_EXPORT UInt32Value : } static const UInt32Value& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const UInt32Value* internal_default_instance() { return reinterpret_cast( &_UInt32Value_default_instance_); @@ -908,7 +825,7 @@ class PROTOBUF_EXPORT UInt32Value : } inline void Swap(UInt32Value* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -916,7 +833,7 @@ class PROTOBUF_EXPORT UInt32Value : } void UnsafeArenaSwap(UInt32Value* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -956,13 +873,6 @@ class PROTOBUF_EXPORT UInt32Value : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -994,7 +904,6 @@ class PROTOBUF_EXPORT UInt32Value : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1004,10 +913,10 @@ class PROTOBUF_EXPORT UInt32Value : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT BoolValue : +class PROTOBUF_EXPORT BoolValue PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BoolValue) */ { public: - BoolValue(); + inline BoolValue() : BoolValue(nullptr) {} virtual ~BoolValue(); BoolValue(const BoolValue& from); @@ -1021,7 +930,7 @@ class PROTOBUF_EXPORT BoolValue : return *this; } inline BoolValue& operator=(BoolValue&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1029,12 +938,6 @@ class PROTOBUF_EXPORT BoolValue : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1046,7 +949,6 @@ class PROTOBUF_EXPORT BoolValue : } static const BoolValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const BoolValue* internal_default_instance() { return reinterpret_cast( &_BoolValue_default_instance_); @@ -1059,7 +961,7 @@ class PROTOBUF_EXPORT BoolValue : } inline void Swap(BoolValue* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1067,7 +969,7 @@ class PROTOBUF_EXPORT BoolValue : } void UnsafeArenaSwap(BoolValue* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1107,13 +1009,6 @@ class PROTOBUF_EXPORT BoolValue : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1145,7 +1040,6 @@ class PROTOBUF_EXPORT BoolValue : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1155,10 +1049,10 @@ class PROTOBUF_EXPORT BoolValue : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT StringValue : +class PROTOBUF_EXPORT StringValue PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.StringValue) */ { public: - StringValue(); + inline StringValue() : StringValue(nullptr) {} virtual ~StringValue(); StringValue(const StringValue& from); @@ -1172,7 +1066,7 @@ class PROTOBUF_EXPORT StringValue : return *this; } inline StringValue& operator=(StringValue&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1180,12 +1074,6 @@ class PROTOBUF_EXPORT StringValue : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1197,7 +1085,6 @@ class PROTOBUF_EXPORT StringValue : } static const StringValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const StringValue* internal_default_instance() { return reinterpret_cast( &_StringValue_default_instance_); @@ -1210,7 +1097,7 @@ class PROTOBUF_EXPORT StringValue : } inline void Swap(StringValue* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1218,7 +1105,7 @@ class PROTOBUF_EXPORT StringValue : } void UnsafeArenaSwap(StringValue* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1258,13 +1145,6 @@ class PROTOBUF_EXPORT StringValue : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1293,15 +1173,6 @@ class PROTOBUF_EXPORT StringValue : std::string* mutable_value(); std::string* release_value(); void set_allocated_value(std::string* value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_value( - std::string* value); private: const std::string& _internal_value() const; void _internal_set_value(const std::string& value); @@ -1312,7 +1183,6 @@ class PROTOBUF_EXPORT StringValue : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1322,10 +1192,10 @@ class PROTOBUF_EXPORT StringValue : }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT BytesValue : +class PROTOBUF_EXPORT BytesValue PROTOBUF_FINAL : public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.BytesValue) */ { public: - BytesValue(); + inline BytesValue() : BytesValue(nullptr) {} virtual ~BytesValue(); BytesValue(const BytesValue& from); @@ -1339,7 +1209,7 @@ class PROTOBUF_EXPORT BytesValue : return *this; } inline BytesValue& operator=(BytesValue&& from) noexcept { - if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (GetArena() == from.GetArena()) { if (this != &from) InternalSwap(&from); } else { CopyFrom(from); @@ -1347,12 +1217,6 @@ class PROTOBUF_EXPORT BytesValue : return *this; } - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArena() const final { - return GetArenaNoVirtual(); - } - inline void* GetMaybeArenaPointer() const final { - return MaybeArenaPtr(); - } static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() { return GetDescriptor(); } @@ -1364,7 +1228,6 @@ class PROTOBUF_EXPORT BytesValue : } static const BytesValue& default_instance(); - static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY static inline const BytesValue* internal_default_instance() { return reinterpret_cast( &_BytesValue_default_instance_); @@ -1377,7 +1240,7 @@ class PROTOBUF_EXPORT BytesValue : } inline void Swap(BytesValue* other) { if (other == this) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArena() == other->GetArena()) { InternalSwap(other); } else { ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other); @@ -1385,7 +1248,7 @@ class PROTOBUF_EXPORT BytesValue : } void UnsafeArenaSwap(BytesValue* other) { if (other == this) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + GOOGLE_DCHECK(GetArena() == other->GetArena()); InternalSwap(other); } @@ -1425,13 +1288,6 @@ class PROTOBUF_EXPORT BytesValue : private: static void ArenaDtor(void* object); inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena); - private: - inline ::PROTOBUF_NAMESPACE_ID::Arena* GetArenaNoVirtual() const { - return _internal_metadata_.arena(); - } - inline void* MaybeArenaPtr() const { - return _internal_metadata_.raw_arena_ptr(); - } public: ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final; @@ -1460,15 +1316,6 @@ class PROTOBUF_EXPORT BytesValue : std::string* mutable_value(); std::string* release_value(); void set_allocated_value(std::string* value); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - std::string* unsafe_arena_release_value(); - GOOGLE_PROTOBUF_RUNTIME_DEPRECATED("The unsafe_arena_ accessors for" - " string fields are deprecated and will be removed in a" - " future release.") - void unsafe_arena_set_allocated_value( - std::string* value); private: const std::string& _internal_value() const; void _internal_set_value(const std::string& value); @@ -1479,7 +1326,6 @@ class PROTOBUF_EXPORT BytesValue : private: class _Internal; - ::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_; template friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -1668,7 +1514,7 @@ inline void BoolValue::set_value(bool value) { // string value = 1; inline void StringValue::clear_value() { - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + value_.ClearToEmpty(); } inline const std::string& StringValue::value() const { // @@protoc_insertion_point(field_get:google.protobuf.StringValue.value) @@ -1687,36 +1533,34 @@ inline const std::string& StringValue::_internal_value() const { } inline void StringValue::_internal_set_value(const std::string& value) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void StringValue::set_value(std::string&& value) { value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.StringValue.value) } inline void StringValue::set_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.StringValue.value) } inline void StringValue::set_value(const char* value, size_t size) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.StringValue.value) } inline std::string* StringValue::_internal_mutable_value() { - return value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* StringValue::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value) - - return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void StringValue::set_allocated_value(std::string* value) { if (value != nullptr) { @@ -1725,28 +1569,9 @@ inline void StringValue::set_allocated_value(std::string* value) { } value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value) } -inline std::string* StringValue::unsafe_arena_release_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.StringValue.value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return value_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void StringValue::unsafe_arena_set_allocated_value( - std::string* value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (value != nullptr) { - - } else { - - } - value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - value, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.StringValue.value) -} // ------------------------------------------------------------------- @@ -1754,7 +1579,7 @@ inline void StringValue::unsafe_arena_set_allocated_value( // bytes value = 1; inline void BytesValue::clear_value() { - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + value_.ClearToEmpty(); } inline const std::string& BytesValue::value() const { // @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value) @@ -1773,36 +1598,34 @@ inline const std::string& BytesValue::_internal_value() const { } inline void BytesValue::_internal_set_value(const std::string& value) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void BytesValue::set_value(std::string&& value) { value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArenaNoVirtual()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.BytesValue.value) } inline void BytesValue::set_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.BytesValue.value) } inline void BytesValue::set_value(const void* value, size_t size) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( - reinterpret_cast(value), size), GetArenaNoVirtual()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( + reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.BytesValue.value) } inline std::string* BytesValue::_internal_mutable_value() { - return value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* BytesValue::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value) - - return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaNoVirtual()); + return value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } inline void BytesValue::set_allocated_value(std::string* value) { if (value != nullptr) { @@ -1811,28 +1634,9 @@ inline void BytesValue::set_allocated_value(std::string* value) { } value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, - GetArenaNoVirtual()); + GetArena()); // @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value) } -inline std::string* BytesValue::unsafe_arena_release_value() { - // @@protoc_insertion_point(field_unsafe_arena_release:google.protobuf.BytesValue.value) - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - - return value_.UnsafeArenaRelease(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - GetArenaNoVirtual()); -} -inline void BytesValue::unsafe_arena_set_allocated_value( - std::string* value) { - GOOGLE_DCHECK(GetArenaNoVirtual() != nullptr); - if (value != nullptr) { - - } else { - - } - value_.UnsafeArenaSetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - value, GetArenaNoVirtual()); - // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.BytesValue.value) -} #ifdef __GNUC__ #pragma GCC diagnostic pop diff --git a/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto index 9ee41e384ac7..d49dd53c8d8f 100644 --- a/src/google/protobuf/wrappers.proto +++ b/src/google/protobuf/wrappers.proto @@ -44,7 +44,7 @@ package google.protobuf; option csharp_namespace = "Google.Protobuf.WellKnownTypes"; option cc_enable_arenas = true; -option go_package = "github.com/golang/protobuf/ptypes/wrappers"; +option go_package = "google.golang.org/protobuf/types/known/wrapperspb"; option java_package = "com.google.protobuf"; option java_outer_classname = "WrappersProto"; option java_multiple_files = true; diff --git a/tests.sh b/tests.sh index 77039d6c0ddd..6d63aad30d0d 100755 --- a/tests.sh +++ b/tests.sh @@ -63,7 +63,8 @@ build_cpp_distcheck() { # List all files that should be included in the distribution package. git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\|src/google/protobuf/.*\.proto\)" |\ grep -v ".gitignore" | grep -v "java/compatibility_tests" | grep -v "java/lite/proguard.pgcfg" |\ - grep -v "python/compatibility_tests" | grep -v "csharp/compatibility_tests" > dist.lst + grep -v "python/compatibility_tests" | grep -v "python/docs" | grep -v "python/.repo-metadata.json" |\ + grep -v "python/protobuf_distutils" | grep -v "csharp/compatibility_tests" > dist.lst # Unzip the dist tar file. DIST=`ls *.tar.gz` tar -xf $DIST @@ -162,10 +163,13 @@ build_golang() { export GOPATH="$HOME/gocode" mkdir -p "$GOPATH/src/github.com/protocolbuffers" + mkdir -p "$GOPATH/src/github.com/golang" rm -f "$GOPATH/src/github.com/protocolbuffers/protobuf" + rm -f "$GOPATH/src/github.com/golang/protobuf" ln -s "`pwd`" "$GOPATH/src/github.com/protocolbuffers/protobuf" export PATH="$GOPATH/bin:$PATH" - go get github.com/golang/protobuf/protoc-gen-go + (cd $GOPATH/src/github.com/golang && git clone https://github.com/golang/protobuf.git && cd protobuf && git checkout v1.3.5) + go install github.com/golang/protobuf/protoc-gen-go cd examples && PROTO_PATH="-I../src -I." make gotest && cd .. } @@ -301,8 +305,6 @@ build_objectivec_tvos_release() { } build_objectivec_cocoapods_integration() { - # Update pod to the latest version. - gem install cocoapods --no_document objectivec/Tests/CocoaPods/run_tests.sh } @@ -312,9 +314,9 @@ build_python() { if [ $(uname -s) == "Linux" ]; then envlist=py\{27,33,34,35,36\}-python else - envlist=py27-python + envlist=py\{27,36\}-python fi - tox -e $envlist + python -m tox -e $envlist cd .. } @@ -322,7 +324,7 @@ build_python_version() { internal_build_cpp cd python envlist=$1 - tox -e $envlist + python -m tox -e $envlist cd .. } @@ -362,7 +364,7 @@ build_python_cpp() { if [ $(uname -s) == "Linux" ]; then envlist=py\{27,33,34,35,36\}-cpp else - envlist=py27-cpp + envlist=py\{27,36\}-cpp fi tox -e $envlist cd .. @@ -435,198 +437,34 @@ build_ruby26() { internal_build_cpp # For conformance tests. cd ruby && bash travis-test.sh ruby-2.6.0 && cd .. } +build_ruby27() { + internal_build_cpp # For conformance tests. + cd ruby && bash travis-test.sh ruby-2.7.0 && cd .. +} build_javascript() { internal_build_cpp + NODE_VERSION=node-v12.16.3-darwin-x64 + NODE_TGZ="$NODE_VERSION.tar.gz" + pushd /tmp + curl -OL https://nodejs.org/dist/v12.16.3/$NODE_TGZ + tar zxvf $NODE_TGZ + export PATH=$PATH:`pwd`/$NODE_VERSION/bin + popd cd js && npm install && npm test && cd .. cd conformance && make test_nodejs && cd .. } -generate_php_test_proto() { - internal_build_cpp - pushd php/tests - # Generate test file - rm -rf generated - mkdir generated - ../../src/protoc --php_out=generated \ - -I../../src -I. \ - proto/empty/echo.proto \ - proto/test.proto \ - proto/test_include.proto \ - proto/test_no_namespace.proto \ - proto/test_prefix.proto \ - proto/test_php_namespace.proto \ - proto/test_empty_php_namespace.proto \ - proto/test_reserved_enum_lower.proto \ - proto/test_reserved_enum_upper.proto \ - proto/test_reserved_enum_value_lower.proto \ - proto/test_reserved_enum_value_upper.proto \ - proto/test_reserved_message_lower.proto \ - proto/test_reserved_message_upper.proto \ - proto/test_service.proto \ - proto/test_service_namespace.proto \ - proto/test_wrapper_type_setters.proto \ - proto/test_descriptors.proto - pushd ../../src - ./protoc --php_out=../php/tests/generated -I../php/tests -I. \ - ../php/tests/proto/test_import_descriptor_proto.proto - popd - popd -} - use_php() { VERSION=$1 export PATH=/usr/local/php-${VERSION}/bin:$PATH - export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$CPLUS_INCLUDE_PATH - export C_INCLUDE_PATH=/usr/local/php-${VERSION}/include/php/main:/usr/local/php-${VERSION}/include/php/:$C_INCLUDE_PATH - generate_php_test_proto + internal_build_cpp } use_php_zts() { VERSION=$1 export PATH=/usr/local/php-${VERSION}-zts/bin:$PATH - export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$CPLUS_INCLUDE_PATH - export C_INCLUDE_PATH=/usr/local/php-${VERSION}-zts/include/php/main:/usr/local/php-${VERSION}-zts/include/php/:$C_INCLUDE_PATH - generate_php_test_proto -} - -use_php_bc() { - VERSION=$1 - export PATH=/usr/local/php-${VERSION}-bc/bin:$PATH - export CPLUS_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$CPLUS_INCLUDE_PATH - export C_INCLUDE_PATH=/usr/local/php-${VERSION}-bc/include/php/main:/usr/local/php-${VERSION}-bc/include/php/:$C_INCLUDE_PATH - generate_php_test_proto -} - -build_php5.5() { - use_php 5.5 - - pushd php - rm -rf vendor - composer update - ./vendor/bin/phpunit - popd - pushd conformance - make test_php - popd -} - -build_php5.5_c() { - IS_64BIT=$1 - use_php 5.5 - pushd php/tests - /bin/bash ./test.sh 5.5 - popd - pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi - popd -} - -build_php5.5_mixed() { - use_php 5.5 - pushd php - rm -rf vendor - composer update - pushd tests - /bin/bash ./compile_extension.sh 5.5 - popd - php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit - popd -} - -build_php5.5_zts_c() { - IS_64BIT=$1 - use_php_zts 5.5 - cd php/tests && /bin/bash ./test.sh 5.5-zts && cd ../.. - pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi - popd -} - -build_php5.6() { - use_php 5.6 - pushd php - rm -rf vendor - composer update - ./vendor/bin/phpunit - popd - pushd conformance - make test_php - popd -} - -build_php5.6_c() { - IS_64BIT=$1 - use_php 5.6 - cd php/tests && /bin/bash ./test.sh 5.6 && cd ../.. - pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi - popd -} - -build_php5.6_mixed() { - use_php 5.6 - pushd php - rm -rf vendor - composer update - pushd tests - /bin/bash ./compile_extension.sh 5.6 - popd - php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit - popd -} - -build_php5.6_zts_c() { - IS_64BIT=$1 - use_php_zts 5.6 - cd php/tests && /bin/bash ./test.sh 5.6-zts && cd ../.. - pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi - popd -} - -build_php5.6_mac() { - generate_php_test_proto - # Install PHP - curl -s https://php-osx.liip.ch/install.sh | bash -s 5.6 - PHP_FOLDER=`find /usr/local -type d -name "php5-5.6*"` # The folder name may change upon time - export PATH="$PHP_FOLDER/bin:$PATH" - - # Install phpunit - curl https://phar.phpunit.de/phpunit-5.6.8.phar -L -o phpunit.phar - chmod +x phpunit.phar - sudo mv phpunit.phar /usr/local/bin/phpunit - - # Install valgrind - echo "#! /bin/bash" > valgrind - chmod ug+x valgrind - sudo mv valgrind /usr/local/bin/valgrind - - # Test - cd php/tests && /bin/bash ./test.sh && cd ../.. - pushd conformance - make test_php_c - popd + internal_build_cpp } build_php7.0() { @@ -634,24 +472,16 @@ build_php7.0() { pushd php rm -rf vendor composer update - ./vendor/bin/phpunit - popd - pushd conformance - make test_php + composer test popd + (cd conformance && make test_php) } build_php7.0_c() { - IS_64BIT=$1 use_php 7.0 - cd php/tests && /bin/bash ./test.sh 7.0 && cd ../.. + php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -660,38 +490,47 @@ build_php7.0_mixed() { pushd php rm -rf vendor composer update - pushd tests - /bin/bash ./compile_extension.sh 7.0 - popd + tests/compile_extension.sh + tests/generate_protos.sh php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit popd } build_php7.0_zts_c() { - IS_64BIT=$1 use_php_zts 7.0 - cd php/tests && /bin/bash ./test.sh 7.0-zts && cd ../.. + php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } build_php7.0_mac() { - generate_php_test_proto + internal_build_cpp # Install PHP curl -s https://php-osx.liip.ch/install.sh | bash -s 7.0 - PHP_FOLDER=`find /usr/local -type d -name "php7-7.0*"` # The folder name may change upon time + PHP_FOLDER=`find /usr/local -type d -name "php5-7.0*"` # The folder name may change upon time + test ! -z "$PHP_FOLDER" export PATH="$PHP_FOLDER/bin:$PATH" - # Install phpunit - curl https://phar.phpunit.de/phpunit-5.6.0.phar -L -o phpunit.phar - chmod +x phpunit.phar - sudo mv phpunit.phar /usr/local/bin/phpunit + # Install valgrind + echo "#! /bin/bash" > valgrind + chmod ug+x valgrind + sudo mv valgrind /usr/local/bin/valgrind + + # Test + php/tests/test.sh + (cd conformance && make test_php_c) +} + +build_php7.3_mac() { + internal_build_cpp + # Install PHP + # We can't test PHP 7.4 with these binaries yet: + # https://github.com/liip/php-osx/issues/276 + curl -s https://php-osx.liip.ch/install.sh | bash -s 7.3 + PHP_FOLDER=`find /usr/local -type d -name "php5-7.3*"` # The folder name may change upon time + test ! -z "$PHP_FOLDER" + export PATH="$PHP_FOLDER/bin:$PATH" # Install valgrind echo "#! /bin/bash" > valgrind @@ -699,10 +538,8 @@ build_php7.0_mac() { sudo mv valgrind /usr/local/bin/valgrind # Test - cd php/tests && /bin/bash ./test.sh && cd ../.. - pushd conformance - make test_php_c - popd + php/tests/test.sh + (cd conformance && make test_php_c) } build_php_compatibility() { @@ -712,9 +549,7 @@ build_php_compatibility() { build_php_multirequest() { use_php 7.4 - pushd php/tests - ./multirequest.sh - popd + php/tests/multirequest.sh } build_php7.1() { @@ -722,24 +557,16 @@ build_php7.1() { pushd php rm -rf vendor composer update - ./vendor/bin/phpunit - popd - pushd conformance - make test_php + composer test popd + (cd conformance && make test_php) } build_php7.1_c() { - IS_64BIT=$1 use_php 7.1 - cd php/tests && /bin/bash ./test.sh 7.1 && cd ../.. + php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -748,24 +575,17 @@ build_php7.1_mixed() { pushd php rm -rf vendor composer update - pushd tests - /bin/bash ./compile_extension.sh 7.1 - popd + tests/compile_extension.sh + tests/generate_protos.sh php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit popd } build_php7.1_zts_c() { - IS_64BIT=$1 use_php_zts 7.1 - cd php/tests && /bin/bash ./test.sh 7.1-zts && cd ../.. + php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c popd } @@ -774,27 +594,16 @@ build_php7.4() { pushd php rm -rf vendor composer update - ./vendor/bin/phpunit - popd - pushd conformance - make test_php + composer test popd + (cd conformance && make test_php) } build_php7.4_c() { - IS_64BIT=$1 use_php 7.4 - cd php/tests && /bin/bash ./test.sh 7.4 && cd ../.. + php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi - popd - pushd php/ext/google/protobuf - phpize --clean + make test_php_c popd } @@ -803,51 +612,69 @@ build_php7.4_mixed() { pushd php rm -rf vendor composer update - pushd tests - /bin/bash ./compile_extension.sh 7.4 - popd + tests/compile_extension.sh + tests/generate_protos.sh php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit popd - pushd php/ext/google/protobuf - phpize --clean - popd } build_php7.4_zts_c() { - IS_64BIT=$1 use_php_zts 7.4 - cd php/tests && /bin/bash ./test.sh 7.4-zts && cd ../.. + php/tests/test.sh pushd conformance - if [ "$IS_64BIT" = "true" ] - then - make test_php_c - else - make test_php_c_32 - fi + make test_php_c + popd +} + +build_php8.0() { + use_php 8.0 + pushd php + rm -rf vendor + composer update + composer test popd - pushd php/ext/google/protobuf - phpize --clean + (cd conformance && make test_php) +} + +build_php8.0_c() { + use_php 8.0 + php/tests/test.sh + pushd conformance + make test_php_c popd } +build_php8.0_c_64() { + build_php8.0_c true +} + +build_php8.0_mixed() { + use_php 8.0 + pushd php + rm -rf vendor + composer update + tests/compile_extension.sh + tests/generate_protos.sh + php -dextension=./ext/google/protobuf/modules/protobuf.so ./vendor/bin/phpunit + popd +} + +build_php8.0_all() { + build_php8.0 + build_php8.0_c_64 + build_php8.0_mixed +} + build_php_all_32() { - build_php5.5 - build_php5.6 build_php7.0 build_php7.1 build_php7.4 - build_php5.5_c $1 - build_php5.6_c $1 build_php7.0_c $1 build_php7.1_c $1 build_php7.4_c $1 - build_php5.5_mixed - build_php5.6_mixed build_php7.0_mixed build_php7.1_mixed build_php7.4_mixed - build_php5.5_zts_c $1 - build_php5.6_zts_c $1 build_php7.0_zts_c $1 build_php7.1_zts_c $1 build_php7.4_zts_c $1 @@ -890,12 +717,9 @@ Usage: $0 { cpp | ruby24 | ruby25 | ruby26 | + ruby27 | jruby | ruby_all | - php5.5 | - php5.5_c | - php5.6 | - php5.6_c | php7.0 | php7.0_c | php_compatibility | diff --git a/third_party/wyhash/LICENSE b/third_party/wyhash/LICENSE new file mode 100644 index 000000000000..471f09f4cfb5 --- /dev/null +++ b/third_party/wyhash/LICENSE @@ -0,0 +1,25 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + diff --git a/third_party/wyhash/wyhash.h b/third_party/wyhash/wyhash.h new file mode 100644 index 000000000000..5658f02df3ce --- /dev/null +++ b/third_party/wyhash/wyhash.h @@ -0,0 +1,145 @@ +/* Copyright 2020 王一 Wang Yi + This is free and unencumbered software released into the public domain. http://unlicense.org/ + See github.com/wangyi-fudan/wyhash/ LICENSE + */ +#ifndef wyhash_final_version +#define wyhash_final_version +//defines that change behavior +#ifndef WYHASH_CONDOM +#define WYHASH_CONDOM 1 //0: read 8 bytes before and after boundaries, dangerous but fastest. 1: normal valid behavior 2: extra protection against entropy loss (probability=2^-63), aka. "blind multiplication" +#endif +#define WYHASH_32BIT_MUM 0 //faster on 32 bit system +//includes +#include +#include +#if defined(_MSC_VER) && defined(_M_X64) + #include + #pragma intrinsic(_umul128) +#endif +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) + #define _likely_(x) __builtin_expect(x,1) + #define _unlikely_(x) __builtin_expect(x,0) +#else + #define _likely_(x) (x) + #define _unlikely_(x) (x) +#endif +//mum function +static inline uint64_t _wyrot(uint64_t x) { return (x>>32)|(x<<32); } +static inline void _wymum(uint64_t *A, uint64_t *B){ +#if(WYHASH_32BIT_MUM) + uint64_t hh=(*A>>32)*(*B>>32), hl=(*A>>32)*(unsigned)*B, lh=(unsigned)*A*(*B>>32), ll=(uint64_t)(unsigned)*A*(unsigned)*B; + #if(WYHASH_CONDOM>1) + *A^=_wyrot(hl)^hh; *B^=_wyrot(lh)^ll; + #else + *A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll; + #endif +#elif defined(__SIZEOF_INT128__) + __uint128_t r=*A; r*=*B; + #if(WYHASH_CONDOM>1) + *A^=(uint64_t)r; *B^=(uint64_t)(r>>64); + #else + *A=(uint64_t)r; *B=(uint64_t)(r>>64); + #endif +#elif defined(_MSC_VER) && defined(_M_X64) + #if(WYHASH_CONDOM>1) + uint64_t a, b; + a=_umul128(*A,*B,&b); + *A^=a; *B^=b; + #else + *A=_umul128(*A,*B,B); + #endif +#else + uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo; + uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t>32)+(rm1>>32)+c; + #if(WYHASH_CONDOM>1) + *A^=lo; *B^=hi; + #else + *A=lo; *B=hi; + #endif +#endif +} +static inline uint64_t _wymix(uint64_t A, uint64_t B){ _wymum(&A,&B); return A^B; } +//read functions +#ifndef WYHASH_LITTLE_ENDIAN + #if defined(_WIN32) || defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + #define WYHASH_LITTLE_ENDIAN 1 + #elif defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + #define WYHASH_LITTLE_ENDIAN 0 + #endif +#endif +#if (WYHASH_LITTLE_ENDIAN) +static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return v;} +static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return v;} +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__) +static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return __builtin_bswap64(v);} +static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return __builtin_bswap32(v);} +#elif defined(_MSC_VER) +static inline uint64_t _wyr8(const uint8_t *p) { uint64_t v; memcpy(&v, p, 8); return _byteswap_uint64(v);} +static inline uint64_t _wyr4(const uint8_t *p) { unsigned v; memcpy(&v, p, 4); return _byteswap_ulong(v);} +#endif +static inline uint64_t _wyr3(const uint8_t *p, unsigned k) { return (((uint64_t)p[0])<<16)|(((uint64_t)p[k>>1])<<8)|p[k-1];} +//wyhash function +static inline uint64_t _wyfinish16(const uint8_t *p, uint64_t len, uint64_t seed, const uint64_t *secret, uint64_t i){ +#if(WYHASH_CONDOM>0) + uint64_t a, b; + if(_likely_(i<=8)){ + if(_likely_(i>=4)){ a=_wyr4(p); b=_wyr4(p+i-4); } + else if (_likely_(i)){ a=_wyr3(p,i); b=0; } + else a=b=0; + } + else{ a=_wyr8(p); b=_wyr8(p+i-8); } + return _wymix(secret[1]^len,_wymix(a^secret[1], b^seed)); +#else + #define oneshot_shift ((i<8)*((8-i)<<3)) + return _wymix(secret[1]^len,_wymix((_wyr8(p)<>oneshot_shift)^seed)); +#endif +} + +static inline uint64_t _wyfinish(const uint8_t *p, uint64_t len, uint64_t seed, const uint64_t *secret, uint64_t i){ + if(_likely_(i<=16)) return _wyfinish16(p,len,seed,secret,i); + return _wyfinish(p+16,len,_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed),secret,i-16); +} + +static inline uint64_t wyhash(const void *key, uint64_t len, uint64_t seed, const uint64_t *secret){ + const uint8_t *p=(const uint8_t *)key; + uint64_t i=len; seed^=*secret; + if(_unlikely_(i>64)){ + uint64_t see1=seed; + do{ + seed=_wymix(_wyr8(p)^secret[1],_wyr8(p+8)^seed)^_wymix(_wyr8(p+16)^secret[2],_wyr8(p+24)^seed); + see1=_wymix(_wyr8(p+32)^secret[3],_wyr8(p+40)^see1)^_wymix(_wyr8(p+48)^secret[4],_wyr8(p+56)^see1); + p+=64; i-=64; + }while(i>64); + seed^=see1; + } + return _wyfinish(p,len,seed,secret,i); +} +//utility functions +const uint64_t _wyp[5] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull, 0x8ebc6af09c88c6e3ull, 0x589965cc75374cc3ull, 0x1d8e4e27c47d124full}; +static inline uint64_t wyhash64(uint64_t A, uint64_t B){ A^=_wyp[0]; B^=_wyp[1]; _wymum(&A,&B); return _wymix(A^_wyp[0],B^_wyp[1]);} +static inline uint64_t wyrand(uint64_t *seed){ *seed+=_wyp[0]; return _wymix(*seed,*seed^_wyp[1]);} +static inline double wy2u01(uint64_t r){ const double _wynorm=1.0/(1ull<<52); return (r>>12)*_wynorm;} +static inline double wy2gau(uint64_t r){ const double _wynorm=1.0/(1ull<<20); return ((r&0x1fffff)+((r>>21)&0x1fffff)+((r>>42)&0x1fffff))*_wynorm-3.0;} +static inline uint64_t wy2u0k(uint64_t r, uint64_t k){ _wymum(&r,&k); return k; } + +static inline void make_secret(uint64_t seed, uint64_t *secret){ + uint8_t c[] = {15, 23, 27, 29, 30, 39, 43, 45, 46, 51, 53, 54, 57, 58, 60, 71, 75, 77, 78, 83, 85, 86, 89, 90, 92, 99, 101, 102, 105, 106, 108, 113, 114, 116, 120, 135, 139, 141, 142, 147, 149, 150, 153, 154, 156, 163, 165, 166, 169, 170, 172, 177, 178, 180, 184, 195, 197, 198, 201, 202, 204, 209, 210, 212, 216, 225, 226, 228, 232, 240 }; + for(size_t i=0;i<5;i++){ + uint8_t ok; + do{ + ok=1; secret[i]=0; + for(size_t j=0;j<64;j+=8) secret[i]|=((uint64_t)c[wyrand(&seed)%sizeof(c)])<